• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2023 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_hisysevent_util.h"
17 
18 #include <cinttypes>
19 #include <tuple>
20 #include <variant>
21 
22 #include "def.h"
23 #include "hilog/log.h"
24 #include "ipc_skeleton.h"
25 #include "json/json.h"
26 #include "ret_code.h"
27 #include "ret_def.h"
28 #include "stringfilter.h"
29 #include "tokenid_kit.h"
30 
31 #undef LOG_DOMAIN
32 #define LOG_DOMAIN 0xD002D08
33 
34 #undef LOG_TAG
35 #define LOG_TAG "NAPI_HISYSEVENT_UTIL"
36 
37 namespace OHOS {
38 namespace HiviewDFX {
39 namespace {
40 constexpr uint32_t JS_STR_PARM_LEN_LIMIT = 1024 * 10; // 10k
41 constexpr uint32_t BUF_SIZE = 1024 * 11; // 11k
42 constexpr int SYS_EVENT_INFO_PARAM_INDEX = 0;
43 constexpr long long DEFAULT_TIME_STAMP = -1;
44 constexpr long long DEFAULT_SEQ = 0;
45 constexpr int32_t DEFAULT_MAX_EVENTS = 1000;
46 constexpr char PARAMS_ATTR[] = "params";
47 constexpr char TAG_ATTR[] = "tag";
48 constexpr char RULE_TYPE_ATTR[] = "ruleType";
49 constexpr char BEGIN_TIME_ATTR[] = "beginTime";
50 constexpr char END_TIME_ATTR[] = "endTime";
51 constexpr char MAX_EVENTS_ATTR[] = "maxEvents";
52 constexpr char BEGIN_SEQ_ATTR[] = "fromSeq";
53 constexpr char END_SEQ_ATTR[] = "toSeq";
54 constexpr char NAMES_ATTR[] = "names";
55 constexpr char CONDITION_ATTR[] = "condition";
56 constexpr char DOMAIN__KEY[] = "domain_";
57 constexpr char NAME__KEY[] = "name_";
58 constexpr char TYPE__KEY[] = "type_";
59 using I64ParseResult = std::pair<bool, int64_t>;
60 using U64ParseResult = std::pair<bool, uint64_t>;
61 using ParsedItem = std::variant<uint64_t, int64_t, double>;
62 enum ParsedItemIndex {
63     U64_INDEX = 0,
64     I64_INDEX,
65     DOUBLE_INDEX,
66 };
67 
68 enum ArrayParseStatus {
69     AS_U64_ARR,
70     AS_I64_ARR,
71     AS_DOUBLE_ARR,
72 };
73 
74 const std::string INVALID_KEY_TYPE_ARR[] = {
75     "[object Object]",
76     "null",
77     "()",
78     ","
79 };
80 
81 template<typename T>
AppendParamsToEventInfo(std::vector<ParsedItem> & src,HiSysEventInfo & info,const std::string & key)82 void AppendParamsToEventInfo(std::vector<ParsedItem>& src,
83     HiSysEventInfo& info, const std::string& key)
84 {
85     std::vector<std::decay_t<T>> dest;
86     for (auto& item : src) {
87         if (item.index() == U64_INDEX) {
88             dest.emplace_back(static_cast<std::decay_t<T>>(std::get<U64_INDEX>(item)));
89         } else if (item.index() == I64_INDEX) {
90             dest.emplace_back(static_cast<std::decay_t<T>>(std::get<I64_INDEX>(item)));
91         } else {
92             dest.emplace_back(static_cast<std::decay_t<T>>(std::get<DOUBLE_INDEX>(item)));
93         }
94     }
95     info.params[key] = dest;
96 }
97 
CheckKeyTypeString(const std::string & str)98 bool CheckKeyTypeString(const std::string& str)
99 {
100     bool ret = true;
101     for (auto invalidType : INVALID_KEY_TYPE_ARR) {
102         if (str.find(invalidType) != std::string::npos) {
103             ret = false;
104             break;
105         }
106     }
107     return ret;
108 }
109 
IsFloatingNumber(double originalVal)110 bool IsFloatingNumber(double originalVal)
111 {
112     int64_t i64Val = static_cast<int64_t>(originalVal);
113     double i64ToDVal = static_cast<double>(i64Val);
114     return fabs(i64ToDVal - originalVal) > 1e-9; // a minumum value
115 }
116 
GetValueType(const napi_env env,const napi_value & value)117 napi_valuetype GetValueType(const napi_env env, const napi_value& value)
118 {
119     napi_valuetype valueType = napi_undefined;
120     napi_status ret = napi_typeof(env, value, &valueType);
121     if (ret != napi_ok) {
122         HILOG_ERROR(LOG_CORE, "failed to parse the type of napi value.");
123     }
124     return valueType;
125 }
126 
IsValueTypeValid(const napi_env env,const napi_value & jsObj,const napi_valuetype typeName)127 bool IsValueTypeValid(const napi_env env, const napi_value& jsObj,
128     const napi_valuetype typeName)
129 {
130     napi_valuetype valueType = GetValueType(env, jsObj);
131     if (valueType != typeName) {
132         HILOG_DEBUG(LOG_CORE, "napi value type not match: valueType=%{public}d, typeName=%{public}d.",
133             valueType, typeName);
134         return false;
135     }
136     return true;
137 }
138 
CheckValueIsArray(const napi_env env,const napi_value & jsObj)139 bool CheckValueIsArray(const napi_env env, const napi_value& jsObj)
140 {
141     if (!IsValueTypeValid(env, jsObj, napi_valuetype::napi_object)) {
142         return false;
143     }
144     bool isArray = false;
145     napi_status ret = napi_is_array(env, jsObj, &isArray);
146     if (ret != napi_ok) {
147         HILOG_ERROR(LOG_CORE, "failed to check array napi value.");
148     }
149     return isArray;
150 }
151 
ParseBoolValue(const napi_env env,const napi_value & value,bool defalutValue=false)152 bool ParseBoolValue(const napi_env env, const napi_value& value, bool defalutValue = false)
153 {
154     bool boolValue = defalutValue;
155     napi_status ret = napi_get_value_bool(env, value, &boolValue);
156     if (ret != napi_ok) {
157         HILOG_ERROR(LOG_CORE, "failed to parse napi value of boolean type.");
158     }
159     return boolValue;
160 }
161 
ParseNumberValue(const napi_env env,const napi_value & value,double defaultValue=0.0)162 double ParseNumberValue(const napi_env env, const napi_value& value, double defaultValue = 0.0)
163 {
164     double numValue = defaultValue;
165     napi_status ret = napi_get_value_double(env, value, &numValue);
166     if (ret != napi_ok) {
167         HILOG_ERROR(LOG_CORE, "failed to parse napi value of number type.");
168     }
169     return numValue;
170 }
171 
ParseStringValue(const napi_env env,const napi_value & value,std::string defaultValue="")172 std::string ParseStringValue(const napi_env env, const napi_value& value, std::string defaultValue = "")
173 {
174     char buf[BUF_SIZE] = {0};
175     size_t bufLength = 0;
176     napi_status status = napi_get_value_string_utf8(env, value, buf, BUF_SIZE - 1, &bufLength);
177     if (status != napi_ok) {
178         HILOG_DEBUG(LOG_CORE, "failed to parse napi value of string type.");
179         return defaultValue;
180     }
181     std::string dest = std::string {buf};
182     return dest;
183 }
184 
ParseSignedBigIntValue(const napi_env env,const napi_value & value)185 I64ParseResult ParseSignedBigIntValue(const napi_env env, const napi_value& value)
186 {
187     I64ParseResult ret = std::make_pair(false, 0); // default result
188     int64_t val = 0;
189     bool lossless = true;
190     napi_status status = napi_get_value_bigint_int64(env, value, &val, &lossless);
191     if (status != napi_ok) {
192         HILOG_DEBUG(LOG_CORE, "failed to parse int64_t number.");
193         return ret;
194     }
195     ret.first = lossless;
196     ret.second = val;
197     return ret;
198 }
199 
ParseUnsignedBigIntValue(const napi_env env,const napi_value & value)200 U64ParseResult ParseUnsignedBigIntValue(const napi_env env, const napi_value& value)
201 {
202     U64ParseResult ret = std::make_pair(false, 0); // default result
203     uint64_t val = 0;
204     bool lossless = true;
205     napi_status status = napi_get_value_bigint_uint64(env, value, &val, &lossless);
206     if (status != napi_ok) {
207         HILOG_DEBUG(LOG_CORE, "failed to parse uint64_t number.");
208         return ret;
209     }
210     ret.first = lossless;
211     ret.second = val;
212     return ret;
213 }
214 
ParseBigIntResultValue(const napi_env env,const napi_value & value,U64ParseResult & u64Ret,I64ParseResult & i64Ret)215 void ParseBigIntResultValue(const napi_env env, const napi_value& value, U64ParseResult& u64Ret,
216     I64ParseResult& i64Ret)
217 {
218     u64Ret = ParseUnsignedBigIntValue(env, value);
219     if (!u64Ret.first) {
220         i64Ret = ParseSignedBigIntValue(env, value);
221     }
222 }
223 
GetTagAttribute(const napi_env env,const napi_value & object,std::string defaultValue="")224 std::string GetTagAttribute(const napi_env env, const napi_value& object, std::string defaultValue = "")
225 {
226     napi_value propertyValue = NapiHiSysEventUtil::GetPropertyByName(env, object, TAG_ATTR);
227     if (IsValueTypeValid(env, propertyValue, napi_valuetype::napi_null) ||
228         IsValueTypeValid(env, propertyValue, napi_valuetype::napi_undefined)) {
229         return defaultValue;
230     }
231     if (IsValueTypeValid(env, propertyValue, napi_valuetype::napi_string)) {
232         return ParseStringValue(env, propertyValue, defaultValue);
233     }
234     NapiHiSysEventUtil::ThrowParamTypeError(env, TAG_ATTR, "string");
235     HILOG_ERROR(LOG_CORE, "type of listener tag is not napi_string.");
236     return defaultValue;
237 }
238 
GetStringTypeAttribute(const napi_env env,const napi_value & object,const std::string & propertyName,std::string defaultValue="")239 std::string GetStringTypeAttribute(const napi_env env, const napi_value& object,
240     const std::string& propertyName, std::string defaultValue = "")
241 {
242     napi_value propertyValue = NapiHiSysEventUtil::GetPropertyByName(env, object, propertyName);
243     if (!IsValueTypeValid(env, propertyValue, napi_valuetype::napi_string)) {
244         NapiHiSysEventUtil::ThrowParamTypeError(env, propertyName, "string");
245         HILOG_ERROR(LOG_CORE, "type is not napi_string.");
246         return defaultValue;
247     }
248     return ParseStringValue(env, propertyValue, defaultValue);
249 }
250 
GetLonglongTypeAttribute(const napi_env env,const napi_value & object,const std::string & propertyName,long long defaultValue=0)251 long long GetLonglongTypeAttribute(const napi_env env, const napi_value& object,
252     const std::string& propertyName, long long defaultValue = 0)
253 {
254     napi_value propertyValue = NapiHiSysEventUtil::GetPropertyByName(env, object, propertyName);
255     bool isNumberType = IsValueTypeValid(env, propertyValue, napi_valuetype::napi_number);
256     bool isBigIntType = IsValueTypeValid(env, propertyValue, napi_valuetype::napi_bigint);
257     if (!isNumberType && !isBigIntType) {
258         HILOG_ERROR(LOG_CORE, "type is not napi_number or napi_bigint.");
259         return defaultValue;
260     }
261     if (isNumberType) {
262         return static_cast<long long>(ParseNumberValue(env, propertyValue, defaultValue));
263     }
264     I64ParseResult ret = ParseSignedBigIntValue(env, propertyValue);
265     return static_cast<long long>(ret.second);
266 }
267 
ParseInt32Value(const napi_env env,const napi_value & value,int32_t defaultValue=0)268 int32_t ParseInt32Value(const napi_env env, const napi_value& value, int32_t defaultValue = 0)
269 {
270     int32_t int32Value = 0;
271     napi_status ret = napi_get_value_int32(env, value, &int32Value);
272     if (ret != napi_ok) {
273         HILOG_ERROR(LOG_CORE, "failed to parse napi value of number type.");
274         return defaultValue;
275     }
276     return int32Value;
277 }
278 
GetInt32TypeAttribute(const napi_env env,const napi_value & object,const std::string & propertyName,int32_t defaultValue=0)279 int32_t GetInt32TypeAttribute(const napi_env env, const napi_value& object,
280     const std::string& propertyName, int32_t defaultValue = 0)
281 {
282     napi_value propertyValue = NapiHiSysEventUtil::GetPropertyByName(env, object, propertyName);
283     if (!IsValueTypeValid(env, propertyValue, napi_valuetype::napi_number)) {
284         NapiHiSysEventUtil::ThrowParamTypeError(env, propertyName, "number");
285         HILOG_ERROR(LOG_CORE, "type is not napi_number.");
286         return defaultValue;
287     }
288     return ParseInt32Value(env, propertyValue);
289 }
290 
AppendBoolArrayData(const napi_env env,HiSysEventInfo & info,const std::string & key,const napi_value array,size_t len)291 void AppendBoolArrayData(const napi_env env, HiSysEventInfo& info, const std::string& key,
292     const napi_value array, size_t len)
293 {
294     std::vector<bool> values;
295     napi_value element;
296     napi_status status;
297     for (uint32_t i = 0; i < len; i++) {
298         status = napi_get_element(env, array, i, &element);
299         if (status != napi_ok) {
300             HILOG_ERROR(LOG_CORE, "failed to get the element of bool array.");
301             continue;
302         }
303         if (IsValueTypeValid(env, element, napi_valuetype::napi_boolean)) {
304             values.emplace_back(ParseBoolValue(env, element));
305         }
306     }
307     info.params[key] = values;
308 }
309 
AppendNumberArrayData(const napi_env env,HiSysEventInfo & info,const std::string & key,const napi_value array,size_t len)310 void AppendNumberArrayData(const napi_env env, HiSysEventInfo& info, const std::string& key,
311     const napi_value array, size_t len)
312 {
313     std::vector<ParsedItem> parsedArray;
314     ArrayParseStatus pStatus = AS_U64_ARR;
315     double parsedVal = 0;
316     napi_value element;
317     napi_status status;
318     for (uint32_t i = 0; i < len; i++) {
319         status = napi_get_element(env, array, i, &element);
320         if (status != napi_ok || !IsValueTypeValid(env, element, napi_valuetype::napi_number)) {
321             HILOG_ERROR(LOG_CORE,
322                 "failed to get the element from array or type not match.");
323             continue;
324         }
325         parsedVal = ParseNumberValue(env, element);
326         if (IsFloatingNumber(parsedVal)) {
327             pStatus = AS_DOUBLE_ARR;
328             parsedArray.emplace_back(parsedVal);
329             continue;
330         }
331         if (parsedVal < 0 && pStatus != AS_DOUBLE_ARR) {
332             pStatus = AS_I64_ARR;
333             parsedArray.emplace_back(static_cast<int64_t>(parsedVal));
334             continue;
335         }
336         parsedArray.emplace_back(static_cast<uint64_t>(parsedVal));
337     }
338     if (pStatus == AS_DOUBLE_ARR) {
339         AppendParamsToEventInfo<double>(parsedArray, info, key);
340     } else if (pStatus == AS_I64_ARR) {
341         AppendParamsToEventInfo<int64_t>(parsedArray, info, key);
342     } else {
343         AppendParamsToEventInfo<uint64_t>(parsedArray, info, key);
344     }
345 }
346 
AppendBigIntArrayData(const napi_env env,HiSysEventInfo & info,const std::string & key,const napi_value array,size_t len)347 void AppendBigIntArrayData(const napi_env env, HiSysEventInfo& info, const std::string& key,
348     const napi_value array, size_t len)
349 {
350     std::vector<ParsedItem> parsedArray;
351     ArrayParseStatus pStatus = AS_U64_ARR;
352     napi_value element;
353     napi_status status;
354     U64ParseResult u64Ret = std::make_pair(false, 0); //default value
355     I64ParseResult i64Ret = std::make_pair(false, 0); //default value
356     for (uint32_t i = 0; i < len; i++) {
357         status = napi_get_element(env, array, i, &element);
358         if (status != napi_ok || !IsValueTypeValid(env, element, napi_valuetype::napi_bigint)) {
359             HILOG_ERROR(LOG_CORE,
360                 "failed to get the element from array or type not match.");
361             continue;
362         }
363         ParseBigIntResultValue(env, element, u64Ret, i64Ret);
364         if (u64Ret.first) {
365             parsedArray.emplace_back(u64Ret.second);
366             continue;
367         }
368         pStatus = AS_I64_ARR;
369         parsedArray.emplace_back(i64Ret.second);
370     }
371     if (pStatus == AS_I64_ARR) {
372         AppendParamsToEventInfo<int64_t>(parsedArray, info, key);
373         return;
374     }
375     AppendParamsToEventInfo<uint64_t>(parsedArray, info, key);
376 }
377 
AppendStringArrayData(const napi_env env,HiSysEventInfo & info,const std::string & key,const napi_value array,size_t len)378 void AppendStringArrayData(const napi_env env, HiSysEventInfo& info, const std::string& key,
379     const napi_value array, size_t len)
380 {
381     std::vector<std::string> values;
382     napi_value element;
383     napi_status status;
384     for (uint32_t i = 0; i < len; i++) {
385         status = napi_get_element(env, array, i, &element);
386         if (status != napi_ok) {
387             HILOG_ERROR(LOG_CORE, "failed to get the element of string array.");
388             continue;
389         }
390         if (IsValueTypeValid(env, element, napi_valuetype::napi_string)) {
391             values.emplace_back(ParseStringValue(env, element));
392         }
393     }
394     info.params[key] = values;
395 }
396 
AddArrayParamToEventInfo(const napi_env env,HiSysEventInfo & info,const std::string & key,napi_value & array)397 void AddArrayParamToEventInfo(const napi_env env, HiSysEventInfo& info, const std::string& key, napi_value& array)
398 {
399     uint32_t len = 0;
400     napi_status status = napi_get_array_length(env, array, &len);
401     if (status != napi_ok) {
402         HILOG_ERROR(LOG_CORE, "failed to get the length of param array.");
403         return;
404     }
405     if (len == 0) {
406         HILOG_WARN(LOG_CORE, "array is empty.");
407         return;
408     }
409     napi_value firstItem;
410     status = napi_get_element(env, array, 0, &firstItem);
411     if (status != napi_ok) {
412         HILOG_ERROR(LOG_CORE, "failed to get the first element in array.");
413         return;
414     }
415     napi_valuetype type;
416     status = napi_typeof(env, firstItem, &type);
417     if (status != napi_ok) {
418         HILOG_ERROR(LOG_CORE, "failed to get the type of the first element in array.");
419         return;
420     }
421     switch (type) {
422         case napi_valuetype::napi_boolean:
423             AppendBoolArrayData(env, info, key, array, len);
424             HILOG_DEBUG(LOG_CORE, "AppendBoolArrayData: %{public}s.", key.c_str());
425             break;
426         case napi_valuetype::napi_number:
427             AppendNumberArrayData(env, info, key, array, len);
428             HILOG_DEBUG(LOG_CORE, "AppendNumberArrayData: %{public}s.", key.c_str());
429             break;
430         case napi_valuetype::napi_bigint:
431             AppendBigIntArrayData(env, info, key, array, len);
432             HILOG_DEBUG(LOG_CORE, "AppendBigIntArrayData: %{public}s.", key.c_str());
433             break;
434         case napi_valuetype::napi_string:
435             AppendStringArrayData(env, info, key, array, len);
436             HILOG_DEBUG(LOG_CORE, "AppendStringArrayData: %{public}s.", key.c_str());
437             break;
438         default:
439             break;
440     }
441 }
442 
AddParamToEventInfo(const napi_env env,HiSysEventInfo & info,const std::string & key,napi_value & value)443 void AddParamToEventInfo(const napi_env env, HiSysEventInfo& info, const std::string& key, napi_value& value)
444 {
445     if (CheckValueIsArray(env, value)) {
446         AddArrayParamToEventInfo(env, info, key, value);
447         return;
448     }
449     napi_valuetype type = GetValueType(env, value);
450     double parsedVal = 0;
451     U64ParseResult u64Ret = std::make_pair(false, 0); //default value
452     I64ParseResult i64Ret = std::make_pair(false, 0); //default value
453     switch (type) {
454         case napi_valuetype::napi_boolean:
455             HILOG_DEBUG(LOG_CORE, "AddBoolParamToEventInfo: %{public}s.", key.c_str());
456             info.params[key] = ParseBoolValue(env, value);
457             break;
458         case napi_valuetype::napi_number:
459             HILOG_DEBUG(LOG_CORE, "AddNumberParamToEventInfo: %{public}s.", key.c_str());
460             parsedVal = ParseNumberValue(env, value);
461             if (IsFloatingNumber(parsedVal)) {
462                 info.params[key] = parsedVal;
463             } else if (parsedVal < 0) {
464                 info.params[key] = static_cast<int64_t>(parsedVal);
465             } else {
466                 info.params[key] = static_cast<uint64_t>(parsedVal);
467             }
468             break;
469         case napi_valuetype::napi_string:
470             HILOG_DEBUG(LOG_CORE, "AddStringParamToEventInfo: %{public}s.", key.c_str());
471             info.params[key] = ParseStringValue(env, value);
472             break;
473         case napi_valuetype::napi_bigint:
474             HILOG_DEBUG(LOG_CORE, "AddBigIntParamToEventInfo: %{public}s.", key.c_str());
475             ParseBigIntResultValue(env, value, u64Ret, i64Ret);
476             if (u64Ret.first) {
477                 info.params[key] = u64Ret.second;
478             } else {
479                 info.params[key] = i64Ret.second;
480             }
481             break;
482         default:
483             break;
484     }
485 }
486 
GetObjectTypeAttribute(const napi_env env,const napi_value & object,const std::string & propertyName,HiSysEventInfo & info)487 void GetObjectTypeAttribute(const napi_env env, const napi_value& object,
488     const std::string& propertyName, HiSysEventInfo& info)
489 {
490     napi_value propertyValue = NapiHiSysEventUtil::GetPropertyByName(env, object, propertyName);
491     if (!IsValueTypeValid(env, propertyValue, napi_valuetype::napi_object)) {
492         HILOG_ERROR(LOG_CORE, "type is not napi_object.");
493         return;
494     }
495     napi_value keyArr = nullptr;
496     napi_status status = napi_get_property_names(env, propertyValue, &keyArr);
497     if (status != napi_ok) {
498         HILOG_ERROR(LOG_CORE, "failed to parse property names of a js object.");
499         return;
500     }
501     uint32_t len = 0;
502     status = napi_get_array_length(env, keyArr, &len);
503     if (status != napi_ok) {
504         HILOG_ERROR(LOG_CORE, "failed to get the length of the key-value pairs.");
505         return;
506     }
507     for (uint32_t i = 0; i < len; i++) {
508         napi_value key = nullptr;
509         napi_get_element(env, keyArr, i, &key);
510         if (!IsValueTypeValid(env, key, napi_valuetype::napi_string)) {
511             HILOG_WARN(LOG_CORE, "this param would be discarded because of invalid type of the key.");
512             continue;
513         }
514         char buf[BUF_SIZE] = {0};
515         size_t valueLen = 0;
516         napi_get_value_string_utf8(env, key, buf, BUF_SIZE - 1, &valueLen);
517         if (!CheckKeyTypeString(buf)) {
518             HILOG_WARN(LOG_CORE, "this param would be discarded because of invalid format of the key.");
519             continue;
520         }
521         napi_value val = NapiHiSysEventUtil::GetPropertyByName(env, propertyValue, buf);
522         AddParamToEventInfo(env, info, buf, val);
523     }
524 }
525 
ParseStringArray(const napi_env env,napi_value & arrayValue,std::vector<std::string> & arrayDest)526 void ParseStringArray(const napi_env env, napi_value& arrayValue, std::vector<std::string>& arrayDest)
527 {
528     if (!CheckValueIsArray(env, arrayValue)) {
529         HILOG_ERROR(LOG_CORE, "try to parse a array from a napi value without array type");
530         return;
531     }
532     uint32_t len = 0;
533     napi_status status = napi_get_array_length(env, arrayValue, &len);
534     if (status != napi_ok) {
535         return;
536     }
537     napi_value element;
538     for (uint32_t i = 0; i < len; i++) {
539         status = napi_get_element(env, arrayValue, i, &element);
540         if (status != napi_ok) {
541             return;
542         }
543         if (IsValueTypeValid(env, element, napi_valuetype::napi_string)) {
544             std::string str = ParseStringValue(env, element);
545             HILOG_DEBUG(LOG_CORE, "parse string: %{public}s.", str.c_str());
546             arrayDest.emplace_back(str);
547         }
548     }
549 }
550 
ParseListenerRule(const napi_env env,const napi_value & jsObj)551 ListenerRule ParseListenerRule(const napi_env env, const napi_value& jsObj)
552 {
553     if (!IsValueTypeValid(env, jsObj, napi_valuetype::napi_object)) {
554         return ListenerRule("", RuleType::WHOLE_WORD);
555     }
556     std::string domain = GetStringTypeAttribute(env, jsObj, NapiHiSysEventUtil::DOMAIN_ATTR);
557     HILOG_DEBUG(LOG_CORE, "domain is %{public}s.", domain.c_str());
558     std::string name = GetStringTypeAttribute(env, jsObj, NapiHiSysEventUtil::NAME_ATTR);
559     HILOG_DEBUG(LOG_CORE, "name is %{public}s.", name.c_str());
560     int32_t ruleType = GetInt32TypeAttribute(env, jsObj, RULE_TYPE_ATTR, RuleType::WHOLE_WORD);
561     HILOG_DEBUG(LOG_CORE, "ruleType is %{public}d.", ruleType);
562     std::string tag = GetTagAttribute(env, jsObj);
563     HILOG_DEBUG(LOG_CORE, "tag is %{public}s.", tag.c_str());
564     return ListenerRule(domain, name, tag, RuleType(ruleType));
565 }
566 
IsQueryRuleValid(const napi_env env,const QueryRule & rule)567 bool IsQueryRuleValid(const napi_env env, const QueryRule& rule)
568 {
569     auto domain = rule.GetDomain();
570     if (!StringFilter::GetInstance().IsValidName(domain, MAX_DOMAIN_LENGTH)) {
571         NapiHiSysEventUtil::ThrowErrorByRet(env, NapiInnerError::ERR_INVALID_DOMAIN_IN_QUERY_RULE);
572         return false;
573     }
574     auto names = rule.GetEventList();
575     if (std::any_of(names.begin(), names.end(), [] (auto& name) {
576         return !StringFilter::GetInstance().IsValidName(name, MAX_EVENT_NAME_LENGTH);
577     })) {
578         NapiHiSysEventUtil::ThrowErrorByRet(env, NapiInnerError::ERR_INVALID_EVENT_NAME_IN_QUERY_RULE);
579         return false;
580     }
581     return true;
582 }
583 
ParseQueryRule(const napi_env env,napi_value & jsObj)584 QueryRule ParseQueryRule(const napi_env env, napi_value& jsObj)
585 {
586     std::vector<std::string> names;
587     if (!IsValueTypeValid(env, jsObj, napi_valuetype::napi_object)) {
588         return QueryRule("", names);
589     }
590     std::string domain = GetStringTypeAttribute(env, jsObj, NapiHiSysEventUtil::DOMAIN_ATTR);
591     HILOG_DEBUG(LOG_CORE, "domain is %{public}s.", domain.c_str());
592     napi_value propertyValue = NapiHiSysEventUtil::GetPropertyByName(env, jsObj, NAMES_ATTR);
593     ParseStringArray(env, propertyValue, names);
594     propertyValue = NapiHiSysEventUtil::GetPropertyByName(env, jsObj, CONDITION_ATTR);
595     std::string condition = ParseStringValue(env, propertyValue);
596     HILOG_DEBUG(LOG_CORE, "condition is %{public}s.", condition.c_str());
597     return QueryRule(domain, names, RuleType::WHOLE_WORD, 0, condition);
598 }
599 
SetNamedProperty(const napi_env env,napi_value & object,const std::string & propertyName,napi_value & propertyValue)600 void SetNamedProperty(const napi_env env, napi_value& object, const std::string& propertyName,
601     napi_value& propertyValue)
602 {
603     napi_status status = napi_set_named_property(env, object, propertyName.c_str(), propertyValue);
604     if (status != napi_ok) {
605         HILOG_ERROR(LOG_CORE, "set property %{public}s failed.", propertyName.c_str());
606     }
607 }
608 
IsBaseInfoKey(const std::string & propertyName)609 bool IsBaseInfoKey(const std::string& propertyName)
610 {
611     return propertyName == DOMAIN__KEY || propertyName == NAME__KEY || propertyName == TYPE__KEY;
612 }
613 
TranslateKeyToAttrName(const std::string & key)614 std::string TranslateKeyToAttrName(const std::string& key)
615 {
616     if (key == DOMAIN__KEY) {
617         return NapiHiSysEventUtil::DOMAIN_ATTR;
618     }
619     if (key == NAME__KEY) {
620         return NapiHiSysEventUtil::NAME_ATTR;
621     }
622     if (key == TYPE__KEY) {
623         return NapiHiSysEventUtil::EVENT_TYPE_ATTR;
624     }
625     return "";
626 }
627 
AppendBaseInfo(const napi_env env,napi_value & sysEventInfo,const std::string & key,Json::Value & value)628 void AppendBaseInfo(const napi_env env, napi_value& sysEventInfo, const std::string& key, Json::Value& value)
629 {
630     if ((key == DOMAIN__KEY || key == NAME__KEY) && value.isString()) {
631         NapiHiSysEventUtil::AppendStringPropertyToJsObject(env, TranslateKeyToAttrName(key),
632             value.asString(), sysEventInfo);
633     }
634     if (key == TYPE__KEY && value.isInt()) {
635         NapiHiSysEventUtil::AppendInt32PropertyToJsObject(env, TranslateKeyToAttrName(key),
636             static_cast<int32_t>(value.asInt()), sysEventInfo);
637     }
638 }
639 
CreateBoolValue(const napi_env env,bool value,napi_value & val)640 void CreateBoolValue(const napi_env env, bool value, napi_value& val)
641 {
642     napi_status status = napi_get_boolean(env, value, &val);
643     HILOG_DEBUG(LOG_CORE, "create napi value of bool type, value is %{public}d.", value);
644     if (status != napi_ok) {
645         HILOG_ERROR(LOG_CORE, "failed to get create napi value of bool type.");
646     }
647 }
648 
CreateDoubleValue(const napi_env env,double value,napi_value & val)649 void CreateDoubleValue(const napi_env env, double value, napi_value& val)
650 {
651     napi_status status = napi_create_double(env, value, &val);
652     HILOG_DEBUG(LOG_CORE, "create napi value of double type, value is %{public}f.", value);
653     if (status != napi_ok) {
654         HILOG_ERROR(LOG_CORE, "failed to get create napi value of double type.");
655     }
656 }
657 
CreateUint32Value(const napi_env env,uint32_t value,napi_value & val)658 void CreateUint32Value(const napi_env env, uint32_t value, napi_value& val)
659 {
660     napi_status status = napi_create_uint32(env, value, &val);
661     HILOG_DEBUG(LOG_CORE, "create napi value of uint32 type, value is %{public}u.", value);
662     if (status != napi_ok) {
663         HILOG_ERROR(LOG_CORE, "failed to get create napi value of uint32 type.");
664     }
665 }
666 
CreateParamItemTypeValue(const napi_env env,Json::Value & jsonValue,napi_value & value)667 bool CreateParamItemTypeValue(const napi_env env, Json::Value& jsonValue, napi_value& value)
668 {
669     if (jsonValue.isBool()) {
670         CreateBoolValue(env, jsonValue.asBool(), value);
671         return true;
672     }
673     if (jsonValue.isInt()) {
674         NapiHiSysEventUtil::CreateInt32Value(env, static_cast<int32_t>(jsonValue.asInt()), value);
675         return true;
676     }
677     if (jsonValue.isUInt()) {
678         CreateUint32Value(env, static_cast<uint32_t>(jsonValue.asUInt()), value);
679         return true;
680     }
681 #ifdef JSON_HAS_INT64
682     if (jsonValue.isInt64() && jsonValue.type() != Json::ValueType::uintValue) {
683         NapiHiSysEventUtil::CreateInt64Value(env, jsonValue.asInt64(), value);
684         return true;
685     }
686     if (jsonValue.isUInt64() && jsonValue.type() != Json::ValueType::intValue) {
687         NapiHiSysEventUtil::CreateUInt64Value(env, jsonValue.asUInt64(), value);
688         return true;
689     }
690 #endif
691     if (jsonValue.isDouble()) {
692         CreateDoubleValue(env, jsonValue.asDouble(), value);
693         return true;
694     }
695     if (jsonValue.isString()) {
696         NapiHiSysEventUtil::CreateStringValue(env, jsonValue.asString(), value);
697         return true;
698     }
699     return false;
700 }
701 
AppendArrayParams(const napi_env env,napi_value & params,const std::string & key,Json::Value & value)702 void AppendArrayParams(const napi_env env, napi_value& params, const std::string& key, Json::Value& value)
703 {
704     size_t len = value.size();
705     napi_value array = nullptr;
706     napi_create_array_with_length(env, len, &array);
707     for (size_t i = 0; i < len; i++) {
708         napi_value item;
709         if (!CreateParamItemTypeValue(env, value[static_cast<int>(i)], item)) {
710             continue;
711         }
712         napi_set_element(env, array, i, item);
713     }
714     SetNamedProperty(env, params, key, array);
715 }
716 
AppendParamsInfo(const napi_env env,napi_value & params,const std::string & key,Json::Value & jsonValue)717 void AppendParamsInfo(const napi_env env, napi_value& params, const std::string& key, Json::Value& jsonValue)
718 {
719     if (jsonValue.isArray()) {
720         AppendArrayParams(env, params, key, jsonValue);
721         return;
722     }
723     napi_value property = nullptr;
724     if (!CreateParamItemTypeValue(env, jsonValue, property)) {
725         return;
726     }
727     SetNamedProperty(env, params, key, property);
728 }
729 }
730 
GetPropertyByName(const napi_env env,const napi_value & object,const std::string & propertyName)731 napi_value NapiHiSysEventUtil::GetPropertyByName(const napi_env env, const napi_value& object,
732     const std::string& propertyName)
733 {
734     napi_value result = nullptr;
735     napi_status status = napi_get_named_property(env, object, propertyName.c_str(), &result);
736     if (status != napi_ok) {
737         HILOG_DEBUG(LOG_CORE, "failed to parse property named %{public}s from JS object.", propertyName.c_str());
738     }
739     return result;
740 }
741 
ParseHiSysEventInfo(const napi_env env,napi_value * param,size_t paramNum,HiSysEventInfo & info)742 void NapiHiSysEventUtil::ParseHiSysEventInfo(const napi_env env, napi_value* param,
743     size_t paramNum, HiSysEventInfo& info)
744 {
745     if (paramNum <= SYS_EVENT_INFO_PARAM_INDEX) {
746         return;
747     }
748     if (!IsValueTypeValid(env, param[SYS_EVENT_INFO_PARAM_INDEX], napi_valuetype::napi_object)) {
749         NapiHiSysEventUtil::ThrowParamTypeError(env, "info", "object");
750         return;
751     }
752     info.domain = GetStringTypeAttribute(env, param[SYS_EVENT_INFO_PARAM_INDEX], NapiHiSysEventUtil::DOMAIN_ATTR);
753     HILOG_DEBUG(LOG_CORE, "domain is %{public}s.", info.domain.c_str());
754     info.name = GetStringTypeAttribute(env, param[SYS_EVENT_INFO_PARAM_INDEX], NapiHiSysEventUtil::NAME_ATTR);
755     HILOG_DEBUG(LOG_CORE, "name is %{public}s.", info.name.c_str());
756     info.eventType = HiSysEvent::EventType(GetInt32TypeAttribute(env,
757         param[SYS_EVENT_INFO_PARAM_INDEX], EVENT_TYPE_ATTR, HiSysEvent::EventType::FAULT));
758     HILOG_DEBUG(LOG_CORE, "eventType is %{public}d.", info.eventType);
759     GetObjectTypeAttribute(env, param[SYS_EVENT_INFO_PARAM_INDEX], PARAMS_ATTR, info);
760 }
761 
HasStrParamLenOverLimit(HiSysEventInfo & info)762 bool NapiHiSysEventUtil::HasStrParamLenOverLimit(HiSysEventInfo& info)
763 {
764     return any_of(info.params.begin(), info.params.end(), [] (auto& item) {
765         if (item.second.index() != STR && item.second.index() != STR_ARR) {
766             return false;
767         }
768         if (item.second.index() == STR) {
769             return std::get<STR>(item.second).size() > JS_STR_PARM_LEN_LIMIT;
770         }
771         auto allStr = std::get<STR_ARR>(item.second);
772         return any_of(allStr.begin(), allStr.end(), [] (auto& item) {
773             return item.size() > JS_STR_PARM_LEN_LIMIT;
774         });
775     });
776 }
777 
CreateHiSysEventInfoJsObject(const napi_env env,const std::string & jsonStr,napi_value & sysEventInfo)778 void NapiHiSysEventUtil::CreateHiSysEventInfoJsObject(const napi_env env, const std::string& jsonStr,
779     napi_value& sysEventInfo)
780 {
781     Json::Value eventJson;
782 #ifdef JSONCPP_VERSION_STRING
783     Json::CharReaderBuilder jsonRBuilder;
784     Json::CharReaderBuilder::strictMode(&jsonRBuilder.settings_);
785     std::unique_ptr<Json::CharReader> const reader(jsonRBuilder.newCharReader());
786     JSONCPP_STRING errs;
787     if (!reader->parse(jsonStr.data(), jsonStr.data() + jsonStr.size(), &eventJson, &errs)) {
788 #else
789     Json::Reader reader(Json::Features::strictMode());
790     if (!reader.parse(jsonStr, eventJson)) {
791 #endif
792         HILOG_ERROR(LOG_CORE, "parse event detail info failed, please check the style of json infomation: %{public}s",
793             jsonStr.c_str());
794         return;
795     }
796     napi_create_object(env, &sysEventInfo);
797     napi_value params = nullptr;
798     napi_create_object(env, &params);
799     auto eventNameList = eventJson.getMemberNames();
800     for (auto it = eventNameList.cbegin(); it != eventNameList.cend(); it++) {
801         auto propertyName = *it;
802         if (IsBaseInfoKey(propertyName)) {
803             AppendBaseInfo(env, sysEventInfo, propertyName, eventJson[propertyName]);
804         } else {
805             AppendParamsInfo(env, params, propertyName, eventJson[propertyName]);
806         }
807     }
808     SetNamedProperty(env, sysEventInfo, PARAMS_ATTR, params);
809 }
810 
811 void NapiHiSysEventUtil::CreateJsSysEventInfoArray(const napi_env env, const std::vector<std::string>& originValues,
812     napi_value& array)
813 {
814     auto len = originValues.size();
815     for (size_t i = 0; i < len; i++) {
816         napi_value item;
817         CreateHiSysEventInfoJsObject(env, originValues[i], item);
818         napi_status status = napi_set_element(env, array, i, item);
819         if (status != napi_ok) {
820             HILOG_DEBUG(LOG_CORE, "napi_set_element failed");
821         }
822     }
823 }
824 
825 void NapiHiSysEventUtil::AppendStringPropertyToJsObject(const napi_env env, const std::string& key,
826     const std::string& value, napi_value& jsObj)
827 {
828     napi_value property = nullptr;
829     NapiHiSysEventUtil::CreateStringValue(env, value, property);
830     SetNamedProperty(env, jsObj, key, property);
831 }
832 
833 void NapiHiSysEventUtil::AppendInt32PropertyToJsObject(const napi_env env, const std::string& key,
834     const int32_t& value, napi_value& jsObj)
835 {
836     napi_value property = nullptr;
837     NapiHiSysEventUtil::CreateInt32Value(env, value, property);
838     SetNamedProperty(env, jsObj, key, property);
839 }
840 
841 int32_t NapiHiSysEventUtil::ParseListenerRules(const napi_env env, napi_value& array,
842     std::vector<ListenerRule>& listenerRules)
843 {
844     if (!CheckValueIsArray(env, array)) {
845         ThrowParamTypeError(env, "rules", "array");
846         return ERR_LISTENER_RULES_TYPE_NOT_ARRAY;
847     }
848     uint32_t len = 0;
849     napi_status status = napi_get_array_length(env, array, &len);
850     if (status != napi_ok) {
851         return ERR_NAPI_PARSED_FAILED;
852     }
853     napi_value firstItem;
854     status = napi_get_element(env, array, 0, &firstItem);
855     if (status != napi_ok) {
856         return ERR_NAPI_PARSED_FAILED;
857     }
858     napi_valuetype type;
859     status = napi_typeof(env, firstItem, &type);
860     if (status != napi_ok) {
861         return ERR_NAPI_PARSED_FAILED;
862     }
863     napi_value element;
864     for (uint32_t i = 0; i < len; i++) {
865         status = napi_get_element(env, array, i, &element);
866         if (status != napi_ok) {
867             return ERR_NAPI_PARSED_FAILED;
868         }
869         if (IsValueTypeValid(env, element, napi_valuetype::napi_object)) {
870             listenerRules.emplace_back(ParseListenerRule(env, element));
871         }
872     }
873     return NAPI_SUCCESS;
874 }
875 
876 int32_t NapiHiSysEventUtil::ParseQueryRules(const napi_env env, napi_value& array, std::vector<QueryRule>& queryRules)
877 {
878     if (!CheckValueIsArray(env, array)) {
879         ThrowParamTypeError(env, "rules", "array");
880         return ERR_QUERY_RULES_TYPE_NOT_ARRAY;
881     }
882     uint32_t len = 0;
883     napi_status status = napi_get_array_length(env, array, &len);
884     if (status != napi_ok) {
885         return ERR_NAPI_PARSED_FAILED;
886     }
887     napi_value firstItem;
888     status = napi_get_element(env, array, 0, &firstItem);
889     if (status != napi_ok) {
890         return ERR_NAPI_PARSED_FAILED;
891     }
892     napi_valuetype type;
893     status = napi_typeof(env, firstItem, &type);
894     if (status != napi_ok) {
895         return ERR_NAPI_PARSED_FAILED;
896     }
897     napi_value element;
898     for (uint32_t i = 0; i < len; i++) {
899         status = napi_get_element(env, array, i, &element);
900         if (status != napi_ok) {
901             return ERR_NAPI_PARSED_FAILED;
902         }
903         if (IsValueTypeValid(env, element, napi_valuetype::napi_object)) {
904             auto queryRule = ParseQueryRule(env, element);
905             if (IsQueryRuleValid(env, queryRule)) {
906                 queryRules.emplace_back(queryRule);
907             }
908         }
909     }
910     return NAPI_SUCCESS;
911 }
912 
913 int32_t NapiHiSysEventUtil::ParseQueryArg(const napi_env env, napi_value& jsObj, QueryArg& queryArg)
914 {
915     if (!IsValueTypeValid(env, jsObj, napi_valuetype::napi_object)) {
916         ThrowParamTypeError(env, "queryArg", "object");
917         return ERR_QUERY_ARG_TYPE_INVALID;
918     }
919     auto beginTime = GetLonglongTypeAttribute(env, jsObj, BEGIN_TIME_ATTR, DEFAULT_TIME_STAMP);
920     queryArg.beginTime = beginTime < 0 ? 0 : beginTime;
921     HILOG_DEBUG(LOG_CORE, "queryArg.beginTime is %{public}lld.", queryArg.beginTime);
922     auto endTime = GetLonglongTypeAttribute(env, jsObj, END_TIME_ATTR, DEFAULT_TIME_STAMP);
923     queryArg.endTime = endTime < 0 ? std::numeric_limits<long long>::max() : endTime;
924     HILOG_DEBUG(LOG_CORE, "queryArg.endTime is %{public}lld.", queryArg.endTime);
925     auto maxEvents = GetInt32TypeAttribute(env, jsObj, MAX_EVENTS_ATTR, DEFAULT_MAX_EVENTS);
926     queryArg.maxEvents = maxEvents < 0 ? std::numeric_limits<int>::max() : maxEvents;
927     HILOG_DEBUG(LOG_CORE, "queryArg.maxEvents is %{public}d.", queryArg.maxEvents);
928     queryArg.fromSeq = GetLonglongTypeAttribute(env, jsObj, BEGIN_SEQ_ATTR, DEFAULT_SEQ);
929     HILOG_DEBUG(LOG_CORE, "queryArg.fromSeq is %{public}lld.", queryArg.fromSeq);
930     queryArg.toSeq = GetLonglongTypeAttribute(env, jsObj, END_SEQ_ATTR, DEFAULT_SEQ);
931     HILOG_DEBUG(LOG_CORE, "queryArg.endSeq is %{public}lld.", queryArg.toSeq);
932     return NAPI_SUCCESS;
933 }
934 
935 void NapiHiSysEventUtil::CreateNull(const napi_env env, napi_value& ret)
936 {
937     napi_status status = napi_get_null(env, &ret);
938     if (status != napi_ok) {
939         HILOG_ERROR(LOG_CORE, "failed to create napi value of null.");
940     }
941 }
942 
943 void NapiHiSysEventUtil::CreateInt32Value(const napi_env env, int32_t value, napi_value& ret)
944 {
945     napi_status status = napi_create_int32(env, value, &ret);
946     HILOG_DEBUG(LOG_CORE, "create napi value of int32 type, value is %{public}d.", value);
947     if (status != napi_ok) {
948         HILOG_ERROR(LOG_CORE, "failed to create napi value of int32 type.");
949     }
950 }
951 
952 void NapiHiSysEventUtil::CreateInt64Value(const napi_env env, int64_t value, napi_value& ret)
953 {
954     napi_status status = napi_create_bigint_int64(env, value, &ret);
955     HILOG_DEBUG(LOG_CORE, "create napi value of int64_t type, value is %{public}" PRId64 ".", value);
956     if (status != napi_ok) {
957         HILOG_ERROR(LOG_CORE, "failed to create napi value of int64_t type.");
958     }
959 }
960 
961 void NapiHiSysEventUtil::CreateUInt64Value(const napi_env env, uint64_t value, napi_value& ret)
962 {
963     napi_status status = napi_create_bigint_uint64(env, value, &ret);
964     HILOG_DEBUG(LOG_CORE, "create napi value of uint64_t type, value is %{public}" PRIu64 ".", value);
965     if (status != napi_ok) {
966         HILOG_ERROR(LOG_CORE, "failed to create napi value of uint64_t type.");
967     }
968 }
969 
970 void NapiHiSysEventUtil::CreateStringValue(const napi_env env, std::string value, napi_value& ret)
971 {
972     napi_status status = napi_create_string_utf8(env, value.c_str(), NAPI_AUTO_LENGTH, &ret);
973     HILOG_DEBUG(LOG_CORE, "create napi value of string type, value is %{public}s.", value.c_str());
974     if (status != napi_ok) {
975         HILOG_ERROR(LOG_CORE, "failed to create napi value of string type.");
976     }
977 }
978 
979 void NapiHiSysEventUtil::ThrowParamMandatoryError(napi_env env, const std::string paramName)
980 {
981     ThrowError(env, NapiError::ERR_PARAM_CHECK, "Parameter error. The " + paramName + " parameter is mandatory.");
982 }
983 
984 void NapiHiSysEventUtil::ThrowParamTypeError(napi_env env, const std::string paramName, std::string paramType)
985 {
986     ThrowError(env, NapiError::ERR_PARAM_CHECK, "Parameter error. The type of " + paramName + " must be "
987         + paramType + ".");
988 }
989 
990 void NapiHiSysEventUtil::ThrowSystemAppPermissionError(napi_env env)
991 {
992     ThrowError(env, NapiError::ERR_NON_SYS_APP_PERMISSION, "Permission denied. "
993         "System api can be invoked only by system applications.");
994 }
995 
996 napi_value NapiHiSysEventUtil::CreateError(napi_env env, int32_t code, const std::string& msg)
997 {
998     napi_value err = nullptr;
999     napi_value napiCode = nullptr;
1000     NapiHiSysEventUtil::CreateStringValue(env, std::to_string(code), napiCode);
1001     napi_value napiStr = nullptr;
1002     NapiHiSysEventUtil::CreateStringValue(env, msg, napiStr);
1003     if (napi_create_error(env, napiCode, napiStr, &err) != napi_ok) {
1004         HILOG_ERROR(LOG_CORE, "failed to create napi error");
1005     }
1006     return err;
1007 }
1008 
1009 void NapiHiSysEventUtil::ThrowError(napi_env env, const int32_t code, const std::string& msg)
1010 {
1011     if (napi_throw_error(env, std::to_string(code).c_str(), msg.c_str()) != napi_ok) {
1012         HILOG_ERROR(LOG_CORE, "failed to throw err, code=%{public}d, msg=%{public}s.", code, msg.c_str());
1013     }
1014 }
1015 
1016 std::pair<int32_t, std::string> NapiHiSysEventUtil::GetErrorDetailByRet(napi_env env, const int32_t retCode)
1017 {
1018     HILOG_DEBUG(LOG_CORE, "original result code is %{public}d.", retCode);
1019     const std::unordered_map<int32_t, std::pair<int32_t, std::string>> errMap = {
1020         // common
1021         {ERR_NO_PERMISSION, {NapiError::ERR_PERMISSION_CHECK,
1022             "Permission denied. An attempt was made to read sysevent forbidden"
1023             " by permission: ohos.permission.READ_DFX_SYSEVENT."}},
1024         // write refer
1025         {ERR_DOMAIN_NAME_INVALID, {NapiError::ERR_INVALID_DOMAIN, "Domain is invalid"}},
1026         {ERR_EVENT_NAME_INVALID, {NapiError::ERR_INVALID_EVENT_NAME, "Event name is invalid"}},
1027         {ERR_DOES_NOT_INIT, {NapiError::ERR_ENV_ABNORMAL, "Environment is abnormal"}},
1028         {ERR_OVER_SIZE, {NapiError::ERR_CONTENT_OVER_LIMIT, "Size of event content is over limit"}},
1029         {ERR_KEY_NAME_INVALID, {NapiError::ERR_INVALID_PARAM_NAME, "Name of param is invalid"}},
1030         {ERR_VALUE_LENGTH_TOO_LONG, {NapiError::ERR_STR_LEN_OVER_LIMIT,
1031             "Size of string type param is over limit"}},
1032         {ERR_KEY_NUMBER_TOO_MUCH, {NapiError::ERR_PARAM_COUNT_OVER_LIMIT, "Count of params is over limit"}},
1033         {ERR_ARRAY_TOO_MUCH, {NapiError::ERR_ARRAY_SIZE_OVER_LIMIT, "Size of array type param is over limit"}},
1034         // ipc common
1035         {ERR_SYS_EVENT_SERVICE_NOT_FOUND, {NapiError::ERR_ENV_ABNORMAL, "Environment is abnormal"}},
1036         {ERR_CAN_NOT_WRITE_DESCRIPTOR, {NapiError::ERR_ENV_ABNORMAL, "Environment is abnormal"}},
1037         {ERR_CAN_NOT_WRITE_PARCEL, {NapiError::ERR_ENV_ABNORMAL, "Environment is abnormal"}},
1038         {ERR_CAN_NOT_WRITE_REMOTE_OBJECT, {NapiError::ERR_ENV_ABNORMAL, "Environment is abnormal"}},
1039         {ERR_CAN_NOT_SEND_REQ, {NapiError::ERR_ENV_ABNORMAL, "Environment is abnormal"}},
1040         {ERR_CAN_NOT_READ_PARCEL, {NapiError::ERR_ENV_ABNORMAL, "Environment is abnormal"}},
1041         {ERR_SEND_FAIL, {NapiError::ERR_ENV_ABNORMAL, "Environment is abnormal"}},
1042         // add watcher
1043         {ERR_TOO_MANY_WATCHERS, {NapiError::ERR_WATCHER_COUNT_OVER_LIMIT, "Count of watchers is over limit"}},
1044         {ERR_TOO_MANY_WATCH_RULES, {NapiError::ERR_WATCH_RULE_COUNT_OVER_LIMIT,
1045             "Count of watch rules is over limit"}},
1046         // remove watcher
1047         {ERR_LISTENER_NOT_EXIST, {NapiError::ERR_WATCHER_NOT_EXIST, "Watcher is not exist"}},
1048         {ERR_NAPI_LISTENER_NOT_FOUND, {NapiError::ERR_WATCHER_NOT_EXIST, "Watcher is not exist"}},
1049         // query refer
1050         {ERR_TOO_MANY_QUERY_RULES, {NapiError::ERR_QUERY_RULE_COUNT_OVER_LIMIT,
1051             "Count of query rules is over limit"}},
1052         {ERR_TOO_MANY_CONCURRENT_QUERIES, {NapiError::ERR_CONCURRENT_QUERY_COUNT_OVER_LIMIT,
1053             "cCount of concurrent queries is over limit"}},
1054         {ERR_QUERY_TOO_FREQUENTLY, {NapiError::ERR_QUERY_TOO_FREQUENTLY, "Frequency of event query is over limit"}},
1055         {NapiInnerError::ERR_INVALID_DOMAIN_IN_QUERY_RULE,
1056             {NapiError::ERR_INVALID_QUERY_RULE, "Query rule is invalid"}},
1057         {ERR_QUERY_RULE_INVALID, {NapiError::ERR_INVALID_QUERY_RULE, "Query rule is invalid"}},
1058         {NapiInnerError::ERR_INVALID_EVENT_NAME_IN_QUERY_RULE,
1059             {NapiError::ERR_INVALID_QUERY_RULE, "Query rule is invalid"}},
1060         // export
1061         {ERR_EXPORT_FREQUENCY_OVER_LIMIT, {NapiError::ERR_QUERY_TOO_FREQUENTLY, "Export frequency is over limit."}},
1062         // add subscriber
1063         {ERR_TOO_MANY_EVENTS, {NapiError::ERR_QUERY_RULE_COUNT_OVER_LIMIT, "Count of query rules is over limit"}},
1064         // remove subscriber
1065         {ERR_REMOVE_SUBSCRIBE, {NapiError::ERR_REMOVE_SUBSCRIBE, "unsubscribe failed"}},
1066     };
1067     return errMap.find(retCode) == errMap.end() ?
1068         std::make_pair(NapiError::ERR_ENV_ABNORMAL, "environment is abnormal") : errMap.at(retCode);
1069 }
1070 
1071 napi_value NapiHiSysEventUtil::CreateErrorByRet(napi_env env, const int32_t retCode)
1072 {
1073     auto detail = GetErrorDetailByRet(env, retCode);
1074     return CreateError(env, detail.first, detail.second);
1075 }
1076 
1077 void NapiHiSysEventUtil::ThrowErrorByRet(napi_env env, const int32_t retCode)
1078 {
1079     auto detail = GetErrorDetailByRet(env, retCode);
1080     ThrowError(env, detail.first, detail.second);
1081 }
1082 
1083 bool NapiHiSysEventUtil::IsSystemAppCall()
1084 {
1085     uint64_t tokenId = IPCSkeleton::GetCallingFullTokenID();
1086     return Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(tokenId);
1087 }
1088 } // namespace HiviewDFX
1089 } // namespace OHOS