1/*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include "codec_log_wrapper.h"
17#include "codec_dfx_service.h"
18#include "malloc.h"
19namespace OHOS {
20namespace HDI {
21namespace Codec {
22namespace V3_0 {
23#define ARGV_FLAG 1
24#define INPUT_PORT_INDEX 0
25#define OUTPUT_PORT_INDEX 1
26CodecDfxService CodecDfxService::dfxInstance_;
27HdfSBuf *CodecDfxService::reply_;
28
29int32_t CodecDfxService::GetCodecComponentListInfo(struct HdfSBuf *reply)
30{
31    CodecStateType state;
32    uint32_t inputBuffCount = 0;
33    uint32_t outputBuffCount = 0;
34    std::shared_ptr<OHOS::Codec::Omx::ComponentNode> dumpNode = nullptr;
35    std::map<uint32_t, sptr<ICodecComponent>> dumpMap = {};
36
37    GetInstance().managerService_->GetManagerMap(dumpMap);
38    if (dumpMap.empty()) {
39        CODEC_LOGE("get manager map failed!");
40        return HDF_ERR_INVALID_PARAM;
41    }
42    for (auto it : dumpMap) {
43        std::string dump = "compName = ";
44        CodecComponentService *componentService = reinterpret_cast<CodecComponentService *>(it.second.GetRefPtr());
45        dump.append(componentService->GetComponentCompName())
46            .append(", compId = ")
47            .append(std::to_string(it.first))
48            .append(", state = ");
49        componentService->GetComponentNode(dumpNode);
50        if (dumpNode == nullptr) {
51            CODEC_LOGE("get dumpNode failed!");
52            return HDF_ERR_INVALID_PARAM;
53        }
54        dumpNode->GetState(state);
55        dump.append(std::to_string(state));
56        dumpNode->GetBuffCount(inputBuffCount, outputBuffCount);
57        dump.append(", inputPortIndex = ")
58            .append(std::to_string(INPUT_PORT_INDEX))
59            .append(", inputBuffCount = ")
60            .append(std::to_string(inputBuffCount))
61            .append(", outputPortIndex = ")
62            .append(std::to_string(OUTPUT_PORT_INDEX))
63            .append(", outputBuffCount = ")
64            .append(std::to_string(outputBuffCount))
65            .append("\n");
66        if (!HdfSbufWriteString(reply, dump.c_str())) {
67            CODEC_LOGE("dump write Fail!");
68            return HDF_ERR_INVALID_PARAM;
69        }
70        if (!HdfSbufWriteString(reply, "------------------------------------------------------------------------ \n")) {
71            CODEC_LOGE("Split symbol write Fail!");
72            return HDF_ERR_INVALID_PARAM;
73        }
74        inputBuffCount = 0;
75        outputBuffCount = 0;
76        componentService = nullptr;
77    }
78    return HDF_SUCCESS;
79}
80
81void CodecDfxService::SetComponentManager(sptr<CodecComponentManagerService> manager)
82{
83    managerService_ = manager;
84}
85
86CodecDfxService& CodecDfxService::GetInstance()
87{
88    return dfxInstance_;
89}
90
91HdfSBuf* CodecDfxService::GetReply()
92{
93    return reply_;
94}
95
96static void WriteMemoryInfo(void *fp, const char *memInfo)
97{
98    if (memInfo == nullptr) {
99        return;
100    }
101    if (!HdfSbufWriteString(CodecDfxService::GetReply(), memInfo)) {
102        CODEC_LOGE("write memory info error!");
103    }
104}
105
106void CodecDfxService::GetCodecMemoryInfo()
107{
108    malloc_stats_print(WriteMemoryInfo, nullptr, nullptr);
109}
110
111int32_t CodecDfxService::DevCodecHostDump(struct HdfSBuf *data, struct HdfSBuf *reply)
112{
113    uint32_t argv = 0;
114    reply_ = reply;
115    (void)HdfSbufReadUint32(data, &argv);
116    if (argv != ARGV_FLAG) {
117        if (!HdfSbufWriteString(reply, "please enter -h for help! \n")) {
118            CODEC_LOGE("help write Fail!");
119            return HDF_ERR_INVALID_PARAM;
120        }
121        return HDF_SUCCESS;
122    }
123
124    const char *para = HdfSbufReadString(data);
125    if (para == nullptr) {
126        CODEC_LOGE("read string data failed");
127        return HDF_ERR_INVALID_PARAM;
128    }
129    if (strcmp(para, "-h") == EOK) {
130        if (!HdfSbufWriteString(reply, "-h: codec dump help! \n")) {
131            CODEC_LOGE("-h write Fail!");
132            return HDF_ERR_INVALID_PARAM;
133        }
134        if (!HdfSbufWriteString(reply, "-l: dump codec components info list! \n")) {
135            CODEC_LOGE("-l write Fail!");
136            return HDF_ERR_INVALID_PARAM;
137        }
138        return HDF_SUCCESS;
139    } else if (strcmp(para, "-l") == EOK) {
140        GetInstance().GetCodecComponentListInfo(reply);
141    } else if (strcmp(para, "-m") == EOK) {
142        GetInstance().GetCodecMemoryInfo();
143    } else {
144        HdfSbufWriteString(reply, "unknow param, please enter -h for help! \n");
145    }
146    return HDF_SUCCESS;
147}
148}  // namespace V3_0
149}  // namespace Codec
150}  // namespace HDI
151}  // namespace OHOS
152