• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) Huawei Technologies Co., Ltd. 2022. All rights reserved.
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 <codecvt>
17 #include <string>
18 #include <malloc.h>
19 #include <parameters.h>
20 
21 #include "application_context.h"
22 #include "context.h"
23 #include "directory_ex.h"
24 #include "faultlogger_client.h"
25 #include "file_ex.h"
26 #include "hiappevent_util.h"
27 #include "hidebug_native_interface.h"
28 #include "hidebug_util.h"
29 #include "hilog/log.h"
30 #include "iservice_registry.h"
31 #include "napi_hidebug_dump.h"
32 #include "napi_hidebug_init.h"
33 #include "napi/native_api.h"
34 #include "napi/native_node_api.h"
35 #include "native_engine/native_engine.h"
36 #include "refbase.h"
37 #include "system_ability_definition.h"
38 #include "napi_hidebug_vm.h"
39 #include "napi_util.h"
40 #include "error_code.h"
41 
42 namespace OHOS {
43 namespace HiviewDFX {
44 namespace {
45 #undef LOG_DOMAIN
46 #define LOG_DOMAIN 0xD002D0A
47 #undef LOG_TAG
48 #define LOG_TAG "HiDebug_NAPI"
49 constexpr int REMOVE_NAPI_WRAP_PARAM_COUNT = 2;
50 constexpr int NAME_LEN = 128;
51 constexpr int BYTE_2_KB_SHIFT_BITS = 10;
52 constexpr int FIRST_POS = 0;
53 constexpr int SECOND_POS = 1;
54 constexpr int THIRD_POS = 2;
55 constexpr int TRIM_LEVEL_MAX = 1;
56 constexpr int ENABLE_ARGS_NO_PARAMS = 0;
57 constexpr int ENABLE_ARGS_ONE_PARAMS = 1;
58 constexpr int ENABLE_ARGS_TWO_PARAMS = 2;
59 constexpr double DEFAULT_SAMPLE_RATE = 2500;
60 constexpr double DEFAULT_MAX_SIMUTANEOUS_ALLOCATIONS = 1000;
61 constexpr int DEFAULT_DURATION = 7;
62 constexpr auto SLASH_STR = "/";
63 constexpr auto JSON_FILE = ".json";
64 constexpr auto KEY_HIVIEW_DEVELOP_TYPE = "persist.hiview.leak_detector";
65 
66 struct GwpAsanParams {
67     bool alwaysEnabled = false;
68     double sampleRate = DEFAULT_SAMPLE_RATE;
69     double maxSimutaneousAllocations = DEFAULT_MAX_SIMUTANEOUS_ALLOCATIONS;
70     int32_t duration = DEFAULT_DURATION;
71 };
72 }
73 
GetDumpParam(napi_env env,napi_callback_info info,int & serviceId,int & fd,std::vector<std::u16string> & args)74 static bool GetDumpParam(napi_env env, napi_callback_info info,
75     int& serviceId, int& fd, std::vector<std::u16string>& args)
76 {
77     constexpr int valueNum = 3;
78     size_t argc = valueNum;
79     napi_value argv[valueNum] = {nullptr};
80     napi_value thisVar = nullptr;
81     void *data = nullptr;
82     napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
83     if (argc != valueNum) {
84         HILOG_ERROR(LOG_CORE, "invalid number = %{public}zu of params.", argc);
85         return false;
86     }
87     if (!GetNapiInt32Value(env, argv[FIRST_POS], serviceId)) {
88         HILOG_ERROR(LOG_CORE, "Get input serviceId failed.");
89         return false;
90     }
91     if (!GetNapiInt32Value(env, argv[SECOND_POS], fd)) {
92         HILOG_ERROR(LOG_CORE, "Get input fd failed.");
93         return false;
94     }
95     uint32_t arraySize = 0;
96     if (!GetNapiArrayLength(env, argv[THIRD_POS], arraySize)) {
97         HILOG_ERROR(LOG_CORE, "Get input args failed.");
98         return false;
99     }
100     for (uint32_t i = 0; i < arraySize; i++) {
101         napi_value jsValue = nullptr;
102         if (napi_get_element(env, argv[THIRD_POS], i, &jsValue) != napi_ok) {
103             HILOG_ERROR(LOG_CORE, "get_element -> Get input args failed.");
104             return false;
105         }
106         const size_t bufSize = 256;
107         size_t bufLen = 0;
108         char buf[bufSize] = {0};
109         if (napi_get_value_string_utf8(env, jsValue, buf, bufSize - 1, &bufLen) != napi_ok) {
110             HILOG_ERROR(LOG_CORE, "get_value -> Get input args failed.");
111             return false;
112         }
113         std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> strCnv;
114         args.push_back(strCnv.from_bytes(buf));
115     }
116     return true;
117 }
118 
GetTraceParam(napi_env env,napi_callback_info info,uint32_t & traceFlag,uint32_t & limitSize,std::vector<uint64_t> & tags)119 static bool GetTraceParam(napi_env env, napi_callback_info info,
120     uint32_t& traceFlag, uint32_t& limitSize, std::vector<uint64_t>& tags)
121 {
122     constexpr int valueNum = 3;
123     size_t argc = valueNum;
124     napi_value argv[valueNum] = {nullptr};
125     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
126     if (argc != valueNum) {
127         HILOG_ERROR(LOG_CORE, "invalid numbers of params!");
128         return false;
129     }
130     uint32_t arraySize = 0;
131     if (!GetNapiArrayLength(env, argv[FIRST_POS], arraySize)) {
132         HILOG_ERROR(LOG_CORE, "Get input tags failed.");
133         return false;
134     }
135     uint64_t tag = 0;
136     bool lossless = true;
137     for (uint32_t i = 0; i < arraySize; ++i) {
138         napi_value jsValue = nullptr;
139         if (napi_get_element(env, argv[FIRST_POS], i, &jsValue) != napi_ok) {
140             HILOG_ERROR(LOG_CORE, "get_element -> Get input tags failed.");
141             return false;
142         }
143         if (napi_get_value_bigint_uint64(env, jsValue, &tag, &lossless) != napi_ok) {
144             HILOG_ERROR(LOG_CORE, "Get input tags failed.");
145             return false;
146         }
147         tags.push_back(tag);
148     }
149     if (!GetNapiUint32Value(env, argv[SECOND_POS], traceFlag)) {
150         HILOG_ERROR(LOG_CORE, "Get input traceFlag failed.");
151         return false;
152     }
153     if (!GetNapiUint32Value(env, argv[THIRD_POS], limitSize)) {
154         HILOG_ERROR(LOG_CORE, "Get input limitSize failed.");
155         return false;
156     }
157     return true;
158 }
159 
StartProfiling(napi_env env,napi_callback_info info)160 napi_value StartProfiling(napi_env env, napi_callback_info info)
161 {
162     ApiInvokeRecorder apiInvokeRecorder("startProfiling");
163     std::string fileName = GetFileNameParam(env, info);
164     auto context = OHOS::AbilityRuntime::Context::GetApplicationContext();
165     if (context == nullptr) {
166         apiInvokeRecorder.SetErrorCode(ErrorCode::SYSTEM_STATUS_ABNORMAL);
167         return CreateErrorMessage(env, "Get ApplicationContext failed.");
168     }
169     std::string filesDir = context->GetFilesDir();
170     if (filesDir.empty()) {
171         apiInvokeRecorder.SetErrorCode(ErrorCode::SYSTEM_STATUS_ABNORMAL);
172         return CreateErrorMessage(env, "Get App files dir failed.");
173     }
174     std::string filePath = filesDir + SLASH_STR + fileName + JSON_FILE;
175     if (!IsLegalPath(filePath)) {
176         apiInvokeRecorder.SetErrorCode(ErrorCode::SYSTEM_STATUS_ABNORMAL);
177         return CreateErrorMessage(env, "input fileName is illegal.");
178     }
179     if (!CreateFile(filePath)) {
180         apiInvokeRecorder.SetErrorCode(ErrorCode::SYSTEM_STATUS_ABNORMAL);
181         return CreateErrorMessage(env, "file created failed.");
182     }
183     NativeEngine *engine = reinterpret_cast<NativeEngine*>(env);
184     engine->StartCpuProfiler(filePath);
185     return CreateUndefined(env);
186 }
187 
StartJsCpuProfiling(napi_env env,napi_callback_info info)188 napi_value StartJsCpuProfiling(napi_env env, napi_callback_info info)
189 {
190     ApiInvokeRecorder apiInvokeRecorder("startJsCpuProfiling");
191     std::string fileName;
192     if (!GetTheOnlyStringParam(env, info, fileName)) {
193         apiInvokeRecorder.SetErrorCode(ErrorCode::PARAMETER_ERROR);
194         std::string paramErrorMessage = "Invalid parameter, require a string parameter.";
195         napi_throw_error(env, std::to_string(ErrorCode::PARAMETER_ERROR).c_str(), paramErrorMessage.c_str());
196         return CreateUndefined(env);
197     }
198     HILOG_INFO(LOG_CORE, "filename: %{public}s.", fileName.c_str());
199     auto context = OHOS::AbilityRuntime::Context::GetApplicationContext();
200     if (context == nullptr) {
201         apiInvokeRecorder.SetErrorCode(ErrorCode::SYSTEM_STATUS_ABNORMAL);
202         return CreateErrorMessage(env, "Get ApplicationContext failed.");
203     }
204     std::string filesDir = context->GetFilesDir();
205     if (filesDir.empty()) {
206         apiInvokeRecorder.SetErrorCode(ErrorCode::SYSTEM_STATUS_ABNORMAL);
207         return CreateErrorMessage(env, "Get App files dir failed.");
208     }
209     std::string filePath = filesDir + SLASH_STR + fileName + JSON_FILE;
210     if (!IsLegalPath(filePath)) {
211         apiInvokeRecorder.SetErrorCode(ErrorCode::SYSTEM_STATUS_ABNORMAL);
212         return CreateErrorMessage(env, "input fileName is illegal.");
213     }
214     if (!CreateFile(filePath)) {
215         apiInvokeRecorder.SetErrorCode(ErrorCode::SYSTEM_STATUS_ABNORMAL);
216         return CreateErrorMessage(env, "file created failed.");
217     }
218     NativeEngine *engine = reinterpret_cast<NativeEngine*>(env);
219     engine->StartCpuProfiler(filePath);
220     return CreateUndefined(env);
221 }
222 
StopProfiling(napi_env env,napi_callback_info info)223 napi_value StopProfiling(napi_env env, napi_callback_info info)
224 {
225     ApiInvokeRecorder apiInvokeRecorder("stopProfiling");
226     NativeEngine *engine = reinterpret_cast<NativeEngine*>(env);
227     engine->StopCpuProfiler();
228     return CreateUndefined(env);
229 }
230 
StopJsCpuProfiling(napi_env env,napi_callback_info info)231 napi_value StopJsCpuProfiling(napi_env env, napi_callback_info info)
232 {
233     ApiInvokeRecorder apiInvokeRecorder("stopJsCpuProfiling");
234     NativeEngine *engine = reinterpret_cast<NativeEngine*>(env);
235     engine->StopCpuProfiler();
236     return CreateUndefined(env);
237 }
238 
GetPss(napi_env env,napi_callback_info info)239 napi_value GetPss(napi_env env, napi_callback_info info)
240 {
241     napi_value retValue = nullptr;
242     auto memInfoOption = HidebugNativeInterface::GetInstance().GetAppNativeMemInfo(false);
243     napi_create_bigint_uint64(env, memInfoOption ? static_cast<uint64_t>(memInfoOption->pss) : 0, &retValue);
244     return retValue;
245 }
246 
GetSharedDirty(napi_env env,napi_callback_info info)247 napi_value GetSharedDirty(napi_env env, napi_callback_info info)
248 {
249     ApiInvokeRecorder apiInvokeRecorder("getSharedDirty");
250     napi_value retValue = nullptr;
251     auto memInfoOption = HidebugNativeInterface::GetInstance().GetAppNativeMemInfo(false);
252     napi_create_bigint_uint64(env, memInfoOption ? static_cast<uint64_t>(memInfoOption->sharedDirty) : 0, &retValue);
253     return retValue;
254 }
255 
GetPrivateDirty(napi_env env,napi_callback_info info)256 napi_value GetPrivateDirty(napi_env env, napi_callback_info info)
257 {
258     ApiInvokeRecorder apiInvokeRecorder("getPrivateDirty");
259     napi_value retValue = nullptr;
260     auto memInfoOption = HidebugNativeInterface::GetInstance().GetAppNativeMemInfo(false);
261     napi_create_bigint_uint64(env, memInfoOption ? static_cast<uint64_t>(memInfoOption->privateDirty) : 0, &retValue);
262     return retValue;
263 }
264 
GetCpuUsage(napi_env env,napi_callback_info info)265 napi_value GetCpuUsage(napi_env env, napi_callback_info info)
266 {
267     constexpr uint32_t reportTimeOutSec = 5 * 60;
268     constexpr uint32_t limitSize = 100;
269     static MultipleRecordReporter multipleRecordReporter(reportTimeOutSec, limitSize);
270     ApiInvokeRecorder apiInvokeRecorder("getCpuUsage", multipleRecordReporter);
271     double cpuUsage = HidebugNativeInterface::GetInstance().GetCpuUsage();
272     napi_value retValue = nullptr;
273     napi_create_double(env, cpuUsage, &retValue);
274     return retValue;
275 }
276 
GetNativeHeapSize(napi_env env,napi_callback_info info)277 napi_value GetNativeHeapSize(napi_env env, napi_callback_info info)
278 {
279     struct mallinfo mi = mallinfo();
280     napi_value retValue = nullptr;
281     napi_create_bigint_uint64(env, uint64_t(mi.uordblks + mi.fordblks), &retValue);
282     return retValue;
283 }
284 
GetNativeHeapAllocatedSize(napi_env env,napi_callback_info info)285 napi_value GetNativeHeapAllocatedSize(napi_env env, napi_callback_info info)
286 {
287     ApiInvokeRecorder apiInvokeRecorder("getNativeHeapAllocatedSize");
288     struct mallinfo mi = mallinfo();
289     napi_value retValue = nullptr;
290     napi_create_bigint_uint64(env, uint64_t(mi.uordblks), &retValue);
291     return retValue;
292 }
293 
GetNativeHeapFreeSize(napi_env env,napi_callback_info info)294 napi_value GetNativeHeapFreeSize(napi_env env, napi_callback_info info)
295 {
296     ApiInvokeRecorder apiInvokeRecorder("getNativeHeapFreeSize");
297     struct mallinfo mi = mallinfo();
298     napi_value retValue = nullptr;
299     napi_create_bigint_uint64(env, uint64_t(mi.fordblks), &retValue);
300     return retValue;
301 }
302 
GetServiceDump(napi_env env,napi_callback_info info)303 static napi_value GetServiceDump(napi_env env, napi_callback_info info)
304 {
305     ApiInvokeRecorder apiInvokeRecorder("getServiceDump");
306     int serviceAbilityId = 0;
307     int fd = 0;
308     std::vector<std::u16string> args;
309     if (!GetDumpParam(env, info, serviceAbilityId, fd, args)) {
310         std::string paramErrorMessage = "The parameter check failed.";
311         napi_throw_error(env, std::to_string(ErrorCode::PARAMETER_ERROR).c_str(), paramErrorMessage.c_str());
312         return CreateUndefined(env);
313     }
314 
315     sptr<ISystemAbilityManager> sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
316     if (!sam) {
317         return CreateUndefined(env);
318     }
319     sptr<IRemoteObject> sa = sam->CheckSystemAbility(serviceAbilityId);
320     if (sa == nullptr) {
321         HILOG_ERROR(LOG_CORE, "no this system ability.");
322         std::string idErrorMessage = "ServiceId invalid. The system ability does not exist.";
323         napi_throw_error(env, std::to_string(ErrorCode::SYSTEM_ABILITY_NOT_FOUND).c_str(), idErrorMessage.c_str());
324         return CreateUndefined(env);
325     }
326     int dumpResult = sa->Dump(fd, args);
327     HILOG_INFO(LOG_CORE, "Dump result: %{public}d", dumpResult);
328     return CreateUndefined(env);
329 }
330 
GetVss(napi_env env,napi_callback_info info)331 napi_value GetVss(napi_env env, napi_callback_info info)
332 {
333     ApiInvokeRecorder apiInvokeRecorder("getVss");
334     napi_value retValue = nullptr;
335     auto vssInfoOption = HidebugNativeInterface::GetInstance().GetVss();
336     napi_create_bigint_uint64(env, vssInfoOption ? vssInfoOption.value() : 0, &retValue);
337     return retValue;
338 }
339 
GetSystemCpuUsage(napi_env env,napi_callback_info info)340 static napi_value GetSystemCpuUsage(napi_env env, napi_callback_info info)
341 {
342     constexpr uint32_t reportTimeOutSec = 5 * 60;
343     constexpr uint32_t limitSize = 100;
344     static MultipleRecordReporter multipleRecordReporter(reportTimeOutSec, limitSize);
345     ApiInvokeRecorder apiInvokeRecorder("getSystemCpuUsage", multipleRecordReporter);
346     auto cpuUsageOptional = HidebugNativeInterface::GetInstance().GetSystemCpuUsage();
347     if (!cpuUsageOptional) {
348         std::string paramErrorMessage = "The status of the system CPU usage is abnormal.";
349         napi_throw_error(env, std::to_string(ErrorCode::SYSTEM_STATUS_ABNORMAL).c_str(), paramErrorMessage.c_str());
350         return CreateUndefined(env);
351     }
352     napi_value retMsg = nullptr;
353     napi_create_double(env, cpuUsageOptional.value(),  &retMsg);
354     return retMsg;
355 }
356 
RemoveNapiWrap(napi_env env,napi_callback_info info)357 static napi_value RemoveNapiWrap(napi_env env, napi_callback_info info)
358 {
359     size_t argc = REMOVE_NAPI_WRAP_PARAM_COUNT;
360     napi_value argv[REMOVE_NAPI_WRAP_PARAM_COUNT] = {nullptr};
361     napi_value thisVar = nullptr;
362     void *data = nullptr;
363     napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
364     if (argc != REMOVE_NAPI_WRAP_PARAM_COUNT ||
365         (!MatchValueType(env, argv[FIRST_POS], napi_object) ||
366         !MatchValueType(env, argv[SECOND_POS], napi_boolean))) {
367         HILOG_DEBUG(LOG_CORE, "RemoveNapiWrap Failed to parse parameters, argc %{public}d", (int)argc);
368         std::string paramErrorMessage = "The parameter check failed.";
369         napi_throw_error(env, std::to_string(ErrorCode::PARAMETER_ERROR).c_str(), paramErrorMessage.c_str());
370         return CreateUndefined(env);
371     }
372 
373     // remove jsObj's wrap
374     auto jsObj = argv[FIRST_POS];
375     void *nativePtr = nullptr;
376     napi_remove_wrap(env, jsObj, (void **)&nativePtr);
377 
378     // remove jsObj's properties wrap
379     bool needRemoveProperty = false;
380     napi_get_value_bool(env, argv[SECOND_POS], &needRemoveProperty);
381     if (needRemoveProperty) {
382         napi_value allPropertyNames = nullptr;
383         napi_object_get_keys(env, jsObj, &allPropertyNames);
384         uint32_t nameCount = 0;
385         napi_get_array_length(env, allPropertyNames, &nameCount);
386         for (size_t i = 0; i < nameCount; ++i) {
387             napi_value propertyName = nullptr;
388             napi_get_element(env, allPropertyNames, i, &propertyName);
389             char name[NAME_LEN] = {0};
390             size_t len = 0;
391             napi_get_value_string_utf8(env, propertyName, name, NAME_LEN, &len);
392             napi_value propertyObj = nullptr;
393             napi_get_named_property(env, jsObj, name, &propertyObj);
394             napi_remove_wrap(env, propertyObj, (void **)&nativePtr);
395         }
396     }
397     return CreateUndefined(env);
398 }
399 
GetAppVMMemoryInfo(napi_env env,napi_callback_info info)400 napi_value GetAppVMMemoryInfo(napi_env env, napi_callback_info info)
401 {
402     ApiInvokeRecorder apiInvokeRecorder("getAppVMMemoryInfo");
403     uint64_t allArraySizeValue{0};
404     uint64_t heapUsedValue{0};
405     uint64_t totalHeapValue{0};
406     NativeEngine *engine = reinterpret_cast<NativeEngine*>(env);
407     if (engine) {
408         allArraySizeValue = engine->GetArrayBufferSize();
409         heapUsedValue = engine->GetHeapUsedSize();
410         totalHeapValue = engine->GetHeapTotalSize();
411     }
412 
413     napi_value vMMemoryInfo;
414     napi_create_object(env, &vMMemoryInfo);
415 
416     napi_value totalHeap;
417     totalHeapValue = totalHeapValue >> BYTE_2_KB_SHIFT_BITS;
418     napi_create_bigint_uint64(env, totalHeapValue, &totalHeap);
419     napi_set_named_property(env, vMMemoryInfo, "totalHeap", totalHeap);
420 
421     napi_value heapUsed;
422     heapUsedValue = heapUsedValue >> BYTE_2_KB_SHIFT_BITS;
423     napi_create_bigint_uint64(env, heapUsedValue, &heapUsed);
424     napi_set_named_property(env, vMMemoryInfo, "heapUsed", heapUsed);
425 
426     napi_value allArraySize;
427     allArraySizeValue = allArraySizeValue >> BYTE_2_KB_SHIFT_BITS;
428     napi_create_bigint_uint64(env, allArraySizeValue, &allArraySize);
429     napi_set_named_property(env, vMMemoryInfo, "allArraySize", allArraySize);
430 
431     return vMMemoryInfo;
432 }
433 
ConvertThreadCpuUsageToJs(napi_env env,napi_value & result,uint32_t threadIdValue,double cpuUsageValue)434 static void ConvertThreadCpuUsageToJs(napi_env env, napi_value &result, uint32_t threadIdValue, double cpuUsageValue)
435 {
436     napi_create_object(env, &result);
437 
438     napi_value threadId = nullptr;
439     napi_create_uint32(env, threadIdValue, &threadId);
440     napi_set_named_property(env, result, "threadId", threadId);
441 
442     napi_value cpuUsage = nullptr;
443     napi_create_double(env, cpuUsageValue, &cpuUsage);
444     napi_set_named_property(env, result, "cpuUsage", cpuUsage);
445 }
446 
ConvertThreadCpuUsageMapToJs(napi_env env,napi_value & result,const std::map<uint32_t,double> & threadMap)447 static void ConvertThreadCpuUsageMapToJs(napi_env env, napi_value &result, const std::map<uint32_t, double> &threadMap)
448 {
449     napi_create_array(env, &result);
450     size_t idx = 0;
451     for (const auto& [threadId, cpuUsage] : threadMap) {
452         napi_value obj = nullptr;
453         ConvertThreadCpuUsageToJs(env, obj, threadId, cpuUsage);
454         napi_set_element(env, result, idx, obj);
455         idx++;
456     }
457 }
458 
GetAppThreadCpuUsage(napi_env env,napi_callback_info info)459 napi_value GetAppThreadCpuUsage(napi_env env, napi_callback_info info)
460 {
461     ApiInvokeRecorder apiInvokeRecorder("getAppThreadCpuUsage");
462     napi_value result = nullptr;
463     std::map<uint32_t, double> threadMap = HidebugNativeInterface::GetInstance().GetAppThreadCpuUsage();
464     ConvertThreadCpuUsageMapToJs(env, result, threadMap);
465     return result;
466 }
467 
GetAppMemoryLimit(napi_env env,napi_callback_info info)468 napi_value GetAppMemoryLimit(napi_env env, napi_callback_info info)
469 {
470     ApiInvokeRecorder apiInvokeRecorder("getAppMemoryLimit");
471     napi_value appMemoryLimit = nullptr;
472     napi_create_object(env, &appMemoryLimit);
473     auto memoryLimitOption = HidebugNativeInterface::GetInstance().GetAppMemoryLimit();
474     if (!memoryLimitOption) {
475         memoryLimitOption.emplace();
476     }
477     napi_value rssLimit = nullptr;
478     napi_create_bigint_uint64(env, memoryLimitOption->rssLimit, &rssLimit);
479     napi_set_named_property(env, appMemoryLimit, "rssLimit", rssLimit);
480 
481     napi_value vssLimit = nullptr;
482     napi_create_bigint_uint64(env, memoryLimitOption->vssLimit, &vssLimit);
483     napi_set_named_property(env, appMemoryLimit, "vssLimit", vssLimit);
484     uint64_t vmHeapLimitValue{0};
485     uint64_t vmTotalHeapSizeValue{0};
486     NativeEngine *engine = reinterpret_cast<NativeEngine *>(env);
487     if (engine) {
488         vmHeapLimitValue = engine->GetHeapLimitSize();
489         vmTotalHeapSizeValue = engine->GetProcessHeapLimitSize();
490     }
491     napi_value vmHeapLimit = nullptr;
492     vmHeapLimitValue = vmHeapLimitValue >> BYTE_2_KB_SHIFT_BITS;
493     napi_create_bigint_uint64(env, vmHeapLimitValue, &vmHeapLimit);
494     napi_set_named_property(env, appMemoryLimit, "vmHeapLimit", vmHeapLimit);
495     napi_value vmTotalHeapSize = nullptr;
496     vmTotalHeapSizeValue = vmTotalHeapSizeValue >> BYTE_2_KB_SHIFT_BITS;
497     napi_create_bigint_uint64(env, vmTotalHeapSizeValue, &vmTotalHeapSize);
498     napi_set_named_property(env, appMemoryLimit, "vmTotalHeapSize", vmTotalHeapSize);
499     return appMemoryLimit;
500 }
501 
ConvertToJsNativeMemInfo(napi_env env,const NativeMemInfo & nativeMemInfo)502 napi_value ConvertToJsNativeMemInfo(napi_env env, const NativeMemInfo& nativeMemInfo)
503 {
504     napi_value memInfo = nullptr;
505     napi_create_object(env, &memInfo);
506     napi_value pss = nullptr;
507     napi_create_bigint_uint64(env, nativeMemInfo.pss, &pss);
508     napi_set_named_property(env, memInfo, "pss", pss);
509 
510     napi_value rss = nullptr;
511     napi_create_bigint_uint64(env, nativeMemInfo.rss, &rss);
512     napi_set_named_property(env, memInfo, "rss", rss);
513 
514     napi_value sharedDirty = nullptr;
515     napi_create_bigint_uint64(env, nativeMemInfo.sharedDirty, &sharedDirty);
516     napi_set_named_property(env, memInfo, "sharedDirty", sharedDirty);
517 
518     napi_value privateDirty = nullptr;
519     napi_create_bigint_uint64(env, nativeMemInfo.privateDirty, &privateDirty);
520     napi_set_named_property(env, memInfo, "privateDirty", privateDirty);
521 
522     napi_value sharedClean = nullptr;
523     napi_create_bigint_uint64(env, nativeMemInfo.sharedClean, &sharedClean);
524     napi_set_named_property(env, memInfo, "sharedClean", sharedClean);
525 
526     napi_value privateClean = nullptr;
527     napi_create_bigint_uint64(env, nativeMemInfo.privateClean, &privateClean);
528     napi_set_named_property(env, memInfo, "privateClean", privateClean);
529 
530     napi_value vss = nullptr;
531     napi_create_bigint_uint64(env, nativeMemInfo.vss, &vss);
532     napi_set_named_property(env, memInfo, "vss", vss);
533     return memInfo;
534 }
535 
GetAppNativeMemInfo(napi_env env,napi_callback_info info)536 napi_value GetAppNativeMemInfo(napi_env env, napi_callback_info info)
537 {
538     ApiInvokeRecorder apiInvokeRecorder("getAppNativeMemInfo");
539     auto memInfoOption = HidebugNativeInterface::GetInstance().GetAppNativeMemInfo(false);
540     return memInfoOption ? ConvertToJsNativeMemInfo(env, *memInfoOption) : ConvertToJsNativeMemInfo(env, {});
541 }
542 
GetAppNativeMemInfoWithCache(napi_env env,napi_callback_info info)543 napi_value GetAppNativeMemInfoWithCache(napi_env env, napi_callback_info info)
544 {
545     ApiInvokeRecorder apiInvokeRecorder("getAppNativeMemInfoWithCache");
546     constexpr auto paramNum = 1;
547     size_t argc = paramNum;
548     napi_value argv = nullptr ;
549     napi_get_cb_info(env, info, &argc, &argv, nullptr, nullptr);
550     bool forceRefresh = false;
551     if (argc > paramNum || (argc == paramNum && !OHOS::HiviewDFX::GetNapiBoolValue(env, argv, forceRefresh))) {
552         constexpr auto paramErrorMessage = "Invalid argument";
553         apiInvokeRecorder.SetErrorCode(ErrorCode::PARAMETER_ERROR);
554         napi_throw_error(env, std::to_string(ErrorCode::PARAMETER_ERROR).c_str(), paramErrorMessage);
555         return CreateUndefined(env);
556     }
557     auto memInfoOption = HidebugNativeInterface::GetInstance().GetAppNativeMemInfo(!forceRefresh);
558     return memInfoOption ? ConvertToJsNativeMemInfo(env, *memInfoOption) : ConvertToJsNativeMemInfo(env, {});
559 }
560 
561 class GetAppNativeMemInfoAsyncTask : public AsyncTask {
562 public:
GetAppNativeMemInfoAsyncTask()563     GetAppNativeMemInfoAsyncTask() : AsyncTask("getAppNativeMemInfoAsync"),
564         apiInvokeRecorder_("getAppNativeMemInfoAsync") {}
565 
566 protected:
Work(napi_env env)567     void Work(napi_env env) override
568     {
569         result_ = HidebugNativeInterface::GetInstance().GetAppNativeMemInfo(false);
570     }
571 
Done(napi_env env,napi_status status)572     void Done(napi_env env, napi_status status) override
573     {
574         napi_value ret = result_ ? ConvertToJsNativeMemInfo(env, result_.value()) : ConvertToJsNativeMemInfo(env, {});
575         napi_resolve_deferred(env, deferred_, ret);
576     }
577 
578 private:
579     std::optional<NativeMemInfo> result_{};
580     ApiInvokeRecorder apiInvokeRecorder_;
581 };
582 
GetAppNativeMemInfoAsync(napi_env env,napi_callback_info info)583 napi_value GetAppNativeMemInfoAsync(napi_env env, napi_callback_info info)
584 {
585     return AsyncTask::GetPromise<GetAppNativeMemInfoAsyncTask>(env);
586 }
587 
GetSystemMemInfo(napi_env env,napi_callback_info info)588 napi_value GetSystemMemInfo(napi_env env, napi_callback_info info)
589 {
590     ApiInvokeRecorder apiInvokeRecorder("getSystemMemInfo");
591     auto systemMemInfoOption = HidebugNativeInterface::GetInstance().GetSystemMemInfo();
592     if (!systemMemInfoOption) {
593         systemMemInfoOption.emplace();
594     }
595     napi_value sysMemInfo = nullptr;
596     napi_create_object(env, &sysMemInfo);
597 
598     napi_value totalMem = nullptr;
599     napi_create_bigint_uint64(env, static_cast<uint64_t>(systemMemInfoOption->totalMem), &totalMem);
600     napi_set_named_property(env, sysMemInfo, "totalMem", totalMem);
601 
602     napi_value freeMem = nullptr;
603     napi_create_bigint_uint64(env, static_cast<uint64_t>(systemMemInfoOption->freeMem), &freeMem);
604     napi_set_named_property(env, sysMemInfo, "freeMem", freeMem);
605 
606     napi_value availableMem = nullptr;
607     napi_create_bigint_uint64(env, static_cast<uint64_t>(systemMemInfoOption->availableMem), &availableMem);
608     napi_set_named_property(env, sysMemInfo, "availableMem", availableMem);
609     return sysMemInfo;
610 }
611 
StartAppTraceCapture(napi_env env,napi_callback_info info)612 napi_value StartAppTraceCapture(napi_env env, napi_callback_info info)
613 {
614     ApiInvokeRecorder apiInvokeRecorder("startAppTraceCapture");
615     napi_value result = nullptr;
616     uint32_t traceFlag = 0;
617     uint32_t limitSize = 0;
618     std::vector<uint64_t> tags;
619     if (!GetTraceParam(env, info, traceFlag, limitSize, tags)) {
620         constexpr auto paramErrorMessage = "Invalid argument";
621         apiInvokeRecorder.SetErrorCode(ErrorCode::PARAMETER_ERROR);
622         napi_throw_error(env, std::to_string(ErrorCode::PARAMETER_ERROR).c_str(), paramErrorMessage);
623     }
624     uint64_t tag = std::accumulate(tags.begin(), tags.end(), 0ull, [](uint64_t a, uint64_t b) { return a | b; });
625     std::string file;
626     auto ret = HidebugNativeInterface::GetInstance().StartAppTraceCapture(tag, traceFlag, limitSize, file);
627     if (ret == TRACE_SUCCESS) {
628         napi_create_string_utf8(env, file.c_str(), NAPI_AUTO_LENGTH, &result);
629         return result;
630     }
631     if (ret == TRACE_INVALID_ARGUMENT) {
632         constexpr auto errorMessage = "Invalid argument";
633         apiInvokeRecorder.SetErrorCode(ErrorCode::PARAMETER_ERROR);
634         napi_throw_error(env, std::to_string(ErrorCode::PARAMETER_ERROR).c_str(), errorMessage);
635         return CreateUndefined(env);
636     }
637     if (ret == TRACE_CAPTURED_ALREADY) {
638         constexpr auto errorMessage = "Capture trace already enabled.";
639         apiInvokeRecorder.SetErrorCode(ErrorCode::HAVA_ALREADY_TRACE);
640         napi_throw_error(env, std::to_string(ErrorCode::HAVA_ALREADY_TRACE).c_str(), errorMessage);
641         return CreateUndefined(env);
642     }
643     if (ret == TRACE_NO_PERMISSION) {
644         constexpr auto errorMessage = "No write permission on the file.";
645         apiInvokeRecorder.SetErrorCode(ErrorCode::WITHOUT_WRITE_PERMISSON);
646         napi_throw_error(env, std::to_string(ErrorCode::WITHOUT_WRITE_PERMISSON).c_str(), errorMessage);
647         return CreateUndefined(env);
648     }
649     constexpr auto errorMessage = "Abnormal trace status.";
650     apiInvokeRecorder.SetErrorCode(ErrorCode::SYSTEM_STATUS_ABNORMAL);
651     napi_throw_error(env, std::to_string(ErrorCode::SYSTEM_STATUS_ABNORMAL).c_str(), errorMessage);
652     return CreateUndefined(env);
653 }
654 
StopAppTraceCapture(napi_env env,napi_callback_info info)655 napi_value StopAppTraceCapture(napi_env env, napi_callback_info info)
656 {
657     ApiInvokeRecorder apiInvokeRecorder("stopAppTraceCapture");
658     const auto ret = HidebugNativeInterface::GetInstance().StopAppTraceCapture();
659     if (ret == TRACE_ABNORMAL) {
660         std::string errorMessage = "The status of the trace is abnormal";
661         apiInvokeRecorder.SetErrorCode(ErrorCode::SYSTEM_STATUS_ABNORMAL);
662         napi_throw_error(env, std::to_string(ErrorCode::SYSTEM_STATUS_ABNORMAL).c_str(), errorMessage.c_str());
663     }
664     if (ret == NO_TRACE_RUNNING) {
665         std::string errorMessage = "No capture trace running";
666         apiInvokeRecorder.SetErrorCode(ErrorCode::NO_CAPTURE_TRACE_RUNNING);
667         napi_throw_error(env, std::to_string(ErrorCode::NO_CAPTURE_TRACE_RUNNING).c_str(), errorMessage.c_str());
668     }
669     return CreateUndefined(env);
670 }
671 
JudgeValueRange(const std::string & type,int32_t value)672 static bool JudgeValueRange(const std::string &type, int32_t value)
673 {
674     if (type == "pss_memory") {
675         constexpr int pssMin = 1024;
676         constexpr int pssMax = 4 * 1024 * 1024;
677         return value >= pssMin && value <= pssMax;
678     }
679     if (type == "js_memory") {
680         constexpr int jsMin = 85;
681         constexpr int jsMax = 95;
682         return value >= jsMin && value <= jsMax;
683     }
684     if (type == "fd_memory") {
685         constexpr int fdMin = 10;
686         constexpr int fdMax = 10000;
687         return value >= fdMin && value <= fdMax;
688     }
689     if (type == "thread_memory") {
690         constexpr int threadMin = 1;
691         constexpr int threadMax = 1000;
692         return value >= threadMin && value <= threadMax;
693     }
694     HILOG_ERROR(LOG_CORE, "GetAppResourceLimitParam failed. Resource type is invalid.");
695     return false;
696 }
697 
GetAppResourceLimitParam(napi_env env,napi_callback_info info,std::string & type,int32_t & value,bool & enabledDebugLog)698 static bool GetAppResourceLimitParam(napi_env env, napi_callback_info info, std::string& type,
699     int32_t& value, bool& enabledDebugLog)
700 {
701     constexpr int valueNum = 3;
702     size_t argc = valueNum;
703     napi_value argv[valueNum] = { nullptr };
704     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
705     if (argc != valueNum) {
706         HILOG_ERROR(LOG_CORE, "GetAppResourceLimitParam failed. Invalid numbers of params!");
707         return false;
708     }
709     constexpr int paramMaxLen = 128;
710     if (!GetNapiStringValue(env, argv[FIRST_POS], type, paramMaxLen)) {
711         HILOG_ERROR(LOG_CORE, "GetAppResourceLimitParam failed. Resource type is invalid.");
712         return false;
713     }
714     if (!GetNapiInt32Value(env, argv[SECOND_POS], value)) {
715         HILOG_ERROR(LOG_CORE, "GetAppResourceLimitParam failed. Input value error.");
716         return false;
717     }
718     if (!JudgeValueRange(type, value)) {
719         HILOG_ERROR(LOG_CORE, "GetAppResourceLimitParam failed. The value range is invalid.");
720         return false;
721     }
722     if (!GetNapiBoolValue(env, argv[THIRD_POS], enabledDebugLog)) {
723         HILOG_ERROR(LOG_CORE, "GetAppResourceLimitParam failed. Get input enabledDebugLog failed.");
724         return false;
725     }
726     return true;
727 }
728 
SetAppResourceLimit(napi_env env,napi_callback_info info)729 napi_value SetAppResourceLimit(napi_env env, napi_callback_info info)
730 {
731     ApiInvokeRecorder apiInvokeRecorder("setAppResourceLimit");
732     CreateResourceLimitDir();
733     if (!IsBetaVersion() && !CheckVersionType("enable", KEY_HIVIEW_DEVELOP_TYPE)) {
734         HILOG_ERROR(LOG_CORE, "SetAppResourceLimit failed. Not developer options or beta versions");
735         apiInvokeRecorder.SetErrorCode(ErrorCode::VERSION_ERROR);
736         return CreateUndefined(env);
737     }
738     std::string type;
739     int32_t value = 0;
740     bool enabledDebugLog = false;
741     if (!GetAppResourceLimitParam(env, info, type, value, enabledDebugLog)) {
742         apiInvokeRecorder.SetErrorCode(ErrorCode::PARAMETER_ERROR);
743         return CreateUndefined(env);
744     }
745     if (type == "js_heap") { // js_heap set value
746         NativeEngine *engine = reinterpret_cast<NativeEngine*>(env);
747         engine->SetJsDumpThresholds(value);
748     }
749     auto abilityManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
750     if (!abilityManager) {
751         apiInvokeRecorder.SetErrorCode(ErrorCode::SYSTEM_ABILITY_NOT_FOUND);
752         return CreateUndefined(env);
753     }
754     sptr<IRemoteObject> remoteObject = abilityManager->CheckSystemAbility(DFX_SYS_HIVIEW_ABILITY_ID);
755     if (remoteObject == nullptr) {
756         HILOG_ERROR(LOG_CORE, "SetAppResourceLimit failed. No this system ability.");
757         std::string idErrorMessage = "system ability is not exist.";
758         napi_throw_error(env, std::to_string(ErrorCode::SYSTEM_STATUS_ABNORMAL).c_str(), idErrorMessage.c_str());
759         apiInvokeRecorder.SetErrorCode(ErrorCode::SYSTEM_STATUS_ABNORMAL);
760         return CreateUndefined(env);
761     }
762     if (HidebugNativeInterface::GetInstance().GetMemoryLeakResource(type, value, enabledDebugLog) != NATIVE_SUCCESS) {
763         apiInvokeRecorder.SetErrorCode(ErrorCode::SYSTEM_STATUS_ABNORMAL);
764     }
765     return CreateUndefined(env);
766 }
767 
IsDebugState(napi_env env,napi_callback_info info)768 napi_value IsDebugState(napi_env env, napi_callback_info info)
769 {
770     ApiInvokeRecorder apiInvokeRecorder("isDebugState");
771     NativeEngine *engine = reinterpret_cast<NativeEngine*>(env);
772     bool debugState = (engine && engine->GetIsDebugModeEnabled()) ||
773         HidebugNativeInterface::GetInstance().IsDebuggerConnected();
774     napi_value result = nullptr;
775     napi_get_boolean(env, debugState, &result);
776     return result;
777 }
778 
779 class GraphicAsyncTask : public AsyncTask {
780 public:
GraphicAsyncTask()781     GraphicAsyncTask() : AsyncTask("graphicAsyncTask"), apiInvokeRecorder_("getGraphicsMemory") {}
782 
783 protected:
Work(napi_env env)784     void Work(napi_env env) override
785     {
786         result_ = HidebugNativeInterface::GetInstance().GetGraphicsMemory();
787     }
788 
Done(napi_env env,napi_status status)789     void Done(napi_env env, napi_status status) override
790     {
791         if (result_) {
792             napi_value ret;
793             napi_create_int32(env, result_.value(), &ret);
794             napi_resolve_deferred(env, deferred_, ret);
795         } else {
796             constexpr const char* errMsg = "Failed to get the application memory due to a remote exception";
797             apiInvokeRecorder_.SetErrorCode(ErrorCode::SYSTEM_STATUS_ABNORMAL);
798             napi_reject_deferred(env, deferred_,
799                 CreateErrorMessage(env, std::to_string(ErrorCode::SYSTEM_STATUS_ABNORMAL), errMsg));
800         }
801     }
802 
803 private:
804     std::optional<int> result_{};
805     ApiInvokeRecorder apiInvokeRecorder_;
806 };
807 
GetGraphicsMemory(napi_env env,napi_callback_info info)808 napi_value GetGraphicsMemory(napi_env env, napi_callback_info info)
809 {
810     return AsyncTask::GetPromise<GraphicAsyncTask>(env);
811 }
812 
GetGraphicsMemorySync(napi_env env,napi_callback_info info)813 napi_value GetGraphicsMemorySync(napi_env env, napi_callback_info info)
814 {
815     ApiInvokeRecorder apiInvokeRecorder("getGraphicsMemorySync");
816     std::optional<int32_t> result = HidebugNativeInterface::GetInstance().GetGraphicsMemory();
817     if (result) {
818         napi_value ret;
819         napi_create_int32(env, result.value(), &ret);
820         return ret;
821     }
822     constexpr const char* errMsg = "Failed to get the application memory due to a remote exception";
823     napi_throw_error(env, std::to_string(ErrorCode::SYSTEM_STATUS_ABNORMAL).c_str(), errMsg);
824     apiInvokeRecorder.SetErrorCode(ErrorCode::SYSTEM_STATUS_ABNORMAL);
825     return CreateUndefined(env);
826 }
827 
ParseGwpAsanOptions(napi_env env,napi_value value,GwpAsanParams & gwpAsanParams)828 bool ParseGwpAsanOptions(napi_env env, napi_value value, GwpAsanParams& gwpAsanParams)
829 {
830     if (!MatchValueType(env, value, napi_object)) {
831         HILOG_ERROR(LOG_CORE, "The type of options must be GwpAsanOptions.");
832         return false;
833     }
834 
835     //alwaysEnabled?: bool
836     napi_value nAlwaysEnabled = nullptr;
837     if (GetNapiObjectProperty(env, value, "alwaysEnabled", nAlwaysEnabled)) {
838         if (!GetNapiBoolValue(env, nAlwaysEnabled, gwpAsanParams.alwaysEnabled)) {
839             HILOG_ERROR(LOG_CORE, "AlwaysEnabled type must be boolean");
840             return false;
841         }
842     }
843 
844     //sampleRate?: number
845     napi_value nSampleRate = nullptr;
846     if (GetNapiObjectProperty(env, value, "sampleRate", nSampleRate)) {
847         if (!GetNapiDoubleValue(env, nSampleRate, gwpAsanParams.sampleRate)) {
848             HILOG_ERROR(LOG_CORE, "SampleRate type must be a num");
849             return false;
850         }
851     }
852 
853     //maxSimutaneousAllocations?: number
854     napi_value nMaxSimutaneousAllocations = nullptr;
855     if (GetNapiObjectProperty(env, value, "maxSimutaneousAllocations", nMaxSimutaneousAllocations)) {
856         if (!GetNapiDoubleValue(env, nMaxSimutaneousAllocations, gwpAsanParams.maxSimutaneousAllocations)) {
857             HILOG_ERROR(LOG_CORE, "MaxSimutaneousAllocations type must be a num");
858             return false;
859         }
860     }
861     if (gwpAsanParams.sampleRate <= 0 || gwpAsanParams.maxSimutaneousAllocations <= 0) {
862         HILOG_ERROR(LOG_CORE, "sampleRate or maxSimutaneousAllocations must be greater than 0");
863         return false;
864     }
865     HILOG_DEBUG(LOG_CORE, "Parse GwpAsanOptions success, alwaysEnabled: %{public}d, sampleRate: %{public}f,"
866         " maxSimutaneousAllocations: %{public}f",
867         gwpAsanParams.alwaysEnabled, gwpAsanParams.sampleRate, gwpAsanParams.maxSimutaneousAllocations);
868     return true;
869 }
870 
UpdateGwpAsanParams(napi_env env,napi_callback_info info,GwpAsanParams & gwpAsanParams,std::string & paramErrorMessage)871 bool UpdateGwpAsanParams(napi_env env, napi_callback_info info, GwpAsanParams& gwpAsanParams,
872     std::string& paramErrorMessage)
873 {
874     size_t argc = ENABLE_ARGS_TWO_PARAMS;
875     napi_value argv[ENABLE_ARGS_TWO_PARAMS] = { nullptr };
876     napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
877     switch (argc) {
878         case ENABLE_ARGS_TWO_PARAMS:
879             if (!GetNapiInt32Value(env, argv[SECOND_POS], gwpAsanParams.duration) ||
880                 gwpAsanParams.duration <= 0) {
881                 paramErrorMessage = "Invalid parameter, set duration must be a num.";
882                 return false;
883             }
884             [[fallthrough]];
885         case ENABLE_ARGS_ONE_PARAMS:
886             if (!ParseGwpAsanOptions(env, argv[FIRST_POS], gwpAsanParams)) {
887                 paramErrorMessage = "Invalid parameter, parse gwpAsanOptions error.";
888                 return false;
889             }
890             [[fallthrough]];
891         case ENABLE_ARGS_NO_PARAMS:
892             return true;
893         default: {
894             paramErrorMessage = "Invalid parameter, the number of parameters "
895                 "cannot exceed two.";
896             return false;
897         }
898     }
899 }
900 
EnableGwpAsanGrayscale(napi_env env,napi_callback_info info)901 napi_value EnableGwpAsanGrayscale(napi_env env, napi_callback_info info)
902 {
903     ApiInvokeRecorder apiInvokeRecorder("enableGwpAsanGrayscale");
904     GwpAsanParams gwpAsanParams;
905     std::string paramErrorMessage;
906     if (!UpdateGwpAsanParams(env, info, gwpAsanParams, paramErrorMessage)) {
907         HILOG_ERROR(LOG_CORE, "EnableGwpAsanGrayscale failed. Invalid params!");
908         apiInvokeRecorder.SetErrorCode(ErrorCode::PARAMETER_ERROR);
909         napi_throw_error(env, std::to_string(ErrorCode::PARAMETER_ERROR).c_str(),
910             paramErrorMessage.c_str());
911         return CreateUndefined(env);
912     }
913     if (!EnableGwpAsanGrayscale(gwpAsanParams.alwaysEnabled, gwpAsanParams.sampleRate,
914         gwpAsanParams.maxSimutaneousAllocations, gwpAsanParams.duration)) {
915         HILOG_ERROR(LOG_CORE, "Failed to enable gwp asan grayscale!");
916         apiInvokeRecorder.SetErrorCode(ErrorCode::OVER_ENABLE_LIMIT);
917         paramErrorMessage = "The number of GWP-ASAN applications of this device overflowed after last boot.";
918         napi_throw_error(env, std::to_string(ErrorCode::OVER_ENABLE_LIMIT).c_str(), paramErrorMessage.c_str());
919         return CreateUndefined(env);
920     }
921     return CreateUndefined(env);
922 }
923 
DisableGwpAsanGrayscale(napi_env env,napi_callback_info info)924 napi_value DisableGwpAsanGrayscale(napi_env env, napi_callback_info info)
925 {
926     ApiInvokeRecorder apiInvokeRecorder("disableGwpAsanGrayscale");
927     DisableGwpAsanGrayscale();
928     return CreateUndefined(env);
929 }
930 
GetGwpAsanGrayscaleState(napi_env env,napi_callback_info info)931 napi_value GetGwpAsanGrayscaleState(napi_env env, napi_callback_info info)
932 {
933     ApiInvokeRecorder apiInvokeRecorder("getGwpAsanGrayscaleState");
934     auto result = GetGwpAsanGrayscaleState();
935     napi_value ret = nullptr;
936     napi_create_uint32(env, result, &ret);
937     return ret;
938 }
939 
GetJsRawHeapTrimLevelParam(napi_env env,napi_callback_info info,uint32_t & level)940 static std::string GetJsRawHeapTrimLevelParam(napi_env env, napi_callback_info info, uint32_t &level)
941 {
942     size_t argc = ENABLE_ARGS_ONE_PARAMS;
943     napi_value argv = nullptr;
944     napi_get_cb_info(env, info, &argc, &argv, nullptr, nullptr);
945     std::string paramErrorMessage;
946     if (argc != ENABLE_ARGS_ONE_PARAMS) {
947         paramErrorMessage = "Param type error, wrong number of parameters.";
948         HILOG_ERROR(LOG_CORE, "%{public}s", paramErrorMessage.c_str());
949         return paramErrorMessage;
950     }
951     if (!MatchValueType(env, argv, napi_number)) {
952         paramErrorMessage = "Param type error, invalid num.";
953         HILOG_ERROR(LOG_CORE, "%{public}s", paramErrorMessage.c_str());
954         return paramErrorMessage;
955     }
956     if (napi_get_value_uint32(env, argv, &level) != napi_ok ||
957         level > TRIM_LEVEL_MAX) {
958         paramErrorMessage = "Param type error, invalid an unsigned num or "
959             "exceeding the maximum value: " + std::to_string(TRIM_LEVEL_MAX);
960         HILOG_ERROR(LOG_CORE, "%{public}s", paramErrorMessage.c_str());
961         return paramErrorMessage;
962     }
963     return paramErrorMessage;
964 }
965 
SetJsRawHeapTrimLevel(napi_env env,napi_callback_info info)966 napi_value SetJsRawHeapTrimLevel(napi_env env, napi_callback_info info)
967 {
968     ApiInvokeRecorder apiInvokeRecorder("setJsRawHeapTrimLevel");
969     uint32_t level = 0;
970     std::string paramErrorMessage = GetJsRawHeapTrimLevelParam(env, info, level);
971     if (!paramErrorMessage.empty()) {
972         apiInvokeRecorder.SetErrorCode(ErrorCode::PARAMETER_ERROR);
973         napi_throw_error(env, std::to_string(ErrorCode::PARAMETER_ERROR).c_str(),
974             paramErrorMessage.c_str());
975         return CreateUndefined(env);
976     }
977 
978     NativeEngine *engine = reinterpret_cast<NativeEngine*>(env);
979     if (engine) {
980         engine->SetRawHeapTrimLevel(level);
981         HILOG_DEBUG(LOG_CORE, "SetRawHeapTrimLevel to level: %{public}d success", level);
982     }
983     return CreateUndefined(env);
984 }
985 
DeclareHiDebugInterface(napi_env env,napi_value exports)986 napi_value DeclareHiDebugInterface(napi_env env, napi_value exports)
987 {
988     ApiRecordReporter::InitProcessor();
989     napi_property_descriptor desc[] = {
990         DECLARE_NAPI_FUNCTION("startProfiling", StartProfiling),
991         DECLARE_NAPI_FUNCTION("stopProfiling", StopProfiling),
992         DECLARE_NAPI_FUNCTION("dumpHeapData", DumpHeapData),
993         DECLARE_NAPI_FUNCTION("startJsCpuProfiling", StartJsCpuProfiling),
994         DECLARE_NAPI_FUNCTION("stopJsCpuProfiling", StopJsCpuProfiling),
995         DECLARE_NAPI_FUNCTION("dumpJsHeapData", DumpJsHeapData),
996         DECLARE_NAPI_FUNCTION("getPss", GetPss),
997         DECLARE_NAPI_FUNCTION("getSharedDirty", GetSharedDirty),
998         DECLARE_NAPI_FUNCTION("getPrivateDirty", GetPrivateDirty),
999         DECLARE_NAPI_FUNCTION("getCpuUsage", GetCpuUsage),
1000         DECLARE_NAPI_FUNCTION("getServiceDump", GetServiceDump),
1001         DECLARE_NAPI_FUNCTION("getNativeHeapSize", GetNativeHeapSize),
1002         DECLARE_NAPI_FUNCTION("getNativeHeapAllocatedSize", GetNativeHeapAllocatedSize),
1003         DECLARE_NAPI_FUNCTION("getNativeHeapFreeSize", GetNativeHeapFreeSize),
1004         DECLARE_NAPI_FUNCTION("getVss", GetVss),
1005         DECLARE_NAPI_FUNCTION("removeNapiWrap", RemoveNapiWrap),
1006         DECLARE_NAPI_FUNCTION("getAppVMMemoryInfo", GetAppVMMemoryInfo),
1007         DECLARE_NAPI_FUNCTION("getAppThreadCpuUsage", GetAppThreadCpuUsage),
1008         DECLARE_NAPI_FUNCTION("getSystemCpuUsage", GetSystemCpuUsage),
1009         DECLARE_NAPI_FUNCTION("getAppMemoryLimit", GetAppMemoryLimit),
1010         DECLARE_NAPI_FUNCTION("getAppNativeMemInfo", GetAppNativeMemInfo),
1011         DECLARE_NAPI_FUNCTION("getAppNativeMemInfoWithCache", GetAppNativeMemInfoWithCache),
1012         DECLARE_NAPI_FUNCTION("getAppNativeMemInfoAsync", GetAppNativeMemInfoAsync),
1013         DECLARE_NAPI_FUNCTION("getSystemMemInfo", GetSystemMemInfo),
1014         DECLARE_NAPI_FUNCTION("startAppTraceCapture", StartAppTraceCapture),
1015         DECLARE_NAPI_FUNCTION("stopAppTraceCapture", StopAppTraceCapture),
1016         DECLARE_NAPI_FUNCTION("getVMRuntimeStats", GetVMRuntimeStats),
1017         DECLARE_NAPI_FUNCTION("getVMRuntimeStat", GetVMRuntimeStat),
1018         DECLARE_NAPI_FUNCTION("setAppResourceLimit", SetAppResourceLimit),
1019         DECLARE_NAPI_FUNCTION("isDebugState", IsDebugState),
1020         DECLARE_NAPI_FUNCTION("getGraphicsMemory", GetGraphicsMemory),
1021         DECLARE_NAPI_FUNCTION("getGraphicsMemorySync", GetGraphicsMemorySync),
1022         DECLARE_NAPI_FUNCTION("dumpJsRawHeapData", DumpJsRawHeapData),
1023         DECLARE_NAPI_FUNCTION("enableGwpAsanGrayscale", EnableGwpAsanGrayscale),
1024         DECLARE_NAPI_FUNCTION("disableGwpAsanGrayscale", DisableGwpAsanGrayscale),
1025         DECLARE_NAPI_FUNCTION("getGwpAsanGrayscaleState", GetGwpAsanGrayscaleState),
1026         DECLARE_NAPI_FUNCTION("setJsRawHeapTrimLevel", SetJsRawHeapTrimLevel),
1027     };
1028     NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc));
1029     InitNapiClass(env, exports);
1030     return exports;
1031 }
1032 
1033 static napi_module hidebugModule = {
1034     .nm_version = 1,
1035     .nm_flags = 0,
1036     .nm_filename = nullptr,
1037     .nm_register_func = HiviewDFX::DeclareHiDebugInterface,
1038     .nm_modname = "hidebug",
1039     .nm_priv = ((void *)0),
1040     .reserved = {0}
1041 };
1042 
HiDebugRegisterModule(void)1043 extern "C" __attribute__((constructor)) void HiDebugRegisterModule(void)
1044 {
1045     napi_module_register(&hidebugModule);
1046 }
1047 } // HiviewDFX
1048 } // OHOS
1049