• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include "napi_config_builder.h"
16 
17 #include "hiappevent_base.h"
18 #include "hilog/log.h"
19 #include "napi_error.h"
20 #include "napi_util.h"
21 #include "resource_overlimit_mgr.h"
22 
23 #undef LOG_DOMAIN
24 #define LOG_DOMAIN 0xD002D07
25 
26 #undef LOG_TAG
27 #define LOG_TAG "NapiConfigBuilder"
28 
29 namespace OHOS {
30 namespace HiviewDFX {
31 namespace {
32 constexpr size_t CONFIG_PARAM_NUM = 2;
33 constexpr size_t INDEX_OF_NAME_CONFIG = 0;
34 constexpr size_t INDEX_OF_VALUE_CONFIG = 1;
35 constexpr const char* const APP_CRASH = "APP_CRASH";
36 constexpr const char* const MAIN_THREAD_JANK = "MAIN_THREAD_JANK";
37 constexpr int CRASH_LOG_MAX_CAPACITY = 5 * 1024 * 1024;  // 5M
38 struct crashConfig {
39     uint8_t type;
40     std::function<bool(const napi_env, const napi_value, const std::string&, uint32_t&)> func;
41 };
42 
GetCrashConfigBoolValue(const napi_env env,const napi_value configs,const std::string & key,uint32_t & out)43 bool GetCrashConfigBoolValue(const napi_env env, const napi_value configs, const std::string& key, uint32_t& out)
44 {
45     napi_value value = NapiUtil::GetProperty(env, configs, key);
46     if (!NapiUtil::IsBoolean(env, value)) {
47         HILOG_ERROR(LOG_CORE, "Set crash config item(%{public}s) failed, the value should be bool type.", key.c_str());
48         return false;
49     }
50 
51     out = NapiUtil::GetBoolean(env, value) == true ? 1 : 0;
52     return true;
53 }
54 
GetCrashConfigUIntValue(const napi_env env,const napi_value configs,const std::string & key,uint32_t & out)55 bool GetCrashConfigUIntValue(const napi_env env, const napi_value configs, const std::string& key, uint32_t& out)
56 {
57     napi_value value = NapiUtil::GetProperty(env, configs, key);
58     if (!NapiUtil::IsNumber(env, value)) {
59         HILOG_ERROR(LOG_CORE, "Set crash config item(%{public}s) failed, the value should be a number.", key.c_str());
60         return false;
61     }
62 
63     int64_t intValue = NapiUtil::GetInt64(env, value);
64     if (intValue < 0 || intValue > CRASH_LOG_MAX_CAPACITY) {
65         HILOG_ERROR(LOG_CORE, "Set crash config item(%{public}s) failed, the value is over range.", key.c_str());
66         return false;
67     }
68 
69     out = static_cast<uint32_t>(intValue);
70     return true;
71 }
72 }
73 
BuildEventConfig(const napi_env env,const napi_value params[],size_t len)74 std::unique_ptr<EventConfigPack> NapiConfigBuilder::BuildEventConfig(const napi_env env, const napi_value params[],
75     size_t len)
76 {
77     if (len < CONFIG_PARAM_NUM) {
78         NapiUtil::ThrowError(env, NapiError::ERR_PARAM, NapiUtil::CreateErrMsg("setEventParam"));
79         return nullptr;
80     }
81     if (!NapiUtil::IsString(env, params[INDEX_OF_NAME_CONFIG])) {
82         NapiUtil::ThrowError(env, NapiError::ERR_PARAM, NapiUtil::CreateErrMsg("name", "string"));
83         return nullptr;
84     }
85     if (!NapiUtil::IsObject(env, params[INDEX_OF_VALUE_CONFIG])) {
86         NapiUtil::ThrowError(env, NapiError::ERR_PARAM, NapiUtil::CreateErrMsg("value", "object"));
87         return nullptr;
88     }
89 
90     eventConfigPack_->eventName = NapiUtil::GetString(env, params[INDEX_OF_NAME_CONFIG]);
91     std::unordered_set<std::string> whiteList = { MAIN_THREAD_JANK, RESOURCE_OVERLIMIT };
92     if (eventConfigPack_->eventName == APP_CRASH) {
93         GetAppCrashConfig(env, params[INDEX_OF_VALUE_CONFIG]);
94     } else if (whiteList.count(eventConfigPack_->eventName) != 0) {
95         GetCommonConfig(env, params[INDEX_OF_VALUE_CONFIG]);
96     } else {
97         HILOG_ERROR(LOG_CORE, "Failed to set event config, name is invalid. name=%{public}s",
98             eventConfigPack_->eventName.c_str());
99     }
100     return std::move(eventConfigPack_);
101 }
102 
GetAppCrashConfig(const napi_env env,const napi_value params)103 void NapiConfigBuilder::GetAppCrashConfig(const napi_env env, const napi_value params)
104 {
105     std::vector<std::string> configKeys;
106     NapiUtil::GetPropertyNames(env, params, configKeys);
107     if (configKeys.empty()) {
108         HILOG_INFO(LOG_CORE, "Set config failed, the config is empty.");
109         return;
110     }
111 
112     std::map<std::string, crashConfig> crashConfigs = {
113         {"extend_pc_lr_printing", {.type = 0, .func = GetCrashConfigBoolValue}},
114         {"log_file_cutoff_sz_bytes", {.type = 1, .func = GetCrashConfigUIntValue}},
115         {"simplify_vma_printing", {.type = 2, .func = GetCrashConfigBoolValue}}
116     };
117 
118     uint32_t configValue = 0;
119     for (const auto& configKey : configKeys) {
120         auto it = crashConfigs.find(configKey);
121         if (it == crashConfigs.end()) {
122             HILOG_WARN(LOG_CORE, "Set crash config item(%{public}s) failed, it is not supported.", configKey.c_str());
123             continue;
124         }
125 
126         if ((it->second.func)(env, params, configKey, configValue)) {
127             eventConfigPack_->configUintMap[it->second.type] = configValue;
128             eventConfigPack_->isValid = true;
129             HILOG_INFO(LOG_CORE, "Set crash config item(%{public}s) success. Value=%{public}d", configKey.c_str(),
130                 configValue);
131         }
132     }
133 }
134 
GetCommonConfig(const napi_env env,const napi_value params)135 void NapiConfigBuilder::GetCommonConfig(const napi_env env, const napi_value params)
136 {
137     std::vector<std::string> configKeys;
138     NapiUtil::GetPropertyNames(env, params, configKeys);
139     if (configKeys.empty()) {
140         HILOG_INFO(LOG_CORE, "Set MainThreadJank config failed, the config is empty.");
141         return;
142     }
143 
144     eventConfigPack_->isValid = true;
145     std::map<std::string, std::string> configMap;
146     for (const auto& configkey : configKeys) {
147         napi_value configValue = NapiUtil::GetProperty(env, params, configkey);
148         if (!NapiUtil::IsString(env, configValue)) {
149             HILOG_ERROR(LOG_CORE, "Failed to get config Value, the value type of the item(%{public}s) is not string.",
150                 configkey.c_str());
151             eventConfigPack_->isValid = false;
152             return;
153         }
154         configMap[configkey] = NapiUtil::GetString(env, configValue);
155     }
156     eventConfigPack_->configStringMap = std::move(configMap);
157 }
158 } // namespace HiviewDFX
159 } // namespace OHOS