1020a203aSopenharmony_ci/*
2020a203aSopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd.
3020a203aSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4020a203aSopenharmony_ci * you may not use this file except in compliance with the License.
5020a203aSopenharmony_ci * You may obtain a copy of the License at
6020a203aSopenharmony_ci *
7020a203aSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8020a203aSopenharmony_ci *
9020a203aSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10020a203aSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11020a203aSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12020a203aSopenharmony_ci * See the License for the specific language governing permissions and
13020a203aSopenharmony_ci * limitations under the License.
14020a203aSopenharmony_ci */
15020a203aSopenharmony_ci
16020a203aSopenharmony_ci#include "hiview_napi_util.h"
17020a203aSopenharmony_ci
18020a203aSopenharmony_ci#include "hiview_err_code.h"
19020a203aSopenharmony_ci#include "hiview_logger.h"
20020a203aSopenharmony_ci#include "ipc_skeleton.h"
21020a203aSopenharmony_ci#include "tokenid_kit.h"
22020a203aSopenharmony_ci
23020a203aSopenharmony_cinamespace OHOS {
24020a203aSopenharmony_cinamespace HiviewDFX {
25020a203aSopenharmony_ciDEFINE_LOG_LABEL(0xD002D03, "HiviewNapiUtil");
26020a203aSopenharmony_cinamespace {
27020a203aSopenharmony_ciconstexpr char FILE_NAME_KEY[] = "name";
28020a203aSopenharmony_ciconstexpr char FILE_TIME_KEY[] = "mtime";
29020a203aSopenharmony_ciconstexpr char FILE_SIZE_KEY[] = "size";
30020a203aSopenharmony_ciconstexpr int32_t BUF_SIZE = 1024;
31020a203aSopenharmony_ci}
32020a203aSopenharmony_ci
33020a203aSopenharmony_civoid HiviewNapiUtil::CreateUndefined(const napi_env env, napi_value& ret)
34020a203aSopenharmony_ci{
35020a203aSopenharmony_ci    if (napi_get_undefined(env, &ret) != napi_ok) {
36020a203aSopenharmony_ci        HIVIEW_LOGE("failed to create undefined value.");
37020a203aSopenharmony_ci    }
38020a203aSopenharmony_ci}
39020a203aSopenharmony_ci
40020a203aSopenharmony_civoid HiviewNapiUtil::CreateInt32Value(const napi_env env, int32_t value, napi_value& ret)
41020a203aSopenharmony_ci{
42020a203aSopenharmony_ci    if (napi_create_int32(env, value, &ret) != napi_ok) {
43020a203aSopenharmony_ci        HIVIEW_LOGE("failed to create int32 napi value.");
44020a203aSopenharmony_ci    }
45020a203aSopenharmony_ci}
46020a203aSopenharmony_ci
47020a203aSopenharmony_civoid HiviewNapiUtil::CreateInt64Value(const napi_env env, int64_t value, napi_value& ret)
48020a203aSopenharmony_ci{
49020a203aSopenharmony_ci    if (napi_create_int64(env, value, &ret) != napi_ok) {
50020a203aSopenharmony_ci        HIVIEW_LOGE("failed to create int64 napi value.");
51020a203aSopenharmony_ci    }
52020a203aSopenharmony_ci}
53020a203aSopenharmony_ci
54020a203aSopenharmony_civoid HiviewNapiUtil::CreateStringValue(const napi_env env, const std::string& value, napi_value& ret)
55020a203aSopenharmony_ci{
56020a203aSopenharmony_ci    if (napi_create_string_utf8(env, value.c_str(), NAPI_AUTO_LENGTH, &ret) != napi_ok) {
57020a203aSopenharmony_ci        HIVIEW_LOGE("failed to create string napi value.");
58020a203aSopenharmony_ci    }
59020a203aSopenharmony_ci}
60020a203aSopenharmony_ci
61020a203aSopenharmony_civoid HiviewNapiUtil::CreateErrorByRet(napi_env env, const int32_t retCode, napi_value& ret)
62020a203aSopenharmony_ci{
63020a203aSopenharmony_ci    auto detail = GetErrorDetailByRet(env, retCode);
64020a203aSopenharmony_ci    napi_value napiCode = nullptr;
65020a203aSopenharmony_ci    CreateStringValue(env, std::to_string(detail.first), napiCode);
66020a203aSopenharmony_ci    napi_value napiStr = nullptr;
67020a203aSopenharmony_ci    CreateStringValue(env, detail.second, napiStr);
68020a203aSopenharmony_ci    if (napi_create_error(env, napiCode, napiStr, &ret) != napi_ok) {
69020a203aSopenharmony_ci        HIVIEW_LOGE("failed to create napi error");
70020a203aSopenharmony_ci    }
71020a203aSopenharmony_ci}
72020a203aSopenharmony_ci
73020a203aSopenharmony_cistd::pair<int32_t, std::string> HiviewNapiUtil::GetErrorDetailByRet(napi_env env, const int32_t retCode)
74020a203aSopenharmony_ci{
75020a203aSopenharmony_ci    HIVIEW_LOGI("origin result code is %{public}d.", retCode);
76020a203aSopenharmony_ci    const std::unordered_map<int32_t, std::pair<int32_t, std::string>> errMap = {
77020a203aSopenharmony_ci        {HiviewNapiErrCode::ERR_PERMISSION_CHECK, {HiviewNapiErrCode::ERR_PERMISSION_CHECK,
78020a203aSopenharmony_ci            "Permission denied. The app does not have the necessary permissions."}},
79020a203aSopenharmony_ci        {HiviewNapiErrCode::ERR_INNER_INVALID_LOGTYPE,
80020a203aSopenharmony_ci            {HiviewNapiErrCode::ERR_PARAM_CHECK, "Parameter error. The value of logType is invalid."}},
81020a203aSopenharmony_ci        {HiviewNapiErrCode::ERR_INNER_READ_ONLY,
82020a203aSopenharmony_ci            {HiviewNapiErrCode::ERR_PARAM_CHECK, "Parameter error. The specified logType is read-only."}},
83020a203aSopenharmony_ci        {HiviewNapiErrCode::ERR_SOURCE_FILE_NOT_EXIST,
84020a203aSopenharmony_ci            {HiviewNapiErrCode::ERR_SOURCE_FILE_NOT_EXIST, "Source file does not exists."}}
85020a203aSopenharmony_ci    };
86020a203aSopenharmony_ci    return errMap.find(retCode) == errMap.end() ?
87020a203aSopenharmony_ci        std::make_pair(HiviewNapiErrCode::ERR_DEFAULT, "Environment is abnormal.") : errMap.at(retCode);
88020a203aSopenharmony_ci}
89020a203aSopenharmony_ci
90020a203aSopenharmony_cibool HiviewNapiUtil::IsMatchType(napi_env env, const napi_value& value, napi_valuetype type)
91020a203aSopenharmony_ci{
92020a203aSopenharmony_ci    napi_valuetype paramType;
93020a203aSopenharmony_ci    napi_typeof(env, value, &paramType);
94020a203aSopenharmony_ci    return paramType == type;
95020a203aSopenharmony_ci}
96020a203aSopenharmony_ci
97020a203aSopenharmony_civoid HiviewNapiUtil::SetNamedProperty(
98020a203aSopenharmony_ci    const napi_env env, napi_value& object, const std::string& propertyName, napi_value& propertyValue)
99020a203aSopenharmony_ci{
100020a203aSopenharmony_ci    if (napi_set_named_property(env, object, propertyName.c_str(), propertyValue) != napi_ok) {
101020a203aSopenharmony_ci        HIVIEW_LOGE("set %{public}s property failed", propertyName.c_str());
102020a203aSopenharmony_ci    }
103020a203aSopenharmony_ci}
104020a203aSopenharmony_ci
105020a203aSopenharmony_cibool HiviewNapiUtil::ParseStringValue(
106020a203aSopenharmony_ci    const napi_env env, const std::string& paramName, const napi_value& value, std::string& retValue)
107020a203aSopenharmony_ci{
108020a203aSopenharmony_ci    if (!IsMatchType(env, value, napi_string)) {
109020a203aSopenharmony_ci        HIVIEW_LOGE("parameter %{public}s type isn't string", paramName.c_str());
110020a203aSopenharmony_ci        ThrowParamTypeError(env, paramName, "string");
111020a203aSopenharmony_ci        return false;
112020a203aSopenharmony_ci    }
113020a203aSopenharmony_ci    char buf[BUF_SIZE] = {0};
114020a203aSopenharmony_ci    size_t bufLength = 0;
115020a203aSopenharmony_ci    if (napi_get_value_string_utf8(env, value, buf, BUF_SIZE - 1, &bufLength) != napi_ok) {
116020a203aSopenharmony_ci        HIVIEW_LOGE("failed to parse napi value of string type.");
117020a203aSopenharmony_ci    } else {
118020a203aSopenharmony_ci        retValue = std::string {buf};
119020a203aSopenharmony_ci    }
120020a203aSopenharmony_ci    return true;
121020a203aSopenharmony_ci}
122020a203aSopenharmony_ci
123020a203aSopenharmony_civoid HiviewNapiUtil::CreateJsFileInfo(const napi_env env, const HiviewFileInfo& fileInfo, napi_value& val)
124020a203aSopenharmony_ci{
125020a203aSopenharmony_ci    napi_value name;
126020a203aSopenharmony_ci    CreateStringValue(env, fileInfo.name, name);
127020a203aSopenharmony_ci    SetNamedProperty(env, val, FILE_NAME_KEY, name);
128020a203aSopenharmony_ci
129020a203aSopenharmony_ci    napi_value mtime;
130020a203aSopenharmony_ci    CreateInt64Value(env, fileInfo.mtime, mtime);
131020a203aSopenharmony_ci    SetNamedProperty(env, val, FILE_TIME_KEY, mtime);
132020a203aSopenharmony_ci
133020a203aSopenharmony_ci    napi_value size;
134020a203aSopenharmony_ci    CreateInt64Value(env, fileInfo.size, size);
135020a203aSopenharmony_ci    SetNamedProperty(env, val, FILE_SIZE_KEY, size);
136020a203aSopenharmony_ci}
137020a203aSopenharmony_ci
138020a203aSopenharmony_cinapi_value HiviewNapiUtil::GenerateFileInfoResult(const napi_env env, const std::vector<HiviewFileInfo>& fileInfos)
139020a203aSopenharmony_ci{
140020a203aSopenharmony_ci    napi_value result;
141020a203aSopenharmony_ci    auto length = fileInfos.size();
142020a203aSopenharmony_ci    napi_create_array_with_length(env, length, &result);
143020a203aSopenharmony_ci    for (decltype(length) i = 0; i < length; ++i) {
144020a203aSopenharmony_ci        napi_value item;
145020a203aSopenharmony_ci        if (napi_create_object(env, &item) != napi_ok) {
146020a203aSopenharmony_ci            HIVIEW_LOGE("failed to create a new napi object.");
147020a203aSopenharmony_ci            break;
148020a203aSopenharmony_ci        }
149020a203aSopenharmony_ci        CreateJsFileInfo(env, fileInfos[i], item);
150020a203aSopenharmony_ci        napi_set_element(env, result, i, item);
151020a203aSopenharmony_ci    }
152020a203aSopenharmony_ci    return result;
153020a203aSopenharmony_ci}
154020a203aSopenharmony_ci
155020a203aSopenharmony_cibool HiviewNapiUtil::CheckDirPath(const std::string& path)
156020a203aSopenharmony_ci{
157020a203aSopenharmony_ci    return path.empty() || path.find("..") == std::string::npos;
158020a203aSopenharmony_ci}
159020a203aSopenharmony_ci
160020a203aSopenharmony_civoid HiviewNapiUtil::ThrowErrorByCode(napi_env env, int32_t errCode)
161020a203aSopenharmony_ci{
162020a203aSopenharmony_ci    auto detail = GetErrorDetailByRet(env, errCode);
163020a203aSopenharmony_ci    ThrowError(env, detail.first, detail.second);
164020a203aSopenharmony_ci}
165020a203aSopenharmony_ci
166020a203aSopenharmony_civoid HiviewNapiUtil::ThrowParamContentError(napi_env env, const std::string& paramName)
167020a203aSopenharmony_ci{
168020a203aSopenharmony_ci    ThrowError(env, HiviewNapiErrCode::ERR_PARAM_CHECK,
169020a203aSopenharmony_ci        "Parameter error. The content of " + paramName + " is invalid.");
170020a203aSopenharmony_ci}
171020a203aSopenharmony_ci
172020a203aSopenharmony_civoid HiviewNapiUtil::ThrowParamTypeError(napi_env env, const std::string& paramName, const std::string& paramType)
173020a203aSopenharmony_ci{
174020a203aSopenharmony_ci    ThrowError(env, HiviewNapiErrCode::ERR_PARAM_CHECK,
175020a203aSopenharmony_ci        "Parameter error. The type of " + paramName + " must be " + paramType + ".");
176020a203aSopenharmony_ci}
177020a203aSopenharmony_ci
178020a203aSopenharmony_civoid HiviewNapiUtil::ThrowError(napi_env env, const int32_t code, const std::string& msg)
179020a203aSopenharmony_ci{
180020a203aSopenharmony_ci    if (napi_throw_error(env, std::to_string(code).c_str(), msg.c_str()) != napi_ok) {
181020a203aSopenharmony_ci        HIVIEW_LOGE("failed to throw error, code=%{public}d, msg=%{public}s", code, msg.c_str());
182020a203aSopenharmony_ci    }
183020a203aSopenharmony_ci}
184020a203aSopenharmony_ci
185020a203aSopenharmony_civoid HiviewNapiUtil::ThrowSystemAppPermissionError(napi_env env)
186020a203aSopenharmony_ci{
187020a203aSopenharmony_ci    ThrowError(env, HiviewNapiErrCode::ERR_NON_SYS_APP_PERMISSION,
188020a203aSopenharmony_ci        "Permission denied, non-system app called system api.");
189020a203aSopenharmony_ci}
190020a203aSopenharmony_ci
191020a203aSopenharmony_cibool HiviewNapiUtil::IsSystemAppCall()
192020a203aSopenharmony_ci{
193020a203aSopenharmony_ci    uint64_t tokenId = IPCSkeleton::GetCallingFullTokenID();
194020a203aSopenharmony_ci    return Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(tokenId);
195020a203aSopenharmony_ci}
196020a203aSopenharmony_ci} // namespace HiviewDFX
197020a203aSopenharmony_ci} // namespace OHOS