139baaf62Sopenharmony_ci/*
239baaf62Sopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd.
339baaf62Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
439baaf62Sopenharmony_ci * you may not use this file except in compliance with the License.
539baaf62Sopenharmony_ci * You may obtain a copy of the License at
639baaf62Sopenharmony_ci *
739baaf62Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0
839baaf62Sopenharmony_ci *
939baaf62Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
1039baaf62Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
1139baaf62Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1239baaf62Sopenharmony_ci * See the License for the specific language governing permissions and
1339baaf62Sopenharmony_ci * limitations under the License.
1439baaf62Sopenharmony_ci */
1539baaf62Sopenharmony_ci
1639baaf62Sopenharmony_ci#include "napi_hichecker.h"
1739baaf62Sopenharmony_ci
1839baaf62Sopenharmony_ci#include <map>
1939baaf62Sopenharmony_ci
2039baaf62Sopenharmony_ci#include "hichecker.h"
2139baaf62Sopenharmony_ci#include "hilog/log_c.h"
2239baaf62Sopenharmony_ci#include "hilog/log_cpp.h"
2339baaf62Sopenharmony_ci
2439baaf62Sopenharmony_cinamespace OHOS {
2539baaf62Sopenharmony_cinamespace HiviewDFX {
2639baaf62Sopenharmony_cinamespace {
2739baaf62Sopenharmony_ci#undef LOG_DOMAIN
2839baaf62Sopenharmony_ci#define LOG_DOMAIN 0xD002D0B
2939baaf62Sopenharmony_ci#undef LOG_TAG
3039baaf62Sopenharmony_ci#define LOG_TAG "HiChecker_NAPI"
3139baaf62Sopenharmony_ciconstexpr int ONE_VALUE_LIMIT = 1;
3239baaf62Sopenharmony_ciconstexpr int ARRAY_INDEX_FIRST = 0;
3339baaf62Sopenharmony_ciconstexpr uint64_t GET_RULE_PARAM_FAIL = 0;
3439baaf62Sopenharmony_ciconstexpr int ERR_PARAM = 401;
3539baaf62Sopenharmony_ci}
3639baaf62Sopenharmony_ci
3739baaf62Sopenharmony_cinapi_value AddRule(napi_env env, napi_callback_info info)
3839baaf62Sopenharmony_ci{
3939baaf62Sopenharmony_ci    uint64_t rule = GetRuleParam(env, info);
4039baaf62Sopenharmony_ci    if (rule != GET_RULE_PARAM_FAIL) {
4139baaf62Sopenharmony_ci        HiChecker::AddRule(rule);
4239baaf62Sopenharmony_ci    }
4339baaf62Sopenharmony_ci    return CreateUndefined(env);
4439baaf62Sopenharmony_ci}
4539baaf62Sopenharmony_ci
4639baaf62Sopenharmony_cinapi_value RemoveRule(napi_env env, napi_callback_info info)
4739baaf62Sopenharmony_ci{
4839baaf62Sopenharmony_ci    uint64_t rule = GetRuleParam(env, info);
4939baaf62Sopenharmony_ci    if (rule != GET_RULE_PARAM_FAIL) {
5039baaf62Sopenharmony_ci        HiChecker::RemoveRule(rule);
5139baaf62Sopenharmony_ci    }
5239baaf62Sopenharmony_ci    return CreateUndefined(env);
5339baaf62Sopenharmony_ci}
5439baaf62Sopenharmony_ci
5539baaf62Sopenharmony_cinapi_value GetRule(napi_env env, napi_callback_info info)
5639baaf62Sopenharmony_ci{
5739baaf62Sopenharmony_ci    uint64_t rule = HiChecker::GetRule();
5839baaf62Sopenharmony_ci    return ToUInt64Value(env, rule);
5939baaf62Sopenharmony_ci}
6039baaf62Sopenharmony_ci
6139baaf62Sopenharmony_cinapi_value Contains(napi_env env, napi_callback_info info)
6239baaf62Sopenharmony_ci{
6339baaf62Sopenharmony_ci    uint64_t rule = GetRuleParam(env, info);
6439baaf62Sopenharmony_ci    napi_value result = nullptr;
6539baaf62Sopenharmony_ci    napi_get_boolean(env, HiChecker::Contains(rule), &result);
6639baaf62Sopenharmony_ci    return result;
6739baaf62Sopenharmony_ci}
6839baaf62Sopenharmony_ci
6939baaf62Sopenharmony_cinapi_value AddCheckRule(napi_env env, napi_callback_info info)
7039baaf62Sopenharmony_ci{
7139baaf62Sopenharmony_ci    uint64_t rule = GetRuleParam(env, info);
7239baaf62Sopenharmony_ci    if (rule != GET_RULE_PARAM_FAIL) {
7339baaf62Sopenharmony_ci        HiChecker::AddRule(rule);
7439baaf62Sopenharmony_ci    } else {
7539baaf62Sopenharmony_ci        ThrowError(env, ERR_PARAM);
7639baaf62Sopenharmony_ci    }
7739baaf62Sopenharmony_ci    return CreateUndefined(env);
7839baaf62Sopenharmony_ci}
7939baaf62Sopenharmony_ci
8039baaf62Sopenharmony_cinapi_value RemoveCheckRule(napi_env env, napi_callback_info info)
8139baaf62Sopenharmony_ci{
8239baaf62Sopenharmony_ci    uint64_t rule = GetRuleParam(env, info);
8339baaf62Sopenharmony_ci    if (rule != GET_RULE_PARAM_FAIL) {
8439baaf62Sopenharmony_ci        HiChecker::RemoveRule(rule);
8539baaf62Sopenharmony_ci    } else {
8639baaf62Sopenharmony_ci        ThrowError(env, ERR_PARAM);
8739baaf62Sopenharmony_ci    }
8839baaf62Sopenharmony_ci    return CreateUndefined(env);
8939baaf62Sopenharmony_ci}
9039baaf62Sopenharmony_ci
9139baaf62Sopenharmony_cinapi_value ContainsCheckRule(napi_env env, napi_callback_info info)
9239baaf62Sopenharmony_ci{
9339baaf62Sopenharmony_ci    napi_value result = nullptr;
9439baaf62Sopenharmony_ci    uint64_t rule = GetRuleParam(env, info);
9539baaf62Sopenharmony_ci    if (rule == GET_RULE_PARAM_FAIL) {
9639baaf62Sopenharmony_ci        ThrowError(env, ERR_PARAM);
9739baaf62Sopenharmony_ci    }
9839baaf62Sopenharmony_ci    napi_get_boolean(env, HiChecker::Contains(rule), &result);
9939baaf62Sopenharmony_ci    return result;
10039baaf62Sopenharmony_ci}
10139baaf62Sopenharmony_ci
10239baaf62Sopenharmony_cinapi_value DeclareHiCheckerInterface(napi_env env, napi_value exports)
10339baaf62Sopenharmony_ci{
10439baaf62Sopenharmony_ci    napi_property_descriptor desc[] = {
10539baaf62Sopenharmony_ci        DECLARE_NAPI_FUNCTION("addRule", AddRule),
10639baaf62Sopenharmony_ci        DECLARE_NAPI_FUNCTION("removeRule", RemoveRule),
10739baaf62Sopenharmony_ci        DECLARE_NAPI_FUNCTION("getRule", GetRule),
10839baaf62Sopenharmony_ci        DECLARE_NAPI_FUNCTION("contains", Contains),
10939baaf62Sopenharmony_ci        DECLARE_NAPI_FUNCTION("addCheckRule", AddCheckRule),
11039baaf62Sopenharmony_ci        DECLARE_NAPI_FUNCTION("removeCheckRule", RemoveCheckRule),
11139baaf62Sopenharmony_ci        DECLARE_NAPI_FUNCTION("containsCheckRule", ContainsCheckRule),
11239baaf62Sopenharmony_ci    };
11339baaf62Sopenharmony_ci    NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc));
11439baaf62Sopenharmony_ci    DeclareHiCheckerRuleEnum(env, exports);
11539baaf62Sopenharmony_ci    return exports;
11639baaf62Sopenharmony_ci}
11739baaf62Sopenharmony_ci
11839baaf62Sopenharmony_cinapi_value DeclareHiCheckerRuleEnum(napi_env env, napi_value exports)
11939baaf62Sopenharmony_ci{
12039baaf62Sopenharmony_ci    napi_property_descriptor desc[] = {
12139baaf62Sopenharmony_ci        DECLARE_NAPI_STATIC_PROPERTY("RULE_CAUTION_PRINT_LOG", ToUInt64Value(env, Rule::RULE_CAUTION_PRINT_LOG)),
12239baaf62Sopenharmony_ci        DECLARE_NAPI_STATIC_PROPERTY("RULE_CAUTION_TRIGGER_CRASH",
12339baaf62Sopenharmony_ci            ToUInt64Value(env, Rule::RULE_CAUTION_TRIGGER_CRASH)),
12439baaf62Sopenharmony_ci        DECLARE_NAPI_STATIC_PROPERTY("RULE_THREAD_CHECK_SLOW_PROCESS",
12539baaf62Sopenharmony_ci            ToUInt64Value(env, Rule::RULE_THREAD_CHECK_SLOW_PROCESS)),
12639baaf62Sopenharmony_ci        DECLARE_NAPI_STATIC_PROPERTY("RULE_CHECK_SLOW_EVENT", ToUInt64Value(env, Rule::RULE_CHECK_SLOW_EVENT)),
12739baaf62Sopenharmony_ci        DECLARE_NAPI_STATIC_PROPERTY("RULE_CHECK_ABILITY_CONNECTION_LEAK",
12839baaf62Sopenharmony_ci            ToUInt64Value(env, Rule::RULE_CHECK_ABILITY_CONNECTION_LEAK)),
12939baaf62Sopenharmony_ci        DECLARE_NAPI_STATIC_PROPERTY("RULE_CHECK_ARKUI_PERFORMANCE",
13039baaf62Sopenharmony_ci            ToUInt64Value(env, Rule::RULE_CHECK_ARKUI_PERFORMANCE)),
13139baaf62Sopenharmony_ci    };
13239baaf62Sopenharmony_ci    NAPI_CALL(env, napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc));
13339baaf62Sopenharmony_ci    return exports;
13439baaf62Sopenharmony_ci}
13539baaf62Sopenharmony_ci
13639baaf62Sopenharmony_cinapi_value ToUInt64Value(napi_env env, uint64_t value)
13739baaf62Sopenharmony_ci{
13839baaf62Sopenharmony_ci    napi_value staticValue = nullptr;
13939baaf62Sopenharmony_ci    napi_create_bigint_uint64(env, value, &staticValue);
14039baaf62Sopenharmony_ci    return staticValue;
14139baaf62Sopenharmony_ci}
14239baaf62Sopenharmony_ci
14339baaf62Sopenharmony_cinapi_value CreateUndefined(napi_env env)
14439baaf62Sopenharmony_ci{
14539baaf62Sopenharmony_ci    napi_value result = nullptr;
14639baaf62Sopenharmony_ci    napi_get_undefined(env, &result);
14739baaf62Sopenharmony_ci    return result;
14839baaf62Sopenharmony_ci}
14939baaf62Sopenharmony_ci
15039baaf62Sopenharmony_civoid ThrowError(napi_env env, int errCode)
15139baaf62Sopenharmony_ci{
15239baaf62Sopenharmony_ci    std::map<int, std::string> errMap = {
15339baaf62Sopenharmony_ci        { ERR_PARAM, "Invalid input parameter! only one bigint type parameter is needed" },
15439baaf62Sopenharmony_ci    };
15539baaf62Sopenharmony_ci    if (errMap.find(errCode) != errMap.end()) {
15639baaf62Sopenharmony_ci        napi_throw_error(env, std::to_string(errCode).c_str(), errMap[errCode].c_str());
15739baaf62Sopenharmony_ci    }
15839baaf62Sopenharmony_ci    return;
15939baaf62Sopenharmony_ci}
16039baaf62Sopenharmony_ci
16139baaf62Sopenharmony_ciuint64_t GetRuleParam(napi_env env, napi_callback_info info)
16239baaf62Sopenharmony_ci{
16339baaf62Sopenharmony_ci    size_t argc = ONE_VALUE_LIMIT;
16439baaf62Sopenharmony_ci    napi_value argv[ONE_VALUE_LIMIT] = { nullptr };
16539baaf62Sopenharmony_ci    napi_value thisVar = nullptr;
16639baaf62Sopenharmony_ci    void *data = nullptr;
16739baaf62Sopenharmony_ci    napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
16839baaf62Sopenharmony_ci    if (argc != ONE_VALUE_LIMIT) {
16939baaf62Sopenharmony_ci        HILOG_ERROR(LOG_CORE, "invalid number=%{public}d of params.", ONE_VALUE_LIMIT);
17039baaf62Sopenharmony_ci        return GET_RULE_PARAM_FAIL;
17139baaf62Sopenharmony_ci    }
17239baaf62Sopenharmony_ci    if (!MatchValueType(env, argv[ARRAY_INDEX_FIRST], napi_bigint)) {
17339baaf62Sopenharmony_ci        HILOG_ERROR(LOG_CORE, "Type error, should be bigint type!");
17439baaf62Sopenharmony_ci        return GET_RULE_PARAM_FAIL;
17539baaf62Sopenharmony_ci    }
17639baaf62Sopenharmony_ci    uint64_t rule = GET_RULE_PARAM_FAIL;
17739baaf62Sopenharmony_ci    bool lossless = true;
17839baaf62Sopenharmony_ci    napi_get_value_bigint_uint64(env, argv[ARRAY_INDEX_FIRST], &rule, &lossless);
17939baaf62Sopenharmony_ci    if (!lossless) {
18039baaf62Sopenharmony_ci        HILOG_ERROR(LOG_CORE, "Type error, bigint should be 64!");
18139baaf62Sopenharmony_ci        return GET_RULE_PARAM_FAIL;
18239baaf62Sopenharmony_ci    }
18339baaf62Sopenharmony_ci    if (rule == GET_RULE_PARAM_FAIL) {
18439baaf62Sopenharmony_ci        HILOG_ERROR(LOG_CORE, "invalid input, please check!");
18539baaf62Sopenharmony_ci    }
18639baaf62Sopenharmony_ci    return rule;
18739baaf62Sopenharmony_ci}
18839baaf62Sopenharmony_ci
18939baaf62Sopenharmony_cibool MatchValueType(napi_env env, napi_value value, napi_valuetype targetType)
19039baaf62Sopenharmony_ci{
19139baaf62Sopenharmony_ci    napi_valuetype valueType = napi_undefined;
19239baaf62Sopenharmony_ci    napi_typeof(env, value, &valueType);
19339baaf62Sopenharmony_ci    return valueType == targetType;
19439baaf62Sopenharmony_ci}
19539baaf62Sopenharmony_ci
19639baaf62Sopenharmony_cistatic napi_module g_module = {
19739baaf62Sopenharmony_ci    .nm_version = 1,
19839baaf62Sopenharmony_ci    .nm_flags = 0,
19939baaf62Sopenharmony_ci    .nm_filename = nullptr,
20039baaf62Sopenharmony_ci    .nm_register_func = DeclareHiCheckerInterface,
20139baaf62Sopenharmony_ci    .nm_modname = "hichecker",
20239baaf62Sopenharmony_ci    .nm_priv = ((void *)0),
20339baaf62Sopenharmony_ci    .reserved = {0}
20439baaf62Sopenharmony_ci};
20539baaf62Sopenharmony_ci
20639baaf62Sopenharmony_ciextern "C" __attribute__((constructor)) void HiCheckerRegisterModule(void)
20739baaf62Sopenharmony_ci{
20839baaf62Sopenharmony_ci    napi_module_register(&g_module);
20939baaf62Sopenharmony_ci}
21039baaf62Sopenharmony_ci} // HiviewDFX
21139baaf62Sopenharmony_ci} // OHOS
212