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 0db7a3c861132894d18563ff96176866579c616b..96aa154a67dc8969dcabda642a3d96700550da38 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,32 +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 loadContentByName(name: string, callback: AsyncCallbackVoid): void { - let ret = this.loadContent(this.nativeObj, name); + 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 disableWindowDecor(): void { @@ -1203,8 +1214,9 @@ 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; - loadContentByName(name: string, callback: AsyncCallbackVoid): void; getMainWindowSync(): Window; getMainWindow(): Promise; getMainWindow(callback: AsyncCallback): void; @@ -1242,8 +1254,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; @@ -1306,9 +1317,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 +1593,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 +1603,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 +1746,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 8ca8f34b54fd1b7ee9e827f54c8a79259b774613..35d74384a2ce789189de1f3da9edce1955234d48 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); @@ -55,6 +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 @@ -83,7 +85,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); @@ -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 4225d6d291650b8aaaa945eb8eee049ca10a2e7f..6f9ae0b8399a71e0876877b1ff8b3d4c70793e6e 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_manager.h b/interfaces/kits/ani/window_runtime/window_stage_ani/include/ani_window_manager.h index 3c741306b4357e78f0494e225f2c9441b0333fb5..b2023d2204a0e42b9af1ff3392a1a72f1562a325 100644 --- a/interfaces/kits/ani/window_runtime/window_stage_ani/include/ani_window_manager.h +++ b/interfaces/kits/ani/window_runtime/window_stage_ani/include/ani_window_manager.h @@ -31,9 +31,9 @@ namespace Rosen { class AniWindowManager { public: static ani_status AniWindowManagerInit(ani_env* env, ani_namespace windowNameSpace); - static ani_object GetLastWindow(ani_env* env, ani_object obj, ani_long nativeObj, ani_object context); + static ani_ref GetLastWindow(ani_env* env, ani_long nativeObj, ani_object context); private: - ani_object OnGetLastWindow(ani_env* env, ani_object context); + ani_ref OnGetLastWindow(ani_env* env, ani_object context); ani_object GetTopWindowTask(ani_env* env, void* contextPtr, bool newApi); }; } // namespace Rosen 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 b496834588d57a31a31de4f433b4dd7ea02a2e7b..84b7a06833e6c50ce4c69775ab1bcc60262b213f 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 ad0c6063e6c6adcaed1f4973d470d6a5312c6d9d..efd0c6c469d06c013721a55d0786c10ca2692bd0 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 c984078fc4820418fb9b3ddb38268f233157d2bd..17126c5de60801f1592bb1b790e51f18b1c00867 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 3abd7b97578b9e7aef1d302ec92af05df12c458d..d454bb030c53ed55568dc5e6c2fc7831c174ddf2 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 g_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,33 +444,40 @@ 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)); - if (obj != localObjs.end()) { + auto obj = g_localObjs.find(reinterpret_cast(aniObj)); + if (obj != g_localObjs.end()) { delete obj->second; } - localObjs.erase(obj); + g_localObjs.erase(obj); } AniWindow* GetWindowObjectFromAni(void* aniObj) { - auto obj = localObjs.find(reinterpret_cast(aniObj)); - if (obj == localObjs.end()) { + auto obj = g_localObjs.find(reinterpret_cast(aniObj)); + if (obj == g_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,8 +501,15 @@ __attribute__((no_sanitize("cfi"))) TLOGE(WmsLogTag::DEFAULT, "[ANI] get ctor fail %{public}u", ret); return nullptr; } - env->Object_CallMethod_Void(obj, setObjFunc, aniWindow.get()); - localObjs.insert(std::pair(obj, aniWindow.release())); + 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; + }; + aniWindow->SetAniRef(ref); + g_localObjs.insert(std::pair(ref, aniWindow.release())); + g_aniWindowMap[windowName] = ref; return obj; } @@ -867,6 +856,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()) { + TLOGI(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 @@ -1087,7 +1102,7 @@ __attribute__((no_sanitize("cfi"))) return nullptr; } env->Object_CallMethod_Void(obj, setObjFunc, reinterpret_cast(uniqueWindow.get())); - localObjs.insert(std::pair(obj, uniqueWindow.release())); + g_localObjs.insert(std::pair(obj, uniqueWindow.release())); return obj; } @@ -1161,11 +1176,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_manager.cpp b/interfaces/kits/ani/window_runtime/window_stage_ani/src/ani_window_manager.cpp index f8d18dc151c87943894ece8432d59f4c9da461a8..e83a7e6e9db301bbf3845935826d2dec5ae5fdd7 100644 --- a/interfaces/kits/ani/window_runtime/window_stage_ani/src/ani_window_manager.cpp +++ b/interfaces/kits/ani/window_runtime/window_stage_ani/src/ani_window_manager.cpp @@ -43,14 +43,14 @@ ani_status AniWindowManager::AniWindowManagerInit(ani_env* env, ani_namespace wi return ret; } -ani_object AniWindowManager::GetLastWindow(ani_env* env, ani_object obj, ani_long nativeObj, ani_object context) +ani_ref AniWindowManager::GetLastWindow(ani_env* env, ani_long nativeObj, ani_object context) { TLOGI(WmsLogTag::DEFAULT, "[ANI]"); AniWindowManager* aniWindowManager = reinterpret_cast(nativeObj); return aniWindowManager != nullptr ? aniWindowManager->OnGetLastWindow(env, context) : nullptr; } -ani_object AniWindowManager::OnGetLastWindow(ani_env* env, ani_object aniContext) +ani_ref AniWindowManager::OnGetLastWindow(ani_env* env, ani_object aniContext) { TLOGI(WmsLogTag::DEFAULT, "[ANI]"); auto contextPtr = AniWindowUtils::GetAbilityContext(env, aniContext); 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 9fe4c446be79c751fc1dd549108c4853c9050427..20b0924f53c6e3fc2f5f3734d967247fa086704f 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 a022dc288e9496c66ed0ff06a387175c2c724f31..07c0cfa22e67a0153944932bfa81bb430f2ab91b 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 @@ -32,7 +32,7 @@ namespace Rosen { namespace { /* used for free, ani has no destructor right now, only free when aniObj freed */ -static std::map localObjs; +static std::map g_localObjs; } // namespace AniWindowStage::AniWindowStage(const std::shared_ptr& windowScene) @@ -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; + } + auto mainWindow = windowScene->GetMainWindow(); + if (mainWindow == nullptr) { + TLOGE(WmsLogTag::WMS_LIFE, "[ANI] mainWindow is nullptr!"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); return; } - win->NapiSetUIContent(content, env, nullptr); + 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(); @@ -77,31 +103,22 @@ ani_object AniWindowStage::GetMainWindow(ani_env* env) void DropWindowStageByAni(ani_object aniObj) { - auto obj = localObjs.find(reinterpret_cast(aniObj)); - if (obj != localObjs.end()) { + auto obj = g_localObjs.find(reinterpret_cast(aniObj)); + if (obj != g_localObjs.end()) { delete obj->second; } - localObjs.erase(obj); + g_localObjs.erase(obj); } AniWindowStage* GetWindowStageFromAni(void* aniObj) { - auto obj = localObjs.find(reinterpret_cast(aniObj)); - if (obj == localObjs.end()) { + auto obj = g_localObjs.find(reinterpret_cast(aniObj)); + if (obj == g_localObjs.end()) { return nullptr; } 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) { @@ -137,11 +149,11 @@ __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())); - localObjs.insert(std::pair(obj, windowStage.release())); + g_localObjs.insert(std::pair(obj, windowStage.release())); return obj; } @@ -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",