From 79734d136338e1535f1ba1b296cac00199bd378a Mon Sep 17 00:00:00 2001 From: dongzhili Date: Wed, 27 Aug 2025 14:16:13 +0800 Subject: [PATCH 1/7] =?UTF-8?q?=E8=93=9D=E9=BB=84=E5=90=8C=E6=AD=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: dongzhili --- .../window_stage_ani/ets/@ohos.window.ets | 55 +++++---- .../window_stage_ani/include/ani_window.h | 9 +- .../include/ani_window_listener.h | 1 + .../include/ani_window_register_manager.h | 4 +- .../include/ani_window_stage.h | 6 +- .../window_stage_ani/src/ani_err_utils.cpp | 21 ++-- .../window_stage_ani/src/ani_window.cpp | 109 ++++++++++-------- .../src/ani_window_register_manager.cpp | 17 ++- .../window_stage_ani/src/ani_window_stage.cpp | 71 ++++++------ 9 files changed, 163 insertions(+), 130 deletions(-) diff --git a/interfaces/kits/ani/window_runtime/window_stage_ani/ets/@ohos.window.ets b/interfaces/kits/ani/window_runtime/window_stage_ani/ets/@ohos.window.ets index 0db7a3c861..84758397d0 100644 --- a/interfaces/kits/ani/window_runtime/window_stage_ani/ets/@ohos.window.ets +++ b/interfaces/kits/ani/window_runtime/window_stage_ani/ets/@ohos.window.ets @@ -1137,28 +1137,43 @@ export interface WindowLimits { export class WindowStageInternal implements WindowStage { static { loadLibrary('windowstageani_kit.z') } - private nativeObj : long; + private nativeObj: long = 0; setNativeObj(nativeObj: long):void { this.nativeObj = nativeObj; } - public native loadContent(nativeObj:long, path: String): int; + public native loadContentSync(nativeObj: long, path: string, storage?: LocalStorage): void; public native disableWindowDecorSync(nativeObj:long): void; public native setShowOnLockScreenSync(nativeObj:long, showOnLockScreen: boolean): void; public native getMainWindowSync(nativeObj: long): Window; - public loadContent(path: string, callback: AsyncCallback): void { - // uicontent not support taskpool, must use ui thread - let ret = this.loadContent(this.nativeObj, String(path)); - if (ret == WMError_WM_DO_NOTHING) { - throw {code: WmErrorCode_WM_ERROR_STAGE_ABNORMALLY, message: - "This window state is abnormal."} as BusinessError; - } else if (ret == WMError_WM_ERROR_INVALID_PARAM) { - throw {code: WmErrorCode_WM_ERROR_INVALID_PARAM, message: - "Parameter error. Possible cause: 1. Mandatory parameters are left unspecified; " + - "2. Incorrect parameter types."} as BusinessError; + public loadContent(path: string, storage: LocalStorage, callback: AsyncCallback): void { + try { + this.loadContentSync(this.nativeObj, path, storage); + callback(new BusinessError(), undefined); + } catch (err: Error) { + callback(err as BusinessError, undefined); + } + } + + public loadContent(path: string, storage?: LocalStorage): Promise { + return new Promise((resolve: (value: undefined) => void, reject: (error: BusinessError) => void): void => { + try { + this.loadContentSync(this.nativeObj, path, storage); + resolve(undefined); + } catch (err: Error) { + reject(err as BusinessError); } - callback({code: WmErrorCode_WM_OK, message: ""} as BusinessError, undefined); + }); + } + + public loadContent(path: string, callback: AsyncCallback): void { + try { + this.loadContentSync(this.nativeObj, path, undefined); + callback(new BusinessError(), undefined); + } catch (err: Error) { + callback(err as BusinessError, undefined); + } } public loadContentByName(name: string, callback: AsyncCallbackVoid): void { @@ -1306,9 +1321,9 @@ export class WindowInternal implements Window { } public setWindowBackgroundColor(color: string | ColorMetrics): void { - if (color instanceof string) { - this.setWindowBackgroundColor(this.nativeObj, color as string); - } + if (color instanceof string) { + this.setWindowBackgroundColor(this.nativeObj, color as string); + } } public setBackgroundColor(color: string): Promise { @@ -1582,7 +1597,7 @@ export class WindowInternal implements Window { public loadContent(path: string): Promise { return new Promise((resolve: (value: undefined) => void, reject: (error: BusinessError) => void): void => { try { - this.loadContentSync(this.nativeObj, path); + this.loadContentSync(this.nativeObj, path, undefined); resolve(undefined); } catch (err: Error) { reject(err as BusinessError); @@ -1592,7 +1607,7 @@ export class WindowInternal implements Window { public loadContent(path: string, callback: AsyncCallback): void { try { - this.loadContentSync(this.nativeObj, path); + this.loadContentSync(this.nativeObj, path, undefined); callback(new BusinessError(), undefined); } catch (err: Error) { callback(err as BusinessError, undefined); @@ -1735,8 +1750,8 @@ export function CreateWindowStageApi(scene: long): WindowStage { return CreateWi export native function CreateWindow(window: long): WindowInternal; let nativeObj: long; -function setNativeObj(nativeObj: long):void { - nativeObj = nativeObj; +export function setNativeObj(nativeObject: long):void { + nativeObj = nativeObject; } native function getLastWindowSync(nativeObj: long, ctx: BaseContext): Window; diff --git a/interfaces/kits/ani/window_runtime/window_stage_ani/include/ani_window.h b/interfaces/kits/ani/window_runtime/window_stage_ani/include/ani_window.h index 8ca8f34b54..89d8b6d011 100644 --- a/interfaces/kits/ani/window_runtime/window_stage_ani/include/ani_window.h +++ b/interfaces/kits/ani/window_runtime/window_stage_ani/include/ani_window.h @@ -34,6 +34,8 @@ public: explicit AniWindow(const sptr& window); explicit AniWindow(const std::shared_ptr& window); sptr GetWindow() { return windowToken_; } + ani_ref GetAniRef() { return aniRef_; } + void SetAniRef(const ani_ref& aniRef) { aniRef_ = aniRef; } /* window obj stored in ANI */ static AniWindow* GetWindowObjectFromEnv(ani_env* env, ani_object obj); @@ -45,8 +47,7 @@ public: static void SetUIContent(ani_env* env, ani_object obj, ani_long nativeObj, ani_string path); static void SetWindowKeepScreenOn(ani_env* env, ani_object obj, ani_long nativeObj, ani_boolean isKeepScreenOn); static void SetWaterMarkFlag(ani_env* env, ani_object obj, ani_long nativeObj, ani_boolean enable); - static void LoadContent(ani_env* env, ani_object obj, ani_long nativeObj, ani_string path); - static void LoadContentNew(ani_env* env, ani_object obj, ani_long nativeObj, + static void LoadContent(ani_env* env, ani_object obj, ani_long nativeObj, ani_string path, ani_object storage); static void SetWindowSystemBarEnable(ani_env* env, ani_object obj, ani_long nativeObj, ani_object nameAry); static ani_object GetUIContext(ani_env* env, ani_object obj, ani_long nativeObj); @@ -100,11 +101,13 @@ private: sptr windowToken_ = nullptr; std::unique_ptr registerManager_ = nullptr; + ani_ref aniRef_ = nullptr; }; /* window obj stored in ANI */ AniWindow* GetWindowObjectFromAni(void* aniObj); -ani_object CreateAniWindowObject(ani_env* env, sptr& window); +ani_ref CreateAniWindowObject(ani_env* env, sptr& window); +ani_ref FindAniWindowObject(const std::string& windowName); void DropWindowObjectByAni(ani_object obj); ani_status ANI_Window_Constructor(ani_vm *vm, uint32_t *result); } // namespace Rosen diff --git a/interfaces/kits/ani/window_runtime/window_stage_ani/include/ani_window_listener.h b/interfaces/kits/ani/window_runtime/window_stage_ani/include/ani_window_listener.h index 4225d6d291..6f9ae0b839 100644 --- a/interfaces/kits/ani/window_runtime/window_stage_ani/include/ani_window_listener.h +++ b/interfaces/kits/ani/window_runtime/window_stage_ani/include/ani_window_listener.h @@ -76,6 +76,7 @@ public: : env_(env), aniCallBack_(callback), caseType_(caseType), weakRef_(wptr (this)) {} ~AniWindowListener(); + ani_ref GetAniCallBack() { return aniCallBack_; } void OnSystemBarPropertyChange(DisplayId displayId, const SystemBarRegionTints& tints) override; void OnSizeChange(Rect rect, WindowSizeChangeReason reason, const std::shared_ptr& rsTransaction = nullptr) override; diff --git a/interfaces/kits/ani/window_runtime/window_stage_ani/include/ani_window_register_manager.h b/interfaces/kits/ani/window_runtime/window_stage_ani/include/ani_window_register_manager.h index b496834588..84b7a06833 100644 --- a/interfaces/kits/ani/window_runtime/window_stage_ani/include/ani_window_register_manager.h +++ b/interfaces/kits/ani/window_runtime/window_stage_ani/include/ani_window_register_manager.h @@ -54,9 +54,9 @@ class AniWindowRegisterManager { public: AniWindowRegisterManager(); ~AniWindowRegisterManager(); - WmErrorCode RegisterListener(sptr window, std::string type, + WmErrorCode RegisterListener(sptr window, const std::string& type, CaseType caseType, ani_env* env, ani_ref callback); - WmErrorCode UnregisterListener(sptr window, std::string type, + WmErrorCode UnregisterListener(sptr window, const std::string& type, CaseType caseType, ani_env* env, ani_ref callback); private: bool IsCallbackRegistered(ani_env* env, std::string type, ani_ref jsListenerObject); diff --git a/interfaces/kits/ani/window_runtime/window_stage_ani/include/ani_window_stage.h b/interfaces/kits/ani/window_runtime/window_stage_ani/include/ani_window_stage.h index ad0c6063e6..efd0c6c469 100644 --- a/interfaces/kits/ani/window_runtime/window_stage_ani/include/ani_window_stage.h +++ b/interfaces/kits/ani/window_runtime/window_stage_ani/include/ani_window_stage.h @@ -31,14 +31,16 @@ class AniWindowStage { public: explicit AniWindowStage(const std::shared_ptr& windowScene); ~AniWindowStage(); + static void LoadContent(ani_env* env, ani_object obj, ani_long nativeObj, + ani_string path, ani_object storage); static void DisableWindowDecor(ani_env* env, ani_object obj, ani_long nativeObj); static void SetShowOnLockScreen(ani_env* env, ani_class cls, ani_long nativeObj, ani_boolean showOnLockScreen); - void LoadContent(ani_env* env, const std::string& content); std::weak_ptr GetWindowScene() { return windowScene_; } - ani_object GetMainWindow(ani_env* env); + ani_ref GetMainWindow(ani_env* env); ani_boolean WindowIsWindowSupportWideGamut(ani_env* env, ani_class cls, ani_object obj); private: + void OnLoadContent(ani_env* env, ani_string path, ani_object storage); void OnDisableWindowDecor(ani_env* env); void OnSetShowOnLockScreen(ani_env* env, ani_boolean showOnLockScreen); std::weak_ptr windowScene_; diff --git a/interfaces/kits/ani/window_runtime/window_stage_ani/src/ani_err_utils.cpp b/interfaces/kits/ani/window_runtime/window_stage_ani/src/ani_err_utils.cpp index c984078fc4..17126c5de6 100644 --- a/interfaces/kits/ani/window_runtime/window_stage_ani/src/ani_err_utils.cpp +++ b/interfaces/kits/ani/window_runtime/window_stage_ani/src/ani_err_utils.cpp @@ -216,38 +216,31 @@ ani_status AniErrUtils::ThrowBusinessError(ani_env* env, WmErrorCode error, std: ani_status AniErrUtils::CreateBusinessError(ani_env* env, int32_t error, std::string message, ani_object* err) { - TLOGI(WmsLogTag::DEFAULT, "[ANI] in2"); + TLOGI(WmsLogTag::DEFAULT, "[ANI] in"); ani_class aniClass; - ani_status status = env->FindClass("L@ohos/window/window/BusinessErrorInternal;", &aniClass); + ani_status status = env->FindClass("L@ohos/base/BusinessError;", &aniClass); if (status != ANI_OK) { TLOGE(WmsLogTag::DEFAULT, "[ANI] class not found, status:%{public}d", static_cast(status)); return status; } ani_method aniCtor; - status = env->Class_FindMethod(aniClass, "", ":V", &aniCtor); + status = env->Class_FindMethod(aniClass, "", "Lstd/core/String;Lescompat/ErrorOptions;:V", &aniCtor); if (status != ANI_OK) { TLOGE(WmsLogTag::DEFAULT, "[ANI] ctor not found, status:%{public}d", static_cast(status)); return status; } - status = env->Object_New(aniClass, aniCtor, err); + ani_string aniMsg; + AniWindowUtils::GetAniString(env, message, &aniMsg); + status = env->Object_New(aniClass, aniCtor, err, aniMsg, AniWindowUtils::CreateAniUndefined(env)); if (status != ANI_OK) { TLOGE(WmsLogTag::DEFAULT, "[ANI] fail to new err, status:%{public}d", static_cast(status)); return status; } - ani_object aniCode; - AniWindowUtils::NewAniObject(env, "Lstd/core/Double;", "D:V", &aniCode, ani_double(static_cast(error))); - status = env->Object_SetFieldByName_Ref(*err, "code", static_cast(aniCode)); + status = env->Object_SetFieldByName_Double(*err, "code", static_cast(error)); if (status != ANI_OK) { TLOGE(WmsLogTag::DEFAULT, "[ANI] fail to set code, status:%{public}d", static_cast(status)); return status; } - ani_string aniMsg; - AniWindowUtils::GetAniString(env, message, &aniMsg); - status = env->Object_SetFieldByName_Ref(*err, "message", static_cast(aniMsg)); - if (status != ANI_OK) { - TLOGE(WmsLogTag::DEFAULT, "[ANI] fail to set message, status:%{public}d", static_cast(status)); - return status; - } return ANI_OK; } diff --git a/interfaces/kits/ani/window_runtime/window_stage_ani/src/ani_window.cpp b/interfaces/kits/ani/window_runtime/window_stage_ani/src/ani_window.cpp index 3abd7b9757..bf8cb9147a 100644 --- a/interfaces/kits/ani/window_runtime/window_stage_ani/src/ani_window.cpp +++ b/interfaces/kits/ani/window_runtime/window_stage_ani/src/ani_window.cpp @@ -17,6 +17,7 @@ #include #include +#include #include "ani.h" #include "ani_err_utils.h" @@ -35,8 +36,9 @@ constexpr int32_t MIN_DECOR_HEIGHT = 37; constexpr int32_t MAX_DECOR_HEIGHT = 112; namespace { /* used for free, ani has no destructor right now, only free when aniObj freed */ -static std::map localObjs; +static std::map localObjs; } // namespace +static thread_local std::map g_aniWindowMap; AniWindow::AniWindow(const sptr& window) : windowToken_(window), registerManager_(std::make_unique()) @@ -137,7 +139,11 @@ void AniWindow::OnSetWindowPrivacyMode(ani_env* env, ani_boolean isPrivacyMode) AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); return; } - auto ret = window->SetPrivacyMode(static_cast(isPrivacyMode)); + auto ret = WM_JS_TO_ERROR_CODE_MAP.at(window->SetPrivacyMode(static_cast(isPrivacyMode))); + if (ret != WmErrorCode::WM_OK) { + TLOGE(WmsLogTag::WMS_ANIMATION, "[ANI] failed"); + AniWindowUtils::AniThrowError(env, ret); + } TLOGI(WmsLogTag::DEFAULT, "[ANI] ret:%{public}d", static_cast(ret)); } @@ -253,36 +259,7 @@ void AniWindow::OnSetWaterMarkFlag(ani_env* env, ani_boolean enable) } } -void AniWindow::LoadContent(ani_env* env, ani_object obj, ani_long nativeObj, ani_string path) -{ - TLOGI(WmsLogTag::DEFAULT, "[ANI]"); - AniWindow* aniWindow = reinterpret_cast(nativeObj); - if (aniWindow != nullptr) { - aniWindow->OnLoadContent(env, path); - } else { - TLOGE(WmsLogTag::DEFAULT, "[ANI] aniWindow is nullptr"); - } -} - -void AniWindow::OnLoadContent(ani_env* env, ani_string path) -{ - TLOGI(WmsLogTag::DEFAULT, "[ANI]"); - auto window = GetWindow(); - if (window == nullptr) { - TLOGE(WmsLogTag::DEFAULT, "[ANI] window is nullptr"); - AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); - return; - } - std::string contentPath; - AniWindowUtils::GetStdString(env, path, contentPath); - TLOGI(WmsLogTag::DEFAULT, "[ANI] contentPath:%{public}s", contentPath.c_str()); - WmErrorCode ret = WM_JS_TO_ERROR_CODE_MAP.at(window->NapiSetUIContent(contentPath, env, nullptr)); - if (ret != WmErrorCode::WM_OK) { - AniWindowUtils::AniThrowError(env, ret, "Window load content failed"); - } -} - -void AniWindow::LoadContentNew(ani_env* env, ani_object obj, ani_long nativeObj, ani_string path, +void AniWindow::LoadContent(ani_env* env, ani_object obj, ani_long nativeObj, ani_string path, ani_object storage) { TLOGI(WmsLogTag::DEFAULT, "[ANI]"); @@ -305,8 +282,7 @@ void AniWindow::OnLoadContent(ani_env* env, ani_string path, ani_object storage) } std::string contentPath; AniWindowUtils::GetStdString(env, path, contentPath); - WmErrorCode ret = WM_JS_TO_ERROR_CODE_MAP.at(window->NapiSetUIContent(contentPath, (napi_env)env, - (napi_value)storage)); + WmErrorCode ret = WM_JS_TO_ERROR_CODE_MAP.at(window->NapiSetUIContent(contentPath, env, storage)); if (ret != WmErrorCode::WM_OK) { AniWindowUtils::AniThrowError(env, ret, "Window load content failed"); } @@ -445,8 +421,7 @@ ani_object AniWindow::OnGetUIContext(ani_env* env) TLOGE(WmsLogTag::DEFAULT, "[ANI] uicontent is nullptr"); return AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); } - // 依赖arkui uicontent->GetUINapiContext(); - return AniWindowUtils::CreateAniUndefined(env); + return uicontent->GetUIAniContext(); } ani_object AniWindow::GetWindowAvoidArea(ani_env* env, ani_object obj, ani_long nativeObj, ani_int type) @@ -469,9 +444,9 @@ ani_object AniWindow::OnGetWindowAvoidArea(ani_env* env, ani_int type) return AniWindowUtils::CreateAniAvoidArea(env, avoidArea, static_cast(type)); } -void DropWindowObjectByAni(ani_object aniObj) +void DropWindowObjectByAni(ani_ref aniObj) { - auto obj = localObjs.find(reinterpret_cast(aniObj)); + auto obj = localObjs.find(reinterpret_cast(aniObj)); if (obj != localObjs.end()) { delete obj->second; } @@ -480,22 +455,29 @@ void DropWindowObjectByAni(ani_object aniObj) AniWindow* GetWindowObjectFromAni(void* aniObj) { - auto obj = localObjs.find(reinterpret_cast(aniObj)); + auto obj = localObjs.find(reinterpret_cast(aniObj)); if (obj == localObjs.end()) { return nullptr; } return obj->second; } -ani_object CreateAniWindowObject(ani_env* env, sptr& window) +ani_ref CreateAniWindowObject(ani_env* env, sptr& window) __attribute__((no_sanitize("cfi"))) { - if (env == nullptr) { - TLOGE(WmsLogTag::DEFAULT, "[ANI] null env"); + if (env == nullptr || window == nullptr) { + TLOGE(WmsLogTag::DEFAULT, "[ANI] invalid env or window"); return nullptr; } - TLOGD(WmsLogTag::DEFAULT, "[ANI] create window obj"); - + std::string windowName = window->GetWindowName(); + // avoid repeatedly create ani window when getWindow + ani_ref aniWindowObj = FindAniWindowObject(windowName); + if (aniWindowObj != nullptr) { + TLOGI(WmsLogTag::DEFAULT, "[ANI] FindAniWindowObject %{public}s", windowName.c_str()); + return aniWindowObj; + } + TLOGI(WmsLogTag::DEFAULT, "[ANI] create window obj"); + ani_status ret; ani_class cls = nullptr; if ((ret = env->FindClass("L@ohos/window/window/WindowInternal;", &cls)) != ANI_OK) { @@ -503,7 +485,7 @@ __attribute__((no_sanitize("cfi"))) return nullptr; } std::unique_ptr aniWindow = std::make_unique(window); - + ani_method initFunc = nullptr; if ((ret = env->Class_FindMethod(cls, "", ":V", &initFunc)) != ANI_OK) { TLOGE(WmsLogTag::DEFAULT, "[ANI] get ctor fail %{public}u", ret); @@ -519,7 +501,12 @@ __attribute__((no_sanitize("cfi"))) TLOGE(WmsLogTag::DEFAULT, "[ANI] get ctor fail %{public}u", ret); return nullptr; } - env->Object_CallMethod_Void(obj, setObjFunc, aniWindow.get()); + env->Object_CallMethod_Void(obj, setObjFunc, reinterpret_cast(aniWindow.get())); + ani_ref ref = nullptr; + if (env->GlobalReference_Create(obj, &ref) != ANI_OK) { + TLOGE(WmsLogTag::DEFAULT, "[ANI] create global ref fail"); + return nullptr; + }; localObjs.insert(std::pair(obj, aniWindow.release())); return obj; } @@ -867,6 +854,32 @@ ani_object AniWindow::SetSpecificSystemBarEnabled(ani_env* env, ani_string name, TLOGE(WmsLogTag::WMS_IMMS, "SetSpecificSystemBarEnabled failed, ret = %{public}d", err); return AniWindowUtils::AniThrowError(env, err); } + +ani_ref FindAniWindowObject(const std::string& windowName) +{ + TLOGI(WmsLogTag::DEFAULT, "[ANI] Try to find window %{public}s in g_aniWindowMap", windowName.c_str()); + if (g_aniWindowMap.find(windowName) == g_aniWindowMap.end()) { + TLGI(WmsLogTag::DEFAULT, "[ANI] Can not find window %{public}s in g_aniWindowMap", windowName.c_str()); + return nullptr; + } + return g_aniWindowMap[windowName]; +} + +void AniWindow::Finalizer(ani_env* env, ani_long nativeObj) +{ + TLOGI(WmsLogTag::DEFAULT, "[ANI]"); + AniWindow* aniWindow = reinterpret_cast(nativeObj); + if (aniWindow != nullptr) { + auto window = aniWindow->GetWindow(); + if (window != nullptr) { + g_aniWindowMap.erase(window->GetWindowName()); + } + DropWindowObjectByAni(aniWindow->GetAniRef()); + env->GlobalReference_Delete(aniWindow->GetAniRef()); + } else { + TLOGE(WmsLogTag::DEFAULT, "[ANI] aniWindow is nullptr"); + } +} } // namespace Rosen } // namespace OHOS @@ -1161,11 +1174,9 @@ ani_status OHOS::Rosen::ANI_Window_Constructor(ani_vm *vm, uint32_t *result) reinterpret_cast(AniWindow::Recover)}, ani_native_function {"setUIContentSync", "JLstd/core/String;:V", reinterpret_cast(AniWindow::SetUIContent)}, - ani_native_function {"loadContentSync", "JLstd/core/String;:V", - reinterpret_cast(AniWindow::LoadContent)}, ani_native_function {"loadContentSync", "JLstd/core/String;Larkui/stateManagement/storages/localStorage/LocalStorage;:V", - reinterpret_cast(AniWindow::LoadContentNew)}, + reinterpret_cast(AniWindow::LoadContent)}, ani_native_function {"setWindowKeepScreenOnSync", "JZ:V", reinterpret_cast(AniWindow::SetWindowKeepScreenOn)}, ani_native_function {"setWindowSystemBarEnableSync", "JLescompat/Array;:V", diff --git a/interfaces/kits/ani/window_runtime/window_stage_ani/src/ani_window_register_manager.cpp b/interfaces/kits/ani/window_runtime/window_stage_ani/src/ani_window_register_manager.cpp index 9fe4c446be..20b0924f53 100644 --- a/interfaces/kits/ani/window_runtime/window_stage_ani/src/ani_window_register_manager.cpp +++ b/interfaces/kits/ani/window_runtime/window_stage_ani/src/ani_window_register_manager.cpp @@ -347,7 +347,7 @@ bool AniWindowRegisterManager::IsCallbackRegistered(ani_env* env, std::string ty return false; } -WmErrorCode AniWindowRegisterManager::RegisterListener(sptr window, std::string type, +WmErrorCode AniWindowRegisterManager::RegisterListener(sptr window, const std::string& type, CaseType caseType, ani_env* env, ani_ref callback) { std::lock_guard lock(mtx_); @@ -469,16 +469,16 @@ WmErrorCode AniWindowRegisterManager::ProcessListener(RegisterListenerType regis const sptr& windowManagerListener, const sptr& window, bool isRegister, ani_env* env) { if (caseType == CaseType::CASE_WINDOW_MANAGER) { - ProcessWindowManagerListener(registerListenerType, windowManagerListener, window, isRegister, env); + return ProcessWindowManagerListener(registerListenerType, windowManagerListener, window, isRegister, env); } else if (caseType == CaseType::CASE_WINDOW) { - ProcessWindowListener(registerListenerType, windowManagerListener, window, isRegister, env); + return ProcessWindowListener(registerListenerType, windowManagerListener, window, isRegister, env); } else if (caseType == CaseType::CASE_STAGE) { - ProcessWindowStageListener(registerListenerType, windowManagerListener, window, isRegister, env); + return ProcessWindowStageListener(registerListenerType, windowManagerListener, window, isRegister, env); } return WmErrorCode::WM_OK; } -WmErrorCode AniWindowRegisterManager::UnregisterListener(sptr window, std::string type, +WmErrorCode AniWindowRegisterManager::UnregisterListener(sptr window, const std::string& type, CaseType caseType, ani_env* env, ani_ref callback) { std::lock_guard lock(mtx_); @@ -497,13 +497,17 @@ WmErrorCode AniWindowRegisterManager::UnregisterListener(sptr window, st return WmErrorCode::WM_ERROR_STATE_ABNORMALLY; } RegisterListenerType listenerType = iterCallbackType->second; - if (callback == nullptr) { + ani_boolean isUndef = ANI_FALSE; + env->Reference_IsUndefined(callback, &isUndef); + if (isUndef == ANI_TRUE) { + TLOGI(WmsLogTag::DEFAULT, "[ANI]Unregister all callbck, type:%{public}s", type.c_str()); for (auto it = jsCbMap_[type].begin(); it != jsCbMap_[type].end();) { WmErrorCode ret = ProcessListener(listenerType, caseType, it->second, window, false, env); if (ret != WmErrorCode::WM_OK) { TLOGE(WmsLogTag::DEFAULT, "[ANI]Unregister type %{public}s failed, no value", type.c_str()); return ret; } + env->GlobalReference_Delete(it->second->GetAniCallBack()); jsCbMap_[type].erase(it++); } } else { @@ -511,6 +515,7 @@ WmErrorCode AniWindowRegisterManager::UnregisterListener(sptr window, st for (auto it = jsCbMap_[type].begin(); it != jsCbMap_[type].end(); ++it) { ani_boolean isEquals = 0; env->Reference_StrictEquals(callback, it->first, &isEquals); + TLOGI(WmsLogTag::DEFAULT, "[ANI]callback isEquals:%{public}d", static_cast(isEquals)); if (!isEquals) { continue; } diff --git a/interfaces/kits/ani/window_runtime/window_stage_ani/src/ani_window_stage.cpp b/interfaces/kits/ani/window_runtime/window_stage_ani/src/ani_window_stage.cpp index a022dc288e..72d6673085 100644 --- a/interfaces/kits/ani/window_runtime/window_stage_ani/src/ani_window_stage.cpp +++ b/interfaces/kits/ani/window_runtime/window_stage_ani/src/ani_window_stage.cpp @@ -44,18 +44,44 @@ AniWindowStage::~AniWindowStage() TLOGE(WmsLogTag::DEFAULT, "[ANI] Ani WindowStage died"); } -void AniWindowStage::LoadContent(ani_env* env, const std::string& content) +void AniWindowStage::LoadContent(ani_env* env, ani_object obj, ani_long nativeObj, ani_string path, + ani_object storage) { - auto weakScene = windowScene_.lock(); - sptr win = weakScene ? weakScene->GetMainWindow() : nullptr; - if (win == nullptr) { - TLOGE(WmsLogTag::DEFAULT, "[NAPI]Get window failed"); + TLOGI(WmsLogTag::WMS_LIFE, "[ANI]"); + AniWindowStage* aniWindowStage = reinterpret_cast(nativeObj); + if (aniWindowStage != nullptr) { + aniWindowStage->OnLoadContent(env, path, storage); + } else { + TLOGE(WmsLogTag::WMS_LIFE, "[ANI] aniWindowStage is nullptr"); + } +} + +void AniWindowStage::OnLoadContent(ani_env* env, ani_string path, ani_object storage) +{ + TLOGI(WmsLogTag::WMS_LIFE, "[ANI]"); + auto windowScene = GetWindowScene().lock(); + if (windowScene == nullptr) { + TLOGE(WmsLogTag::WMS_LIFE, "[ANI]windowScene is nullptr!"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); return; } - win->NapiSetUIContent(content, env, nullptr); + auto mainWindow = windowScene->GetMainWindow(); + if (mainWindow == nullptr) { + TLOGE(WmsLogTag::WMS_LIFE, "[ANI] mainWindow is nullptr!"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); + return; + } + std::string contentPath; + AniWindowUtils::GetStdString(env, path, contentPath); + WmErrorCode ret = WM_JS_TO_ERROR_CODE_MAP.at(mainWindow->NapiSetUIContent(contentPath, env, storage)); + TLOGI(WmsLogTag::WMS_LIFE, "[ANI] Window [%{public}u, %{public}s] load content end, ret=%{public}d", + mainWindow->GetWindowId(), mainWindow->GetWindowName().c_str(), ret); + if (ret != WmErrorCode::WM_OK) { + AniWindowUtils::AniThrowError(env, ret, "Window load content failed"); + } } -ani_object AniWindowStage::GetMainWindow(ani_env* env) +ani_ref AniWindowStage::GetMainWindow(ani_env* env) { TLOGI(WmsLogTag::DEFAULT, "[ANI] Get main window"); std::shared_ptr weakScene = windowScene_.lock(); @@ -93,15 +119,6 @@ AniWindowStage* GetWindowStageFromAni(void* aniObj) return obj->second; } -static void GetStdString(ani_env* env, ani_string str, std::string& result) -{ - ani_size sz {}; - env->String_GetUTF8Size(str, &sz); - result.resize(sz + 1); - env->String_GetUTF8SubString(str, 0, sz, result.data(), result.size(), &sz); - result.resize(sz); -} - ani_object CreateAniWindowStage(ani_env* env, std::shared_ptr& windowScene) __attribute__((no_sanitize("cfi"))) { @@ -119,11 +136,6 @@ __attribute__((no_sanitize("cfi"))) } std::unique_ptr windowStage = std::make_unique(windowScene); - ani_field contextField; - if ((ret = env->Class_FindField(cls, "nativeObj", &contextField)) != ANI_OK) { - TLOGE(WmsLogTag::DEFAULT, "[ANI] get field fail %{public}u", ret); - return nullptr; - } ani_method initFunc = nullptr; if ((ret = env->Class_FindMethod(cls, "", ":V", &initFunc)) != ANI_OK) { @@ -229,17 +241,6 @@ void AniWindowStage::OnSetShowOnLockScreen(ani_env* env, ani_boolean showOnLockS } // namespace Rosen } // namespace OHOS -static ani_int WindowStageLoadContent(ani_env* env, ani_object obj, - ani_long nativeObj, ani_string content) -{ - using namespace OHOS::Rosen; - AniWindowStage* windowStage = reinterpret_cast(nativeObj); - std::string contentStr; - GetStdString(env, content, contentStr); - windowStage->LoadContent(env, contentStr); - return (ani_int)0u; -} - static ani_object WindowStageCreate(ani_env* env, ani_long scene) { using namespace OHOS::Rosen; @@ -247,7 +248,7 @@ static ani_object WindowStageCreate(ani_env* env, ani_long scene) return CreateAniWindowStage(env, scenePtr); // just for test } -static ani_object WindowGetMainWindow(ani_env* env, ani_object obj, ani_long nativeObj) +static ani_ref WindowGetMainWindow(ani_env* env, ani_object obj, ani_long nativeObj) { using namespace OHOS::Rosen; TLOGD(WmsLogTag::DEFAULT, "[ANI]"); @@ -276,7 +277,9 @@ ANI_EXPORT ani_status ANI_Constructor(ani_vm *vm, uint32_t *result) return ANI_NOT_FOUND; } std::array methods = { - ani_native_function {"loadContent", "JLstd/core/String;:I", reinterpret_cast(WindowStageLoadContent)}, + ani_native_function {"loadContentSync", + "JLstd/core/String;Larkui/stateManagement/storages/localStorage/LocalStorage;:V", + reinterpret_cast(AniWindowStage::LoadContent)}, ani_native_function {"disableWindowDecorSync", nullptr, reinterpret_cast(AniWindowStage::DisableWindowDecor)}, ani_native_function {"setShowOnLockScreenSync", -- Gitee From b40c0b12077cfa8e07a5cf09f270fda3e51b2c1b Mon Sep 17 00:00:00 2001 From: dongzhili Date: Wed, 27 Aug 2025 14:55:30 +0800 Subject: [PATCH 2/7] =?UTF-8?q?=E8=93=9D=E9=BB=84=E5=90=8C=E6=AD=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: dongzhili --- .../ani/window_runtime/window_stage_ani/ets/@ohos.window.ets | 4 ---- 1 file changed, 4 deletions(-) diff --git a/interfaces/kits/ani/window_runtime/window_stage_ani/ets/@ohos.window.ets b/interfaces/kits/ani/window_runtime/window_stage_ani/ets/@ohos.window.ets index 84758397d0..70d43b1e3c 100644 --- a/interfaces/kits/ani/window_runtime/window_stage_ani/ets/@ohos.window.ets +++ b/interfaces/kits/ani/window_runtime/window_stage_ani/ets/@ohos.window.ets @@ -1175,10 +1175,6 @@ export class WindowStageInternal implements WindowStage { callback(err as BusinessError, undefined); } } - - public loadContentByName(name: string, callback: AsyncCallbackVoid): void { - let ret = this.loadContent(this.nativeObj, name); - } public disableWindowDecor(): void { this.disableWindowDecorSync(this.nativeObj); -- Gitee From a446acf7f62d76261426e95cc977ebadf2c1b0d6 Mon Sep 17 00:00:00 2001 From: dongzhili Date: Wed, 27 Aug 2025 16:18:32 +0800 Subject: [PATCH 3/7] =?UTF-8?q?=E8=93=9D=E9=BB=84=E5=90=8C=E6=AD=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: dongzhili --- .../ani/window_runtime/window_stage_ani/ets/@ohos.window.ets | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/interfaces/kits/ani/window_runtime/window_stage_ani/ets/@ohos.window.ets b/interfaces/kits/ani/window_runtime/window_stage_ani/ets/@ohos.window.ets index 70d43b1e3c..425e7cfe2d 100644 --- a/interfaces/kits/ani/window_runtime/window_stage_ani/ets/@ohos.window.ets +++ b/interfaces/kits/ani/window_runtime/window_stage_ani/ets/@ohos.window.ets @@ -1215,7 +1215,6 @@ export class WindowStageInternal implements WindowStage { export interface WindowStage { loadContent(path: string, callback: AsyncCallback): void; - loadContentByName(name: string, callback: AsyncCallbackVoid): void; getMainWindowSync(): Window; getMainWindow(): Promise; getMainWindow(callback: AsyncCallback): void; @@ -1253,8 +1252,7 @@ export class WindowInternal implements Window { private native setWindowPrivacyModeSync(nativeObj: long, isPrivacyMode: boolean): void; private native recoverSync(nativeObj: long): void; private native setUIContentSync(nativeObj: long, path: string): void; - private native loadContentSync(nativeObj: long, path: string, storage: LocalStorage): void; - private native loadContentSync(nativeObj: long, path: string): void; + private native loadContentSync(nativeObj: long, path: string, storage?: LocalStorage): void; private native setWindowKeepScreenOnSync(nativeObj: long, isKeepScreenOn: boolean): void; private native setWindowSystemBarEnableSync(nativeObj: long, names: Array<'status' | 'navigation'>): void; private native getUIContextSync(nativeObj: long): UIContext; -- Gitee From 69ecd1dadaa758967ceafd5685ae06962d8b9bd6 Mon Sep 17 00:00:00 2001 From: dongzhili Date: Wed, 27 Aug 2025 16:45:30 +0800 Subject: [PATCH 4/7] =?UTF-8?q?=E8=93=9D=E9=BB=84=E5=90=8C=E6=AD=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: dongzhili --- .../ani/window_runtime/window_stage_ani/ets/@ohos.window.ets | 2 ++ .../ani/window_runtime/window_stage_ani/include/ani_window.h | 3 +-- .../ani/window_runtime/window_stage_ani/src/ani_window.cpp | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/interfaces/kits/ani/window_runtime/window_stage_ani/ets/@ohos.window.ets b/interfaces/kits/ani/window_runtime/window_stage_ani/ets/@ohos.window.ets index 425e7cfe2d..96aa154a67 100644 --- a/interfaces/kits/ani/window_runtime/window_stage_ani/ets/@ohos.window.ets +++ b/interfaces/kits/ani/window_runtime/window_stage_ani/ets/@ohos.window.ets @@ -1214,6 +1214,8 @@ export class WindowStageInternal implements WindowStage { } export interface WindowStage { + loadContent(path: string, storage: LocalStorage, callback: AsyncCallback): void; + loadContent(path: string, storage?: LocalStorage): Promise; loadContent(path: string, callback: AsyncCallback): void; getMainWindowSync(): Window; getMainWindow(): Promise; diff --git a/interfaces/kits/ani/window_runtime/window_stage_ani/include/ani_window.h b/interfaces/kits/ani/window_runtime/window_stage_ani/include/ani_window.h index 89d8b6d011..4de3413708 100644 --- a/interfaces/kits/ani/window_runtime/window_stage_ani/include/ani_window.h +++ b/interfaces/kits/ani/window_runtime/window_stage_ani/include/ani_window.h @@ -56,7 +56,7 @@ public: ani_ref callback); static void UnregisterWindowCallback(ani_env* env, ani_object obj, ani_long nativeObj, ani_string type, ani_ref callback); - + static void Finalizer(ani_env* env, ani_long nativeObj); /* * Window Layout */ @@ -84,7 +84,6 @@ private: void OnSetUIContent(ani_env* env, ani_string path); void OnSetWindowKeepScreenOn(ani_env* env, ani_boolean isKeepScreenOn); void OnSetWaterMarkFlag(ani_env* env, ani_boolean enable); - void OnLoadContent(ani_env* env, ani_string path); void OnLoadContent(ani_env* env, ani_string path, ani_object storage); void OnSetWindowSystemBarEnable(ani_env* env, ani_object nameAry); ani_object OnGetUIContext(ani_env* env); diff --git a/interfaces/kits/ani/window_runtime/window_stage_ani/src/ani_window.cpp b/interfaces/kits/ani/window_runtime/window_stage_ani/src/ani_window.cpp index bf8cb9147a..ddd41890fa 100644 --- a/interfaces/kits/ani/window_runtime/window_stage_ani/src/ani_window.cpp +++ b/interfaces/kits/ani/window_runtime/window_stage_ani/src/ani_window.cpp @@ -859,7 +859,7 @@ ani_ref FindAniWindowObject(const std::string& windowName) { TLOGI(WmsLogTag::DEFAULT, "[ANI] Try to find window %{public}s in g_aniWindowMap", windowName.c_str()); if (g_aniWindowMap.find(windowName) == g_aniWindowMap.end()) { - TLGI(WmsLogTag::DEFAULT, "[ANI] Can not find window %{public}s in g_aniWindowMap", windowName.c_str()); + TLOGI(WmsLogTag::DEFAULT, "[ANI] Can not find window %{public}s in g_aniWindowMap", windowName.c_str()); return nullptr; } return g_aniWindowMap[windowName]; -- Gitee From 52aa2156369e84d0749b75fdfdc35d996f70a271 Mon Sep 17 00:00:00 2001 From: dongzhili Date: Wed, 27 Aug 2025 16:47:19 +0800 Subject: [PATCH 5/7] =?UTF-8?q?=E8=93=9D=E9=BB=84=E5=90=8C=E6=AD=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: dongzhili --- .../ani/window_runtime/window_stage_ani/include/ani_window.h | 1 + 1 file changed, 1 insertion(+) diff --git a/interfaces/kits/ani/window_runtime/window_stage_ani/include/ani_window.h b/interfaces/kits/ani/window_runtime/window_stage_ani/include/ani_window.h index 4de3413708..35d74384a2 100644 --- a/interfaces/kits/ani/window_runtime/window_stage_ani/include/ani_window.h +++ b/interfaces/kits/ani/window_runtime/window_stage_ani/include/ani_window.h @@ -57,6 +57,7 @@ public: static void UnregisterWindowCallback(ani_env* env, ani_object obj, ani_long nativeObj, ani_string type, ani_ref callback); static void Finalizer(ani_env* env, ani_long nativeObj); + /* * Window Layout */ -- Gitee From f711a57e4b721093af40b36e420927f0769efe5e Mon Sep 17 00:00:00 2001 From: dongzhili Date: Wed, 27 Aug 2025 18:14:51 +0800 Subject: [PATCH 6/7] =?UTF-8?q?=E8=93=9D=E9=BB=84=E5=90=8C=E6=AD=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: dongzhili --- .../ani/window_runtime/window_stage_ani/src/ani_window.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/interfaces/kits/ani/window_runtime/window_stage_ani/src/ani_window.cpp b/interfaces/kits/ani/window_runtime/window_stage_ani/src/ani_window.cpp index ddd41890fa..11fd554c3e 100644 --- a/interfaces/kits/ani/window_runtime/window_stage_ani/src/ani_window.cpp +++ b/interfaces/kits/ani/window_runtime/window_stage_ani/src/ani_window.cpp @@ -507,7 +507,9 @@ __attribute__((no_sanitize("cfi"))) TLOGE(WmsLogTag::DEFAULT, "[ANI] create global ref fail"); return nullptr; }; - localObjs.insert(std::pair(obj, aniWindow.release())); + aniWindow->SetAniRef(ref); + localObjs.insert(std::pair(ref, aniWindow.release())); + g_aniWindowMap[windowName] = ref; return obj; } -- Gitee From 09c307866df8ce1cb4dc6b3b2e269229dffff8e8 Mon Sep 17 00:00:00 2001 From: dongzhili Date: Wed, 27 Aug 2025 18:31:33 +0800 Subject: [PATCH 7/7] =?UTF-8?q?=E8=93=9D=E9=BB=84=E5=90=8C=E6=AD=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: dongzhili --- .../window_runtime/window_stage_ani/src/ani_window_stage.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interfaces/kits/ani/window_runtime/window_stage_ani/src/ani_window_stage.cpp b/interfaces/kits/ani/window_runtime/window_stage_ani/src/ani_window_stage.cpp index 72d6673085..e990c91f18 100644 --- a/interfaces/kits/ani/window_runtime/window_stage_ani/src/ani_window_stage.cpp +++ b/interfaces/kits/ani/window_runtime/window_stage_ani/src/ani_window_stage.cpp @@ -149,7 +149,7 @@ __attribute__((no_sanitize("cfi"))) } ani_method setObjFunc = nullptr; if ((ret = env->Class_FindMethod(cls, "setNativeObj", "J:V", &setObjFunc)) != ANI_OK) { - TLOGE(WmsLogTag::DEFAULT, "[ANI] get ctor fail %{public}u", ret); + TLOGE(WmsLogTag::DEFAULT, "[ANI] call setNativeObj fail %{public}u", ret); return nullptr; } env->Object_CallMethod_Void(obj, setObjFunc, reinterpret_cast(windowStage.get())); -- Gitee