1 /*
2  * Copyright (c) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "napi_hichecker.h"
17 
18 #include <map>
19 
20 #include "hichecker.h"
21 #include "hilog/log_c.h"
22 #include "hilog/log_cpp.h"
23 
24 namespace OHOS {
25 namespace HiviewDFX {
26 namespace {
27 #undef LOG_DOMAIN
28 #define LOG_DOMAIN 0xD002D0B
29 #undef LOG_TAG
30 #define LOG_TAG "HiChecker_NAPI"
31 constexpr int ONE_VALUE_LIMIT = 1;
32 constexpr int ARRAY_INDEX_FIRST = 0;
33 constexpr uint64_t GET_RULE_PARAM_FAIL = 0;
34 constexpr int ERR_PARAM = 401;
35 }
36 
AddRule(napi_env env,napi_callback_info info)37 napi_value AddRule(napi_env env, napi_callback_info info)
38 {
39     uint64_t rule = GetRuleParam(env, info);
40     if (rule != GET_RULE_PARAM_FAIL) {
41         HiChecker::AddRule(rule);
42     }
43     return CreateUndefined(env);
44 }
45 
RemoveRule(napi_env env,napi_callback_info info)46 napi_value RemoveRule(napi_env env, napi_callback_info info)
47 {
48     uint64_t rule = GetRuleParam(env, info);
49     if (rule != GET_RULE_PARAM_FAIL) {
50         HiChecker::RemoveRule(rule);
51     }
52     return CreateUndefined(env);
53 }
54 
GetRule(napi_env env,napi_callback_info info)55 napi_value GetRule(napi_env env, napi_callback_info info)
56 {
57     uint64_t rule = HiChecker::GetRule();
58     return ToUInt64Value(env, rule);
59 }
60 
Contains(napi_env env,napi_callback_info info)61 napi_value Contains(napi_env env, napi_callback_info info)
62 {
63     uint64_t rule = GetRuleParam(env, info);
64     napi_value result = nullptr;
65     napi_get_boolean(env, HiChecker::Contains(rule), &result);
66     return result;
67 }
68 
AddCheckRule(napi_env env,napi_callback_info info)69 napi_value AddCheckRule(napi_env env, napi_callback_info info)
70 {
71     uint64_t rule = GetRuleParam(env, info);
72     if (rule != GET_RULE_PARAM_FAIL) {
73         HiChecker::AddRule(rule);
74     } else {
75         ThrowError(env, ERR_PARAM);
76     }
77     return CreateUndefined(env);
78 }
79 
RemoveCheckRule(napi_env env,napi_callback_info info)80 napi_value RemoveCheckRule(napi_env env, napi_callback_info info)
81 {
82     uint64_t rule = GetRuleParam(env, info);
83     if (rule != GET_RULE_PARAM_FAIL) {
84         HiChecker::RemoveRule(rule);
85     } else {
86         ThrowError(env, ERR_PARAM);
87     }
88     return CreateUndefined(env);
89 }
90 
ContainsCheckRule(napi_env env,napi_callback_info info)91 napi_value ContainsCheckRule(napi_env env, napi_callback_info info)
92 {
93     napi_value result = nullptr;
94     uint64_t rule = GetRuleParam(env, info);
95     if (rule == GET_RULE_PARAM_FAIL) {
96         ThrowError(env, ERR_PARAM);
97     }
98     napi_get_boolean(env, HiChecker::Contains(rule), &result);
99     return result;
100 }
101 
DeclareHiCheckerInterface(napi_env env,napi_value exports)102 napi_value DeclareHiCheckerInterface(napi_env env, napi_value exports)
103 {
104     napi_property_descriptor desc[] = {
105         DECLARE_NAPI_FUNCTION("addRule", AddRule),
106         DECLARE_NAPI_FUNCTION("removeRule", RemoveRule),
107         DECLARE_NAPI_FUNCTION("getRule", GetRule),
108         DECLARE_NAPI_FUNCTION("contains", Contains),
109         DECLARE_NAPI_FUNCTION("addCheckRule", AddCheckRule),
110         DECLARE_NAPI_FUNCTION("removeCheckRule", RemoveCheckRule),
111         DECLARE_NAPI_FUNCTION("containsCheckRule", ContainsCheckRule),
112     };
113     NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc));
114     DeclareHiCheckerRuleEnum(env, exports);
115     return exports;
116 }
117 
DeclareHiCheckerRuleEnum(napi_env env,napi_value exports)118 napi_value DeclareHiCheckerRuleEnum(napi_env env, napi_value exports)
119 {
120     napi_property_descriptor desc[] = {
121         DECLARE_NAPI_STATIC_PROPERTY("RULE_CAUTION_PRINT_LOG", ToUInt64Value(env, Rule::RULE_CAUTION_PRINT_LOG)),
122         DECLARE_NAPI_STATIC_PROPERTY("RULE_CAUTION_TRIGGER_CRASH",
123             ToUInt64Value(env, Rule::RULE_CAUTION_TRIGGER_CRASH)),
124         DECLARE_NAPI_STATIC_PROPERTY("RULE_THREAD_CHECK_SLOW_PROCESS",
125             ToUInt64Value(env, Rule::RULE_THREAD_CHECK_SLOW_PROCESS)),
126         DECLARE_NAPI_STATIC_PROPERTY("RULE_CHECK_SLOW_EVENT", ToUInt64Value(env, Rule::RULE_CHECK_SLOW_EVENT)),
127         DECLARE_NAPI_STATIC_PROPERTY("RULE_CHECK_ABILITY_CONNECTION_LEAK",
128             ToUInt64Value(env, Rule::RULE_CHECK_ABILITY_CONNECTION_LEAK)),
129         DECLARE_NAPI_STATIC_PROPERTY("RULE_CHECK_ARKUI_PERFORMANCE",
130             ToUInt64Value(env, Rule::RULE_CHECK_ARKUI_PERFORMANCE)),
131     };
132     NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc));
133     return exports;
134 }
135 
ToUInt64Value(napi_env env,uint64_t value)136 napi_value ToUInt64Value(napi_env env, uint64_t value)
137 {
138     napi_value staticValue = nullptr;
139     napi_create_bigint_uint64(env, value, &staticValue);
140     return staticValue;
141 }
142 
CreateUndefined(napi_env env)143 napi_value CreateUndefined(napi_env env)
144 {
145     napi_value result = nullptr;
146     napi_get_undefined(env, &result);
147     return result;
148 }
149 
ThrowError(napi_env env,int errCode)150 void ThrowError(napi_env env, int errCode)
151 {
152     std::map<int, std::string> errMap = {
153         { ERR_PARAM, "Invalid input parameter! only one bigint type parameter is needed" },
154     };
155     if (errMap.find(errCode) != errMap.end()) {
156         napi_throw_error(env, std::to_string(errCode).c_str(), errMap[errCode].c_str());
157     }
158     return;
159 }
160 
GetRuleParam(napi_env env,napi_callback_info info)161 uint64_t GetRuleParam(napi_env env, napi_callback_info info)
162 {
163     size_t argc = ONE_VALUE_LIMIT;
164     napi_value argv[ONE_VALUE_LIMIT] = { nullptr };
165     napi_value thisVar = nullptr;
166     void *data = nullptr;
167     napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
168     if (argc != ONE_VALUE_LIMIT) {
169         HILOG_ERROR(LOG_CORE, "invalid number=%{public}d of params.", ONE_VALUE_LIMIT);
170         return GET_RULE_PARAM_FAIL;
171     }
172     if (!MatchValueType(env, argv[ARRAY_INDEX_FIRST], napi_bigint)) {
173         HILOG_ERROR(LOG_CORE, "Type error, should be bigint type!");
174         return GET_RULE_PARAM_FAIL;
175     }
176     uint64_t rule = GET_RULE_PARAM_FAIL;
177     bool lossless = true;
178     napi_get_value_bigint_uint64(env, argv[ARRAY_INDEX_FIRST], &rule, &lossless);
179     if (!lossless) {
180         HILOG_ERROR(LOG_CORE, "Type error, bigint should be 64!");
181         return GET_RULE_PARAM_FAIL;
182     }
183     if (rule == GET_RULE_PARAM_FAIL) {
184         HILOG_ERROR(LOG_CORE, "invalid input, please check!");
185     }
186     return rule;
187 }
188 
MatchValueType(napi_env env,napi_value value,napi_valuetype targetType)189 bool MatchValueType(napi_env env, napi_value value, napi_valuetype targetType)
190 {
191     napi_valuetype valueType = napi_undefined;
192     napi_typeof(env, value, &valueType);
193     return valueType == targetType;
194 }
195 
196 static napi_module g_module = {
197     .nm_version = 1,
198     .nm_flags = 0,
199     .nm_filename = nullptr,
200     .nm_register_func = DeclareHiCheckerInterface,
201     .nm_modname = "hichecker",
202     .nm_priv = ((void *)0),
203     .reserved = {0}
204 };
205 
HiCheckerRegisterModule(void)206 extern "C" __attribute__((constructor)) void HiCheckerRegisterModule(void)
207 {
208     napi_module_register(&g_module);
209 }
210 } // HiviewDFX
211 } // OHOS
212