1/*
2 * Copyright (c) 2024 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 "hidebug/hidebug.h"
17
18#include <memory>
19#include <vector>
20#include <unistd.h>
21
22#include "hidebug/hidebug_type.h"
23#include "hidebug_native_interface.h"
24#include "securec.h"
25
26double OH_HiDebug_GetAppCpuUsage()
27{
28    double cpuUsage = OHOS::HiviewDFX::HidebugNativeInterface::CreateInstance()->GetCpuUsage();
29    return cpuUsage;
30}
31
32double OH_HiDebug_GetSystemCpuUsage()
33{
34    auto cpuUsageOptional = OHOS::HiviewDFX::HidebugNativeInterface::CreateInstance()->GetSystemCpuUsage();
35    if (cpuUsageOptional.has_value()) {
36        return cpuUsageOptional.value();
37    }
38    return 0;
39}
40
41HiDebug_ThreadCpuUsagePtr OH_HiDebug_GetAppThreadCpuUsage()
42{
43    auto nativeInterface = OHOS::HiviewDFX::HidebugNativeInterface::CreateInstance();
44    if (!nativeInterface) {
45        return nullptr;
46    }
47    std::map<uint32_t, double> threadMap = nativeInterface->GetAppThreadCpuUsage();
48    HiDebug_ThreadCpuUsagePtr head = nullptr;
49    HiDebug_ThreadCpuUsagePtr prev = nullptr;
50    for (const auto[threadId, cpuUsage] : threadMap) {
51        HiDebug_ThreadCpuUsagePtr node = (HiDebug_ThreadCpuUsagePtr) malloc(sizeof(HiDebug_ThreadCpuUsage));
52        if (node == nullptr) {
53            continue;
54        }
55        node->threadId = threadId;
56        node->cpuUsage = cpuUsage;
57        node->next = nullptr;
58        if (prev == nullptr) {
59            head = node;
60        } else {
61            prev->next = node;
62        }
63        prev = node;
64    }
65    return head;
66}
67
68void OH_HiDebug_FreeThreadCpuUsage(HiDebug_ThreadCpuUsagePtr *threadCpuUsage)
69{
70    if (threadCpuUsage == nullptr || *threadCpuUsage == nullptr) {
71        return;
72    }
73    HiDebug_ThreadCpuUsagePtr node = *threadCpuUsage;
74    while (node != nullptr) {
75        HiDebug_ThreadCpuUsagePtr next = node->next;
76        free(node);
77        node = next;
78    }
79    *threadCpuUsage = nullptr;
80}
81
82void OH_HiDebug_GetAppMemoryLimit(HiDebug_MemoryLimit *memoryLimit)
83{
84    if (!memoryLimit) {
85        return;
86    }
87    auto nativeInterface = OHOS::HiviewDFX::HidebugNativeInterface::CreateInstance();
88    if (!nativeInterface) {
89        return;
90    }
91    auto collectResult = nativeInterface->GetAppMemoryLimit();
92    if (!collectResult) {
93        return;
94    }
95    memoryLimit->vssLimit = collectResult->vssLimit;
96    memoryLimit->rssLimit = collectResult->rssLimit;
97}
98
99void OH_HiDebug_GetAppNativeMemInfo(HiDebug_NativeMemInfo *nativeMemInfo)
100{
101    auto nativeInterface = OHOS::HiviewDFX::HidebugNativeInterface::CreateInstance();
102    if (!nativeMemInfo || !nativeInterface) {
103        return;
104    }
105    auto nativeMemoryInfo = nativeInterface->GetAppNativeMemInfo();
106    if (!nativeMemoryInfo) {
107        return;
108    }
109
110    nativeMemInfo->pss = static_cast<uint32_t>(nativeMemoryInfo->pss);
111    nativeMemInfo->vss = static_cast<uint32_t>(nativeMemoryInfo->vss);
112    nativeMemInfo->rss = static_cast<uint32_t>(nativeMemoryInfo->rss);
113    nativeMemInfo->sharedDirty = static_cast<uint32_t>(nativeMemoryInfo->sharedDirty);
114    nativeMemInfo->privateDirty = static_cast<uint32_t>(nativeMemoryInfo->privateDirty);
115    nativeMemInfo->sharedClean = static_cast<uint32_t>(nativeMemoryInfo->sharedClean);
116    nativeMemInfo->privateClean = static_cast<uint32_t>(nativeMemoryInfo->privateClean);
117}
118
119void OH_HiDebug_GetSystemMemInfo(HiDebug_SystemMemInfo *systemMemInfo)
120{
121    auto nativeInterface = OHOS::HiviewDFX::HidebugNativeInterface::CreateInstance();
122    if (!systemMemInfo || !nativeInterface) {
123        return;
124    }
125    auto sysMemInfo = nativeInterface->GetSystemMemInfo();
126    if (!sysMemInfo) {
127        return;
128    }
129
130    systemMemInfo->totalMem = static_cast<uint32_t>(sysMemInfo->memTotal);
131    systemMemInfo->freeMem = static_cast<uint32_t>(sysMemInfo->memFree);
132    systemMemInfo->availableMem = static_cast<uint32_t>(sysMemInfo->memAvailable);
133}
134
135HiDebug_ErrorCode OH_HiDebug_StartAppTraceCapture(HiDebug_TraceFlag flag,
136    uint64_t tags, uint32_t limitSize, char* fileName, uint32_t length)
137{
138    if (fileName == nullptr) {
139        return HIDEBUG_INVALID_ARGUMENT;
140    }
141    auto nativeInterface = OHOS::HiviewDFX::HidebugNativeInterface::CreateInstance();
142    if (!nativeInterface) {
143        return HIDEBUG_TRACE_ABNORMAL;
144    }
145    std::string file;
146    auto ret = nativeInterface->StartAppTraceCapture(tags, flag, limitSize, file);
147    if (ret != HIDEBUG_SUCCESS) {
148        return ret;
149    }
150    if (strcpy_s(fileName, length, file.c_str()) != EOK) {
151        nativeInterface->StopAppTraceCapture();
152        return HIDEBUG_INVALID_ARGUMENT;
153    }
154    return HIDEBUG_SUCCESS;
155}
156
157
158HiDebug_ErrorCode OH_HiDebug_StopAppTraceCapture()
159{
160    auto nativeInterface = OHOS::HiviewDFX::HidebugNativeInterface::CreateInstance();
161    if (!nativeInterface) {
162        return HIDEBUG_TRACE_ABNORMAL;
163    }
164    return nativeInterface->StopAppTraceCapture();
165}
166
167HiDebug_ErrorCode OH_HiDebug_GetGraphicsMemory(uint32_t *value)
168{
169    if (value == nullptr) {
170        return HIDEBUG_INVALID_ARGUMENT;
171    }
172    auto nativeInterface = OHOS::HiviewDFX::HidebugNativeInterface::CreateInstance();
173    if (!nativeInterface) {
174        return HIDEBUG_TRACE_ABNORMAL;
175    }
176    std::optional<int32_t> ret = nativeInterface->GetGraphicsMemory();
177    if (!ret.has_value() || ret < 0) {
178        return HIDEBUG_TRACE_ABNORMAL;
179    }
180    *value = static_cast<uint32_t>(ret.value());
181    return HIDEBUG_SUCCESS;
182}