• 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 #ifndef BUNDLE_FRAMEWORK_INTERFACES_KITS_ANI_COMMON_FUN_ANI_H
17 #define BUNDLE_FRAMEWORK_INTERFACES_KITS_ANI_COMMON_FUN_ANI_H
18 
19 #include <ani.h>
20 #include <cstring>
21 #include <iostream>
22 #include <string>
23 #include <type_traits>
24 #include <vector>
25 
26 #include "app_log_wrapper.h"
27 #include "bundle_mgr_interface.h"
28 #include "bundle_resource_info.h"
29 #include "clone_param.h"
30 #include "enum_util.h"
31 #include "install_param.h"
32 #include "launcher_ability_info.h"
33 
34 namespace OHOS {
35 namespace AppExecFwk {
36 using Want = OHOS::AAFwk::Want;
37 
38 #define RETURN_IF_NULL(ptr)          \
39     do {                             \
40         if ((ptr) == nullptr) {      \
41             APP_LOGE("ptr is null"); \
42             return;                  \
43         }                            \
44     } while (0)
45 #define RETURN_NULL_IF_NULL(ptr)     \
46     do {                             \
47         if ((ptr) == nullptr) {      \
48             APP_LOGE("ptr is null"); \
49             return nullptr;          \
50         }                            \
51     } while (0)
52 #define RETURN_FALSE_IF_NULL(ptr)    \
53     do {                             \
54         if ((ptr) == nullptr) {      \
55             APP_LOGE("ptr is null"); \
56             return false;            \
57         }                            \
58     } while (0)
59 #define RETURN_NULL_IF_FALSE(condition)     \
60     do {                                    \
61         if (!(condition)) {                 \
62             APP_LOGE("condition is false"); \
63             return nullptr;                 \
64         }                                   \
65     } while (0)
66 #define RETURN_FALSE_IF_FALSE(condition)    \
67     do {                                    \
68         if (!(condition)) {                 \
69             APP_LOGE("condition is false"); \
70             return false;                   \
71         }                                   \
72     } while (0)
73 #define RETURN_ANI_STATUS_IF_NOT_OK(res, err) \
74     do {                                      \
75         if ((res) != ANI_OK) {                \
76             APP_LOGE(err);                    \
77             return res;                       \
78         }                                     \
79     } while (0)
80 class CommonFunAni {
81 public:
82     // Data conversion.
AniBooleanToBool(ani_boolean value)83     static inline bool AniBooleanToBool(ani_boolean value)
84     {
85         return value == ANI_TRUE;
86     }
BoolToAniBoolean(bool value)87     static inline ani_boolean BoolToAniBoolean(bool value)
88     {
89         return value ? ANI_TRUE : ANI_FALSE;
90     }
91     static std::string AniStrToString(ani_env* env, ani_string aniStr);
92     static bool ParseString(ani_env* env, ani_string aniStr, std::string& result);
StringToAniStr(ani_env * env,const std::string & str,ani_string & aniStr)93     static inline bool StringToAniStr(ani_env* env, const std::string& str, ani_string& aniStr)
94     {
95         ani_status status = env->String_NewUTF8(str.c_str(), str.size(), &aniStr);
96         if (status != ANI_OK) {
97             APP_LOGE("String_NewUTF8 failed %{public}d", status);
98             return false;
99         }
100         return true;
101     }
102 
103     // Convert from native to ets
104     static ani_object ConvertMultiAppMode(ani_env* env, const MultiAppModeData& multiAppMode);
105     static ani_object ConvertMetadata(ani_env* env, const Metadata& metadata);
106     static ani_object ConvertModuleMetaInfosItem(
107         ani_env* env, const std::pair<std::string, std::vector<Metadata>>& metadata);
108     static ani_object ConvertResource(ani_env* env, const Resource& resource);
109     static ani_object ConvertApplicationInfo(ani_env* env, const ApplicationInfo& appInfo);
110 
111     static ani_object ConvertAbilityInfo(ani_env* env, const AbilityInfo& abilityInfo);
112     static ani_object ConvertWindowSize(ani_env* env, const AbilityInfo& abilityInfo);
113     static ani_object ConvertExtensionInfo(ani_env* env, const ExtensionAbilityInfo& extensionInfo);
114     static ani_object ConvertDependency(ani_env* env, const Dependency& dependency);
115     static ani_object ConvertPreloadItem(ani_env* env, const PreloadItem& preloadItem);
116     static ani_object ConvertHapModuleInfo(ani_env* env, const HapModuleInfo& hapModuleInfo);
117 
118     static ani_object ConvertRequestPermissionUsedScene(
119         ani_env* env, const RequestPermissionUsedScene& requestPermissionUsedScene);
120     static ani_object ConvertRequestPermission(ani_env* env, const RequestPermission& requestPermission);
121 
122     static ani_object ConvertSignatureInfo(ani_env* env, const SignatureInfo& signatureInfo);
123 
124     static ani_object ConvertKeyValuePair(
125         ani_env* env, const std::pair<std::string, std::string>& item, const char* className);
126     static ani_object ConvertDataItem(ani_env* env, const std::pair<std::string, std::string>& item);
127     static ani_object ConvertRouterItem(ani_env* env, const RouterItem& routerItem);
128 
129     static ani_object ConvertElementName(ani_env* env, const ElementName& elementName);
130 
131     static ani_object ConvertAbilitySkillUriInner(ani_env* env, const SkillUri& skillUri, bool isExtension);
ConvertAbilitySkillUri(ani_env * env,const SkillUri & skillUri)132     static inline ani_object ConvertAbilitySkillUri(ani_env* env, const SkillUri& skillUri)
133     {
134         return ConvertAbilitySkillUriInner(env, skillUri, false);
135     }
ConvertExtensionAbilitySkillUri(ani_env * env,const SkillUri & skillUri)136     static inline ani_object ConvertExtensionAbilitySkillUri(ani_env* env, const SkillUri& skillUri)
137     {
138         return ConvertAbilitySkillUriInner(env, skillUri, true);
139     }
140     static ani_object ConvertAbilitySkillInner(ani_env* env, const Skill& skill, bool isExtension);
ConvertAbilitySkill(ani_env * env,const Skill & skill)141     static inline ani_object ConvertAbilitySkill(ani_env* env, const Skill& skill)
142     {
143         return ConvertAbilitySkillInner(env, skill, false);
144     }
ConvertExtensionAbilitySkill(ani_env * env,const Skill & skill)145     static inline ani_object ConvertExtensionAbilitySkill(ani_env* env, const Skill& skill)
146     {
147         return ConvertAbilitySkillInner(env, skill, true);
148     }
149     static ani_object ConvertBundleInfo(ani_env* env, const BundleInfo& bundleInfo, int32_t flags);
150 
151     static ani_object ConvertAppCloneIdentity(ani_env* env, const std::string& bundleName, const int32_t appIndex);
152 
153     static ani_object ConvertBundleResourceInfo(ani_env* env, const BundleResourceInfo& bundleResInfo);
154     static ani_object ConvertLauncherAbilityResourceInfo(ani_env* env,
155         const LauncherAbilityResourceInfo& launcherAbilityResourceInfo);
156 
157     static ani_object ConvertShortcutInfo(ani_env* env, const ShortcutInfo& shortcutInfo);
158     static ani_object ConvertShortcutIntent(ani_env* env, const ShortcutIntent& shortcutIntent);
159     static ani_object ConvertShortcutIntentParameter(ani_env* env, const std::pair<std::string, std::string>& item);
160 
161     static ani_object ConvertLauncherAbilityInfo(ani_env* env, const LauncherAbilityInfo& launcherAbility);
162 
163     static ani_object ConvertOverlayModuleInfo(ani_env* env, const OverlayModuleInfo& overlayModuleInfo);
164 
165     static ani_object CreateBundleChangedInfo(
166         ani_env* env, const std::string& bundleName, int32_t userId, int32_t appIndex);
167     static ani_object ConvertVersion(ani_env* env, const Version& version);
168     static ani_object ConvertPackageApp(ani_env* env, const PackageApp& packageApp);
169     static ani_object ConvertAbilityFormInfo(ani_env* env, const AbilityFormInfo& abilityFormInfo);
170     static ani_object ConvertModuleAbilityInfo(ani_env* env, const ModuleAbilityInfo& moduleAbilityInfo);
171     static ani_object ConvertModuleDistro(ani_env* env, const ModuleDistro& moduleDistro);
172     static ani_object ConvertApiVersion(ani_env* env, const ApiVersion& apiVersion);
173     static ani_object ConvertExtensionAbilities(ani_env* env, const ExtensionAbilities& extensionAbilities);
174     static ani_object ConvertPackageModule(ani_env* env, const PackageModule& packageModule);
175     static ani_object ConvertSummary(ani_env* env, const Summary& summary, bool withApp);
176     static ani_object ConvertPackages(ani_env* env, const Packages& packages);
177     static ani_object ConvertBundlePackInfo(ani_env* env, const BundlePackInfo& bundlePackInfo, const uint32_t flag);
178     static ani_object CreateDispatchInfo(
179         ani_env* env, const std::string& version, const std::string& dispatchAPIVersion);
180     static ani_object ConvertWantInfo(ani_env* env, const Want& want);
181 
182     // Parse from ets to native
183     static bool ParseShortcutInfo(ani_env* env, ani_object object, ShortcutInfo& shortcutInfo);
184     static bool ParseShortcutIntent(ani_env* env, ani_object object, ShortcutIntent& shortcutIntent);
185     static bool ParseKeyValuePair(ani_env* env, ani_object object, std::pair<std::string, std::string>& pair);
186     static bool ParseKeyValuePairWithName(ani_env* env, ani_object object, std::pair<std::string, std::string>& pair,
187         const char* keyName, const char* valueName);
188 
189     static ani_class CreateClassByName(ani_env* env, const std::string& className);
190     static ani_object CreateNewObjectByClass(ani_env* env, ani_class cls);
ConvertAniArrayString(ani_env * env,const std::vector<std::string> & strings)191     static inline ani_object ConvertAniArrayString(ani_env* env, const std::vector<std::string>& strings)
192     {
193         return ConvertAniArray(env, strings, [](ani_env* env, const std::string& nativeStr) {
194             ani_string aniStr = nullptr;
195             return StringToAniStr(env, nativeStr, aniStr) ? aniStr : nullptr;
196         });
197     }
ParseStrArray(ani_env * env,ani_object arrayObj,std::vector<std::string> & strings)198     static inline bool ParseStrArray(ani_env* env, ani_object arrayObj, std::vector<std::string>& strings)
199     {
200         return ParseAniArray(env, arrayObj, strings, [](ani_env* env, ani_object aniStr, std::string& nativeStr) {
201             nativeStr = AniStrToString(env, static_cast<ani_string>(aniStr));
202             return true;
203         });
204     }
205     template<typename enumType>
ParseEnumArray(ani_env * env,ani_object arrayObj,std::vector<enumType> & enums)206     static inline bool ParseEnumArray(ani_env* env, ani_object arrayObj, std::vector<enumType>& enums)
207     {
208         return ParseAniArray(env, arrayObj, enums, [](ani_env* env, ani_object aniItem, enumType& nativeItem) {
209             return EnumUtils::EnumETSToNative(env, reinterpret_cast<ani_enum_item>(aniItem), nativeItem);
210         });
211     }
212     static bool ParseInstallParam(ani_env* env, ani_object object, InstallParam& installParam);
213     static bool ParseHashParams(ani_env* env, ani_object object, std::pair<std::string, std::string>& pair);
214     static bool ParsePgoParams(ani_env* env, ani_object object, std::pair<std::string, std::string>& pair);
215     static bool ParseUninstallParam(ani_env* env, ani_object object, UninstallParam& uninstallParam);
216     static bool ParseCreateAppCloneParam(ani_env* env, ani_object object, int32_t& userId, int32_t& appIdx);
217     static bool ParseDestroyAppCloneParam(ani_env* env, ani_object object, DestroyAppCloneParam& destroyAppCloneParam);
218     static bool ParsePluginParam(ani_env* env, ani_object object, InstallPluginParam& installPluginParam);
219     static bool ParseMetadata(ani_env* env, ani_object object, Metadata& metadata);
220     static bool ParseResource(ani_env* env, ani_object object, Resource& resource);
221     static bool ParseMultiAppMode(ani_env* env, ani_object object, MultiAppModeData& multiAppMode);
222     static bool ParseApplicationInfo(ani_env* env, ani_object object, ApplicationInfo& appInfo);
223     static bool ParseWindowSize(ani_env* env, ani_object object, AbilityInfo& abilityInfo);
224     static bool ParseAbilitySkillUriInner(ani_env* env, ani_object object, SkillUri& skillUri, bool isExtension);
ParseAbilitySkillUri(ani_env * env,ani_object object,SkillUri & skillUri)225     static inline bool ParseAbilitySkillUri(ani_env* env, ani_object object, SkillUri& skillUri)
226     {
227         return ParseAbilitySkillUriInner(env, object, skillUri, false);
228     }
ParseExtensionAbilitySkillUri(ani_env * env,ani_object object,SkillUri & skillUri)229     static inline bool ParseExtensionAbilitySkillUri(ani_env* env, ani_object object, SkillUri& skillUri)
230     {
231         return ParseAbilitySkillUriInner(env, object, skillUri, true);
232     }
233     static bool ParseAbilitySkillInner(ani_env* env, ani_object object, Skill& skill, bool isExtension);
ParseAbilitySkill(ani_env * env,ani_object object,Skill & skill)234     static inline bool ParseAbilitySkill(ani_env* env, ani_object object, Skill& skill)
235     {
236         return ParseAbilitySkillInner(env, object, skill, false);
237     }
ParseExtensionAbilitySkill(ani_env * env,ani_object object,Skill & skill)238     static inline bool ParseExtensionAbilitySkill(ani_env* env, ani_object object, Skill& skill)
239     {
240         return ParseAbilitySkillInner(env, object, skill, true);
241     }
242     static bool ParseAbilityInfo(ani_env* env, ani_object object, AbilityInfo& abilityInfo);
243 
244     template<typename toType>
TryCastDoubleTo(const double fromValue,toType * toValue)245     static bool TryCastDoubleTo(const double fromValue, toType* toValue)
246     {
247         RETURN_FALSE_IF_NULL(toValue);
248 
249         if (std::isnan(fromValue)) {
250             APP_LOGE("value is NaN");
251             return false;
252         }
253         if (std::isinf(fromValue)) {
254             APP_LOGE("value is Inf");
255             return false;
256         }
257         if (fromValue > static_cast<double>(std::numeric_limits<toType>::max())) {
258             APP_LOGE("value too large");
259             return false;
260         }
261         if (fromValue < static_cast<double>(std::numeric_limits<toType>::lowest())) {
262             APP_LOGE("value too small");
263             return false;
264         }
265 
266         *toValue = static_cast<toType>(fromValue);
267         return true;
268     }
269 
270     template<typename enumType>
ConvertAniArrayEnum(ani_env * env,const std::vector<enumType> & cArray,ani_enum_item (* converter)(ani_env *,const int32_t))271     static ani_object ConvertAniArrayEnum(
272         ani_env* env, const std::vector<enumType>& cArray, ani_enum_item (*converter)(ani_env*, const int32_t))
273     {
274         RETURN_NULL_IF_NULL(env);
275         RETURN_NULL_IF_NULL(converter);
276 
277         ani_class arrayCls = nullptr;
278         ani_status status = env->FindClass("Lescompat/Array;", &arrayCls);
279         if (status != ANI_OK) {
280             APP_LOGE("FindClass failed %{public}d", status);
281             return nullptr;
282         }
283 
284         ani_method arrayCtor;
285         status = env->Class_FindMethod(arrayCls, "<ctor>", "I:V", &arrayCtor);
286         if (status != ANI_OK) {
287             APP_LOGE("Class_FindMethod failed %{public}d", status);
288             return nullptr;
289         }
290 
291         ani_object arrayObj;
292         ani_size length = cArray.size();
293         status = env->Object_New(arrayCls, arrayCtor, &arrayObj, length);
294         if (status != ANI_OK) {
295             APP_LOGE("Object_New failed %{public}d", status);
296             return nullptr;
297         }
298         if (length > 0) {
299             for (ani_size i = 0; i < length; ++i) {
300                 ani_enum_item item = converter(env, static_cast<int32_t>(cArray[i]));
301                 if (item == nullptr) {
302                     APP_LOGE("convert failed");
303                     return nullptr;
304                 }
305                 status = env->Object_CallMethodByName_Void(arrayObj, "$_set", "ILstd/core/Object;:V", i, item);
306                 env->Reference_Delete(item);
307                 if (status != ANI_OK) {
308                     APP_LOGE("Object_CallMethodByName_Void failed %{public}d", status);
309                     return nullptr;
310                 }
311             }
312         }
313 
314         return arrayObj;
315     }
316 
317     template<typename containerType, typename Converter, typename... Args>
ConvertAniArray(ani_env * env,const containerType & nativeArray,Converter converter,Args &&...args)318     static ani_object ConvertAniArray(ani_env* env,
319         const containerType& nativeArray, Converter converter, Args&&... args)
320     {
321         RETURN_NULL_IF_NULL(env);
322         RETURN_NULL_IF_NULL(converter);
323 
324         ani_class arrayCls = nullptr;
325         ani_status status = env->FindClass("Lescompat/Array;", &arrayCls);
326         if (status != ANI_OK) {
327             APP_LOGE("FindClass failed %{public}d", status);
328             return nullptr;
329         }
330 
331         ani_method arrayCtor;
332         status = env->Class_FindMethod(arrayCls, "<ctor>", "I:V", &arrayCtor);
333         if (status != ANI_OK) {
334             APP_LOGE("Class_FindMethod failed %{public}d", status);
335             return nullptr;
336         }
337 
338         ani_size length = nativeArray.size();
339         ani_object arrayObj;
340         status = env->Object_New(arrayCls, arrayCtor, &arrayObj, length);
341         if (status != ANI_OK) {
342             APP_LOGE("Object_New failed %{public}d", status);
343             return nullptr;
344         }
345 
346         ani_size i = 0;
347         for (const auto& iter : nativeArray) {
348             ani_object item = converter(env, iter, std::forward<Args>(args)...);
349             RETURN_NULL_IF_NULL(item);
350             status = env->Object_CallMethodByName_Void(arrayObj, "$_set", "ILstd/core/Object;:V", i, item);
351             env->Reference_Delete(item);
352             if (status != ANI_OK) {
353                 APP_LOGE("Object_CallMethodByName_Void failed %{public}d", status);
354                 return nullptr;
355             }
356             ++i;
357         }
358 
359         return arrayObj;
360     }
361 
362     template<typename callbackType, typename... Args>
AniArrayForeach(ani_env * env,ani_object aniArray,callbackType callback,Args &&...args)363     static bool AniArrayForeach(ani_env* env, ani_object aniArray, callbackType callback, Args&&... args)
364     {
365         RETURN_FALSE_IF_NULL(env);
366         RETURN_FALSE_IF_NULL(aniArray);
367 
368         ani_double length;
369         ani_status status = env->Object_GetPropertyByName_Double(aniArray, "length", &length);
370         if (status != ANI_OK) {
371             APP_LOGE("Object_GetPropertyByName_Double failed %{public}d", status);
372             return false;
373         }
374         for (ani_int i = 0; i < static_cast<ani_int>(length); ++i) {
375             ani_ref ref;
376             status = env->Object_CallMethodByName_Ref(aniArray, "$_get", "I:Lstd/core/Object;", &ref, i);
377             if (status != ANI_OK) {
378                 APP_LOGE("Object_CallMethodByName_Ref failed %{public}d", status);
379                 return false;
380             }
381             bool result = callback(reinterpret_cast<ani_object>(ref), std::forward<Args>(args)...);
382             env->Reference_Delete(ref);
383             if (!result) {
384                 return false;
385             }
386         }
387         return true;
388     }
389 
390     template<typename nativeType, typename Parser, typename... Args>
ParseAniArray(ani_env * env,ani_object aniArray,std::vector<nativeType> & nativeArray,Parser parser,Args &&...args)391     static bool ParseAniArray(ani_env* env,
392         ani_object aniArray, std::vector<nativeType>& nativeArray, Parser parser, Args&&... args)
393     {
394         return AniArrayForeach(
395             env, aniArray,
396             [env, &nativeArray, parser](ani_object aniObj, Args&&... args) {
397                 nativeType nativeObj;
398                 bool result = parser(env, aniObj, nativeObj, std::forward<Args>(args)...);
399                 if (result) {
400                     nativeArray.emplace_back(nativeObj);
401                     return true;
402                 } else {
403                     nativeArray.clear();
404                     return false;
405                 }
406             },
407             std::forward<Args>(args)...);
408     }
409 
410     template<typename valueType>
CallGetter(ani_env * env,ani_object object,const char * propertyName,valueType * value)411     static bool CallGetter(ani_env* env, ani_object object, const char* propertyName, valueType* value)
412     {
413         RETURN_FALSE_IF_NULL(env);
414         RETURN_FALSE_IF_NULL(object);
415 
416         ani_status status = ANI_ERROR;
417         if constexpr (std::is_pointer_v<valueType> && std::is_base_of_v<__ani_ref, std::remove_pointer_t<valueType>>) {
418             status = env->Object_GetPropertyByName_Ref(object, propertyName, reinterpret_cast<ani_ref*>(value));
419         } else if constexpr (std::is_same_v<valueType, ani_boolean>) {
420             status = env->Object_GetPropertyByName_Boolean(object, propertyName, value);
421         } else if constexpr (std::is_same_v<valueType, ani_char>) {
422             status = env->Object_GetPropertyByName_Char(object, propertyName, value);
423         } else if constexpr (std::is_same_v<valueType, ani_byte> || std::is_same_v<valueType, ani_short> ||
424                              std::is_same_v<valueType, ani_int> || std::is_same_v<valueType, uint32_t> ||
425                              std::is_same_v<valueType, ani_long> || std::is_same_v<valueType, uint64_t> ||
426                              std::is_same_v<valueType, ani_float> || std::is_same_v<valueType, ani_double>) {
427             // uint64_t -> BigInt later
428             double d = 0;
429             status = env->Object_GetPropertyByName_Double(object, propertyName, &d);
430             if (status != ANI_OK) {
431                 APP_LOGE("Object_GetPropertyByName %{public}s failed %{public}d", propertyName, status);
432                 return false;
433             }
434             if (!TryCastDoubleTo(d, value)) {
435                 APP_LOGE("TryCastDoubleTo %{public}s failed", propertyName);
436                 return false;
437             }
438             return true;
439         } else {
440             APP_LOGE("Object_GetPropertyByName %{public}s Unsupported", propertyName);
441             return false;
442         }
443 
444         if (status != ANI_OK) {
445             APP_LOGE("Object_GetPropertyByName %{public}s failed %{public}d", propertyName, status);
446             return false;
447         }
448 
449         return true;
450     }
451 
452     template<typename valueType>
CallGetterOptional(ani_env * env,ani_object object,const char * propertyName,valueType * value)453     static bool CallGetterOptional(ani_env* env, ani_object object, const char* propertyName, valueType* value)
454     {
455         RETURN_FALSE_IF_NULL(env);
456         RETURN_FALSE_IF_NULL(object);
457 
458         ani_ref ref = nullptr;
459         ani_status status = env->Object_GetPropertyByName_Ref(object, propertyName, &ref);
460         if (status != ANI_OK) {
461             APP_LOGE("Object_GetPropertyByName_Ref %{public}s failed %{public}d", propertyName, status);
462             return false;
463         }
464 
465         ani_boolean isUndefined;
466         status = env->Reference_IsUndefined(ref, &isUndefined);
467         if (status != ANI_OK) {
468             APP_LOGE("Reference_IsUndefined %{public}s failed %{public}d", propertyName, status);
469             return false;
470         }
471         if (isUndefined) {
472             return false;
473         }
474 
475         if constexpr (std::is_pointer_v<valueType> && std::is_base_of_v<__ani_ref, std::remove_pointer_t<valueType>>) {
476             *value = reinterpret_cast<valueType>(ref);
477         } else {
478             status = ANI_ERROR;
479             if constexpr (std::is_same_v<valueType, ani_boolean>) {
480                 status = env->Object_CallMethodByName_Boolean(
481                     reinterpret_cast<ani_object>(ref), "unboxed", ":Z", value);
482             } else if constexpr (std::is_same_v<valueType, ani_char>) {
483                 status = env->Object_CallMethodByName_Char(reinterpret_cast<ani_object>(ref), "unboxed", ":C", value);
484             } else if constexpr (std::is_same_v<valueType, ani_byte> || std::is_same_v<valueType, ani_short> ||
485                                  std::is_same_v<valueType, ani_int> || std::is_same_v<valueType, uint32_t> ||
486                                  std::is_same_v<valueType, ani_long> ||
487                                  std::is_same_v<valueType, ani_float> || std::is_same_v<valueType, ani_double>) {
488                 double d = 0;
489                 status =
490                     env->Object_CallMethodByName_Double(reinterpret_cast<ani_object>(ref), "unboxed", nullptr, &d);
491                 if (status != ANI_OK) {
492                     APP_LOGE("Object_GetPropertyByName %{public}s failed %{public}d", propertyName, status);
493                     return false;
494                 }
495                 *value = static_cast<valueType>(d);
496                 if (!TryCastDoubleTo(d, value)) {
497                     APP_LOGE("TryCastDoubleTo %{public}s failed", propertyName);
498                     return false;
499                 }
500                 return true;
501             } else {
502                 APP_LOGE("Object_CallMethodByName %{public}s Unsupported", propertyName);
503                 return false;
504             }
505             if (status != ANI_OK) {
506                 APP_LOGE("Object_CallMethodByName %{public}s failed %{public}d", propertyName, status);
507                 return false;
508             }
509         }
510 
511         return true;
512     }
513 
514     template<typename valueType>
CallSetField(ani_env * env,ani_class cls,ani_object object,const char * name,valueType * value)515     static bool CallSetField(ani_env *env, ani_class cls, ani_object object, const char *name, valueType* value)
516     {
517         RETURN_FALSE_IF_NULL(env);
518         RETURN_FALSE_IF_NULL(cls);
519 
520         ani_field field = nullptr;
521         ani_status status = env->Class_FindField(cls, name, &field);
522         if (status != ANI_OK) {
523             APP_LOGE("Class_FindField %{public}s failed %{public}d", name, status);
524             return false;
525         }
526         status = env->Object_SetField_Ref(object, field, value);
527         if (status != ANI_OK) {
528             APP_LOGE("Object_SetField_Ref %{public}s failed %{public}d", name, status);
529             return false;
530         }
531         return true;
532     }
533 
534     template<typename valueType>
CallSetter(ani_env * env,ani_class cls,ani_object object,const char * propertyName,valueType value)535     static bool CallSetter(ani_env* env, ani_class cls, ani_object object, const char* propertyName, valueType value)
536     {
537         RETURN_FALSE_IF_NULL(env);
538         RETURN_FALSE_IF_NULL(cls);
539         RETURN_FALSE_IF_NULL(object);
540 
541         std::string setterName("<set>");
542         setterName.append(propertyName);
543         ani_method setter;
544         ani_status status = env->Class_FindMethod(cls, setterName.c_str(), nullptr, &setter);
545         if (status != ANI_OK) {
546             APP_LOGE("Class_FindMethod %{public}s failed %{public}d", propertyName, status);
547             return false;
548         }
549 
550         if constexpr (std::is_same_v<valueType, ani_byte> || std::is_same_v<valueType, ani_short> ||
551                       std::is_same_v<valueType, ani_int> || std::is_same_v<valueType, uint32_t> ||
552                       std::is_same_v<valueType, ani_long> ||
553                       std::is_same_v<valueType, ani_float> || std::is_same_v<valueType, ani_double>) {
554             status = env->Object_CallMethod_Void(object, setter, static_cast<double>(value));
555         } else {
556             status = env->Object_CallMethod_Void(object, setter, value);
557         }
558 
559         if (status != ANI_OK) {
560             APP_LOGE("Object_CallMethod_Void %{public}s failed %{public}d", propertyName, status);
561             return false;
562         }
563 
564         return true;
565     }
566 
567     // sets property to null
CallSetterNull(ani_env * env,ani_class cls,ani_object object,const char * propertyName)568     static bool CallSetterNull(ani_env* env, ani_class cls, ani_object object, const char* propertyName)
569     {
570         RETURN_FALSE_IF_NULL(env);
571         RETURN_FALSE_IF_NULL(cls);
572         RETURN_FALSE_IF_NULL(object);
573 
574         ani_ref nullRef = nullptr;
575         ani_status status = env->GetNull(&nullRef);
576         if (status != ANI_OK) {
577             APP_LOGE("GetNull %{public}s failed %{public}d", propertyName, status);
578             return false;
579         }
580 
581         return CallSetter(env, cls, object, propertyName, nullRef);
582     }
583 
584     // sets optional property to undefined
CallSetterOptionalUndefined(ani_env * env,ani_class cls,ani_object object,const char * propertyName)585     static bool CallSetterOptionalUndefined(ani_env* env, ani_class cls, ani_object object, const char* propertyName)
586     {
587         RETURN_FALSE_IF_NULL(env);
588         RETURN_FALSE_IF_NULL(cls);
589         RETURN_FALSE_IF_NULL(object);
590 
591         ani_ref undefined = nullptr;
592         ani_status status = env->GetUndefined(&undefined);
593         if (status != ANI_OK) {
594             APP_LOGE("GetUndefined %{public}s failed %{public}d", propertyName, status);
595             return false;
596         }
597 
598         return CallSetter(env, cls, object, propertyName, undefined);
599     }
600 
601     template<typename valueType>
CallSetterOptional(ani_env * env,ani_class cls,ani_object object,const char * propertyName,valueType value)602     static bool CallSetterOptional(
603         ani_env* env, ani_class cls, ani_object object, const char* propertyName, valueType value)
604     {
605         RETURN_FALSE_IF_NULL(env);
606         RETURN_FALSE_IF_NULL(cls);
607         RETURN_FALSE_IF_NULL(object);
608 
609         if constexpr (std::is_pointer_v<valueType> && std::is_base_of_v<__ani_ref, std::remove_pointer_t<valueType>>) {
610             return CallSetter(env, cls, object, propertyName, value);
611         }
612 
613         const char* valueClassName = nullptr;
614         const char* ctorSig = nullptr;
615         if constexpr (std::is_same_v<valueType, ani_boolean>) {
616             valueClassName = "Lstd/core/Boolean;";
617             ctorSig = "Z:V";
618         } else if constexpr (std::is_same_v<valueType, ani_char>) {
619             valueClassName = "Lstd/core/Char;";
620             ctorSig = "C:V";
621         } else if constexpr (std::is_same_v<valueType, ani_byte> || std::is_same_v<valueType, ani_short> ||
622                              std::is_same_v<valueType, ani_int> || std::is_same_v<valueType, uint32_t> ||
623                              std::is_same_v<valueType, ani_long> ||
624                              std::is_same_v<valueType, ani_float> || std::is_same_v<valueType, ani_double>) {
625             valueClassName = "Lstd/core/Double;";
626             ctorSig = "D:V";
627         } else {
628             APP_LOGE("Classname %{public}s Unsupported", propertyName);
629             return false;
630         }
631 
632         ani_class valueClass = nullptr;
633         ani_status status = env->FindClass(valueClassName, &valueClass);
634         if (status != ANI_OK) {
635             APP_LOGE("FindClass %{public}s %{public}s failed %{public}d", propertyName, valueClassName, status);
636             return false;
637         }
638 
639         ani_method ctor = nullptr;
640         status = env->Class_FindMethod(valueClass, "<ctor>", ctorSig, &ctor);
641         if (status != ANI_OK) {
642             APP_LOGE("Class_FindMethod <ctor> %{public}s failed %{public}d", propertyName, status);
643             return false;
644         }
645 
646         ani_object valueObj = nullptr;
647         if constexpr (std::is_same_v<valueType, ani_boolean> || std::is_same_v<valueType, ani_char>) {
648             status = env->Object_New(valueClass, ctor, &valueObj, value);
649         } else if constexpr (std::is_same_v<valueType, ani_byte> || std::is_same_v<valueType, ani_short> ||
650                              std::is_same_v<valueType, ani_int> || std::is_same_v<valueType, uint32_t> ||
651                              std::is_same_v<valueType, ani_long> || std::is_same_v<valueType, ani_float> ||
652                              std::is_same_v<valueType, ani_double>) {
653             status = env->Object_New(valueClass, ctor, &valueObj, static_cast<double>(value));
654         } else {
655             APP_LOGE("Classname %{public}s Unsupported", propertyName);
656             return false;
657         }
658 
659         if (status != ANI_OK) {
660             APP_LOGE("Object_New %{public}s failed %{public}d", propertyName, status);
661             return false;
662         }
663 
664         return CallSetter(env, cls, object, propertyName, valueObj);
665     }
666 };
667 } // namespace AppExecFwk
668 } // namespace OHOS
669 #endif