diff --git a/interfaces/kits/ani/window_runtime/window_stage_ani/include/ani_window_utils.h b/interfaces/kits/ani/window_runtime/window_stage_ani/include/ani_window_utils.h index 2d79d57d3e4dc3f3dce64292906b6b98e7d00609..522a7fd319bcb7ea244028963a6c3ebde97c8759 100644 --- a/interfaces/kits/ani/window_runtime/window_stage_ani/include/ani_window_utils.h +++ b/interfaces/kits/ani/window_runtime/window_stage_ani/include/ani_window_utils.h @@ -107,7 +107,7 @@ public: std::map& systemBarProperties); static bool ParseWindowMask(ani_env* env, ani_array windowMaskArray, std::vector>& windowMask); - static bool ParseWindowMaskInnerValue(ani_env* env, ani_array_long innerArray, std::vector& elementArray); + static bool ParseWindowMaskInnerValue(ani_env* env, ani_array innerArray, std::vector& elementArray); static WmErrorCode ParseTouchableAreas(ani_env* env, ani_array rects, const Rect& windowRect, std::vector& touchableAreas); static bool ParseAndCheckRect(ani_env* env, ani_object rect, const Rect& windowRect, Rect& touchableRect); diff --git a/interfaces/kits/ani/window_runtime/window_stage_ani/src/ani_window_utils.cpp b/interfaces/kits/ani/window_runtime/window_stage_ani/src/ani_window_utils.cpp index 440fbf4d4e5c8844542298dd1e2069c3135b576e..a65e61caf0dc5ea7c7b8c44a7fb4da8aa543e038 100644 --- a/interfaces/kits/ani/window_runtime/window_stage_ani/src/ani_window_utils.cpp +++ b/interfaces/kits/ani/window_runtime/window_stage_ani/src/ani_window_utils.cpp @@ -31,6 +31,16 @@ namespace OHOS { namespace Rosen { namespace { constexpr int32_t MAX_TOUCHABLE_AREAS = 10; +ani_ref g_booleanCls {}; +ani_ref g_doubleCls {}; +ani_ref g_intCls {}; +ani_ref g_longCls {}; + +ani_method unboxBoolean {}; +ani_method unboxDouble {}; +ani_method unboxInt {}; +ani_method unboxLong {}; + std::string GetHexColor(uint32_t color) { std::stringstream ioss; @@ -46,6 +56,96 @@ std::string GetHexColor(uint32_t color) } } +template +ani_status unbox(ani_env* env, ani_object obj, T* result) +{ + return ANI_INVALID_TYPE; +} + +template<> +ani_status unbox(ani_env* env, ani_object obj, ani_double* result) +{ + if (g_doubleCls == nullptr) { + ani_class doubleCls {}; + auto status = env->FindClass("std.core.Double", &doubleCls); + if (status != ANI_OK) { + return status; + } + status = env->GlobalReference_Create(doubleCls, &g_doubleCls); + if (status != ANI_OK) { + return status; + } + status = env->Class_FindMethod(doubleCls, "unboxed", ":d", &unboxDouble); + if (status != ANI_OK) { + return status; + } + } + return env->Object_CallMethod_Double(obj, unboxDouble, result); +} + +template<> +ani_status unbox(ani_env* env, ani_object obj, ani_boolean* result) +{ + if (g_booleanCls == nullptr) { + ani_class booleanCls {}; + auto status = env->FindClass("std.core.Boolean", &booleanCls); + if (status != ANI_OK) { + return status; + } + status = env->GlobalReference_Create(booleanCls, &g_booleanCls); + if (status != ANI_OK) { + return status; + } + status = env->Class_FindMethod(booleanCls, "unboxed", ":z", &unboxBoolean); + if (status != ANI_OK) { + return status; + } + } + return env->Object_CallMethod_Boolean(obj, unboxBoolean, result); +} + +template<> +ani_status unbox(ani_env* env, ani_object obj, ani_int* result) +{ + if (g_intCls == nullptr) { + ani_class intCls {}; + auto status = env->FindClass("std.core.Integer", &intCls); + if (status != ANI_OK) { + return status; + } + status = env->GlobalReference_Create(intCls, &g_intCls); + if (status != ANI_OK) { + return status; + } + status = env->Class_FindMethod(intCls, "unboxed", ":i", &unboxInt); + if (status != ANI_OK) { + return status; + } + } + return env->Object_CallMethod_Int(obj, unboxInt, result); +} + +template<> +ani_status unbox(ani_env* env, ani_object obj, ani_long* result) +{ + if (g_longCls == nullptr) { + ani_class longCls {}; + auto status = env->FindClass("std.core.Long", &longCls); + if (status != ANI_OK) { + return status; + } + status = env->GlobalReference_Create(longCls, &g_longCls); + if (status != ANI_OK) { + return status; + } + status = env->Class_FindMethod(longCls, "unboxed", ":l", &unboxLong); + if (status != ANI_OK) { + return status; + } + } + return env->Object_CallMethod_Long(obj, unboxLong, result); +} + ani_status AniWindowUtils::GetStdString(ani_env *env, ani_string ani_str, std::string &result) { ani_size strSize; @@ -1259,16 +1359,20 @@ bool AniWindowUtils::ParseWindowMask(ani_env* env, ani_array windowMaskArray, return false; } std::vector elementArray; - if (!ParseWindowMaskInnerValue(env, static_cast(innerArrayRef), elementArray)) { + if (!ParseWindowMaskInnerValue(env, static_cast(innerArrayRef), elementArray)) { TLOGE(WmsLogTag::WMS_PC, "[ANI]Failed to convert parameter to window mask!"); return false; } windowMask.emplace_back(elementArray); } + aniRet = env->GlobalReference_Delete(g_longCls); + if (aniRet != ANI_OK) { + TLOGE(WmsLogTag::WMS_PC, "[ANI]Failed to delete g_longCls ref, ret: %{public}u", aniRet); + } return true; } -bool AniWindowUtils::ParseWindowMaskInnerValue(ani_env* env, ani_array_long innerArray, +bool AniWindowUtils::ParseWindowMaskInnerValue(ani_env* env, ani_array innerArray, std::vector& elementArray) { ani_size size; @@ -1285,7 +1389,7 @@ bool AniWindowUtils::ParseWindowMaskInnerValue(ani_env* env, ani_array_long inne return false; } ani_long maskValue = 0; - aniRet = env->Object_CallMethodByName_Long(static_cast(maskValueRef), "unboxed", ":l", &maskValue); + aniRet = unbox(env, static_cast(maskValueRef), &maskValue); if (aniRet != ANI_OK) { TLOGE(WmsLogTag::WMS_PC, "[ANI]Get maskValue failed, ret: %{public}u", aniRet); return false;