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