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 8cf431404d1b219a0c957beddccf61483eb4b9c0..4f99569c2f46ee12245f56a824f33797f7f33f2a 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 de5515815a99b8b72cd0a967eb3400199bc7ae04..42f4e6721245715e9a406b1a247d455f20d3c0a9 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 0e0df5fc1ffe8f5659be81436cc523be07512514..db16a55bcaca8f43c27815cd09a9f0b992d3aa56 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 5ea5565237b244752254979b3e2810093320efa6..49590eb0638607deba781c16bf48a1b79874d010 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 7178d018395d4aebc39058faaef274618a5468fc..fc793a0c11c01d9b38d605424f960f5b8fb78f1c 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())); } @@ -77,6 +72,13 @@ void DisplayAniListener::RemoveCallback(ani_env* env, const std::string& type, a void DisplayAniListener::RemoveAllCallback() { std::lock_guard lock(aniCallbackMtx_); + for (const auto& [typeString, callbacks] : aniCallback_) { + for (auto callback : callbacks) { + if (env_) { + env_->GlobalReference_Delete(callback); + } + } + } aniCallback_.clear(); } @@ -107,11 +109,9 @@ void DisplayAniListener::OnCreate(DisplayId id) return; } ani_boolean undefRes = 0; - ani_boolean nullRes = 0; 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] { @@ -154,11 +154,9 @@ void DisplayAniListener::OnDestroy(DisplayId id) return; } ani_boolean undefRes = 0; - ani_boolean nullRes = 0; 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] { @@ -198,11 +196,9 @@ void DisplayAniListener::OnChange(DisplayId id) return; } ani_boolean undefRes = 0; - ani_boolean nullRes = 0; 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 160affb2b2f6072386b0e77c81bb7b52e61d5651..e4d5ea360a66684883bab239c580c92575bea95b 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,29 +197,34 @@ 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()); + env->GlobalReference_Delete(cbRef); + 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); + env->GlobalReference_Delete(cbRef); 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); + sptr displayAniListener = sptr::MakeSptr(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,12 +234,30 @@ 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; } // 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 +305,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) { @@ -307,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) @@ -360,7 +387,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 +417,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 d6b050eab368042478d172e1106379e9e8df149e..374ae6e506048450af0ebad779cb33c64520feee 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 61fca6915c88bc0d66fb90d0dc66109f0b0d5067..4606502229b010b338ff2183ccdf3369b004f109 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 47ace25c35e7aac826c91945ea4a2d27b6fcd76b..0f9c197337c60d2ad56eefb051942939c4cd5919 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 945efbefbd9028385bd5ccee1fd7e75fd90ee211..b03fe40c1163b9202f8f72c3508a53837e695445 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())); } @@ -103,12 +98,10 @@ void ScreenAniListener::OnConnect(ScreenId id) return; } ani_boolean undefRes = 0; - ani_boolean nullRes = 0; 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; } @@ -152,12 +145,10 @@ void ScreenAniListener::OnDisconnect(ScreenId id) return; } ani_boolean undefRes = 0; - ani_boolean nullRes = 0; 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,7 +185,6 @@ 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) { @@ -203,21 +192,21 @@ void ScreenAniListener::OnChange(ScreenId id) return; } ani_boolean undefRes = 0; - ani_boolean nullRes = 0; 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 3d0ec5aff5aff9577bf92c3ff75fca87617063c7..e81507856d6db964ea4f7be886c9864a99c81894 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 @@ -59,43 +59,49 @@ 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"); + 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; + } ani_boolean callbackUndefined = 0; - ani_boolean callbackIsNull = 0; - env->Reference_IsUndefined(callback, &callbackUndefined); - env->Reference_IsNull(callback, &callbackIsNull); - DmErrorCode ret; - if (callbackUndefined || callbackIsNull) { + env->Reference_IsUndefined(cbRef, &callbackUndefined); + if (callbackUndefined) { + TLOGE(WmsLogTag::DMS, "undefined"); + env->GlobalReference_Delete(cbRef); std::string errMsg = "[ANI] failed to register screen 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 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; } // add listener to map - jsCbMap_[typeString][callback] = screenAniListener; + jsCbMap_[typeString][cbRef] = screenAniListener; } DmErrorCode ScreenManagerAni::ProcessRegisterCallback(ani_env* env, std::string& typeStr, @@ -116,10 +122,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 +144,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 +185,14 @@ 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); + } + env->GlobalReference_Delete(cbRef); 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 f16352c8680a6bb48882f66bb6650cde68ba9dc4..9699f2d6fa30965479cc30ae151a2084aa59bbf9 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;