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