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