• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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 "hiappevent_ani_util.h"
17 
18 #include "json/json.h"
19 
20 #undef LOG_DOMAIN
21 #define LOG_DOMAIN 0xD002D07
22 
23 #undef LOG_TAG
24 #define LOG_TAG "HIAPPEVENT_ANI_UTIL"
25 
26 using namespace OHOS::HiviewDFX;
27 static const std::pair<const char*, AniArgsType> OBJECT_TYPE[] = {
28     {CLASS_NAME_INT, AniArgsType::ANI_INT},
29     {CLASS_NAME_BOOLEAN, AniArgsType::ANI_BOOLEAN},
30     {CLASS_NAME_DOUBLE, AniArgsType::ANI_DOUBLE},
31     {CLASS_NAME_STRING, AniArgsType::ANI_STRING},
32 };
33 
34 static const std::map<EventTypeAni, int32_t> ANI_EVENTTYPE_INDEX_MAP = {
35     {EventTypeAni::FAULT, 0},
36     {EventTypeAni::STATISTIC, 1},
37     {EventTypeAni::SECURITY, 2},
38     {EventTypeAni::BEHAVIOR, 3},
39 };
40 
CreateErrMsg(const std::string & name)41 std::string HiAppEventAniUtil::CreateErrMsg(const std::string& name)
42 {
43     return "Parameter error. The " + name + " parameter is mandatory.";
44 }
45 
CreateErrMsg(const std::string & name,const std::string & type)46 std::string HiAppEventAniUtil::CreateErrMsg(const std::string &name, const std::string &type)
47 {
48     return "Parameter error. The type of " + name + " must be " + type + ".";
49 }
50 
IsArray(ani_env * env,ani_object object)51 bool HiAppEventAniUtil::IsArray(ani_env *env, ani_object object)
52 {
53     ani_boolean IsArray = ANI_FALSE;
54     ani_class cls {};
55     if (env == nullptr) {
56         return false;
57     }
58     if (env->FindClass(CLASS_NAME_ARRAY, &cls) != ANI_OK) {
59         return false;
60     }
61     ani_static_method static_method {};
62     if (env->Class_FindStaticMethod(cls, "isArray", nullptr, &static_method) != ANI_OK) {
63         return false;
64     }
65     if (env->Class_CallStaticMethod_Boolean(cls, static_method, &IsArray, object) != ANI_OK) {
66         return false;
67     }
68     return static_cast<bool>(IsArray);
69 }
70 
IsRefUndefined(ani_env * env,ani_ref ref)71 bool HiAppEventAniUtil::IsRefUndefined(ani_env *env, ani_ref ref)
72 {
73     ani_boolean isUndefined = ANI_FALSE;
74     if (env != nullptr) {
75         env->Reference_IsUndefined(ref, &isUndefined);
76     }
77     return isUndefined;
78 }
79 
ParseRecord(ani_env * env,ani_ref recordRef,std::map<std::string,ani_ref> & recordResult)80 void HiAppEventAniUtil::ParseRecord(ani_env *env, ani_ref recordRef, std::map<std::string, ani_ref>& recordResult)
81 {
82     if (env == nullptr) {
83         return;
84     }
85     ani_ref keys {};
86     if (env->Object_CallMethodByName_Ref(static_cast<ani_object>(recordRef), "keys",
87         ":Lescompat/IterableIterator;", &keys) != ANI_OK) {
88         HILOG_ERROR(LOG_CORE, "call method keys() failed.");
89     }
90     ani_boolean done = ANI_FALSE;
91     while (!done) {
92         ani_ref next {};
93         if (env->Object_CallMethodByName_Ref(static_cast<ani_object>(keys), "next", nullptr, &next) != ANI_OK) {
94             HILOG_ERROR(LOG_CORE, "call method next() failed.");
95             break;
96         }
97         if (env->Object_GetFieldByName_Boolean(static_cast<ani_object>(next), "done", &done) != ANI_OK) {
98             HILOG_ERROR(LOG_CORE, "get field done failed.");
99             break;
100         }
101         if (done) {
102             break;
103         }
104         ani_ref keyRef {};
105         if (env->Object_GetFieldByName_Ref(static_cast<ani_object>(next), "value", &keyRef) != ANI_OK) {
106             HILOG_ERROR(LOG_CORE, "get field value failed.");
107             break;
108         }
109         ani_ref valueRef {};
110         if (env->Object_CallMethodByName_Ref(static_cast<ani_object>(recordRef),
111             "$_get", nullptr, &valueRef, keyRef) != ANI_OK) {
112             HILOG_ERROR(LOG_CORE, "call method $_get failed.");
113             break;
114         }
115         std::string keyStr = ParseStringValue(env, keyRef);
116         recordResult[keyStr] = valueRef;
117     }
118 }
119 
ParseStringValue(ani_env * env,ani_ref aniStrRef)120 std::string HiAppEventAniUtil::ParseStringValue(ani_env *env, ani_ref aniStrRef)
121 {
122     if (env == nullptr) {
123         return "";
124     }
125     ani_size strSize = 0;
126     if (env->String_GetUTF8Size(static_cast<ani_string>(aniStrRef), &strSize) != ANI_OK) {
127         HILOG_ERROR(LOG_CORE, "get ani string size failed");
128         return "";
129     }
130     std::vector<char> buffer(strSize + 1);
131     char* utf8Buffer = buffer.data();
132     ani_size bytesWritten = 0;
133     if (env->String_GetUTF8(static_cast<ani_string>(aniStrRef), utf8Buffer, strSize + 1, &bytesWritten) != ANI_OK) {
134         HILOG_ERROR(LOG_CORE, "get ani string failed");
135         return "";
136     }
137     utf8Buffer[bytesWritten] = '\0';
138     std::string content = std::string(utf8Buffer);
139     return content;
140 }
141 
ParseIntValue(ani_env * env,ani_ref elementRef)142 int32_t HiAppEventAniUtil::ParseIntValue(ani_env *env, ani_ref elementRef)
143 {
144     ani_int intVal = 0;
145     if (env == nullptr) {
146         return static_cast<int32_t>(intVal);
147     }
148     ani_class cls {};
149     ani_method unboxedMethod {};
150     if (env->FindClass(CLASS_NAME_INT, &cls)) {
151         HILOG_ERROR(LOG_CORE, "find class %{public}s failed", CLASS_NAME_INT);
152         return static_cast<int32_t>(intVal);
153     }
154     if (env->Class_FindMethod(cls, FUNC_NAME_UNBOXED, ":I", &unboxedMethod) != ANI_OK) {
155         HILOG_ERROR(LOG_CORE, "find method %{public}s failed", FUNC_NAME_UNBOXED);
156         return static_cast<int32_t>(intVal);
157     }
158     if (env->Object_CallMethod_Int(static_cast<ani_object>(elementRef), unboxedMethod, &intVal) != ANI_OK) {
159         HILOG_ERROR(LOG_CORE, "call method %{public}s failed", FUNC_NAME_UNBOXED);
160         return static_cast<int32_t>(intVal);
161     }
162     return static_cast<int32_t>(intVal);
163 }
164 
ParseBoolValue(ani_env * env,ani_ref elementRef)165 bool HiAppEventAniUtil::ParseBoolValue(ani_env *env, ani_ref elementRef)
166 {
167     if (env == nullptr) {
168         return false;
169     }
170     ani_class cls {};
171     if (env->FindClass(CLASS_NAME_BOOLEAN, &cls) != ANI_OK) {
172         HILOG_ERROR(LOG_CORE, "find class %{public}s failed", CLASS_NAME_BOOLEAN);
173         return false;
174     }
175     ani_method unboxedMethod {};
176     if (env->Class_FindMethod(cls, FUNC_NAME_UNBOXED, ":Z", &unboxedMethod) != ANI_OK) {
177         HILOG_ERROR(LOG_CORE, "find method %{public}s failed", FUNC_NAME_UNBOXED);
178         return false;
179     }
180     ani_boolean booleanVal = static_cast<ani_boolean>(false);
181     if (env->Object_CallMethod_Boolean(static_cast<ani_object>(elementRef), unboxedMethod, &booleanVal) != ANI_OK) {
182         HILOG_ERROR(LOG_CORE, "call method %{public}s failed", FUNC_NAME_UNBOXED);
183         return false;
184     }
185     return static_cast<bool>(booleanVal);
186 }
187 
ParseNumberValue(ani_env * env,ani_ref elementRef)188 double HiAppEventAniUtil::ParseNumberValue(ani_env *env, ani_ref elementRef)
189 {
190     ani_double doubleVal = 0;
191     if (env == nullptr) {
192         return static_cast<double>(doubleVal);
193     }
194     ani_class cls {};
195     if (env->FindClass(CLASS_NAME_DOUBLE, &cls) != ANI_OK) {
196         HILOG_ERROR(LOG_CORE, "find class %{public}s failed", CLASS_NAME_DOUBLE);
197         return static_cast<double>(doubleVal);
198     }
199     ani_method unboxedMethod {};
200     if (env->Class_FindMethod(cls, FUNC_NAME_UNBOXED, ":D", &unboxedMethod) != ANI_OK) {
201         HILOG_ERROR(LOG_CORE, "find method %{public}s failed", FUNC_NAME_UNBOXED);
202         return static_cast<double>(doubleVal);
203     }
204     if (env->Object_CallMethod_Double(static_cast<ani_object>(elementRef), unboxedMethod, &doubleVal) != ANI_OK) {
205         HILOG_ERROR(LOG_CORE, "call method %{public}s failed", FUNC_NAME_UNBOXED);
206     }
207     return static_cast<double>(doubleVal);
208 }
209 
GetStringsToSet(ani_env * env,ani_ref Ref,std::unordered_set<std::string> & arr)210 void HiAppEventAniUtil::GetStringsToSet(ani_env *env, ani_ref Ref, std::unordered_set<std::string> &arr)
211 {
212     ani_double doubleVal = 0;
213     if (env == nullptr) {
214         return;
215     }
216     ani_size length = 0;
217     if (env->Array_GetLength(static_cast<ani_array_ref>(Ref), &length) != ANI_OK) {
218         HILOG_ERROR(LOG_CORE, "get array length failed");
219     }
220     for (ani_size i = 0; i < length; i++) {
221         ani_ref value {};
222         if (env->Array_Get_Ref(static_cast<ani_array_ref>(Ref), i, &value) != ANI_OK) {
223             HILOG_ERROR(LOG_CORE, "get array element failed");
224             continue;
225         }
226         arr.insert(ParseStringValue(env, static_cast<ani_string>(value)));
227     }
228 }
229 
GetIntValueToVector(ani_env * env,ani_ref Ref,std::vector<int> & arr)230 void HiAppEventAniUtil::GetIntValueToVector(ani_env *env, ani_ref Ref, std::vector<int> &arr)
231 {
232     if (env == nullptr) {
233         return;
234     }
235     ani_size length = 0;
236     if (env->Array_GetLength(static_cast<ani_array_ref>(Ref), &length) != ANI_OK) {
237         HILOG_ERROR(LOG_CORE, "get array length failed");
238         return;
239     }
240     for (ani_size i = 0; i < length; i++) {
241         ani_ref value {};
242         if (env->Array_Get_Ref(static_cast<ani_array_ref>(Ref), i, &value) != ANI_OK) {
243             HILOG_ERROR(LOG_CORE, "get array element failed");
244             continue;
245         }
246         ani_int aniInt = 0;
247         if (env->EnumItem_GetValue_Int(static_cast<ani_enum_item>(value), &aniInt) != ANI_OK) {
248             HILOG_ERROR(LOG_CORE, "enumItem get int value failed");
249             return;
250         }
251         arr.emplace_back(static_cast<int32_t>(aniInt));
252     }
253 }
254 
GetProperty(ani_env * env,ani_object object,const std::string & name)255 ani_ref HiAppEventAniUtil::GetProperty(ani_env *env, ani_object object, const std::string &name)
256 {
257     ani_ref value = nullptr;
258     if (env == nullptr) {
259         return value;
260     }
261     if (env->Object_GetPropertyByName_Ref(object, name.c_str(), &value) != ANI_OK) {
262         HILOG_ERROR(LOG_CORE, "failed to get property %{public}s from object", name.c_str());
263     }
264     return value;
265 }
266 
ThrowAniError(ani_env * env,int32_t code,const std::string & message)267 void HiAppEventAniUtil::ThrowAniError(ani_env *env, int32_t code, const std::string &message)
268 {
269     if (env == nullptr) {
270         return;
271     }
272     ani_class cls {};
273     if (env->FindClass(CLASS_NAME_BUSINESSERROR, &cls) != ANI_OK) {
274         HILOG_ERROR(LOG_CORE, "find class %{public}s failed", CLASS_NAME_BUSINESSERROR);
275         return;
276     }
277     ani_method ctor {};
278     if (env->Class_FindMethod(cls, "<ctor>", ":V", &ctor) != ANI_OK) {
279         HILOG_ERROR(LOG_CORE, "find method BusinessError constructor failed");
280         return;
281     }
282     ani_object error {};
283     if (env->Object_New(cls, ctor, &error) != ANI_OK) {
284         HILOG_ERROR(LOG_CORE, "new object %{public}s failed", CLASS_NAME_BUSINESSERROR);
285         return;
286     }
287     if (env->Object_SetPropertyByName_Double(error, "code", static_cast<ani_double>(code)) != ANI_OK) {
288         HILOG_ERROR(LOG_CORE, "set property BusinessError.code failed");
289         return;
290     }
291     ani_string messageRef {};
292     if (env->String_NewUTF8(message.c_str(), message.size(), &messageRef) != ANI_OK) {
293         HILOG_ERROR(LOG_CORE, "new message string failed");
294         return;
295     }
296     if (env->Object_SetPropertyByName_Ref(error, "message", static_cast<ani_ref>(messageRef)) != ANI_OK) {
297         HILOG_ERROR(LOG_CORE, "set property BusinessError.message failed");
298         return;
299     }
300     if (env->ThrowError(static_cast<ani_error>(error)) != ANI_OK) {
301         HILOG_ERROR(LOG_CORE, "throwError ani_error object failed");
302     }
303 }
304 
Result(ani_env * env,std::pair<int32_t,std::string> result)305 ani_object HiAppEventAniUtil::Result(ani_env *env, std::pair<int32_t, std::string> result)
306 {
307     ani_object results_obj {};
308     if (env == nullptr) {
309         return results_obj;
310     }
311 
312     ani_class cls {};
313     if (env->FindClass(CLASS_NAME_RESULTS, &cls) != ANI_OK) {
314         HILOG_ERROR(LOG_CORE, "failed to find class %{public}s", CLASS_NAME_RESULTS);
315         return results_obj;
316     }
317 
318     ani_method ctor {};
319     if (env->Class_FindMethod(cls, "<ctor>", nullptr, &ctor) != ANI_OK) {
320         HILOG_ERROR(LOG_CORE, "get method %{public}s <ctor> failed", CLASS_NAME_RESULTS);
321         return results_obj;
322     }
323 
324     if (env->Object_New(cls, ctor, &results_obj) != ANI_OK) {
325         HILOG_ERROR(LOG_CORE, "create object %{public}s failed", CLASS_NAME_RESULTS);
326         return results_obj;
327     }
328 
329     ani_method codeSetter {};
330     if (env->Class_FindMethod(cls, "<set>code", nullptr, &codeSetter) != ANI_OK) {
331         HILOG_ERROR(LOG_CORE, "get method codeSetter %{public}s failed", CLASS_NAME_RESULTS);
332         return results_obj;
333     }
334 
335     if (env->Object_CallMethod_Void(results_obj, codeSetter, result.first) != ANI_OK) {
336         HILOG_ERROR(LOG_CORE, "call method codeSetter %{public}s failed", CLASS_NAME_RESULTS);
337         return results_obj;
338     }
339 
340     ani_method messageSetter {};
341     if (env->Class_FindMethod(cls, "<set>message", nullptr, &messageSetter) != ANI_OK) {
342         HILOG_ERROR(LOG_CORE, "find method messageSetter %{public}s failed", CLASS_NAME_RESULTS);
343         return results_obj;
344     }
345 
346     ani_string message_string = HiAppEventAniUtil::CreateAniString(env, result.second);
347     if (env->Object_CallMethod_Void(results_obj, messageSetter, message_string) != ANI_OK) {
348         HILOG_ERROR(LOG_CORE, "call method messageSetter Fail %{public}s", CLASS_NAME_RESULTS);
349         return results_obj;
350     }
351 
352     return results_obj;
353 }
354 
BuildErrorByResult(int32_t result)355 std::pair<int32_t, std::string> HiAppEventAniUtil::BuildErrorByResult(int32_t result)
356 {
357     const std::map<int32_t, std::pair<int32_t, std::string>> codeMap = {
358         { ERR_CODE_SUCC,
359             { ERR_CODE_SUCC, "Success." } },
360         { ErrorCode::ERROR_INVALID_EVENT_NAME,
361             { ERR_INVALID_NAME, "Invalid event name." } },
362         { ErrorCode::ERROR_INVALID_EVENT_DOMAIN,
363             { ERR_INVALID_DOMAIN, "Invalid event domain." } },
364         { ErrorCode::ERROR_HIAPPEVENT_DISABLE,
365             { ERR_DISABLE, "Function disabled." } },
366         { ErrorCode::ERROR_INVALID_PARAM_NAME,
367             { ERR_INVALID_KEY, "Invalid event parameter name." } },
368         { ErrorCode::ERROR_INVALID_PARAM_VALUE_LENGTH,
369             { ERR_INVALID_STR_LEN, "Invalid string length of the event parameter." } },
370         { ErrorCode::ERROR_INVALID_PARAM_NUM,
371             { ERR_INVALID_PARAM_NUM, "Invalid number of event parameters." } },
372         { ErrorCode::ERROR_INVALID_LIST_PARAM_SIZE,
373             { ERR_INVALID_ARR_LEN, "Invalid array length of the event parameter." } },
374         { ErrorCode::ERROR_INVALID_CUSTOM_PARAM_NUM,
375             { ERR_INVALID_CUSTOM_PARAM_NUM, "The number of parameter keys exceeds the limit." }},
376     };
377     auto it = codeMap.find(result);
378     return it == codeMap.end() ? std::make_pair(-1, "ErrMsg not found.") : it->second;
379 }
380 
GetArgType(ani_env * env,ani_object elementObj)381 AniArgsType HiAppEventAniUtil::GetArgType(ani_env *env, ani_object elementObj)
382 {
383     if (env == nullptr) {
384         return AniArgsType::ANI_UNKNOWN;
385     }
386     if (HiAppEventAniUtil::IsRefUndefined(env, static_cast<ani_ref>(elementObj))) {
387         return AniArgsType::ANI_UNDEFINED;
388     }
389     for (const auto &objType : OBJECT_TYPE) {
390         ani_class cls {};
391         if (env->FindClass(objType.first, &cls) != ANI_OK) {
392             continue;
393         }
394         ani_boolean isInstance = ANI_FALSE;
395         if (env->Object_InstanceOf(elementObj, cls, &isInstance) != ANI_OK) {
396             continue;
397         }
398         if (static_cast<bool>(isInstance)) {
399             return objType.second;
400         }
401     }
402     return AniArgsType::ANI_UNKNOWN;
403 }
404 
GetArrayType(ani_env * env,ani_ref arrayRef)405 AniArgsType HiAppEventAniUtil::GetArrayType(ani_env *env, ani_ref arrayRef)
406 {
407     if (env == nullptr) {
408         return AniArgsType::ANI_UNKNOWN;
409     }
410     ani_size len = 0;
411     if (env->Array_GetLength(static_cast<ani_array_ref>(arrayRef), &len) != ANI_OK) {
412         HILOG_ERROR(LOG_CORE, "failed to get the length of array");
413         return AniArgsType::ANI_UNDEFINED;
414     }
415     AniArgsType type = AniArgsType::ANI_NULL; // note: empty array returns null type
416     for (ani_size i = 0; i < len; ++i) {
417         ani_ref element = nullptr;
418         if (env->Array_Get_Ref(static_cast<ani_array_ref>(arrayRef), i, &element) != ANI_OK) {
419             HILOG_ERROR(LOG_CORE, "failed to get the element of array");
420             return AniArgsType::ANI_UNDEFINED;
421         }
422         if (i == 0) {
423             type = GetArgType(env, static_cast<ani_object>(element));
424             continue;
425         }
426         if (type != GetArgType(env, static_cast<ani_object>(element))) {
427             HILOG_ERROR(LOG_CORE, "array has different element types");
428             return AniArgsType::ANI_UNDEFINED;
429         }
430     }
431     return type;
432 }
433 
ConvertToString(ani_env * env,ani_ref valueRef)434 std::string HiAppEventAniUtil::ConvertToString(ani_env *env, ani_ref valueRef)
435 {
436     if (env == nullptr) {
437         return "";
438     }
439     AniArgsType type = GetArgType(env, static_cast<ani_object>(valueRef));
440     std::string result = "";
441     switch (type) {
442         case AniArgsType::ANI_BOOLEAN:
443             result = HiAppEventAniUtil::ParseBoolValue(env, valueRef) ? "true" : "false";
444             break;
445         case AniArgsType::ANI_DOUBLE:
446             result = std::to_string(ParseNumberValue(env, valueRef));
447             break;
448         case AniArgsType::ANI_STRING:
449             result = HiAppEventAniUtil::ParseStringValue(env, valueRef);
450             break;
451         default:
452             break;
453     }
454     return result;
455 }
456 
CreateGlobalReference(ani_env * env,ani_ref func)457 ani_ref HiAppEventAniUtil::CreateGlobalReference(ani_env *env, ani_ref func)
458 {
459     ani_ref objectGRef {};
460     if (env == nullptr) {
461         return objectGRef;
462     }
463     if (env->GlobalReference_Create(func, &objectGRef) != ANI_OK) {
464         HILOG_ERROR(LOG_CORE, "failed to create global reference");
465         return objectGRef;
466     }
467     return objectGRef;
468 }
469 
CreateDouble(ani_env * env,int32_t num)470 ani_object HiAppEventAniUtil::CreateDouble(ani_env *env, int32_t num)
471 {
472     ani_class cls {};
473     ani_object obj {};
474     if (env == nullptr) {
475         return obj;
476     }
477     if (env->FindClass(CLASS_NAME_DOUBLE, &cls) != ANI_OK) {
478         HILOG_ERROR(LOG_CORE, "find class %{public}s failed", CLASS_NAME_DOUBLE);
479         return obj;
480     }
481     ani_method ctor;
482     env->Class_FindMethod(cls, "<ctor>", "D:V", &ctor);
483     env->Object_New(cls, ctor, &obj, static_cast<ani_double>(num));
484     return obj;
485 }
486 
ToAniEnum(ani_env * env,EventTypeAni value)487 static ani_enum_item ToAniEnum(ani_env *env, EventTypeAni value)
488 {
489     ani_enum_item aniEnumItem {};
490     if (env == nullptr) {
491         return aniEnumItem;
492     }
493     auto it = ANI_EVENTTYPE_INDEX_MAP.find(value);
494     if (it == ANI_EVENTTYPE_INDEX_MAP.end()) {
495         HILOG_ERROR(LOG_CORE, "Unsupport enum: %{public}d", value);
496         return aniEnumItem;
497     }
498     ani_int enumIndex = static_cast<ani_int>(it->second);
499 
500     ani_enum aniEnum {};
501     if (env->FindEnum(ENUM_NAME_EVENT_TYPE, &aniEnum) != ANI_OK) {
502         HILOG_ERROR(LOG_CORE, "find enum %{public}s failed", ENUM_NAME_EVENT_TYPE);
503         return aniEnumItem;
504     }
505     if (env->Enum_GetEnumItemByIndex(aniEnum, enumIndex, &aniEnumItem)) {
506         HILOG_ERROR(LOG_CORE, "get enum eventType value failed");
507         return aniEnumItem;
508     }
509     return aniEnumItem;
510 }
511 
CreateBool(ani_env * env,bool boolValue)512 ani_object HiAppEventAniUtil::CreateBool(ani_env *env, bool boolValue)
513 {
514     ani_class cls {};
515     ani_object obj {};
516     if (env == nullptr) {
517         return obj;
518     }
519     if (env->FindClass(CLASS_NAME_BOOLEAN, &cls) != ANI_OK) {
520         HILOG_ERROR(LOG_CORE, "find class %{public}s failed", CLASS_NAME_BOOLEAN);
521         return obj;
522     }
523     ani_method ctor;
524     env->Class_FindMethod(cls, "<ctor>", "Z:V", &ctor);
525     env->Object_New(cls, ctor, &obj, static_cast<ani_boolean>(boolValue));
526     return obj;
527 }
528 
CreateAniString(ani_env * env,const std::string & str)529 ani_string HiAppEventAniUtil::CreateAniString(ani_env *env, const std::string &str)
530 {
531     ani_string aniString {};
532     if (env != nullptr) {
533         env->String_NewUTF8(str.c_str(), str.size(), &aniString);
534     }
535     return aniString;
536 }
537 
CreateArray(ani_env * env,size_t length)538 static ani_ref CreateArray(ani_env *env, size_t length)
539 {
540     ani_class cls {};
541     ani_object array {};
542     if (env == nullptr) {
543         return array;
544     }
545     if (env->FindClass(CLASS_NAME_ARRAY, &cls) != ANI_OK) {
546         HILOG_ERROR(LOG_CORE, "FindClass %{public}s Failed", CLASS_NAME_ARRAY);
547         return array;
548     }
549     ani_method method {};
550     if (env->Class_FindMethod(cls, "<ctor>", "I:V", &method) != ANI_OK) {
551         HILOG_ERROR(LOG_CORE, "%{public}s Find Method ctor Failed", CLASS_NAME_ARRAY);
552         return array;
553     }
554     if (env->Object_New(cls, method, &array, length) != ANI_OK) {
555         HILOG_ERROR(LOG_CORE, "%{public}s Call Method ctor Failed", CLASS_NAME_ARRAY);
556         return array;
557     }
558     return array;
559 }
560 
CreateArray(ani_env * env,const std::string & name,ani_size length)561 static ani_ref CreateArray(ani_env *env, const std::string &name, ani_size length)
562 {
563     ani_array_ref array {};
564     if (env == nullptr) {
565         return array;
566     }
567     ani_class cls {};
568     if (env->FindClass(name.c_str(), &cls) != ANI_OK) {
569         HILOG_ERROR(LOG_CORE, "FindClass %{public}s Failed", name.c_str());
570         return array;
571     }
572     if (env->Array_New_Ref(cls, length, nullptr, &array) != ANI_OK) {
573         HILOG_ERROR(LOG_CORE, "New %{public}s Array Ref Failed.", name.c_str());
574         return array;
575     }
576     return array;
577 }
578 
FindArrayMethodSet(ani_env * env)579 static ani_method FindArrayMethodSet(ani_env *env)
580 {
581     ani_class cls {};
582     ani_method setMethod {};
583     if (env == nullptr) {
584         return setMethod;
585     }
586     if (env->FindClass(CLASS_NAME_ARRAY, &cls) != ANI_OK) {
587         HILOG_ERROR(LOG_CORE, "FindClass %{public}s Failed", CLASS_NAME_ARRAY);
588         return setMethod;
589     }
590     if (env->Class_FindMethod(cls, "$_set", "ILstd/core/Object;:V", &setMethod) != ANI_OK) {
591         HILOG_ERROR(LOG_CORE, "FindMethod $_set %{public}s Failed", CLASS_NAME_ARRAY);
592         return setMethod;
593     }
594     return setMethod;
595 }
596 
CreateStrings(ani_env * env,const std::vector<std::string> & strs)597 ani_ref HiAppEventAniUtil::CreateStrings(ani_env *env, const std::vector<std::string>& strs)
598 {
599     ani_ref arr = CreateArray(env, CLASS_NAME_STRING, strs.size());
600     for (size_t i = 0; i < strs.size(); ++i) {
601         env->Array_Set_Ref(static_cast<ani_array_ref>(arr),
602             static_cast<ani_size>(i), HiAppEventAniUtil::CreateAniString(env, strs[i]));
603     }
604     return arr;
605 }
606 
CreateObject(ani_env * env,const std::string & name)607 ani_object HiAppEventAniUtil::CreateObject(ani_env *env, const std::string &name)
608 {
609     if (env == nullptr) {
610         return nullptr;
611     }
612 
613     ani_class cls {};
614     if (env->FindClass(name.c_str(), &cls) != ANI_OK) {
615         HILOG_ERROR(LOG_CORE, "FindClass %{public}s Failed", name.c_str());
616     }
617 
618     ani_method ctor {};
619     if (env->Class_FindMethod(cls, "<ctor>", nullptr, &ctor) != ANI_OK) {
620         HILOG_ERROR(LOG_CORE, "get %{public}s ctor Failed", name.c_str());
621     }
622 
623     ani_object obj {};
624     if (env->Object_New(cls, ctor, &obj) != ANI_OK) {
625         HILOG_ERROR(LOG_CORE, "Create Object Failed: %{public}s", name.c_str());
626     }
627     return obj;
628 }
629 
CreateBaseValueByJson(ani_env * env,const Json::Value & jsonValue)630 static ani_ref CreateBaseValueByJson(ani_env *env, const Json::Value& jsonValue)
631 {
632     if (env == nullptr) {
633         return nullptr;
634     }
635     if (jsonValue.isBool()) {
636         return HiAppEventAniUtil::CreateBool(env, jsonValue.asBool());
637     }
638     if (jsonValue.isDouble()) {
639         return HiAppEventAniUtil::CreateDouble(env, jsonValue.asDouble());
640     }
641     if (jsonValue.isString()) {
642         return HiAppEventAniUtil::CreateAniString(env, jsonValue.asString());
643     }
644     return nullptr;
645 }
646 
GetRecordSetMethod(ani_env * env)647 static ani_method GetRecordSetMethod(ani_env *env)
648 {
649     if (env == nullptr) {
650         return nullptr;
651     }
652 
653     ani_class cls {};
654     if (env->FindClass(CLASS_NAME_RECORD, &cls) != ANI_OK) {
655         HILOG_ERROR(LOG_CORE, "FindClass %{public}s Failed", CLASS_NAME_RECORD);
656         return nullptr;
657     }
658 
659     ani_method set {};
660     if (env->Class_FindMethod(cls, "$_set", nullptr, &set) != ANI_OK) {
661         HILOG_ERROR(LOG_CORE, "get %{public}s set Failed", CLASS_NAME_RECORD);
662         return nullptr;
663     }
664     return set;
665 }
666 
CreateValueByJson(ani_env * env,const Json::Value & jsonValue)667 static ani_ref CreateValueByJson(ani_env *env, const Json::Value& jsonValue)
668 {
669     if (env == nullptr) {
670         return nullptr;
671     }
672 
673     if (jsonValue.isArray()) {
674         if (jsonValue[0].isBool()) {
675             ani_ref boolArray = CreateArray(env, CLASS_NAME_BOOLEAN, jsonValue.size());
676             for (Json::ArrayIndex i = 0; i < jsonValue.size(); ++i) {
677                 env->Array_Set_Ref(static_cast<ani_array_ref>(boolArray), static_cast<ani_size>(i),
678                     CreateValueByJson(env, jsonValue[static_cast<int>(i)]));
679             }
680             return boolArray;
681         }
682         if (jsonValue[0].isDouble()) {
683             ani_ref doubleArray = CreateArray(env, CLASS_NAME_DOUBLE, jsonValue.size());
684             for (Json::ArrayIndex i = 0; i < jsonValue.size(); ++i) {
685                 env->Array_Set_Ref(static_cast<ani_array_ref>(doubleArray), static_cast<ani_size>(i),
686                     CreateValueByJson(env, jsonValue[static_cast<int>(i)]));
687             }
688             return doubleArray;
689         }
690         if (jsonValue[0].isString()) {
691             ani_ref stringArray = CreateArray(env, CLASS_NAME_STRING, jsonValue.size());
692             for (Json::ArrayIndex i = 0; i < jsonValue.size(); ++i) {
693                 env->Array_Set_Ref(static_cast<ani_array_ref>(stringArray), static_cast<ani_size>(i),
694                     CreateValueByJson(env, jsonValue[static_cast<int>(i)]));
695             }
696             return stringArray;
697         }
698     }
699     if (jsonValue.isObject()) {
700         ani_object obj = HiAppEventAniUtil::CreateObject(env, CLASS_NAME_RECORD);
701         ani_method set = GetRecordSetMethod(env);
702         auto eventNameList = jsonValue.getMemberNames();
703         for (auto it = eventNameList.cbegin(); it != eventNameList.cend(); ++it) {
704             auto propertyName = *it;
705             if (env->Object_CallMethod_Void(obj, set, HiAppEventAniUtil::CreateAniString(env, propertyName),
706                 CreateValueByJson(env, jsonValue[propertyName])) != ANI_OK) {
707                 HILOG_ERROR(LOG_CORE, "set record params Fail: %{public}s", CLASS_NAME_RECORD);
708                 return obj;
709             }
710         }
711         return obj;
712     }
713     return CreateBaseValueByJson(env, jsonValue);
714 }
715 
CreateValueByJsonStr(ani_env * env,const std::string & jsonStr)716 static ani_ref CreateValueByJsonStr(ani_env *env, const std::string& jsonStr)
717 {
718     if (env == nullptr) {
719         return nullptr;
720     }
721     Json::Value jsonValue;
722     Json::Reader reader(Json::Features::strictMode());
723     if (!reader.parse(jsonStr, jsonValue)) {
724         HILOG_ERROR(LOG_CORE, "parse event detail info failed, please check the style of json");
725         return nullptr;
726     }
727     return CreateValueByJson(env, jsonValue);
728 }
729 
CreateEventInfo(ani_env * env,std::shared_ptr<AppEventPack> event)730 static ani_object CreateEventInfo(ani_env *env, std::shared_ptr<AppEventPack> event)
731 {
732     if (env == nullptr) {
733         return nullptr;
734     }
735     ani_object obj = HiAppEventAniUtil::CreateObject(env, CLASS_NAME_EVENT_INFO);
736     env->Object_SetPropertyByName_Ref(obj, EVENT_CONFIG_DOMAIN.c_str(),
737         HiAppEventAniUtil::CreateAniString(env, event->GetDomain()));
738     env->Object_SetPropertyByName_Ref(obj, EVENT_CONFIG_NAME.c_str(),
739         HiAppEventAniUtil::CreateAniString(env, event->GetName()));
740     env->Object_SetPropertyByName_Ref(obj, EVENT_INFO_EVENT_TYPE.c_str(),
741         ToAniEnum(env, static_cast<EventTypeAni>(event->GetType())));
742     env->Object_SetPropertyByName_Ref(obj, EVENT_INFO_PARAMS.c_str(),
743         CreateValueByJsonStr(env, event->GetParamStr()));
744     return obj;
745 }
746 
CreateEventInfoArray(ani_env * env,const std::vector<std::shared_ptr<AppEventPack>> & events)747 ani_ref HiAppEventAniUtil::CreateEventInfoArray(ani_env *env, const std::vector<std::shared_ptr<AppEventPack>>& events)
748 {
749     ani_ref arr = CreateArray(env, events.size());
750     ani_method setMethod = FindArrayMethodSet(env);
751     for (size_t i = 0; i < events.size(); ++i) {
752         env->Object_CallMethod_Void(static_cast<ani_object>(arr), setMethod, i, CreateEventInfo(env, events[i]));
753     }
754     return arr;
755 }
756 
CreateEventGroups(ani_env * env,const std::vector<std::shared_ptr<AppEventPack>> & events)757 ani_ref HiAppEventAniUtil::CreateEventGroups(ani_env *env, const std::vector<std::shared_ptr<AppEventPack>>& events)
758 {
759     std::unordered_map<std::string, std::vector<std::shared_ptr<AppEventPack>>> eventMap;
760     for (auto event : events) {
761         eventMap[event->GetName()].emplace_back(event);
762     }
763 
764     ani_ref eventGroups = CreateArray(env, eventMap.size());
765     ani_method setMethod = FindArrayMethodSet(env);
766     size_t index = 0;
767     for (auto it = eventMap.begin(); it != eventMap.end(); ++it) {
768         ani_ref eventInfos = CreateArray(env, it->second.size());
769         for (size_t i = 0; i < it->second.size(); ++i) {
770             env->Object_CallMethod_Void(static_cast<ani_object>(eventInfos),
771                 setMethod, i, CreateEventInfo(env, it->second[i]));
772         }
773         ani_object obj = HiAppEventAniUtil::CreateObject(env, CLASS_NAME_EVENT_GROUP);
774         env->Object_SetPropertyByName_Ref(obj, EVENT_CONFIG_NAME.c_str(),
775             HiAppEventAniUtil::CreateAniString(env, it->first));
776         env->Object_SetPropertyByName_Ref(obj, EVENT_INFOS_PROPERTY.c_str(), eventInfos);
777         env->Object_CallMethod_Void(static_cast<ani_object>(eventGroups), setMethod, index, obj);
778         ++index;
779     }
780     return eventGroups;
781 }
782 
GetBooleans(ani_env * env,ani_ref arrayRef)783 std::vector<bool> HiAppEventAniUtil::GetBooleans(ani_env *env, ani_ref arrayRef)
784 {
785     std::vector<bool> bools;
786     ani_size len = 0;
787     if (env->Array_GetLength(static_cast<ani_array_ref>(arrayRef), &len) != ANI_OK) {
788         HILOG_ERROR(LOG_CORE, "failed to get the length of array");
789         return bools;
790     }
791     for (ani_size i = 0; i < len; i++) {
792         ani_ref element = nullptr;
793         if (env->Array_Get_Ref(static_cast<ani_array_ref>(arrayRef), i, &element) != ANI_OK) {
794             HILOG_ERROR(LOG_CORE, "failed to get the element of array");
795             break;
796         }
797         bools.emplace_back(HiAppEventAniUtil::ParseBoolValue(env, element));
798     }
799     return bools;
800 }
801 
GetDoubles(ani_env * env,ani_ref arrayRef)802 std::vector<double> HiAppEventAniUtil::GetDoubles(ani_env *env, ani_ref arrayRef)
803 {
804     std::vector<double> doubles;
805     ani_size len = 0;
806     if (env->Array_GetLength(static_cast<ani_array_ref>(arrayRef), &len) != ANI_OK) {
807         HILOG_ERROR(LOG_CORE, "failed to get the length of array");
808         return doubles;
809     }
810     for (ani_size i = 0; i < len; i++) {
811         ani_ref element = nullptr;
812         if (env->Array_Get_Ref(static_cast<ani_array_ref>(arrayRef), i, &element) != ANI_OK) {
813             HILOG_ERROR(LOG_CORE, "failed to get the element of array");
814             break;
815         }
816         doubles.emplace_back(HiAppEventAniUtil::ParseNumberValue(env, element));
817     }
818     return doubles;
819 }
820 
GetStrings(ani_env * env,ani_ref arrayRef)821 std::vector<std::string> HiAppEventAniUtil::GetStrings(ani_env *env, ani_ref arrayRef)
822 {
823     std::vector<std::string> strs;
824     ani_size len = 0;
825     if (env->Array_GetLength(static_cast<ani_array_ref>(arrayRef), &len) != ANI_OK) {
826         HILOG_ERROR(LOG_CORE, "failed to get the length of array");
827         return strs;
828     }
829     for (ani_size i = 0; i < len; i++) {
830         ani_ref element = nullptr;
831         if (env->Array_Get_Ref(static_cast<ani_array_ref>(arrayRef), i, &element) != ANI_OK) {
832             HILOG_ERROR(LOG_CORE, "failed to get the element of array");
833             break;
834         }
835         strs.emplace_back(HiAppEventAniUtil::ParseStringValue(env, element));
836     }
837     return strs;
838 }
839 
GetInts(ani_env * env,ani_ref arrayRef)840 std::vector<int> HiAppEventAniUtil::GetInts(ani_env *env, ani_ref arrayRef)
841 {
842     std::vector<int> ints;
843     ani_size len = 0;
844     if (env->Array_GetLength(static_cast<ani_array_ref>(arrayRef), &len) != ANI_OK) {
845         HILOG_ERROR(LOG_CORE, "failed to get the length of array");
846         return ints;
847     }
848     for (ani_size i = 0; i < len; i++) {
849         ani_ref element = nullptr;
850         if (env->Array_Get_Ref(static_cast<ani_array_ref>(arrayRef), i, &element) != ANI_OK) {
851             HILOG_ERROR(LOG_CORE, "failed to get the element of array");
852             break;
853         }
854         ints.emplace_back(HiAppEventAniUtil::ParseIntValue(env, element));
855     }
856     return ints;
857 }
858