• 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 "sts_events_json_common.h"
17 #include <cstring>
18 #include "event_logger.h"
19 #include "securec.h"
20 
21 namespace OHOS {
22 namespace AppExecFwk {
23 namespace {
24 DEFINE_EH_HILOG_LABEL("EventsEmitter");
25 }
26 constexpr const char* CLASSNAME_DOUBLE = "Lstd/core/Double;";
27 constexpr const char* CLASSNAME_BOOLEAN = "Lstd/core/Boolean;";
28 
GetIntByName(ani_env * env,ani_object param,const char * name,int32_t & value)29 bool GetIntByName(ani_env *env, ani_object param, const char *name, int32_t &value)
30 {
31     ani_int res = 0;
32     auto status = env->Object_GetFieldByName_Int(param, name, &res);
33     if (status != ANI_OK) {
34         HILOGI("status : %{public}d", status);
35         return false;
36     }
37 
38     value = static_cast<int32_t>(res);
39     return true;
40 }
41 
GetDoubleOrUndefined(ani_env * env,ani_object param,const char * name,ani_double & value)42 bool GetDoubleOrUndefined(ani_env *env, ani_object param, const char *name, ani_double &value)
43 {
44     ani_ref obj = nullptr;
45     ani_boolean isUndefined = true;
46     ani_status status = ANI_ERROR;
47 
48     if ((status = env->Object_GetFieldByName_Ref(param, name, &obj)) != ANI_OK) {
49         HILOGI("status : %{public}d", status);
50         return false;
51     }
52     if ((status = env->Reference_IsUndefined(obj, &isUndefined)) != ANI_OK) {
53         HILOGI("status : %{public}d", status);
54         return false;
55     }
56     if (isUndefined) {
57         HILOGI("%{public}s : undefined", name);
58         return false;
59     }
60     if ((status = env->Object_CallMethodByName_Double(
61         reinterpret_cast<ani_object>(obj), "unboxed", nullptr, &value)) != ANI_OK) {
62         HILOGI("status : %{public}d", status);
63         return false;
64     }
65     return true;
66 }
67 
GetBoolOrUndefined(ani_env * env,ani_object param,const char * name)68 bool GetBoolOrUndefined(ani_env *env, ani_object param, const char *name)
69 {
70     ani_ref obj = nullptr;
71     ani_boolean isUndefined = true;
72     ani_status status = ANI_ERROR;
73     ani_boolean res = 0.0;
74 
75     if ((status = env->Object_GetFieldByName_Ref(param, name, &obj)) != ANI_OK) {
76         HILOGI("status : %{public}d", status);
77         return res;
78     }
79     if ((status = env->Reference_IsUndefined(obj, &isUndefined)) != ANI_OK) {
80         HILOGI("status : %{public}d", status);
81         return res;
82     }
83     if (isUndefined) {
84         HILOGI("%{public}s : undefined", name);
85         return res;
86     }
87     if ((status = env->Object_CallMethodByName_Boolean(
88         reinterpret_cast<ani_object>(obj), "booleanValue", nullptr, &res)) != ANI_OK) {
89         HILOGI("status : %{public}d", status);
90         return res;
91     }
92     return res;
93 }
94 
GetStringOrUndefined(ani_env * env,ani_object param,const char * name,std::string & res)95 bool GetStringOrUndefined(ani_env *env, ani_object param, const char *name, std::string &res)
96 {
97     ani_ref obj = nullptr;
98     ani_boolean isUndefined = true;
99     ani_status status = ANI_ERROR;
100 
101     if ((status = env->Object_GetFieldByName_Ref(param, name, &obj)) != ANI_OK) {
102         HILOGI("status : %{public}d", status);
103         return false;
104     }
105     if ((status = env->Reference_IsUndefined(obj, &isUndefined)) != ANI_OK) {
106         HILOGI("status : %{public}d", status);
107         return false;
108     }
109     if (isUndefined) {
110         HILOGI("%{public}s : undefined", name);
111         return false;
112     }
113     if (!GetStdString(env, reinterpret_cast<ani_string>(obj), res)) {
114         HILOGI("GetStdString failed");
115         return false;
116     }
117     return true;
118 }
119 
GetFixedStringArrayOrUndefined(ani_env * env,ani_object param,const char * name,std::vector<std::string> & res)120 bool GetFixedStringArrayOrUndefined(ani_env *env, ani_object param, const char *name, std::vector<std::string> &res)
121 {
122     ani_ref obj = nullptr;
123     ani_status status;
124 
125     if ((status = env->Object_GetFieldByName_Ref(param, name, &obj)) != ANI_OK) {
126         HILOGI("status : %{public}d", status);
127         return false;
128     }
129     ani_boolean isUndefined = true;
130     if ((status = env->Reference_IsUndefined(obj, &isUndefined)) != ANI_OK) {
131         HILOGI("status : %{public}d", status);
132         return false;
133     }
134     if (isUndefined) {
135         HILOGI("%{public}s : undefined", name);
136         return false;
137     }
138 
139     ani_size size = 0;
140     if ((status = env->Array_GetLength(reinterpret_cast<ani_array>(obj), &size)) != ANI_OK) {
141         HILOGI("status : %{public}d", status);
142         return false;
143     }
144 
145     ani_ref ref = nullptr;
146     for (ani_size index = 0; index < size; index++) {
147         if ((status = env->Array_Get_Ref(reinterpret_cast<ani_array_ref>(obj), index, &ref)) != ANI_OK) {
148             HILOGI("status : %{public}d, index: %{public}zu", status, index);
149             return false;
150         }
151 
152         std::string strItem = "";
153         if (!GetStdString(env, reinterpret_cast<ani_string>(ref), strItem)) {
154             HILOGI("GetStdString failed, index: %{public}zu", index);
155             return false;
156         }
157 
158         res.push_back(strItem);
159     }
160 
161     return true;
162 }
163 
SetFieldFixedArrayString(ani_env * env,ani_class cls,ani_object object,const std::string & fieldName,const std::vector<std::string> & values)164 bool SetFieldFixedArrayString(ani_env *env, ani_class cls, ani_object object, const std::string &fieldName,
165     const std::vector<std::string> &values)
166 {
167     ani_field field = nullptr;
168     ani_status status = env->Class_FindField(cls, fieldName.c_str(), &field);
169     if (status != ANI_OK) {
170         HILOGI("status : %{public}d", status);
171         return false;
172     }
173 
174     ani_class stringCls = nullptr;
175     status = env->FindClass("Lstd/core/String;", &stringCls);
176     if (status != ANI_OK) {
177         HILOGI("status : %{public}d", status);
178         return false;
179     }
180 
181     ani_ref undefinedRef = nullptr;
182     status = env->GetUndefined(&undefinedRef);
183     if (status != ANI_OK) {
184         HILOGI("status : %{public}d", status);
185         return false;
186     }
187 
188     ani_array_ref array = nullptr;
189     status = env->Array_New_Ref(stringCls, values.size(), undefinedRef, &array);
190     if (status != ANI_OK) {
191         HILOGI("status : %{public}d", status);
192         return false;
193     }
194 
195     for (size_t i = 0; i < values.size(); ++i) {
196         ani_string strItem = nullptr;
197         status = env->String_NewUTF8(values[i].c_str(), values[i].size(), &strItem);
198         if (status != ANI_OK) {
199             HILOGI("status : %{public}d", status);
200             return false;
201         }
202         status = env->Array_Set_Ref(array, i, strItem);
203         if (status != ANI_OK) {
204             HILOGI("status : %{public}d", status);
205             return false;
206         }
207     }
208     status = env->Object_SetField_Ref(object, field, array);
209     if (status != ANI_OK) {
210         HILOGI("status : %{public}d", status);
211         return false;
212     }
213     return true;
214 }
215 
GetStringArrayOrUndefined(ani_env * env,ani_object param,const char * name,std::vector<std::string> & res)216 bool GetStringArrayOrUndefined(ani_env *env, ani_object param, const char *name, std::vector<std::string> &res)
217 {
218     ani_ref arrayObj = nullptr;
219     ani_boolean isUndefined = true;
220     ani_status status = ANI_OK;
221     ani_double length;
222 
223     if ((status = env->Object_GetFieldByName_Ref(param, name, &arrayObj)) != ANI_OK) {
224         HILOGI("status : %{public}d", status);
225         return false;
226     }
227     if ((status = env->Reference_IsUndefined(arrayObj, &isUndefined)) != ANI_OK) {
228         HILOGI("status : %{public}d", status);
229         return false;
230     }
231     if (isUndefined) {
232         HILOGI("%{public}s : undefined", name);
233         return false;
234     }
235 
236     status = env->Object_GetPropertyByName_Double(reinterpret_cast<ani_object>(arrayObj), "length", &length);
237     if (status != ANI_OK) {
238         HILOGI("status : %{public}d", status);
239         return false;
240     }
241 
242     for (int32_t index = 0; index < static_cast<int32_t>(length); index++) {
243         ani_ref stringEntryRef;
244         status = env->Object_CallMethodByName_Ref(reinterpret_cast<ani_object>(arrayObj),
245             "$_get", "I:Lstd/core/Object;", &stringEntryRef, static_cast<ani_int>(index));
246         if (status != ANI_OK) {
247             HILOGI("status : %{public}d, index: %{public}d", status, index);
248             return false;
249         }
250 
251         std::string str = "";
252         if (!GetStdString(env, reinterpret_cast<ani_string>(stringEntryRef), str)) {
253             HILOGI("GetStdString failed, index: %{public}d", index);
254             return false;
255         }
256 
257         res.push_back(str);
258     }
259 
260     return true;
261 }
262 
263 
SetFieldArrayString(ani_env * env,ani_class cls,ani_object object,const std::string & fieldName,const std::vector<std::string> & values)264 bool SetFieldArrayString(ani_env *env, ani_class cls, ani_object object, const std::string &fieldName,
265     const std::vector<std::string> &values)
266 {
267     ani_field field = nullptr;
268     ani_class arrayCls = nullptr;
269     ani_method arrayCtor;
270     ani_object arrayObj;
271 
272     ani_status status = env->Class_FindField(cls, fieldName.c_str(), &field);
273     if (status != ANI_OK) {
274         HILOGI("status : %{public}d", status);
275         return false;
276     }
277 
278     status = env->FindClass("Lescompat/Array;", &arrayCls);
279     if (status != ANI_OK) {
280         HILOGI("status : %{public}d", status);
281         return false;
282     }
283 
284     status = env->Class_FindMethod(arrayCls, "<ctor>", "I:V", &arrayCtor);
285     if (status != ANI_OK) {
286         HILOGI("status : %{public}d", status);
287         return false;
288     }
289 
290     status = env->Object_New(arrayCls, arrayCtor, &arrayObj, values.size());
291     if (status != ANI_OK) {
292         HILOGI("status : %{public}d", status);
293         return false;
294     }
295 
296     for (size_t i = 0; i < values.size(); i++) {
297         ani_string strItem = nullptr;
298         status = env->String_NewUTF8(values[i].c_str(), values[i].size(), &strItem);
299         if (status != ANI_OK) {
300             HILOGI("status : %{public}d", status);
301             return false;
302         }
303 
304         status = env->Object_CallMethodByName_Void(arrayObj, "$_set", "ILstd/core/Object;:V", i, strItem);
305         if (status != ANI_OK) {
306             HILOGI("status : %{public}d", status);
307             return false;
308         }
309     }
310     status = env->Object_SetField_Ref(object, field, arrayObj);
311     if (status != ANI_OK) {
312         HILOGI("status : %{public}d", status);
313         return false;
314     }
315 
316     return true;
317 }
318 
GetStdString(ani_env * env,ani_string str,std::string & res)319 bool GetStdString(ani_env *env, ani_string str, std::string &res)
320 {
321     ani_size sz {};
322     ani_status status = ANI_ERROR;
323     if ((status = env->String_GetUTF8Size(str, &sz)) != ANI_OK) {
324         HILOGW("status : %{public}d", status);
325         return false;
326     }
327     res.resize(sz + 1);
328     if ((status = env->String_GetUTF8SubString(str, 0, sz, res.data(), res.size(), &sz)) != ANI_OK) {
329         HILOGI("status : %{public}d", status);
330         return false;
331     }
332     res.resize(sz);
333     return true;
334 }
335 
GetAniString(ani_env * env,const std::string & str)336 ani_string GetAniString(ani_env *env, const std::string &str)
337 {
338     ani_string aniStr = nullptr;
339     ani_status status = env->String_NewUTF8(str.c_str(), str.size(), &aniStr);
340     if (status != ANI_OK) {
341         HILOGI("status : %{public}d", status);
342         return nullptr;
343     }
344     return aniStr;
345 }
346 
GetAniArrayString(ani_env * env,const std::vector<std::string> & values)347 ani_array_ref GetAniArrayString(ani_env *env, const std::vector<std::string> &values)
348 {
349     ani_array_ref aArrayRef = nullptr;
350     return aArrayRef;
351 }
352 
GetRefPropertyByName(ani_env * env,ani_object param,const char * name,ani_ref & ref)353 bool GetRefPropertyByName(ani_env *env, ani_object param, const char *name, ani_ref &ref)
354 {
355     ani_status status = ANI_ERROR;
356     if ((status = env->Object_GetPropertyByName_Ref(param, name, &ref)) != ANI_OK) {
357         HILOGI("Object_GetFieldByName_Ref failed, status : %{public}d", status);
358         return false;
359     }
360 
361     ani_boolean isUndefined = true;
362     if ((status = env->Reference_IsUndefined(ref, &isUndefined)) != ANI_OK) {
363         HILOGI("Reference_IsUndefined failed, status : %{public}d", status);
364         return false;
365     }
366     if (isUndefined) {
367         HILOGI("wantParams is undefined");
368         return false;
369     }
370     isUndefined = true;
371 
372     if ((status = env->Reference_IsNull(ref, &isUndefined)) != ANI_OK) {
373         HILOGI("Reference_IsNull failed, status : %{public}d", status);
374         return false;
375     }
376 
377     if (isUndefined) {
378         HILOGI("wantParams is null");
379         return false;
380     }
381     isUndefined = true;
382 
383     if ((status = env->Reference_IsNullishValue(ref, &isUndefined)) != ANI_OK) {
384         HILOGI("Reference_IsNullishValue failed, status : %{public}d", status);
385         return false;
386     }
387 
388     if (isUndefined) {
389         HILOGI("wantParams is nullish");
390         return false;
391     }
392     return true;
393 }
394 
createDouble(ani_env * env,ani_double value)395 ani_object createDouble(ani_env *env, ani_double value)
396 {
397     ani_class persion_cls;
398     ani_status status = ANI_ERROR;
399     if ((status = env->FindClass(CLASSNAME_DOUBLE, &persion_cls)) != ANI_OK) {
400         HILOGI("status : %{public}d", status);
401         return nullptr;
402     }
403     ani_method personInfoCtor;
404     if ((status = env->Class_FindMethod(persion_cls, "<ctor>", "D:V", &personInfoCtor)) != ANI_OK) {
405         HILOGI("status : %{public}d", status);
406         return nullptr;
407     }
408     ani_object personInfoObj;
409     if ((status = env->Object_New(persion_cls, personInfoCtor, &personInfoObj, value)) != ANI_OK) {
410         HILOGI("status : %{public}d", status);
411         return nullptr;
412     }
413     return personInfoObj;
414 }
415 
createBoolean(ani_env * env,ani_boolean value)416 ani_object createBoolean(ani_env *env, ani_boolean value)
417 {
418     ani_class persion_cls;
419     ani_status status = ANI_ERROR;
420     if ((status = env->FindClass(CLASSNAME_BOOLEAN, &persion_cls)) != ANI_OK) {
421         HILOGI("status : %{public}d", status);
422         return nullptr;
423     }
424     ani_method personInfoCtor;
425     if ((status = env->Class_FindMethod(persion_cls, "<ctor>", "Z:V", &personInfoCtor)) != ANI_OK) {
426         HILOGI("status : %{public}d", status);
427         return nullptr;
428     }
429     ani_object personInfoObj;
430     if ((status = env->Object_New(persion_cls, personInfoCtor, &personInfoObj, value)) != ANI_OK) {
431         HILOGI("status : %{public}d", status);
432         return nullptr;
433     }
434     return personInfoObj;
435 }
436 
SetFieldString(ani_env * env,ani_class cls,ani_object object,const std::string & fieldName,const std::string & value)437 bool SetFieldString(ani_env *env, ani_class cls, ani_object object,
438     const std::string &fieldName, const std::string &value)
439 {
440     ani_field field = nullptr;
441     ani_status status = env->Class_FindField(cls, fieldName.c_str(), &field);
442     if (status != ANI_OK) {
443         HILOGI("status : %{public}d", status);
444         return false;
445     }
446 
447     if (value.empty()) {
448         ani_ref nullRef = nullptr;
449         if ((status = env->GetNull(&nullRef)) != ANI_OK) {
450             HILOGI("status : %{public}d", status);
451             return false;
452         }
453         if ((status = env->Object_SetField_Ref(object, field, nullRef)) != ANI_OK) {
454             HILOGI("status : %{public}d", status);
455             return false;
456         }
457         return true;
458     }
459 
460     ani_string strItem = nullptr;
461     if ((status = env->String_NewUTF8(value.c_str(), value.size(), &strItem)) != ANI_OK) {
462         HILOGI("status : %{public}d", status);
463         return false;
464     }
465 
466     if ((status = env->Object_SetField_Ref(object, field, strItem)) != ANI_OK) {
467         HILOGI("status : %{public}d", status);
468         return false;
469     }
470     return true;
471 }
472 
SetFieldDouble(ani_env * env,ani_class cls,ani_object object,const std::string & fieldName,double value)473 bool SetFieldDouble(ani_env *env, ani_class cls, ani_object object, const std::string &fieldName, double value)
474 {
475     ani_field field = nullptr;
476     ani_status status = env->Class_FindField(cls, fieldName.c_str(), &field);
477     if (status != ANI_OK) {
478         HILOGI("status : %{public}d", status);
479         return false;
480     }
481 
482     status = env->Object_SetField_Double(object, field, value);
483     if (status != ANI_OK) {
484         HILOGI("status : %{public}d", status);
485         return false;
486     }
487     return true;
488 }
489 
SetFieldBoolean(ani_env * env,ani_class cls,ani_object object,const std::string & fieldName,bool value)490 bool SetFieldBoolean(ani_env *env, ani_class cls, ani_object object, const std::string &fieldName, bool value)
491 {
492     ani_field field = nullptr;
493     ani_status status = env->Class_FindField(cls, fieldName.c_str(), &field);
494     if (status != ANI_OK) {
495         HILOGI("status : %{public}d", status);
496         return false;
497     }
498     status = env->Object_SetField_Boolean(object, field, value);
499     if (status != ANI_OK) {
500         HILOGI("status : %{public}d", status);
501         return false;
502     }
503     return true;
504 }
505 
SetFieldInt(ani_env * env,ani_class cls,ani_object object,const std::string & fieldName,int32_t value)506 bool SetFieldInt(ani_env *env, ani_class cls, ani_object object, const std::string &fieldName, int32_t value)
507 {
508     ani_field field = nullptr;
509     ani_status status = env->Class_FindField(cls, fieldName.c_str(), &field);
510     if (status != ANI_OK) {
511         HILOGI("status : %{public}d, field name: %{public}s", status, fieldName.c_str());
512         return false;
513     }
514     status = env->Object_SetField_Int(object, field, value);
515     if (status != ANI_OK) {
516         HILOGI("status : %{public}d, field name: %{public}s", status, fieldName.c_str());
517         return false;
518     }
519     return true;
520 }
521 
SetFieldRef(ani_env * env,ani_class cls,ani_object object,const std::string & fieldName,ani_ref value)522 bool SetFieldRef(ani_env *env, ani_class cls, ani_object object, const std::string &fieldName, ani_ref value)
523 {
524     ani_field field = nullptr;
525     ani_status status = env->Class_FindField(cls, fieldName.c_str(), &field);
526     if (status != ANI_OK) {
527         HILOGI("FindField %{public}s failed, status: %{public}d", fieldName.c_str(), status);
528         return false;
529     }
530     status = env->Object_SetField_Ref(object, field, value);
531     if (status != ANI_OK) {
532         HILOGI("SetField_Ref %{public}s failed, status: %{public}d", fieldName.c_str(), status);
533         return false;
534     }
535     return true;
536 }
537 }  // namespace AppExecFwk
538 }  // namespace OHOS