From ba20e48033eba2cb97d54bfbe91a61c1ad73a074 Mon Sep 17 00:00:00 2001 From: zhangweihua Date: Mon, 28 Jul 2025 16:37:09 +0800 Subject: [PATCH 1/3] ani bugfix Signed-off-by: zhangweihua --- .../display_ani/ets/@ohos.display.ets | 4 +- .../display_ani/include/display_ani_manager.h | 1 + .../display_ani/src/ani_err_utils.cpp | 2 +- .../display_ani/src/display_ani.cpp | 12 ++-- .../display_ani/src/display_ani_listener.cpp | 42 +++++------ .../display_ani/src/display_ani_manager.cpp | 63 +++++++++++------ .../screen_ani/ets/@ohos.screen.ets | 10 ++- .../screen_ani/include/screen_ani_manager.h | 1 + .../screen_ani/src/ani_err_utils.cpp | 2 +- .../screen_ani/src/screen_ani_listener.cpp | 51 ++++++-------- .../screen_ani/src/screen_ani_manager.cpp | 69 +++++++++++++------ .../screenshot_ani/src/ani_err_utils.cpp | 2 +- 12 files changed, 146 insertions(+), 113 deletions(-) diff --git a/interfaces/kits/ani/display_runtime/display_ani/ets/@ohos.display.ets b/interfaces/kits/ani/display_runtime/display_ani/ets/@ohos.display.ets index 8cf431404d..4f99569c2f 100644 --- a/interfaces/kits/ani/display_runtime/display_ani/ets/@ohos.display.ets +++ b/interfaces/kits/ani/display_runtime/display_ani/ets/@ohos.display.ets @@ -272,7 +272,7 @@ export class DisplayImpl implements Display { minusRectArray(res.boundingRects); return res; }).then((ret: NullishType) => { - callback(new BusinessError(), ret as CutoutInfo); + callback(null, ret as CutoutInfo); }).catch((err: NullishType) => { callback(err as BusinessError, new CutoutInfoImpl()); }); @@ -426,7 +426,7 @@ export function getAllDisplays(callback: AsyncCallback>): void { try { getAllDisplaysSyncNative(res); minusDisplayArray(res); - callback(new BusinessError(), res); + callback(null, res); } catch (err: BusinessError) { hilog.error(DOMAIN, TAG, 'get all display from err'); callback(err, res); diff --git a/interfaces/kits/ani/display_runtime/display_ani/include/display_ani_manager.h b/interfaces/kits/ani/display_runtime/display_ani/include/display_ani_manager.h index de5515815a..42f4e67212 100644 --- a/interfaces/kits/ani/display_runtime/display_ani/include/display_ani_manager.h +++ b/interfaces/kits/ani/display_runtime/display_ani/include/display_ani_manager.h @@ -52,6 +52,7 @@ private: void OnUnRegisterCallback(ani_env* env, ani_string type, ani_ref callback); void OnGetCurrentFoldCreaseRegion(ani_env* env, ani_object obj); void OnGetAllDisplayPhysicalResolution(ani_env* env, ani_object arrayObj); + bool IsCallbackRegistered(ani_env* env, const std::string& type, ani_ref callback); std::mutex mtx_; std::map>> jsCbMap_; }; diff --git a/interfaces/kits/ani/display_runtime/display_ani/src/ani_err_utils.cpp b/interfaces/kits/ani/display_runtime/display_ani/src/ani_err_utils.cpp index 0e0df5fc1f..db16a55bca 100644 --- a/interfaces/kits/ani/display_runtime/display_ani/src/ani_err_utils.cpp +++ b/interfaces/kits/ani/display_runtime/display_ani/src/ani_err_utils.cpp @@ -165,7 +165,7 @@ ani_status AniErrUtils::CreateBusinessError(ani_env* env, int32_t error, std::st TLOGE(WmsLogTag::DMS, "[ANI] fail to new err, status:%{public}d", static_cast(status)); return status; } - status = env->Object_SetFieldByName_Double(*err, "code", static_cast(error)); + status = env->Object_SetFieldByName_Int(*err, "code", static_cast(error)); if (status != ANI_OK) { TLOGE(WmsLogTag::DMS, "[ANI] fail to set code, status:%{public}d", static_cast(status)); return status; diff --git a/interfaces/kits/ani/display_runtime/display_ani/src/display_ani.cpp b/interfaces/kits/ani/display_runtime/display_ani/src/display_ani.cpp index 5ea5565237..49590eb063 100644 --- a/interfaces/kits/ani/display_runtime/display_ani/src/display_ani.cpp +++ b/interfaces/kits/ani/display_runtime/display_ani/src/display_ani.cpp @@ -150,12 +150,10 @@ void DisplayAni::OnRegisterCallback(ani_env* env, ani_object obj, ani_string typ std::string typeString; DisplayAniUtils::GetStdString(env, type, typeString); ani_boolean callbackUndefined = 0; - ani_boolean callbackIsNull = 0; env->Reference_IsUndefined(callback, &callbackUndefined); - env->Reference_IsNull(callback, &callbackIsNull); - if (callbackUndefined || callbackIsNull) { + if (callbackUndefined) { std::string errMsg = "[ANI] failed to register display listener with type, cbk null or undefined"; - TLOGE(WmsLogTag::DMS, "callbackNull or undefined"); + TLOGE(WmsLogTag::DMS, "callback undef"); AniErrUtils::ThrowBusinessError(env, DmErrorCode::DM_ERROR_INVALID_PARAM, errMsg); return; } @@ -213,10 +211,10 @@ void DisplayAni::OnUnRegisterCallback(ani_env* env, ani_object obj, ani_string t TLOGI(WmsLogTag::DMS, "[ANI] begin"); std::string typeString; DisplayAniUtils::GetStdString(env, type, typeString); - ani_boolean callbackNull = 0; - env->Reference_IsUndefined(callback, &callbackNull); + ani_boolean callbackUndefined = 0; + env->Reference_IsUndefined(callback, &callbackUndefined); DmErrorCode ret; - if (callbackNull) { + if (callbackUndefined) { TLOGI(WmsLogTag::DMS, "[ANI] for all"); ret = DM_JS_TO_ERROR_CODE_MAP.at(UnregisterAllDisplayListenerWithType(typeString)); } else { diff --git a/interfaces/kits/ani/display_runtime/display_ani/src/display_ani_listener.cpp b/interfaces/kits/ani/display_runtime/display_ani/src/display_ani_listener.cpp index 7178d01839..9128946847 100644 --- a/interfaces/kits/ani/display_runtime/display_ani/src/display_ani_listener.cpp +++ b/interfaces/kits/ani/display_runtime/display_ani/src/display_ani_listener.cpp @@ -42,12 +42,7 @@ void DisplayAniListener::AddCallback(const std::string& type, ani_ref callback) return; } std::lock_guard lock(aniCallbackMtx_); - ani_ref cbRef{}; - if (env_->GlobalReference_Create(callback, &cbRef) != ANI_OK) { - TLOGE(WmsLogTag::DMS, "[ANI]create global ref fail"); - return; - }; - aniCallback_[type].emplace_back(cbRef); + aniCallback_[type].emplace_back(callback); TLOGI(WmsLogTag::DMS, "[ANI] AddCallback success aniCallback_ size: %{public}u!", static_cast(aniCallback_[type].size())); } @@ -76,8 +71,15 @@ void DisplayAniListener::RemoveCallback(ani_env* env, const std::string& type, a void DisplayAniListener::RemoveAllCallback() { - std::lock_guard lock(aniCallbackMtx_); - aniCallback_.clear(); + std::lock_guard lock(aniCallBackMtx_); + for (auto& [typeString, callbacks] : aniCallBack_) { + for (auto callback : callbacks) { + if (env_) { + env_->GlobalReference_Delete(callback); + } + } + } + aniCallBack_.clear(); } void DisplayAniListener::OnCreate(DisplayId id) @@ -106,12 +108,10 @@ void DisplayAniListener::OnCreate(DisplayId id) TLOGE(WmsLogTag::DMS, "[ANI] null env"); return; } - ani_boolean undefRes = 0; - ani_boolean nullRes = 0; + ani_boolean undefRes; env_->Reference_IsUndefined(oneAniCallback, &undefRes); - env_->Reference_IsNull(oneAniCallback, &nullRes); - if (undefRes != 0 || nullRes != 0) { - TLOGE(WmsLogTag::DMS, "[ANI] oneAniCallback is undefRes or null"); + if (undefRes) { + TLOGE(WmsLogTag::DMS, "[ANI] oneAniCallback is undef"); continue; } auto task = [env = env_, oneAniCallback, id] { @@ -153,12 +153,10 @@ void DisplayAniListener::OnDestroy(DisplayId id) TLOGE(WmsLogTag::DMS, "[ANI] null env"); return; } - ani_boolean undefRes = 0; - ani_boolean nullRes = 0; + ani_boolean undefRes; env_->Reference_IsUndefined(oneAniCallback, &undefRes); - env_->Reference_IsNull(oneAniCallback, &nullRes); - if (undefRes != 0 || nullRes != 0) { - TLOGE(WmsLogTag::DMS, "[ANI] oneAniCallback is undefRes or null"); + if (undefRes) { + TLOGE(WmsLogTag::DMS, "[ANI] oneAniCallback is undef"); continue; } auto task = [env = env_, oneAniCallback, id] { @@ -197,12 +195,10 @@ void DisplayAniListener::OnChange(DisplayId id) TLOGE(WmsLogTag::DMS, "[ANI] null env"); return; } - ani_boolean undefRes = 0; - ani_boolean nullRes = 0; + ani_boolean undefRes; env_->Reference_IsUndefined(oneAniCallback, &undefRes); - env_->Reference_IsNull(oneAniCallback, &nullRes); - if (undefRes != 0 || nullRes != 0) { - TLOGE(WmsLogTag::DMS, "[ANI] oneAniCallback undefRes, return"); + if (undefRes) { + TLOGE(WmsLogTag::DMS, "[ANI] oneAniCallback undef, return"); continue; } auto task = [env = env_, oneAniCallback, id] { diff --git a/interfaces/kits/ani/display_runtime/display_ani/src/display_ani_manager.cpp b/interfaces/kits/ani/display_runtime/display_ani/src/display_ani_manager.cpp index 160affb2b2..c0546f27b1 100644 --- a/interfaces/kits/ani/display_runtime/display_ani/src/display_ani_manager.cpp +++ b/interfaces/kits/ani/display_runtime/display_ani/src/display_ani_manager.cpp @@ -162,11 +162,9 @@ void DisplayManagerAni::GetDisplayByIdSyncAni(ani_env* env, ani_object obj, ani_ return; } sptr display = SingletonContainer::Get().GetDisplayById(static_cast(displayId)); - if (display == nullptr) { - AniErrUtils::ThrowBusinessError(env, DmErrorCode::DM_ERROR_SYSTEM_INNORMAL, ""); - } if (display == nullptr) { TLOGE(WmsLogTag::DMS, "[ANI] Display null"); + AniErrUtils::ThrowBusinessError(env, DmErrorCode::DM_ERROR_SYSTEM_INNORMAL, ""); return; } DisplayAniUtils::CvtDisplay(display, env, obj); @@ -199,26 +197,28 @@ void DisplayManagerAni::RegisterCallback(ani_env* env, ani_string type, void DisplayManagerAni::OnRegisterCallback(ani_env* env, ani_string type, ani_ref callback) { - TLOGI(WmsLogTag::DMS, "[ANI] begin"); - std::lock_guard lock(mtx_); std::string typeString; DisplayAniUtils::GetStdString(env, type, typeString); + ani_ref cbRef{}; + if (env->GlobalReference_Create(callback, &cbRef) != ANI_OK) { + TLOGE(WmsLogTag::DMS, "[ANI] create global ref fail"); + return; + } + std::lock_guard lock(mtx_); + if (IsCallbackRegistered(env, typeString, cbRef)) { + TLOGI(WmsLogTag::DMS, "[ANI] type %{public}s callback already registered!", typeString.c_str()); + return; + } + TLOGI(WmsLogTag::DMS, "[ANI] onRegisterCallback"); ani_boolean callbackUndefined = 0; - ani_boolean callbackIsNull = 0; - env->Reference_IsUndefined(callback, &callbackUndefined); - env->Reference_IsNull(callback, &callbackIsNull); + env->Reference_IsUndefined(cbRef, &callbackUndefined); DmErrorCode ret; - if (callbackUndefined || callbackIsNull) { + if (callbackUndefined) { std::string errMsg = "[ANI] failed to register display listener with type, cbk null or undefined"; TLOGE(WmsLogTag::DMS, "callbackNull or undefined"); AniErrUtils::ThrowBusinessError(env, DmErrorCode::DM_ERROR_INVALID_PARAM, errMsg); return; } - ani_ref cbRef{}; - if (env->GlobalReference_Create(callback, &cbRef) != ANI_OK) { - TLOGE(WmsLogTag::DEFAULT, "[ANI]create global ref fail"); - }; - TLOGI(WmsLogTag::DMS, "create listener"); sptr displayAniListener = new(std::nothrow) DisplayAniListener(env); if (displayAniListener == nullptr) { TLOGE(WmsLogTag::DMS, "[ANI]displayListener is nullptr"); @@ -236,7 +236,24 @@ void DisplayManagerAni::OnRegisterCallback(ani_env* env, ani_string type, ani_re return; } // add listener to map - jsCbMap_[typeString][callback] = displayAniListener; + jsCbMap_[typeString][cbRef] = displayAniListener; +} + +bool DisplayManagerAni::IsCallbackRegistered(ani_env* env, const std::string& type, ani_ref callback) +{ + if (jsCbMap_.empty() || jsCbMap_.find(type) == jsCbMap_.end()) { + TLOGI(WmsLogTag::DMS, "method %{public}s not registered!", type.c_str()); + return false; + } + for (const auto& iter : jsCbMap_[type]) { + ani_boolean isEquals = false; + env->Reference_StrictEquals(callback, iter.first, &isEquals); + if (isEquals) { + TLOGE(WmsLogTag::DMS, "callback already registered!"); + return true; + } + } + return false; } DmErrorCode DisplayManagerAni::ProcessRegisterCallback(ani_env* env, std::string& typeStr, @@ -284,18 +301,23 @@ void DisplayManagerAni::UnRegisterCallback(ani_env* env, ani_string type, void DisplayManagerAni::OnUnRegisterCallback(ani_env* env, ani_string type, ani_ref callback) { TLOGI(WmsLogTag::DMS, "[ANI] begin"); + ani_ref cbRef{}; + if (env->GlobalReference_Create(callback, &cbRef) != ANI_OK) { + TLOGE(WmsLogTag::DMS, "[ANI] create global ref fail"); + return; + } std::string typeString; DisplayAniUtils::GetStdString(env, type, typeString); std::lock_guard lock(mtx_); ani_boolean callbackNull = 0; - env->Reference_IsUndefined(callback, &callbackNull); + env->Reference_IsUndefined(cbRef, &callbackNull); DmErrorCode ret; if (callbackNull) { - TLOGI(WmsLogTag::DMS, "[ANI] OnUnRegisterCallback for all"); + TLOGI(WmsLogTag::DMS, "[ANI] for all"); ret = DM_JS_TO_ERROR_CODE_MAP.at(UnregisterAllDisplayListenerWithType(typeString)); } else { - TLOGI(WmsLogTag::DMS, "[ANI] OnUnRegisterCallback with type"); - ret = DM_JS_TO_ERROR_CODE_MAP.at(UnRegisterDisplayListenerWithType(typeString, env, callback)); + TLOGI(WmsLogTag::DMS, "[ANI] with type"); + ret = DM_JS_TO_ERROR_CODE_MAP.at(UnRegisterDisplayListenerWithType(typeString, env, cbRef)); } if (ret != DmErrorCode::DM_OK) { @@ -360,7 +382,7 @@ DMError DisplayManagerAni::UnregisterAllDisplayListenerWithType(std::string type { TLOGI(WmsLogTag::DMS, "[ANI] begin"); if (jsCbMap_.empty() || jsCbMap_.find(type) == jsCbMap_.end()) { - TLOGI(WmsLogTag::DMS, "[ANI] UnregisterAllDisplayListenerWithType methodName %{public}s not registered!", + TLOGI(WmsLogTag::DMS, "[ANI] methodName %{public}s not registered!", type.c_str()); return DMError::DM_OK; } @@ -390,7 +412,6 @@ DMError DisplayManagerAni::UnregisterAllDisplayListenerWithType(std::string type ret = SingletonContainer::Get().UnregisterPrivateWindowListener(thisListener); } jsCbMap_[type].erase(it++); - TLOGI(WmsLogTag::DMS, "[ANI] UnregisterAllDisplayListenerWithType end"); } jsCbMap_.erase(type); return ret; diff --git a/interfaces/kits/ani/screen_runtime/screen_ani/ets/@ohos.screen.ets b/interfaces/kits/ani/screen_runtime/screen_ani/ets/@ohos.screen.ets index d6b050eab3..374ae6e506 100644 --- a/interfaces/kits/ani/screen_runtime/screen_ani/ets/@ohos.screen.ets +++ b/interfaces/kits/ani/screen_runtime/screen_ani/ets/@ohos.screen.ets @@ -20,17 +20,15 @@ export default namespace screen { loadLibrary('screenani_kit.z'); -export function on(eventType: 'connect' | 'disconnect' | 'change', callback: Callback): void{ +export function on(eventType: string, callback: Callback): void{ syncOn(eventType, callback, screenMgrRef); } -native function syncOn(eventType: 'connect' | 'disconnect' | 'change', - callback: Callback, nativeObj: long): void; +native function syncOn(eventType: string, callback: object, nativeObj: long): void; -export function off(eventType: 'connect' | 'disconnect' | 'change', callback?: Callback): void{ +export function off(eventType: string, callback?: Callback): void{ syncOff(eventType, screenMgrRef, callback); } -native function syncOff(eventType: 'connect' | 'disconnect' | 'change', - nativeObj: long, callback?: Callback): void; +native function syncOff(eventType: string, nativeObj: long, callback?: object): void; export function makeMirror(mainScreen: number, mirrorScreen: Array, callback: AsyncCallback): void { taskpool.execute((): number => { diff --git a/interfaces/kits/ani/screen_runtime/screen_ani/include/screen_ani_manager.h b/interfaces/kits/ani/screen_runtime/screen_ani/include/screen_ani_manager.h index 61fca6915c..4606502229 100644 --- a/interfaces/kits/ani/screen_runtime/screen_ani/include/screen_ani_manager.h +++ b/interfaces/kits/ani/screen_runtime/screen_ani/include/screen_ani_manager.h @@ -43,6 +43,7 @@ private: void OnUnRegisterCallback(ani_env* env, ani_string type, ani_ref callback); DMError UnRegisterScreenListenerWithType(std::string type, ani_env* env, ani_ref callback); DMError UnRegisterAllScreenListenerWithType(std::string type); + bool IsCallbackRegistered(ani_env* env, const std::string& type, ani_ref callback); std::mutex mtx_; std::map>> jsCbMap_; }; diff --git a/interfaces/kits/ani/screen_runtime/screen_ani/src/ani_err_utils.cpp b/interfaces/kits/ani/screen_runtime/screen_ani/src/ani_err_utils.cpp index 47ace25c35..0f9c197337 100644 --- a/interfaces/kits/ani/screen_runtime/screen_ani/src/ani_err_utils.cpp +++ b/interfaces/kits/ani/screen_runtime/screen_ani/src/ani_err_utils.cpp @@ -136,7 +136,7 @@ ani_status AniErrUtils::CreateBusinessError(ani_env* env, int32_t error, std::st TLOGE(WmsLogTag::DMS, "[ANI] fail to new err, status:%{public}d", static_cast(status)); return status; } - status = env->Object_SetFieldByName_Double(*err, "code", static_cast(error)); + status = env->Object_SetFieldByName_Int(*err, "code", static_cast(error)); if (status != ANI_OK) { TLOGE(WmsLogTag::DMS, "[ANI] fail to set code, status:%{public}d", static_cast(status)); return status; diff --git a/interfaces/kits/ani/screen_runtime/screen_ani/src/screen_ani_listener.cpp b/interfaces/kits/ani/screen_runtime/screen_ani/src/screen_ani_listener.cpp index 945efbefbd..5614fb54d5 100644 --- a/interfaces/kits/ani/screen_runtime/screen_ani/src/screen_ani_listener.cpp +++ b/interfaces/kits/ani/screen_runtime/screen_ani/src/screen_ani_listener.cpp @@ -41,12 +41,7 @@ void ScreenAniListener::AddCallback(const std::string& type, ani_ref callback) return; } std::lock_guard lock(mtx_); - ani_ref cbRef{}; - if (env_->GlobalReference_Create(callback, &cbRef) != ANI_OK) { - TLOGE(WmsLogTag::DMS, "[ANI]create global ref fail"); - return; - }; - aniCallback_[type].emplace_back(cbRef); + aniCallback_[type].emplace_back(callback); TLOGI(WmsLogTag::DMS, "[ANI] AddCallback success aniCallback_ size: %{public}u!", static_cast(aniCallback_[type].size())); } @@ -102,13 +97,11 @@ void ScreenAniListener::OnConnect(ScreenId id) TLOGE(WmsLogTag::DMS, "[ANI] null env"); return; } - ani_boolean undefRes = 0; - ani_boolean nullRes = 0; + ani_boolean undefRes; env_->Reference_IsUndefined(oneAniCallback, &undefRes); - env_->Reference_IsNull(oneAniCallback, &nullRes); // judge is null or undefined - if (undefRes != 0 || nullRes != 0) { - TLOGE(WmsLogTag::DMS, "[ANI] oneAniCallback is undefRes or null"); + if (undefRes) { + TLOGE(WmsLogTag::DMS, "[ANI] oneAniCallback is undef"); continue; } @@ -151,13 +144,11 @@ void ScreenAniListener::OnDisconnect(ScreenId id) TLOGE(WmsLogTag::DMS, "[ANI] null env"); return; } - ani_boolean undefRes = 0; - ani_boolean nullRes = 0; + ani_boolean undefRes; env_->Reference_IsUndefined(oneAniCallback, &undefRes); - env_->Reference_IsNull(oneAniCallback, &nullRes); // judge is null or undefined - if (undefRes != 0 || nullRes != 0) { - TLOGE(WmsLogTag::DMS, "[ANI] oneAniCallback is undefRes or null"); + if (undefRes) { + TLOGE(WmsLogTag::DMS, "[ANI] oneAniCallback is undef"); continue; } @@ -173,8 +164,7 @@ void ScreenAniListener::OnDisconnect(ScreenId id) AppExecFwk::EventQueue::Priority::IMMEDIATE); } } - -// need to implement + void ScreenAniListener::OnChange(ScreenId id) { TLOGI(WmsLogTag::DMS, "[ANI] begin"); @@ -195,29 +185,28 @@ void ScreenAniListener::OnChange(ScreenId id) return; } std::vector vec = it->second; - TLOGI(WmsLogTag::DMS, "vec_callback size: %{public}d", vec.size()); // find callbacks in vector for (auto oneAniCallback : vec) { if (env_ == nullptr) { TLOGE(WmsLogTag::DMS, "[ANI] null env"); return; } - ani_boolean undefRes = 0; - ani_boolean nullRes = 0; + ani_boolean undefRes; env_->Reference_IsUndefined(oneAniCallback, &undefRes); - env_->Reference_IsNull(oneAniCallback, &nullRes); - // judge is null or undefined - if (undefRes == 1) { - TLOGE(WmsLogTag::DMS, "[ANI] oneAniCallback undefRes, return"); - return; + if (undefRes) { + TLOGE(WmsLogTag::DMS, "[ANI] oneAniCallback undefRes, continue"); + continue; } - if (nullRes == 1) { - TLOGE(WmsLogTag::DMS, "[ANI] oneAniCallback null, return"); + auto task = [env = env_, oneAniCallback, id] () { + ScreenAniUtils::CallAniFunctionVoid(env, "L@ohos/screen/screen;", "screenEventCallBack", + "Lstd/core/Object;D:V", oneAniCallback, static_cast(id)); + }; + if (!eventHandler_) { + TLOGE(WmsLogTag::DMS, "get main event handler failed!"); return; } - - ScreenAniUtils::CallAniFunctionVoid(env_, "L@ohos/screen/screen;", "screenEventCallBack", - "Lstd/core/Object;D:V", oneAniCallback, static_cast(id)); + eventHandler_->PostTask(task, "dms:AniScreenListener::CreateCallBack", 0, + AppExecFwk::EventQueue::Priority::IMMEDIATE); } } diff --git a/interfaces/kits/ani/screen_runtime/screen_ani/src/screen_ani_manager.cpp b/interfaces/kits/ani/screen_runtime/screen_ani/src/screen_ani_manager.cpp index 3d0ec5aff5..e904897963 100644 --- a/interfaces/kits/ani/screen_runtime/screen_ani/src/screen_ani_manager.cpp +++ b/interfaces/kits/ani/screen_runtime/screen_ani/src/screen_ani_manager.cpp @@ -58,25 +58,28 @@ void ScreenManagerAni::UnRegisterCallback(ani_env* env, ani_string type, ani_lon void ScreenManagerAni::OnRegisterCallback(ani_env* env, ani_string type, ani_ref callback) { - TLOGI(WmsLogTag::DMS, "[ANI] begin"); - std::lock_guard lock(mtx_); + ani_ref cbRef{}; std::string typeString; ScreenAniUtils::GetStdString(env, type, typeString); + if (env->GlobalReference_Create(callback, &cbRef) != ANI_OK) { + TLOGE(WmsLogTag::DMS, "[ANI] create global ref fail"); + return; + } + std::lock_guard lock(mtx_); + if (IsCallbackRegistered(env, typeString, cbRef)) { + TLOGI(WmsLogTag::DMS, "[ANI] type %{public}s callback already registered!", typeString.c_str()); + return; + } + TLOGI(WmsLogTag::DMS, "[ANI] begin"); ani_boolean callbackUndefined = 0; - ani_boolean callbackIsNull = 0; - env->Reference_IsUndefined(callback, &callbackUndefined); - env->Reference_IsNull(callback, &callbackIsNull); + env->Reference_IsUndefined(cbRef, &callbackUndefined); DmErrorCode ret; - if (callbackUndefined || callbackIsNull) { + if (callbackUndefined) { std::string errMsg = "[ANI] failed to register screen listener with type, cbk null or undefined"; - TLOGE(WmsLogTag::DMS, "callbackNull or undefined"); + TLOGE(WmsLogTag::DMS, "undefined"); AniErrUtils::ThrowBusinessError(env, DmErrorCode::DM_ERROR_INVALID_PARAM, errMsg); return; } - ani_ref cbRef{}; - if (env->GlobalReference_Create(callback, &cbRef) != ANI_OK) { - TLOGE(WmsLogTag::DEFAULT, "[ANI]create global ref fail"); - }; TLOGI(WmsLogTag::DMS, "create listener"); sptr screenAniListener = new(std::nothrow) ScreenAniListener(env); if (screenAniListener == nullptr) { @@ -86,7 +89,6 @@ void ScreenManagerAni::OnRegisterCallback(ani_env* env, ani_string type, ani_ref } screenAniListener->AddCallback(typeString, cbRef); screenAniListener->SetMainEventHandler(); - ret = ProcessRegisterCallback(env, typeString, screenAniListener); if (ret != DmErrorCode::DM_OK) { TLOGE(WmsLogTag::DMS, "[ANI] register screen listener with type, errcode: %{public}d", ret); @@ -95,7 +97,7 @@ void ScreenManagerAni::OnRegisterCallback(ani_env* env, ani_string type, ani_ref return; } // add listener to map - jsCbMap_[typeString][callback] = screenAniListener; + jsCbMap_[typeString][cbRef] = screenAniListener; } DmErrorCode ScreenManagerAni::ProcessRegisterCallback(ani_env* env, std::string& typeStr, @@ -116,10 +118,10 @@ void ScreenManagerAni::OnUnRegisterCallback(ani_env* env, ani_string type, ani_r std::string typeString; ScreenAniUtils::GetStdString(env, type, typeString); std::lock_guard lock(mtx_); - ani_boolean callbackNull = 0; - env->Reference_IsUndefined(callback, &callbackNull); + ani_boolean callbackUndefined = 0; + env->Reference_IsUndefined(callback, &callbackUndefined); DmErrorCode ret; - if (callbackNull) { + if (callbackUndefined) { TLOGI(WmsLogTag::DMS, "[ANI] OnUnRegisterCallback for all"); ret = DM_JS_TO_ERROR_CODE_MAP.at(UnRegisterAllScreenListenerWithType(typeString)); } else { @@ -138,17 +140,39 @@ void ScreenManagerAni::OnUnRegisterCallback(ani_env* env, ani_string type, ani_r } } +bool ScreenManagerAni::IsCallbackRegistered(ani_env* env, const std::string& type, ani_ref callback) +{ + if (jsCbMap_.empty() || jsCbMap_.find(type) == jsCbMap_.end()) { + TLOGI(WmsLogTag::DMS, "method %{public}s not registered!", type.c_str()); + return false; + } + for (const auto& iter : jsCbMap_[type]) { + ani_boolean isEquals = false; + env->Reference_StrictEquals(callback, iter.first, &isEquals); + if (isEquals) { + TLOGE(WmsLogTag::DMS, "callback already registered!"); + return true; + } + } + return false; +} + DMError ScreenManagerAni::UnRegisterScreenListenerWithType(std::string type, ani_env* env, ani_ref callback) { - TLOGI(WmsLogTag::DMS, "[ANI] begin"); + TLOGI(WmsLogTag::DMS, "[ANI] UnRegisterScreenListenerWithType begin"); + DMError ret = DMError::DM_OK; if (jsCbMap_.empty() || jsCbMap_.find(type) == jsCbMap_.end()) { TLOGI(WmsLogTag::DMS, "[ANI] methodName %{public}s not registered!", type.c_str()); - return DMError::DM_OK; + return ret; + } + ani_ref cbRef{}; + if (env->GlobalReference_Create(callback, &cbRef) != ANI_OK) { + TLOGE(WmsLogTag::DMS, "[ANI]create global ref fail"); + return DMError::DM_ERROR_INVALID_PARAM; } - DMError ret = DMError::DM_OK; for (auto it = jsCbMap_[type].begin(); it != jsCbMap_[type].end(); it++) { ani_boolean isEquals = 0; - env->Reference_StrictEquals(callback, it->first, &isEquals); + env->Reference_StrictEquals(cbRef, it->first, &isEquals); if (isEquals) { it->second->RemoveCallback(env, type, callback); if (type == EVENT_CHANGE) { @@ -157,8 +181,13 @@ DMError ScreenManagerAni::UnRegisterScreenListenerWithType(std::string type, ani sptr thisListener(it->second); ret = SingletonContainer::Get().UnregisterScreenListener(thisListener); } + jsCbMap_[type].erase(it); + break; } } + if (jsCbMap_[type].empty()) { + jsCbMap_.erase(type); + } return ret; } diff --git a/interfaces/kits/ani/screenshot_runtime/screenshot_ani/src/ani_err_utils.cpp b/interfaces/kits/ani/screenshot_runtime/screenshot_ani/src/ani_err_utils.cpp index f16352c868..9699f2d6fa 100644 --- a/interfaces/kits/ani/screenshot_runtime/screenshot_ani/src/ani_err_utils.cpp +++ b/interfaces/kits/ani/screenshot_runtime/screenshot_ani/src/ani_err_utils.cpp @@ -136,7 +136,7 @@ ani_status AniErrUtils::CreateBusinessError(ani_env* env, int32_t error, std::st TLOGE(WmsLogTag::DMS, "[ANI] fail to new err, status:%{public}d", static_cast(status)); return status; } - status = env->Object_SetFieldByName_Double(*err, "code", static_cast(error)); + status = env->Object_SetFieldByName_Int(*err, "code", static_cast(error)); if (status != ANI_OK) { TLOGE(WmsLogTag::DMS, "[ANI] fail to set code, status:%{public}d", static_cast(status)); return status; -- Gitee From 045c202dba1749ac6c36ec07efc1aa677b7d4d88 Mon Sep 17 00:00:00 2001 From: zhangweihua Date: Tue, 29 Jul 2025 11:51:02 +0800 Subject: [PATCH 2/3] ani bugfix Signed-off-by: zhangweihua --- .../display_ani/src/display_ani_listener.cpp | 12 ++++++------ .../display_ani/src/display_ani_manager.cpp | 5 +++++ .../screen_ani/src/screen_ani_listener.cpp | 6 +++--- .../screen_ani/src/screen_ani_manager.cpp | 11 ++++++++--- 4 files changed, 22 insertions(+), 12 deletions(-) diff --git a/interfaces/kits/ani/display_runtime/display_ani/src/display_ani_listener.cpp b/interfaces/kits/ani/display_runtime/display_ani/src/display_ani_listener.cpp index 9128946847..1646fae8bb 100644 --- a/interfaces/kits/ani/display_runtime/display_ani/src/display_ani_listener.cpp +++ b/interfaces/kits/ani/display_runtime/display_ani/src/display_ani_listener.cpp @@ -71,15 +71,15 @@ void DisplayAniListener::RemoveCallback(ani_env* env, const std::string& type, a void DisplayAniListener::RemoveAllCallback() { - std::lock_guard lock(aniCallBackMtx_); - for (auto& [typeString, callbacks] : aniCallBack_) { + std::lock_guard lock(aniCallbackMtx_); + for (auto& [typeString, callbacks] : aniCallback_) { for (auto callback : callbacks) { if (env_) { env_->GlobalReference_Delete(callback); } } } - aniCallBack_.clear(); + aniCallback_.clear(); } void DisplayAniListener::OnCreate(DisplayId id) @@ -108,7 +108,7 @@ void DisplayAniListener::OnCreate(DisplayId id) TLOGE(WmsLogTag::DMS, "[ANI] null env"); return; } - ani_boolean undefRes; + ani_boolean undefRes = 0; env_->Reference_IsUndefined(oneAniCallback, &undefRes); if (undefRes) { TLOGE(WmsLogTag::DMS, "[ANI] oneAniCallback is undef"); @@ -153,7 +153,7 @@ void DisplayAniListener::OnDestroy(DisplayId id) TLOGE(WmsLogTag::DMS, "[ANI] null env"); return; } - ani_boolean undefRes; + ani_boolean undefRes = 0; env_->Reference_IsUndefined(oneAniCallback, &undefRes); if (undefRes) { TLOGE(WmsLogTag::DMS, "[ANI] oneAniCallback is undef"); @@ -195,7 +195,7 @@ void DisplayAniListener::OnChange(DisplayId id) TLOGE(WmsLogTag::DMS, "[ANI] null env"); return; } - ani_boolean undefRes; + ani_boolean undefRes = 0; env_->Reference_IsUndefined(oneAniCallback, &undefRes); if (undefRes) { TLOGE(WmsLogTag::DMS, "[ANI] oneAniCallback undef, return"); diff --git a/interfaces/kits/ani/display_runtime/display_ani/src/display_ani_manager.cpp b/interfaces/kits/ani/display_runtime/display_ani/src/display_ani_manager.cpp index c0546f27b1..4f0811c733 100644 --- a/interfaces/kits/ani/display_runtime/display_ani/src/display_ani_manager.cpp +++ b/interfaces/kits/ani/display_runtime/display_ani/src/display_ani_manager.cpp @@ -207,6 +207,7 @@ void DisplayManagerAni::OnRegisterCallback(ani_env* env, ani_string type, ani_re std::lock_guard lock(mtx_); if (IsCallbackRegistered(env, typeString, cbRef)) { TLOGI(WmsLogTag::DMS, "[ANI] type %{public}s callback already registered!", typeString.c_str()); + env->GlobalReference_Delete(cbRef); return; } TLOGI(WmsLogTag::DMS, "[ANI] onRegisterCallback"); @@ -217,11 +218,13 @@ void DisplayManagerAni::OnRegisterCallback(ani_env* env, ani_string type, ani_re std::string errMsg = "[ANI] failed to register display listener with type, cbk null or undefined"; TLOGE(WmsLogTag::DMS, "callbackNull or undefined"); AniErrUtils::ThrowBusinessError(env, DmErrorCode::DM_ERROR_INVALID_PARAM, errMsg); + env->GlobalReference_Delete(cbRef); return; } sptr displayAniListener = new(std::nothrow) DisplayAniListener(env); if (displayAniListener == nullptr) { TLOGE(WmsLogTag::DMS, "[ANI]displayListener is nullptr"); + env->GlobalReference_Delete(cbRef); AniErrUtils::ThrowBusinessError(env, DMError::DM_ERROR_INVALID_PARAM, "displayListener is nullptr"); return; } @@ -231,6 +234,7 @@ void DisplayManagerAni::OnRegisterCallback(ani_env* env, ani_string type, ani_re ret = ProcessRegisterCallback(env, typeString, displayAniListener); if (ret != DmErrorCode::DM_OK) { TLOGE(WmsLogTag::DMS, "[ANI] register display listener with type, errcode: %{public}d", ret); + env->GlobalReference_Delete(cbRef); std::string errMsg = "Failed to register display listener with type"; AniErrUtils::ThrowBusinessError(env, ret, errMsg); return; @@ -329,6 +333,7 @@ void DisplayManagerAni::OnUnRegisterCallback(ani_env* env, ani_string type, ani_ TLOGE(WmsLogTag::DMS, "[ANI] failed to unregister display listener with type"); AniErrUtils::ThrowBusinessError(env, DMError::DM_ERROR_INVALID_PARAM, errMsg); } + env->GlobalReference_Delete(cbRef); } DMError DisplayManagerAni::UnRegisterDisplayListenerWithType(std::string type, ani_env* env, ani_ref callback) diff --git a/interfaces/kits/ani/screen_runtime/screen_ani/src/screen_ani_listener.cpp b/interfaces/kits/ani/screen_runtime/screen_ani/src/screen_ani_listener.cpp index 5614fb54d5..b03fe40c11 100644 --- a/interfaces/kits/ani/screen_runtime/screen_ani/src/screen_ani_listener.cpp +++ b/interfaces/kits/ani/screen_runtime/screen_ani/src/screen_ani_listener.cpp @@ -97,7 +97,7 @@ void ScreenAniListener::OnConnect(ScreenId id) TLOGE(WmsLogTag::DMS, "[ANI] null env"); return; } - ani_boolean undefRes; + ani_boolean undefRes = 0; env_->Reference_IsUndefined(oneAniCallback, &undefRes); // judge is null or undefined if (undefRes) { @@ -144,7 +144,7 @@ void ScreenAniListener::OnDisconnect(ScreenId id) TLOGE(WmsLogTag::DMS, "[ANI] null env"); return; } - ani_boolean undefRes; + ani_boolean undefRes = 0; env_->Reference_IsUndefined(oneAniCallback, &undefRes); // judge is null or undefined if (undefRes) { @@ -191,7 +191,7 @@ void ScreenAniListener::OnChange(ScreenId id) TLOGE(WmsLogTag::DMS, "[ANI] null env"); return; } - ani_boolean undefRes; + ani_boolean undefRes = 0; env_->Reference_IsUndefined(oneAniCallback, &undefRes); if (undefRes) { TLOGE(WmsLogTag::DMS, "[ANI] oneAniCallback undefRes, continue"); diff --git a/interfaces/kits/ani/screen_runtime/screen_ani/src/screen_ani_manager.cpp b/interfaces/kits/ani/screen_runtime/screen_ani/src/screen_ani_manager.cpp index e904897963..8d6e357316 100644 --- a/interfaces/kits/ani/screen_runtime/screen_ani/src/screen_ani_manager.cpp +++ b/interfaces/kits/ani/screen_runtime/screen_ani/src/screen_ani_manager.cpp @@ -63,20 +63,22 @@ void ScreenManagerAni::OnRegisterCallback(ani_env* env, ani_string type, ani_ref ScreenAniUtils::GetStdString(env, type, typeString); if (env->GlobalReference_Create(callback, &cbRef) != ANI_OK) { TLOGE(WmsLogTag::DMS, "[ANI] create global ref fail"); + env->GlobalReference_Delete(cbRef); return; } std::lock_guard lock(mtx_); if (IsCallbackRegistered(env, typeString, cbRef)) { TLOGI(WmsLogTag::DMS, "[ANI] type %{public}s callback already registered!", typeString.c_str()); + env->GlobalReference_Delete(cbRef); return; } TLOGI(WmsLogTag::DMS, "[ANI] begin"); ani_boolean callbackUndefined = 0; env->Reference_IsUndefined(cbRef, &callbackUndefined); - DmErrorCode ret; if (callbackUndefined) { - std::string errMsg = "[ANI] failed to register screen listener with type, cbk null or undefined"; TLOGE(WmsLogTag::DMS, "undefined"); + env->GlobalReference_Delete(cbRef); + std::string errMsg = "[ANI] failed to register screen listener with type, cbk null or undefined"; AniErrUtils::ThrowBusinessError(env, DmErrorCode::DM_ERROR_INVALID_PARAM, errMsg); return; } @@ -84,14 +86,16 @@ void ScreenManagerAni::OnRegisterCallback(ani_env* env, ani_string type, ani_ref sptr screenAniListener = new(std::nothrow) ScreenAniListener(env); if (screenAniListener == nullptr) { TLOGE(WmsLogTag::DMS, "[ANI] screenListener is nullptr"); + env->GlobalReference_Delete(cbRef); AniErrUtils::ThrowBusinessError(env, DMError::DM_ERROR_INVALID_PARAM, "screenListener is nullptr"); return; } screenAniListener->AddCallback(typeString, cbRef); screenAniListener->SetMainEventHandler(); - ret = ProcessRegisterCallback(env, typeString, screenAniListener); + DmErrorCode ret = ProcessRegisterCallback(env, typeString, screenAniListener); if (ret != DmErrorCode::DM_OK) { TLOGE(WmsLogTag::DMS, "[ANI] register screen listener with type, errcode: %{public}d", ret); + env->GlobalReference_Delete(cbRef); std::string errMsg = "Failed to register screen listener with type"; AniErrUtils::ThrowBusinessError(env, ret, errMsg); return; @@ -188,6 +192,7 @@ DMError ScreenManagerAni::UnRegisterScreenListenerWithType(std::string type, ani if (jsCbMap_[type].empty()) { jsCbMap_.erase(type); } + env->GlobalReference_Delete(cbRef); return ret; } -- Gitee From 82e3340506c927c55a71b21a25718bcd181246ea Mon Sep 17 00:00:00 2001 From: zhangweihua Date: Tue, 29 Jul 2025 18:11:17 +0800 Subject: [PATCH 3/3] ani bugfix Signed-off-by: zhangweihua --- .../display_runtime/display_ani/src/display_ani_listener.cpp | 2 +- .../ani/display_runtime/display_ani/src/display_ani_manager.cpp | 2 +- .../ani/screen_runtime/screen_ani/src/screen_ani_manager.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/interfaces/kits/ani/display_runtime/display_ani/src/display_ani_listener.cpp b/interfaces/kits/ani/display_runtime/display_ani/src/display_ani_listener.cpp index 1646fae8bb..fc793a0c11 100644 --- a/interfaces/kits/ani/display_runtime/display_ani/src/display_ani_listener.cpp +++ b/interfaces/kits/ani/display_runtime/display_ani/src/display_ani_listener.cpp @@ -72,7 +72,7 @@ void DisplayAniListener::RemoveCallback(ani_env* env, const std::string& type, a void DisplayAniListener::RemoveAllCallback() { std::lock_guard lock(aniCallbackMtx_); - for (auto& [typeString, callbacks] : aniCallback_) { + for (const auto& [typeString, callbacks] : aniCallback_) { for (auto callback : callbacks) { if (env_) { env_->GlobalReference_Delete(callback); diff --git a/interfaces/kits/ani/display_runtime/display_ani/src/display_ani_manager.cpp b/interfaces/kits/ani/display_runtime/display_ani/src/display_ani_manager.cpp index 4f0811c733..e4d5ea360a 100644 --- a/interfaces/kits/ani/display_runtime/display_ani/src/display_ani_manager.cpp +++ b/interfaces/kits/ani/display_runtime/display_ani/src/display_ani_manager.cpp @@ -221,7 +221,7 @@ void DisplayManagerAni::OnRegisterCallback(ani_env* env, ani_string type, ani_re env->GlobalReference_Delete(cbRef); return; } - sptr displayAniListener = new(std::nothrow) DisplayAniListener(env); + sptr displayAniListener = sptr::MakeSptr(env); if (displayAniListener == nullptr) { TLOGE(WmsLogTag::DMS, "[ANI]displayListener is nullptr"); env->GlobalReference_Delete(cbRef); diff --git a/interfaces/kits/ani/screen_runtime/screen_ani/src/screen_ani_manager.cpp b/interfaces/kits/ani/screen_runtime/screen_ani/src/screen_ani_manager.cpp index 8d6e357316..e81507856d 100644 --- a/interfaces/kits/ani/screen_runtime/screen_ani/src/screen_ani_manager.cpp +++ b/interfaces/kits/ani/screen_runtime/screen_ani/src/screen_ani_manager.cpp @@ -58,6 +58,7 @@ void ScreenManagerAni::UnRegisterCallback(ani_env* env, ani_string type, ani_lon void ScreenManagerAni::OnRegisterCallback(ani_env* env, ani_string type, ani_ref callback) { + TLOGI(WmsLogTag::DMS, "[ANI] begin"); ani_ref cbRef{}; std::string typeString; ScreenAniUtils::GetStdString(env, type, typeString); @@ -72,7 +73,6 @@ void ScreenManagerAni::OnRegisterCallback(ani_env* env, ani_string type, ani_ref env->GlobalReference_Delete(cbRef); return; } - TLOGI(WmsLogTag::DMS, "[ANI] begin"); ani_boolean callbackUndefined = 0; env->Reference_IsUndefined(cbRef, &callbackUndefined); if (callbackUndefined) { -- Gitee