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