diff --git a/interfaces/kits/ani/BUILD.gn b/interfaces/kits/ani/BUILD.gn index a142a7e1c4f78965ccc7ba0dc4c46e3242a3299c..4c0d3cc3058353ff387edcb8ccb6b8d4a69e48b2 100644 --- a/interfaces/kits/ani/BUILD.gn +++ b/interfaces/kits/ani/BUILD.gn @@ -18,6 +18,7 @@ group("ani_packages") { "display_runtime:display_ani", "embeddable_window_stage:embeddable_window_stage_ani", "screen_runtime:screen_ani", + "screenshot_runtime:screenshot_ani", "window_runtime:window_stage_ani_pack", ] } diff --git a/interfaces/kits/ani/display_runtime/BUILD.gn b/interfaces/kits/ani/display_runtime/BUILD.gn index 1c6f20ff69597e8320c097f9f989242c8f9f60fb..b1f7cc334408db89b11332aa496a674a86e24457 100644 --- a/interfaces/kits/ani/display_runtime/BUILD.gn +++ b/interfaces/kits/ani/display_runtime/BUILD.gn @@ -24,6 +24,7 @@ config("display_common_config") { "../../../innerkits/wm", "../../../innerkits/dm", "../../../../wm/include", + "../../napi/display_runtime", ] } @@ -62,6 +63,7 @@ ohos_shared_library("displayani_kit") { "../../../../dm:libdm", "../../../../utils:libwmutil", "../../../../utils:libwmutil_base", + "../../../../interfaces/kits/napi/display_runtime:display_kit" ] external_deps = [ @@ -72,6 +74,8 @@ ohos_shared_library("displayani_kit") { "hilog:libhilog", "hitrace:hitrace_meter", "runtime_core:ani", + "napi:ace_napi", + "runtime_core:ani_helpers", ] innerapi_tags = [ "platformsdk" ] 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 ba2f154c0287a5d6a153d421546c69dd94f55ec5..d634b2b6112403fc817c5ba287a8c9fcced0afac 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 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Copyright (c) 2025-2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -25,23 +25,23 @@ const DISPLAY_ARRAY_LENGTH = 15; const CUTO_ARRAY_LENGTH = 5; export interface Rect { - left: number; + left: long; - top: number; + top: long; - width: number; + width: long; - height: number; + height: long; } export class RectImpl implements Rect { - left: number; + left: long; - top: number; + top: long; - width: number; + width: long; - height: number; + height: long; } interface WaterfallDisplayAreaRects { @@ -91,7 +91,7 @@ export class CutoutInfoImpl implements CutoutInfo { } export interface FoldCreaseRegion { - readonly displayId: number; + readonly displayId: long; readonly creaseRects: Array; } @@ -104,13 +104,12 @@ export class FoldCreaseRegionImpl implements FoldCreaseRegion { } } - readonly displayId: number; + readonly displayId: long; readonly creaseRects: Array; } export enum FoldDisplayMode { - FOLD_DISPLAY_MODE_UNKNOWN = 0, FOLD_DISPLAY_MODE_FULL, @@ -123,7 +122,6 @@ export enum FoldDisplayMode { } export enum Orientation { - PORTRAIT = 0, LANDSCAPE = 1, @@ -140,11 +138,22 @@ export enum FoldStatus { FOLD_STATUS_FOLDED, - FOLD_STATUS_HALF_FOLDED - } + FOLD_STATUS_HALF_FOLDED, + + FOLD_STATUS_EXPANDED_WITH_SECOND_EXPANDED = 11, + + FOLD_STATUS_EXPANDED_WITH_SECOND_HALF_FOLDED = 21, + + FOLD_STATUS_FOLDED_WITH_SECOND_EXPANDED = 12, -enum DisplayState { + FOLD_STATUS_FOLDED_WITH_SECOND_HALF_FOLDED = 22, + FOLD_STATUS_HALF_FOLDED_WITH_SECOND_EXPANDED = 13, + + FOLD_STATUS_HALF_FOLDED_WITH_SECOND_HALF_FOLDED = 23 + } + +export enum DisplayState { STATE_UNKNOWN = 0, STATE_OFF, @@ -160,8 +169,28 @@ enum DisplayState { STATE_ON_SUSPEND } +export enum ScreenShape { + + RECTANGLE = 0, + + ROUND = 1 +} + +export enum DisplaySourceMode { + + NONE = 0, + + MAIN = 1, + + MIRROR = 2, + + EXTEND = 3, + + ALONE = 4 +} + export interface Display { - id: double; + id: long; name: string; @@ -169,17 +198,17 @@ export interface Display { state: DisplayState; - refreshRate: double; + refreshRate: int; - rotation: double; + rotation: int; - width: double; + width: long; - height: double; + height: long; - availableHeight: double; + availableHeight: long; - availableWidth: double; + availableWidth: long; densityDPI: double; @@ -193,13 +222,33 @@ export interface Display { yDPI: double; + screenShape?: ScreenShape; + colorSpaces: Array; hdrFormats: Array; + sourceMode?:DisplaySourceMode; + + x?: long; + + y?: long; + + supportedRefreshRates?: Array; + getCutoutInfo(callback: AsyncCallback): void; getCutoutInfo(): Promise; + + getAvailableArea(): Promise; + + hasImmersiveWindow(callback: AsyncCallback): void; + + hasImmersiveWindow(): Promise; + + on(type: string, callback: Callback): void; + + off(type: string, callback?: Callback): void; } export class DisplayImpl implements Display { @@ -208,9 +257,10 @@ export class DisplayImpl implements Display { constructor() { this.colorSpaces = new Array(); this.hdrFormats = new Array(); + this.supportedRefreshRates = new Array(); } - id: double; + id: long; name: string; @@ -218,17 +268,17 @@ export class DisplayImpl implements Display { state: DisplayState; - refreshRate: double; + refreshRate: int; - rotation: double; + rotation: int; - width: double; + width: long; - height: double; + height: long; - availableHeight: double; + availableHeight: long; - availableWidth: double; + availableWidth: long; densityDPI: double; @@ -242,18 +292,34 @@ export class DisplayImpl implements Display { yDPI: double; + screenShape?: ScreenShape; + colorSpaces: Array; hdrFormats: Array; + sourceMode?: DisplaySourceMode; + + x?: long; + + y?: long; + + supportedRefreshRates?: Array; + + displayRef: long; + + setDisplayRef(nativeObj : long) : void{ + this.displayRef = nativeObj; + } + getCutoutInfo(callback: AsyncCallback): void { taskpool.execute((): CutoutInfo => { - let res: CutoutInfo = new CutoutInfoImpl() + let res: CutoutInfo = new CutoutInfoImpl(); this.getCutoutInfoInternal(res); 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()); }); @@ -274,8 +340,75 @@ export class DisplayImpl implements Display { }); } - public native getCutoutInfoInternal(cutoutInfo: CutoutInfo): void; + hasImmersiveWindow(callback: AsyncCallback): void { + taskpool.execute((): boolean => { + return this.hasImmersiveWindowInternal(); + }).then((ret: NullishType) => { + callback(null, ret as boolean); + }).catch((err: NullishType) => { + callback(err as BusinessError, false); + }); + } + + hasImmersiveWindow(): Promise { + return new Promise((resolve: (value: boolean) => void, reject: (error: BusinessError) => void ) => { + taskpool.execute((): boolean => { + return this.hasImmersiveWindowInternal(); + }).then((ret: NullishType) => { + resolve(ret as boolean); + }).catch((err: NullishType) => { + reject(err as BusinessError); + }); + }); + } + + getAvailableArea(): Promise { + return new Promise((resolve: (value: Rect) => void, reject: (error: BusinessError) => void ) => { + taskpool.execute((): Rect => { + let res: Rect = new RectImpl(); + this.getAvailableAreaInternal(res); + return res; + }).then((ret: NullishType) => { + resolve(ret as Rect); + }).catch((err: NullishType) => { + reject(err as BusinessError); + }); + }) + } + + on(type: string, callback: Callback): void { + this.syncOn(type, callback as object); + } + + off(type: string, callback?: Callback): void { + this.syncOff(type, callback); + } + + static transferStatic(input: Any): Object { + let display = new DisplayImpl(); + let display_input: ESValue = ESValue.wrap(input); + let ret = false; + if (display_input !== ESValue.Undefined) { + ret = DisplayImpl.nativeTransferStatic(display_input, display as Object); + } + if (!ret) { + return {}; + } + return display as Object; + } + + static transferDynamic(input: Object): Any { + return DisplayImpl.nativeTransferDynamic((input as DisplayImpl).displayRef).unwrap(); + } + + native syncOn(type: string, callback: object): void; + native syncOff(type: string, callback?: object): void; + native getAvailableAreaInternal(rect: Rect): void; + native getCutoutInfoInternal(cutoutInfo: CutoutInfo): void; + native hasImmersiveWindowInternal(): boolean; + native static nativeTransferStatic(input: ESValue, display: Object): boolean; + native static nativeTransferDynamic(nativeObj: long): ESValue; } function minusRectArray(rectArr: Array): void { @@ -290,6 +423,8 @@ function minusRectArray(rectArr: Array): void { export native function isFoldable(): boolean; +export native function isCaptured(): boolean; + export function getFoldDisplayMode(): FoldDisplayMode { let res = getFoldDisplayModeNative(); return res as FoldDisplayMode; @@ -327,16 +462,16 @@ function minusCreaseRects(foldCreaseRegionObj: FoldCreaseRegion): void { export native function getCurrentFoldCreaseRegionNative(foldCreaseRegion: object, nativeObj: long): void; // display sync interfaces -export function getDisplayByIdSync(displayId: number): Display { - let display:Display = new DisplayImpl(); +export function getDisplayByIdSync(displayId: long): Display { + let display = new DisplayImpl(); getDisplayByIdSyncNative(display as object, displayId); return display; } -export native function getDisplayByIdSyncNative(obj: object, displayId: number): void; +export native function getDisplayByIdSyncNative(obj: object, displayId: long): void; export function getDefaultDisplaySync(): Display { - let display:Display = new DisplayImpl(); + let display = new DisplayImpl(); getDefaultDisplaySyncNative(display as object); return display; } @@ -353,7 +488,7 @@ export function getAllDisplays(callback: AsyncCallback>): void { try { getAllDisplaysSyncNative(res); minusDisplayArray(res); - callback(new BusinessError(), res); + callback(null, res); } catch (err: BusinessError) { callback(err, res); } @@ -383,6 +518,7 @@ function minusDisplayArray(displayArr: Array): void { if (displayArr[i].width == 0) { break; } + let dp = displayArr[i] as DisplayImpl; } displayArr.splice(i); } @@ -403,9 +539,9 @@ export function off(type: string, callback?: Callback): void { export native function syncOff(type: string, nativeObj: long, callback?: object) : void; -export function displayEventCallBack(cb: object, cbArg: double): void { - const func = cb as (cbArg: double) => void; - func(cbArg as double); +export function displayEventCallBack(cb: object, cbArg: long): void { + const func = cb as (cbArg: long) => void; + func(cbArg as long); } export function foldStatusCallback(cb: object, cbArg: int): void { @@ -418,6 +554,73 @@ export function foldDisplayModeCallback(cb: object, cbArg: int): void { func(cbArg as FoldDisplayMode); } +export function foldAngleChangeCallback(cb: object, cbArg: object): void { + const func = cb as (cbArg: Array) => void; + func(cbArg as Array); +} + +export function captureStatusChangedCallback(cb: object, cbArg: boolean): void { + const func = cb as (cbArg: boolean) => void; + func(cbArg as boolean); +} + +export function availableAreaChangedCallback(cb: object, cbArg: object): void { + const func = cb as (cbArg: Rect) => void; + func(cbArg as Rect); +} + +export native function hasPrivateWindow(displayId: long): boolean; + +export function getAllDisplayPhysicalResolution(): Promise> { + return new Promise>((resolve: (value: Array) => void, + reject: (error: BusinessError) => void ) => { + taskpool.execute((): Array => { + let res: Array = new Array(5); + for (let i = 0; i < res.length; i++) { + res[i] = new DisplayPhysicalResolutionImpl(); + } + getAllDisplayPhysicalResolutionNative(res, displayMgrRef); + minusResolutionArray(res); + return res; + }).then((ret: NullishType) => { + resolve(ret as Array); + }).catch((err: NullishType) => { + reject(err as BusinessError); + }); + }); +} + +function minusResolutionArray(resolutions: Array): void { + let index = 0; + for (; index < resolutions.length; index++) { + if (resolutions[index].physicalWidth == 0) { + break; + } + let resolution = resolutions[index] as DisplayPhysicalResolutionImpl; + resolution.foldDisplayMode = resolution.foldDisplayMode_ as FoldDisplayMode; + } + resolutions.splice(index); +} + +export native function getAllDisplayPhysicalResolutionNative(PhysicalResolutions: Array, nativeObj: long): void; + +export interface DisplayPhysicalResolution { + foldDisplayMode: FoldDisplayMode; + + physicalWidth: long; + + physicalHeight: long; +} + +export class DisplayPhysicalResolutionImpl implements DisplayPhysicalResolution{ + foldDisplayMode: FoldDisplayMode; + foldDisplayMode_: int; + + physicalWidth: long; + + physicalHeight: long; +} + export let displayMgrRef: long; export function setDisplayMgrRef(nativeObj : long) : void{ diff --git a/interfaces/kits/ani/display_runtime/display_ani/ets/display_entry.ets b/interfaces/kits/ani/display_runtime/display_ani/ets/display_entry.ets deleted file mode 100644 index 600a4d73bdd21ebb8daeffa4028ceeb6f41529f4..0000000000000000000000000000000000000000 --- a/interfaces/kits/ani/display_runtime/display_ani/ets/display_entry.ets +++ /dev/null @@ -1,25 +0,0 @@ -import display from '@ohos.display' - -loadLibrary('displayani_kit.z'); - -function main() { - let isFoldable = display.isFoldable(); - console.log('[ANI] isfoldable test, result = ' + isFoldable); - display.getFoldDisplayMode(); - let disret : display.Display = display.getDefaultDisplaySync(); - let cbk = (i : number): void => { - console.log('[ANI] isfoldable test, result = ' + i); - } - display.on('add', cbk); - display.getDisplayByIdSync(0); - let asyncCbk = (err: display.BusinessError, arr : Array):void => { - console.log('AsyncCallBack'); - } - display.getAllDisplays(asyncCbk); - display.getCurrentFoldCreaseRegion(); - let dis : display.Display = new display.DisplayImpl(); - let asyncbk = (err: display.BusinessError, arr : display.CutoutInfo):void => { - console.log('AsyncCallBack'); - } - dis.getCutoutInfo(asyncbk); -} \ No newline at end of file diff --git a/interfaces/kits/ani/display_runtime/display_ani/include/ani_err_utils.h b/interfaces/kits/ani/display_runtime/display_ani/include/ani_err_utils.h index 9f5cd855a265f94c5db8398ebef9245a695062d3..87fab95a96a238e8f71a2202bfe56036e2ac0cb5 100644 --- a/interfaces/kits/ani/display_runtime/display_ani/include/ani_err_utils.h +++ b/interfaces/kits/ani/display_runtime/display_ani/include/ani_err_utils.h @@ -18,7 +18,6 @@ #include "ani.h" #include "dm_common.h" -#include "wm_common.h" namespace OHOS::Rosen { class AniErrUtils { diff --git a/interfaces/kits/ani/display_runtime/display_ani/include/display_ani.h b/interfaces/kits/ani/display_runtime/display_ani/include/display_ani.h index 5c6fd9778f04055f815ba000ae24d3afc3f6d063..d12fe8187bd0c01b27a0f3009a0fbd11541f602b 100644 --- a/interfaces/kits/ani/display_runtime/display_ani/include/display_ani.h +++ b/interfaces/kits/ani/display_runtime/display_ani/include/display_ani.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Copyright (c) 2025-2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -17,15 +17,35 @@ #include "ani.h" #include "display.h" +#include "display_ani_listener.h" namespace OHOS { namespace Rosen { class DisplayAni { public: - explicit DisplayAni(const std::shared_ptr& display); + explicit DisplayAni(const sptr& display); - static void getCutoutInfo(ani_env* env, ani_object obj, ani_object cutoutInfoObj); + static void GetCutoutInfo(ani_env* env, ani_object obj, ani_object cutoutInfoObj); + static void GetAvailableArea(ani_env* env, ani_object obj, ani_object availableAreaObj); + static ani_boolean HasImmersiveWindow(ani_env* env, ani_object obj); + static void RegisterCallback(ani_env* env, ani_object obj, ani_string type, ani_ref aniCallback); + static void UnRegisterCallback(ani_env* env, ani_object obj, ani_string type, ani_ref aniCallback); + static void CreateDisplayAni(sptr display, ani_object displayAni, ani_env* env); + void OnRegisterCallback(ani_env* env, ani_object obj, ani_string type, ani_ref aniCallback); + void OnUnRegisterCallback(ani_env* env, ani_object obj, ani_string type, ani_ref aniCallback); + static ani_status NspBindNativeFunctions(ani_env* env, ani_namespace nsp); + static ani_status ClassBindNativeFunctions(ani_env* env, ani_class displayCls); + static ani_boolean TransferStatic(ani_env* env, ani_object obj, ani_object input, ani_object displayAniObj); + static ani_object TransferDynamic(ani_env* env, ani_object obj, ani_long nativeObj); + sptr GetDisplay() const { return display_; } +private: + DMError UnregisterAllDisplayListenerWithType(std::string type); + DMError UnregisterDisplayListenerWithType(std::string type, ani_env *env, ani_ref aniCallback); + bool IsCallbackRegistered(ani_env* env, const std::string& type, ani_ref callback); + sptr display_ = nullptr; + std::map>> jsCbMap_; + std::mutex mtx_; }; } // namespace Rosen } // namespace OHOS diff --git a/interfaces/kits/ani/display_runtime/display_ani/include/display_ani_listener.h b/interfaces/kits/ani/display_runtime/display_ani/include/display_ani_listener.h index b22b3ef1f6393a0cf22aee0811729b3f132ee70d..082028bf70503801118fce6453d326efa40cadba 100644 --- a/interfaces/kits/ani/display_runtime/display_ani/include/display_ani_listener.h +++ b/interfaces/kits/ani/display_runtime/display_ani/include/display_ani_listener.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -54,20 +54,20 @@ public: private: ani_env* env_; - std::mutex aniCallBackMtx_; - std::map> aniCallBack_; + std::mutex aniCallbackMtx_; + std::map> aniCallback_; wptr weakRef_ = nullptr; std::shared_ptr eventHandler_ = nullptr; }; -const std::string EVENT_ADD = "add"; -const std::string EVENT_REMOVE = "remove"; -const std::string EVENT_CHANGE = "change"; -const std::string EVENT_PRIVATE_MODE_CHANGE = "privateModeChange"; -const std::string EVENT_FOLD_STATUS_CHANGED = "foldStatusChange"; -const std::string EVENT_FOLD_ANGLE_CHANGED = "foldAngleChange"; -const std::string EVENT_CAPTURE_STATUS_CHANGED = "captureStatusChange"; -const std::string EVENT_DISPLAY_MODE_CHANGED = "foldDisplayModeChange"; -const std::string EVENT_AVAILABLE_AREA_CHANGED = "availableAreaChange"; +const std::string ANI_EVENT_ADD = "add"; +const std::string ANI_EVENT_REMOVE = "remove"; +const std::string ANI_EVENT_CHANGE = "change"; +const std::string ANI_EVENT_PRIVATE_MODE_CHANGE = "privateModeChange"; +const std::string ANI_EVENT_FOLD_STATUS_CHANGED = "foldStatusChange"; +const std::string ANI_EVENT_FOLD_ANGLE_CHANGED = "foldAngleChange"; +const std::string ANI_EVENT_CAPTURE_STATUS_CHANGED = "captureStatusChange"; +const std::string ANI_EVENT_DISPLAY_MODE_CHANGED = "foldDisplayModeChange"; +const std::string ANI_EVENT_AVAILABLE_AREA_CHANGED = "availableAreaChange"; } // namespace Rosen } // namespace OHOS #endif \ No newline at end of file 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 62f9af2f3d9f31138fc1f63d98d34e16eccaa321..549f0d895a21e05e1861a47f181a8b539039599d 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 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Copyright (c) 2025-2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -25,29 +25,34 @@ namespace Rosen { class DisplayManagerAni { public: explicit DisplayManagerAni(); - static ani_status initDisplayManagerAni(ani_namespace displayNameSpace, ani_env* env); + static ani_status InitDisplayManagerAni(ani_namespace displayNameSpace, ani_env* env); - static ani_int getFoldDisplayModeAni(ani_env* env); - static ani_boolean isFoldableAni(ani_env* env); - static ani_int getFoldStatus(ani_env* env); - static void getCurrentFoldCreaseRegion(ani_env* env, ani_object obj, ani_long nativeObj); + static ani_int GetFoldDisplayModeAni(ani_env* env); + static ani_boolean IsFoldableAni(ani_env* env); + static ani_int GetFoldStatus(ani_env* env); + static ani_boolean IsCaptured(ani_env* env); + static void GetCurrentFoldCreaseRegion(ani_env* env, ani_object obj, ani_long nativeObj); - static void getAllDisplaysAni(ani_env* env, ani_object arrayObj); - static void getDisplayByIdSyncAni(ani_env* env, ani_object obj, ani_double displayId); - static void getDefaultDisplaySyncAni(ani_env* env, ani_object obj); + static void GetAllDisplaysAni(ani_env* env, ani_object arrayObj); + static void GetDisplayByIdSyncAni(ani_env* env, ani_object obj, ani_long displayId); + static void GetDefaultDisplaySyncAni(ani_env* env, ani_object obj); - static void registerCallback(ani_env* env, ani_string type, + static void RegisterCallback(ani_env* env, ani_string type, ani_ref callback, ani_long nativeObj); - static void unRegisterCallback(ani_env* env, ani_string type, + static void UnRegisterCallback(ani_env* env, ani_string type, ani_long nativeObj, ani_ref callback); DMError UnRegisterDisplayListenerWithType(std::string type, ani_env* env, ani_ref callback); DMError UnregisterAllDisplayListenerWithType(std::string type); - DmErrorCode processRegisterCallback(ani_env* env, std::string& typeStr, + DmErrorCode ProcessRegisterCallback(ani_env* env, std::string& typeStr, sptr displayAniListener); + static ani_boolean HasPrivateWindow(ani_env* env, ani_long displayId); + static void GetAllDisplayPhysicalResolution(ani_env* env, ani_object arrayObj, ani_long nativeObj); private: - void onRegisterCallback(ani_env* env, ani_string type, ani_ref callback); - void onUnRegisterCallback(ani_env* env, ani_string type, ani_ref callback); - void onGetCurrentFoldCreaseRegion(ani_env* env, ani_object obj); + void OnRegisterCallback(ani_env* env, ani_string type, ani_ref callback); + 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/include/display_ani_utils.h b/interfaces/kits/ani/display_runtime/display_ani/include/display_ani_utils.h index 23845605e849ee1247284224f17fd4ee6c6b89bd..20d54fed94a05b9c0667cf63516208f1323b73e9 100644 --- a/interfaces/kits/ani/display_runtime/display_ani/include/display_ani_utils.h +++ b/interfaces/kits/ani/display_runtime/display_ani/include/display_ani_utils.h @@ -29,12 +29,17 @@ namespace Rosen { class DisplayAniUtils { public: -static void convertRect(DMRect rect, ani_object rectObj, ani_env* env); +static void ConvertRect(DMRect rect, ani_object rectObj, ani_env* env); -static void convertWaterArea(WaterfallDisplayAreaRects waterfallDisplayAreaRects, +static void ConvertWaterArea(WaterfallDisplayAreaRects waterfallDisplayAreaRects, ani_object waterfallObj, ani_env *env); -static ani_status cvtDisplay(sptr display, ani_env* env, ani_object obj); +static void ConvertDisplayPhysicalResolution(std::vector &displayPhysicalArray, + ani_object arrayObj, ani_env *env); + +static ani_enum_item CreateAniEnum(ani_env* env, const char* enum_descriptor, ani_size index); + +static ani_status CvtDisplay(sptr display, ani_env* env, ani_object obj); static ani_status GetStdString(ani_env *env, ani_string ani_str, std::string &result); @@ -46,10 +51,14 @@ static ani_object CreateAniUndefined(ani_env* env); static void CreateAniArrayInt(ani_env* env, ani_size size, ani_array_int *aniArray, std::vector vec); +static void CreateAniArrayDouble(ani_env* env, ani_size size, ani_array_double *aniArray, std::vector vec); + static ani_status GetAniString(ani_env* env, const std::string& str, ani_string* result); -static ani_status CallAniFunctionVoid(ani_env *env, const char* ns, +static ani_status CallAniFunctionVoid(ani_env* env, const char* ns, const char* fn, const char* signature, ...); + +static ani_object CreateRectObject(ani_env* env); }; } } 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 e60d854ce25cab3434d529037d9bb95a3981feda..88f4f88e5a8d6646ace8fc2869e5d10efa7d4b9a 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 @@ -98,10 +98,10 @@ ani_object AniErrUtils::CreateAniError(ani_env* env, const DMError& errorCode, s env->String_NewUTF8(msg.c_str(), msg.size(), &aniMsg); ani_object aniError = nullptr; ani_class cls; - if (ANI_OK != env->FindClass("Lescompat/Error", &cls)) { + if (ANI_OK != env->FindClass("escompat.Error", &cls)) { TLOGE(WmsLogTag::DMS, "[ANI] null class FoldCreaseRegionImpl"); } - DisplayAniUtils::NewAniObject(env, cls, "Lstd/core/String;Lescompat/ErrorOptions;:V", &aniError, aniMsg); + DisplayAniUtils::NewAniObject(env, cls, "C{std.core.String}C{escompat.ErrorOptions}:", &aniError, aniMsg); return aniError; } @@ -112,10 +112,10 @@ ani_object AniErrUtils::CreateAniError(ani_env* env, const DmErrorCode& errorCod env->String_NewUTF8(msg.c_str(), msg.size(), &aniMsg); ani_object aniError = nullptr; ani_class cls; - if (ANI_OK != env->FindClass("Lescompat/Error", &cls)) { + if (ANI_OK != env->FindClass("escompat.Error", &cls)) { TLOGE(WmsLogTag::DMS, "[ANI] null class FoldCreaseRegionImpl"); } - DisplayAniUtils::NewAniObject(env, cls, "Lstd/core/String;Lescompat/ErrorOptions;:V", &aniError, aniMsg); + DisplayAniUtils::NewAniObject(env, cls, "C{std.core.String}C{escompat.ErrorOptions}:", &aniError, aniMsg); return aniError; } @@ -147,13 +147,13 @@ ani_status AniErrUtils::CreateBusinessError(ani_env* env, int32_t error, std::st { TLOGI(WmsLogTag::DMS, "[ANI] in"); ani_class aniClass; - ani_status status = env->FindClass("L@ohos/display/BusinessError;", &aniClass); + ani_status status = env->FindClass("@ohos.base.BusinessError", &aniClass); if (status != ANI_OK) { TLOGE(WmsLogTag::DMS, "[ANI] class not found, status:%{public}d", static_cast(status)); return status; } ani_method aniCtor; - status = env->Class_FindMethod(aniClass, "", "Lstd/core/String;Lescompat/ErrorOptions;:V", &aniCtor); + status = env->Class_FindMethod(aniClass, "", "C{std.core.String}C{escompat.ErrorOptions}:", &aniCtor); if (status != ANI_OK) { TLOGE(WmsLogTag::DMS, "[ANI] ctor not found, status:%{public}d", static_cast(status)); return status; @@ -165,13 +165,11 @@ 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_Int(*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; } - status = env->Object_SetFieldByName_Int(*err, "code", static_cast(error)); - return ANI_OK; } 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 ac51ee677e380f2f6ab5d675ce3493169ec5c4b5..5e9bb5b478ca9480a3c37699be6f6a8c92eca897 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 @@ -15,30 +15,35 @@ #include #include "ani.h" +#include "ani_err_utils.h" +#include "display.h" #include "display_ani.h" +#include "display_ani_manager.h" +#include "display_ani_utils.h" #include "display_info.h" -#include "display.h" -#include "singleton_container.h" #include "display_manager.h" -#include "window_manager_hilog.h" #include "dm_common.h" -#include "display_ani_utils.h" +#include "interop_js/arkts_esvalue.h" +#include "interop_js/arkts_interop_js_api.h" +#include "interop_js/hybridgref_ani.h" +#include "interop_js/hybridgref_napi.h" +#include "js_display.h" #include "refbase.h" -#include "display_ani_manager.h" -#include "ani_err_utils.h" +#include "singleton_container.h" +#include "window_manager_hilog.h" namespace OHOS { namespace Rosen { // construct, set registerManager. -DisplayAni::DisplayAni(const std::shared_ptr& display) +DisplayAni::DisplayAni(const sptr& display) : display_(display) { } -void DisplayAni::getCutoutInfo(ani_env* env, ani_object obj, ani_object cutoutInfoObj) +void DisplayAni::GetCutoutInfo(ani_env* env, ani_object obj, ani_object cutoutInfoObj) { auto display = SingletonContainer::Get().GetDefaultDisplay(); - TLOGI(WmsLogTag::DMS, "[ANI] getCutoutInfo begin"); + TLOGI(WmsLogTag::DMS, "[ANI] begin"); sptr cutoutInfo = display->GetCutoutInfo(); if (cutoutInfo == nullptr) { AniErrUtils::ThrowBusinessError(env, DmErrorCode::DM_ERROR_INVALID_SCREEN, ""); @@ -50,77 +55,422 @@ void DisplayAni::getCutoutInfo(ani_env* env, ani_object obj, ani_object cutoutIn if (ANI_OK != status) { TLOGE(WmsLogTag::DMS, "[ANI] get field bounding rects fail, ani_status = %{public}d", status); } - ani_double length; - if (ANI_OK != env->Object_GetPropertyByName_Double(static_cast(boundingRects), "length", &length)) { + ani_int length; + if (ANI_OK != env->Object_GetPropertyByName_Int(static_cast(boundingRects), "length", &length)) { TLOGE(WmsLogTag::DMS, "[ANI] get ani_array len fail"); } for (int i = 0; i < std::min(int(length), static_cast(rects.size())); i++) { ani_ref currentCutoutInfo; if (ANI_OK != env->Object_CallMethodByName_Ref(static_cast(boundingRects), "$_get", - "I:Lstd/core/Object;", ¤tCutoutInfo, (ani_int)i)) { + "i:C{std.core.Object}", ¤tCutoutInfo, (ani_int)i)) { TLOGE(WmsLogTag::DMS, "[ANI] get ani_array index %{public}u fail", (ani_int)i); } TLOGI(WmsLogTag::DMS, "current i: %{public}d", i); - DisplayAniUtils::convertRect(rects[i], static_cast(currentCutoutInfo), env); + DisplayAniUtils::ConvertRect(rects[i], static_cast(currentCutoutInfo), env); } // waterfall area ani_ref waterfallObj = nullptr; env->Object_GetFieldByName_Ref(cutoutInfoObj, "waterfallDisplayAreaRects", &waterfallObj); auto waterfallDisplayAreaRects = cutoutInfo->GetWaterfallDisplayAreaRects(); - DisplayAniUtils::convertWaterArea(waterfallDisplayAreaRects, static_cast(waterfallObj), env); + DisplayAniUtils::ConvertWaterArea(waterfallDisplayAreaRects, static_cast(waterfallObj), env); +} + +void DisplayAni::GetAvailableArea(ani_env* env, ani_object obj, ani_object availableAreaObj) +{ + TLOGI(WmsLogTag::DMS, "[ANI] begin"); + ani_long id; + env->Object_GetFieldByName_Long(obj, "id", &id); + auto display = SingletonContainer::Get().GetDisplayById(id); + if (display == nullptr) { + TLOGE(WmsLogTag::DMS, "[ANI] can not find display."); + AniErrUtils::ThrowBusinessError(env, DmErrorCode::DM_ERROR_INVALID_SCREEN, + "JsDisplay::GetAvailableArea failed, can not find display."); + return; + } + DMRect area; + DmErrorCode ret = DM_JS_TO_ERROR_CODE_MAP.at(display->GetAvailableArea(area)); + if (ret != DmErrorCode::DM_OK) { + TLOGE(WmsLogTag::DMS, "[ANI] Display get available area failed."); + AniErrUtils::ThrowBusinessError(env, ret, "JsDisplay::GetAvailableArea failed."); + return; + } + DisplayAniUtils::ConvertRect(area, availableAreaObj, env); +} + +ani_boolean DisplayAni::HasImmersiveWindow(ani_env* env, ani_object obj) +{ + TLOGI(WmsLogTag::DMS, "[ANI] begin"); + ani_long id; + env->Object_GetFieldByName_Long(obj, "id", &id); + auto display = SingletonContainer::Get().GetDisplayById(id); + if (display == nullptr) { + TLOGE(WmsLogTag::DMS, "[ANI]can not find display."); + AniErrUtils::ThrowBusinessError(env, DmErrorCode::DM_ERROR_INVALID_SCREEN, + "can not find display."); + return false; + } + bool immersive = false; + DmErrorCode ret = DM_JS_TO_ERROR_CODE_MAP.at(display->HasImmersiveWindow(immersive)); + if (ret != DmErrorCode::DM_OK) { + TLOGE(WmsLogTag::DMS, "[ANI] get display has immersive window failed."); + AniErrUtils::ThrowBusinessError(env, ret, "JsDisplay::HasImmersiveWindow failed."); + return false; + } + return immersive; +} + +bool DisplayAni::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 is already registered!"); + return true; + } + } + return false; +} + +void DisplayAni::RegisterCallback(ani_env* env, ani_object obj, ani_string type, ani_ref callback) +{ + TLOGI(WmsLogTag::DMS, "[ANI] begin"); + ani_long displayRef; + env->Object_GetFieldByName_Long(obj, "displayRef", &displayRef); + DisplayAni* displayAni = reinterpret_cast(displayRef); + if (displayAni != nullptr) { + displayAni->OnRegisterCallback(env, obj, type, callback); + } else { + TLOGE(WmsLogTag::DMS, "[ANI] displayAni not found"); + } +} + +void DisplayAni::OnRegisterCallback(ani_env* env, ani_object obj, ani_string type, ani_ref callback) +{ + std::string typeString; + DisplayAniUtils::GetStdString(env, type, typeString); + ani_boolean callbackUndefined = 0; + env->Reference_IsUndefined(callback, &callbackUndefined); + if (callbackUndefined) { + std::string errMsg = "[ANI] failed to register display listener with type, cbk null or undefined"; + TLOGE(WmsLogTag::DMS, "callback undef"); + AniErrUtils::ThrowBusinessError(env, DmErrorCode::DM_ERROR_INVALID_PARAM, errMsg); + return; + } + if (IsCallbackRegistered(env, typeString, callback)) { + TLOGI(WmsLogTag::DMS, "Callback has already been registered!"); + return; + } + + sptr displayAniListener = new(std::nothrow) DisplayAniListener(env); + if (displayAniListener == nullptr) { + TLOGE(WmsLogTag::DMS, "[ANI]displayListener is nullptr"); + AniErrUtils::ThrowBusinessError(env, DMError::DM_ERROR_INVALID_PARAM, "displayListener is nullptr"); + return; + } + DMError ret = DMError::DM_OK; + std::lock_guard lock(mtx_); + if (typeString == ANI_EVENT_AVAILABLE_AREA_CHANGED) { + auto displayId = display_->GetId(); + TLOGI(WmsLogTag::DMS, "[ANI] availableAreaChange begin"); + ret = SingletonContainer::Get().RegisterAvailableAreaListener(displayAniListener, displayId); + } else { + ret = DMError::DM_ERROR_INVALID_PARAM; + } + DmErrorCode retCode = DM_JS_TO_ERROR_CODE_MAP.at(ret); + if (retCode != DmErrorCode::DM_OK) { + TLOGI(WmsLogTag::DMS, "Failed to register display listener with type"); + std::string errMsg = "Failed to register display listener with type"; + AniErrUtils::ThrowBusinessError(env, DMError::DM_ERROR_INVALID_PARAM, errMsg); + return; + } + ani_ref cbRef{}; + if (ANI_OK != env->GlobalReference_Create(callback, &cbRef)) { + TLOGE(WmsLogTag::DMS, "[ANI]create global ref fail"); + return; + } + displayAniListener->AddCallback(typeString, cbRef); + displayAniListener->SetMainEventHandler(); + jsCbMap_[typeString][callback] = displayAniListener; +} + +void DisplayAni::UnRegisterCallback(ani_env* env, ani_object obj, ani_string type, ani_ref callback) +{ + TLOGI(WmsLogTag::DMS, "[ANI] begin"); + ani_long displayRef; + env->Object_GetFieldByName_Long(obj, "displayRef", &displayRef); + DisplayAni* displayAni = reinterpret_cast(displayRef); + if (displayAni != nullptr) { + displayAni->OnUnRegisterCallback(env, obj, type, callback); + } else { + TLOGE(WmsLogTag::DMS, "[ANI] DisplayAni null"); + } +} + +void DisplayAni::OnUnRegisterCallback(ani_env* env, ani_object obj, ani_string type, ani_ref callback) +{ + TLOGI(WmsLogTag::DMS, "[ANI] begin"); + std::string typeString; + DisplayAniUtils::GetStdString(env, type, typeString); + ani_boolean callbackUndefined = 0; + env->Reference_IsUndefined(callback, &callbackUndefined); + DmErrorCode ret; + if (callbackUndefined) { + TLOGI(WmsLogTag::DMS, "[ANI] for all"); + ret = DM_JS_TO_ERROR_CODE_MAP.at(UnregisterAllDisplayListenerWithType(typeString)); + } else { + TLOGI(WmsLogTag::DMS, "[ANI] with type"); + ret = DM_JS_TO_ERROR_CODE_MAP.at(UnregisterDisplayListenerWithType(typeString, env, callback)); + } + + if (ret != DmErrorCode::DM_OK) { + std::string errMsg = "[ANI] failed to unregister display listener with type"; + TLOGE(WmsLogTag::DMS, "[ANI] failed to unregister display listener with type"); + AniErrUtils::ThrowBusinessError(env, DMError::DM_ERROR_INVALID_PARAM, errMsg); + } +} + +DMError DisplayAni::UnregisterAllDisplayListenerWithType(std::string type) +{ + TLOGI(WmsLogTag::DMS, "[ANI] begin"); + std::lock_guard lock(mtx_); + if (jsCbMap_.empty() || jsCbMap_.find(type) == jsCbMap_.end()) { + TLOGI(WmsLogTag::DMS, "[ANI] methodName %{public}s not registered!", + type.c_str()); + return DMError::DM_OK; + } + DMError ret = DMError::DM_OK; + for (auto it = jsCbMap_[type].begin(); it != jsCbMap_[type].end();) { + if (it->second == nullptr) { + TLOGE(WmsLogTag::DMS, "listener is null"); + continue; + } + it->second->RemoveAllCallback(); + if (type == ANI_EVENT_AVAILABLE_AREA_CHANGED) { + auto displayId = display_->GetId(); + sptr thisListener(it->second); + ret = SingletonContainer::Get().UnregisterAvailableAreaListener(thisListener, displayId); + } else { + ret = DMError::DM_ERROR_INVALID_PARAM; + } + jsCbMap_[type].erase(it++); + } + jsCbMap_.erase(type); + return ret; +} + +DMError DisplayAni::UnregisterDisplayListenerWithType(std::string type, ani_env* env, ani_ref callback) +{ + TLOGI(WmsLogTag::DMS, "[ANI] begin"); + std::lock_guard lock(mtx_); + if (jsCbMap_.empty() || jsCbMap_.find(type) == jsCbMap_.end()) { + TLOGI(WmsLogTag::DMS, "[ANI] methodName %{public}s not registered!", type.c_str()); + return DMError::DM_OK; + } + DMError ret = DMError::DM_OK; + for (auto it = jsCbMap_[type].begin(); it != jsCbMap_[type].end();) { + ani_boolean isEquals = 0; + env->Reference_StrictEquals(callback, it->first, &isEquals); + if (isEquals) { + if (it->second == nullptr) { + TLOGE(WmsLogTag::DMS, "listener is null"); + continue; + } + it->second->RemoveCallback(env, type, callback); + if (type == ANI_EVENT_AVAILABLE_AREA_CHANGED) { + TLOGI(WmsLogTag::DMS, "[ANI] start to unregis display event listener! event = %{public}s", + type.c_str()); + auto displayId = display_->GetId(); + sptr thisListener(it->second); + ret = SingletonContainer::Get().UnregisterAvailableAreaListener(thisListener, + displayId); + } else { + ret = DMError::DM_ERROR_INVALID_PARAM; + } + jsCbMap_[type].erase(it++); + TLOGI(WmsLogTag::DMS, "[ANI] unregister display listener with type: %{public}s ret: %{public}u", + type.c_str(), ret); + break; + } else { + it++; + } + } + if (jsCbMap_[type].empty()) { + jsCbMap_.erase(type); + } + return ret; +} + +void DisplayAni::CreateDisplayAni(sptr display, ani_object displayObj, ani_env* env) +{ + std::unique_ptr displayAni = std::make_unique(display); + if (ANI_OK != env->Object_SetFieldByName_Long(static_cast(displayObj), + "displayRef", reinterpret_cast(displayAni.release()))) { + TLOGE(WmsLogTag::DMS, "[ANI] set displayAni ref fail"); + } +} + +ani_boolean DisplayAni::TransferStatic(ani_env* env, ani_object obj, ani_object input, ani_object displayAniObj) +{ + TLOGI(WmsLogTag::DMS, "begin"); + void* unwrapResult = nullptr; + auto ret = arkts_esvalue_unwrap(env, input, &unwrapResult); + if (!ret) { + TLOGE(WmsLogTag::DMS, "[ANI] fail to unwrap input, %{public}d", ret); + return false; + } + if (unwrapResult == nullptr) { + TLOGE(WmsLogTag::DMS, "[ANI] unwrapResult is nullptr"); + return false; + } + JsDisplay* jsDisplay = static_cast(unwrapResult); + if (jsDisplay == nullptr) { + TLOGE(WmsLogTag::DMS, "[ANI] jsDisplay is nullptr"); + return false; + } + + sptr display = jsDisplay->GetDisplay(); + if (DisplayAniUtils::CvtDisplay(display, env, displayAniObj) != ANI_OK) { + TLOGE(WmsLogTag::DMS, "[ANI] convert display failed"); + return false; + } + DisplayAni::CreateDisplayAni(display, displayAniObj, env); + return true; +} + +ani_object DisplayAni::TransferDynamic(ani_env* env, ani_object obj, ani_long nativeObj) +{ + TLOGI(WmsLogTag::DMS, "begin"); + DisplayAni* aniDisplay = reinterpret_cast(nativeObj); + if (aniDisplay == nullptr) { + TLOGE(WmsLogTag::DMS, "[ANI] aniDisplay is nullptr"); + return nullptr; + } + napi_env napiEnv = {}; + if (!arkts_napi_scope_open(env, &napiEnv)) { + TLOGE(WmsLogTag::DMS, "arkts_napi_scope_open failed"); + return nullptr; + } + + sptr display = aniDisplay->GetDisplay(); + napi_value jsDisplay = CreateJsDisplayObject(napiEnv, display); + hybridgref ref = nullptr; + if (!hybridgref_create_from_napi(napiEnv, jsDisplay, &ref)) { + TLOGE(WmsLogTag::DMS, "hybridgref_create_from_napi failed"); + return nullptr; + } + ani_object result = nullptr; + if (!hybridgref_get_esvalue(env, ref, &result)) { + hybridgref_delete_from_napi(napiEnv, ref); + TLOGE(WmsLogTag::DMS, "hybridgref_get_esvalue failed"); + return nullptr; + } + hybridgref_delete_from_napi(napiEnv, ref); + if (!arkts_napi_scope_close_n(napiEnv, 0, nullptr, nullptr)) { + TLOGE(WmsLogTag::DMS, "arkts_napi_scope_close_n failed"); + return nullptr; + } + return result; +} + +ani_status DisplayAni::NspBindNativeFunctions(ani_env* env, ani_namespace nsp) +{ + std::array funcs = { + ani_native_function {"isFoldable", ":z", reinterpret_cast(DisplayManagerAni::IsFoldableAni)}, + ani_native_function {"getFoldDisplayModeNative", ":i", + reinterpret_cast(DisplayManagerAni::GetFoldDisplayModeAni)}, + ani_native_function {"getFoldStatusNative", ":i", reinterpret_cast(DisplayManagerAni::GetFoldStatus)}, + ani_native_function {"getCurrentFoldCreaseRegionNative", "C{std.core.Object}l:", + reinterpret_cast(DisplayManagerAni::GetCurrentFoldCreaseRegion)}, + ani_native_function {"getDisplayByIdSyncNative", "C{std.core.Object}l:", + reinterpret_cast(DisplayManagerAni::GetDisplayByIdSyncAni)}, + ani_native_function {"getDefaultDisplaySyncNative", "C{std.core.Object}:", + reinterpret_cast(DisplayManagerAni::GetDefaultDisplaySyncAni)}, + ani_native_function {"getAllDisplaysSyncNative", "C{escompat.Array}:", + reinterpret_cast(DisplayManagerAni::GetAllDisplaysAni)}, + ani_native_function {"syncOn", nullptr, + reinterpret_cast(DisplayManagerAni::RegisterCallback)}, + ani_native_function {"syncOff", nullptr, + reinterpret_cast(DisplayManagerAni::UnRegisterCallback)}, + ani_native_function {"hasPrivateWindow", nullptr, + reinterpret_cast(DisplayManagerAni::HasPrivateWindow)}, + ani_native_function {"getAllDisplayPhysicalResolutionNative", nullptr, + reinterpret_cast(DisplayManagerAni::GetAllDisplayPhysicalResolution)}, + ani_native_function {"isCaptured", nullptr, reinterpret_cast(DisplayManagerAni::IsCaptured)}, + }; + auto ret = env->Namespace_BindNativeFunctions(nsp, funcs.data(), funcs.size()); + if (ret != ANI_OK) { + TLOGE(WmsLogTag::DMS, "[ANI] bind namespace fail %{public}u", ret); + return ANI_NOT_FOUND; + } + return ANI_OK; +} + +ani_status DisplayAni::ClassBindNativeFunctions(ani_env* env, ani_class displayCls) +{ + std::array methods = { + ani_native_function {"getCutoutInfoInternal", "C{@ohos.display.display.CutoutInfo}:", + reinterpret_cast(DisplayAni::GetCutoutInfo)}, + ani_native_function {"getAvailableAreaInternal", "C{@ohos.display.display.Rect}:", + reinterpret_cast(DisplayAni::GetAvailableArea)}, + ani_native_function {"hasImmersiveWindowInternal", ":z", + reinterpret_cast(DisplayAni::HasImmersiveWindow)}, + ani_native_function {"syncOn", nullptr, + reinterpret_cast(DisplayAni::RegisterCallback)}, + ani_native_function {"syncOff", nullptr, + reinterpret_cast(DisplayAni::UnRegisterCallback)}, + ani_native_function {"nativeTransferStatic", "C{std.interop.ESValue}C{std.core.Object}:z", + reinterpret_cast(DisplayAni::TransferStatic)}, + ani_native_function {"nativeTransferDynamic", "l:C{std.interop.ESValue}", + reinterpret_cast(DisplayAni::TransferDynamic)}, + }; + auto ret = env->Class_BindNativeMethods(displayCls, methods.data(), methods.size()); + if (ret != ANI_OK) { + TLOGE(WmsLogTag::DMS, "[ANI] bind class fail %{public}u", ret); + return ANI_NOT_FOUND; + } + return ANI_OK; } extern "C" { -ANI_EXPORT ani_status ANI_Constructor(ani_vm *vm, uint32_t *result) +ANI_EXPORT ani_status ANI_Constructor(ani_vm* vm, uint32_t* result) { using namespace OHOS::Rosen; ani_status ret; - ani_env *env; + ani_env* env; if ((ret = vm->GetEnv(ANI_VERSION_1, &env)) != ANI_OK) { TLOGE(WmsLogTag::DMS, "[ANI] null env"); return ANI_NOT_FOUND; } ani_namespace nsp; - if ((ret = env->FindNamespace("L@ohos/display/display;", &nsp)) != ANI_OK) { + if ((ret = env->FindNamespace("@ohos.display.display", &nsp)) != ANI_OK) { TLOGE(WmsLogTag::DMS, "[ANI] null env %{public}u", ret); return ANI_NOT_FOUND; } - DisplayManagerAni::initDisplayManagerAni(nsp, env); - std::array funcs = { - ani_native_function {"isFoldable", ":Z", reinterpret_cast(DisplayManagerAni::isFoldableAni)}, - ani_native_function {"getFoldDisplayModeNative", ":I", - reinterpret_cast(DisplayManagerAni::getFoldDisplayModeAni)}, - ani_native_function {"getFoldStatusNative", ":I", reinterpret_cast(DisplayManagerAni::getFoldStatus)}, - ani_native_function {"getCurrentFoldCreaseRegionNative", "Lstd/core/Object;J:V", - reinterpret_cast(DisplayManagerAni::getCurrentFoldCreaseRegion)}, - ani_native_function {"getDisplayByIdSyncNative", "Lstd/core/Object;D:V", - reinterpret_cast(DisplayManagerAni::getDisplayByIdSyncAni)}, - ani_native_function {"getDefaultDisplaySyncNative", "Lstd/core/Object;:V", - reinterpret_cast(DisplayManagerAni::getDefaultDisplaySyncAni)}, - ani_native_function {"getAllDisplaysSyncNative", "Lescompat/Array;:V", - reinterpret_cast(DisplayManagerAni::getAllDisplaysAni)}, - ani_native_function {"syncOn", nullptr, - reinterpret_cast(DisplayManagerAni::registerCallback)}, - ani_native_function {"syncOff", nullptr, - reinterpret_cast(DisplayManagerAni::unRegisterCallback)} - }; - if ((ret = env->Namespace_BindNativeFunctions(nsp, funcs.data(), funcs.size()))) { + DisplayManagerAni::InitDisplayManagerAni(nsp, env); + ret = DisplayAni::NspBindNativeFunctions(env, nsp); + if (ret != ANI_OK) { TLOGE(WmsLogTag::DMS, "[ANI] bind namespace fail %{public}u", ret); - return ANI_NOT_FOUND; + return ret; } ani_class displayCls = nullptr; - if ((ret = env->FindClass("L@ohos/display/display/DisplayImpl;", &displayCls)) != ANI_OK) { + if ((ret = env->FindClass("@ohos.display.display.DisplayImpl", &displayCls)) != ANI_OK) { TLOGE(WmsLogTag::DMS, "[ANI] null env %{public}u", ret); return ANI_NOT_FOUND; } - std::array methods = { - ani_native_function {"getCutoutInfoInternal", "L@ohos/display/display/CutoutInfo;:V", - reinterpret_cast(DisplayAni::getCutoutInfo)}, - }; - if ((ret = env->Class_BindNativeMethods(displayCls, methods.data(), methods.size())) != ANI_OK) { - TLOGE(WmsLogTag::DMS, "[ANI] bind fail %{public}u", ret); - return ANI_NOT_FOUND; + ret = DisplayAni::ClassBindNativeFunctions(env, displayCls); + if (ANI_OK != ret) { + TLOGE(WmsLogTag::DMS, "[ANI] bind class fail %{public}u", ret); + return ret; + } + if (result == nullptr) { + TLOGE(WmsLogTag::DMS, "[ANI] Result is nullptr"); + return ANI_INVALID_ARGS; } *result = ANI_VERSION_1; return ANI_OK; 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 f9c0410cc3a8cd3407c9e269a594e0f8177c0906..514d06d8e5fd605c17db98656d3058a79ad15d49 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 @@ -38,25 +38,20 @@ void DisplayAniListener::AddCallback(const std::string& type, ani_ref callback) { TLOGI(WmsLogTag::DMS, "[ANI] AddCallback is called, type = %{public}s", type.c_str()); if (env_ == nullptr) { - TLOGE(WmsLogTag::DMS, "env_ nullptr"); + TLOGE(WmsLogTag::DMS, "[ANI] env nullptr"); return; } - std::lock_guard lock(aniCallBackMtx_); - ani_ref cbRef{}; - if (env_->GlobalReference_Create(callback, &cbRef) != ANI_OK) { - TLOGE(WmsLogTag::DEFAULT, "[ANI]create global ref fail"); - return; - }; - aniCallBack_[type].emplace_back(cbRef); - TLOGI(WmsLogTag::DMS, "[ANI] AddCallback success aniCallBack_ size: %{public}u!", - static_cast(aniCallBack_[type].size())); + std::lock_guard lock(aniCallbackMtx_); + aniCallback_[type].emplace_back(callback); + TLOGI(WmsLogTag::DMS, "[ANI] AddCallback success aniCallback_ size: %{public}u!", + static_cast(aniCallback_[type].size())); } void DisplayAniListener::RemoveCallback(ani_env* env, const std::string& type, ani_ref callback) { - std::lock_guard lock(aniCallBackMtx_); - auto it = aniCallBack_.find(type); - if (it == aniCallBack_.end()) { + std::lock_guard lock(aniCallbackMtx_); + auto it = aniCallback_.find(type); + if (it == aniCallback_.end()) { TLOGE(WmsLogTag::DMS, "[ANI] Listener no callback to remove"); return; } @@ -76,184 +71,369 @@ void DisplayAniListener::RemoveCallback(ani_env* env, const std::string& type, a void DisplayAniListener::RemoveAllCallback() { - std::lock_guard lock(aniCallBackMtx_); - aniCallBack_.clear(); + std::lock_guard lock(aniCallbackMtx_); + for (const auto& [typeString, callbacks] : aniCallback_) { + for (auto callback : callbacks) { + if (env_) { + env_->GlobalReference_Delete(callback); + } + } + } + aniCallback_.clear(); } void DisplayAniListener::OnCreate(DisplayId id) { - TLOGI(WmsLogTag::DMS, "[ANI] OnCreate begin"); + TLOGI(WmsLogTag::DMS, "[ANI] begin, displayId: %{public}" PRIu64, id); auto thisListener = weakRef_.promote(); if (thisListener == nullptr) { - TLOGE(WmsLogTag::DEFAULT, "[ANI] this listener is nullptr"); + TLOGE(WmsLogTag::DMS, "[ANI] this listener is nullptr"); return; } - TLOGI(WmsLogTag::DMS, "[ANI] OnCreate is called, displayId: %{public}d", static_cast(id)); - if (aniCallBack_.empty()) { - TLOGE(WmsLogTag::DMS, "[ANI] OnCreate not register!"); + std::lock_guard lock(aniCallbackMtx_); + if (aniCallback_.empty()) { + TLOGE(WmsLogTag::DMS, "[ANI] Ani callback is empty!"); return; } - std::lock_guard lock(aniCallBackMtx_); - auto it = aniCallBack_.find(EVENT_ADD); - if (it == aniCallBack_.end()) { - TLOGE(WmsLogTag::DMS, "[ANI] OnCreate not this event, return"); + auto it = aniCallback_.find(ANI_EVENT_ADD); + if (it == aniCallback_.end()) { + TLOGE(WmsLogTag::DMS, "[ANI] Add callback has not been registered"); return; } std::vector vec = it->second; + TLOGI(WmsLogTag::DMS, "vec_callback size: %{public}d", vec.size()); + // find callbacks in vector for (ani_ref oneAniCallback : vec) { - ani_boolean result; - if (ANI_OK != env_->Reference_IsUndefined(oneAniCallback, &result)) { - TLOGE(WmsLogTag::DMS, "[ANI] OnCreate Callback is undefined, return"); + if (env_ == nullptr) { + TLOGE(WmsLogTag::DMS, "[ANI] null env"); return; } - if (ANI_OK != env_->Reference_IsNull(oneAniCallback, &result)) { - TLOGE(WmsLogTag::DMS, "[ANI] OnCreate Callback is null, return"); - return; + ani_boolean undefRes = 0; + env_->Reference_IsUndefined(oneAniCallback, &undefRes); + if (undefRes) { + TLOGE(WmsLogTag::DMS, "[ANI] oneAniCallback is undef"); + continue; } - auto task = [env = env_, oneAniCallback, id] () { - DisplayAniUtils::CallAniFunctionVoid(env, "L@ohos/display/display;", "displayEventCallBack", + auto task = [env = env_, oneAniCallback, id] { + DisplayAniUtils::CallAniFunctionVoid(env, "@ohos.display.display", "displayEventCallBack", nullptr, oneAniCallback, static_cast(id)); }; if (!eventHandler_) { - TLOGE(WmsLogTag::DEFAULT, "get main event handler failed!"); + TLOGE(WmsLogTag::DMS, "[ANI] get main event handler failed!"); return; } - eventHandler_->PostTask(task, "dms:AniDisplayListener::CreateCallBack", 0, + eventHandler_->PostTask(std::move(task), "dms:AniDisplayListener::CreateCallBack", 0, AppExecFwk::EventQueue::Priority::IMMEDIATE); } } void DisplayAniListener::OnDestroy(DisplayId id) { + TLOGI(WmsLogTag::DMS, "[ANI] begin, displayId: %{public}" PRIu64, id); + auto thisListener = weakRef_.promote(); + if (thisListener == nullptr) { + TLOGE(WmsLogTag::DMS, "[ANI] this listener is nullptr"); + return; + } + std::lock_guard lock(aniCallbackMtx_); + if (aniCallback_.empty()) { + TLOGE(WmsLogTag::DMS, "[ANI] Ani callback is empty!"); + return; + } + auto it = aniCallback_.find(ANI_EVENT_REMOVE); + if (it == aniCallback_.end()) { + TLOGE(WmsLogTag::DMS, "[ANI] Remove callback has not been registered"); + return; + } + std::vector vec = it->second; + TLOGI(WmsLogTag::DMS, "vec_callback size: %{public}d", vec.size()); + // find callbacks in vector + for (ani_ref oneAniCallback : vec) { + if (env_ == nullptr) { + TLOGE(WmsLogTag::DMS, "[ANI] null env"); + return; + } + ani_boolean undefRes = 0; + env_->Reference_IsUndefined(oneAniCallback, &undefRes); + if (undefRes) { + TLOGE(WmsLogTag::DMS, "[ANI] oneAniCallback is undef"); + continue; + } + auto task = [env = env_, oneAniCallback, id] { + DisplayAniUtils::CallAniFunctionVoid(env, "@ohos.display.display", "displayEventCallBack", + nullptr, oneAniCallback, static_cast(id)); + }; + if (!eventHandler_) { + TLOGE(WmsLogTag::DMS, "[ANI] get main event handler failed!"); + return; + } + eventHandler_->PostTask(std::move(task), "dms:AniDisplayListener::CreateCallBack", 0, + AppExecFwk::EventQueue::Priority::IMMEDIATE); + } } void DisplayAniListener::OnChange(DisplayId id) { - TLOGI(WmsLogTag::DMS, "[ANI] OnChange begin"); + TLOGI(WmsLogTag::DMS, "[ANI] begin, displayId: %{public}" PRIu64, id); auto thisListener = weakRef_.promote(); if (thisListener == nullptr) { - TLOGE(WmsLogTag::DEFAULT, "[ANI] this listener is nullptr"); + TLOGE(WmsLogTag::DMS, "[ANI] this listener is nullptr"); return; } - TLOGI(WmsLogTag::DMS, "[ANI] OnChange is called, displayId: %{public}d", static_cast(id)); - std::lock_guard lock(aniCallBackMtx_); - if (aniCallBack_.empty()) { + std::lock_guard lock(aniCallbackMtx_); + if (aniCallback_.empty()) { TLOGE(WmsLogTag::DMS, "[ANI] OnChange not register!"); return; } - auto it = aniCallBack_.find(EVENT_CHANGE); - if (it == aniCallBack_.end()) { + auto it = aniCallback_.find(ANI_EVENT_CHANGE); + if (it == aniCallback_.end()) { TLOGE(WmsLogTag::DMS, "[ANI] OnChange not this event, return"); return; } std::vector vec = it->second; for (auto oneAniCallback : vec) { if (env_ == nullptr) { - TLOGI(WmsLogTag::DMS, "OnDestroy: null env_"); + TLOGE(WmsLogTag::DMS, "[ANI] null env"); return; } - ani_boolean undefRes; - ani_boolean nullRes; + ani_boolean undefRes = 0; env_->Reference_IsUndefined(oneAniCallback, &undefRes); - env_->Reference_IsNull(oneAniCallback, &nullRes); - if (undefRes || nullRes) { - TLOGE(WmsLogTag::DMS, "[ANI] oneAniCallback undefRes, return"); - return; + if (undefRes) { + TLOGE(WmsLogTag::DMS, "[ANI] oneAniCallback undef, return"); + continue; } - auto task = [env = env_, oneAniCallback, id] () { - DisplayAniUtils::CallAniFunctionVoid(env, "L@ohos/display/display;", "displayEventCallBack", + auto task = [env = env_, oneAniCallback, id] { + DisplayAniUtils::CallAniFunctionVoid(env, "@ohos.display.display", "displayEventCallBack", nullptr, oneAniCallback, static_cast(id)); }; if (!eventHandler_) { - TLOGE(WmsLogTag::DEFAULT, "get main event handler failed!"); + TLOGE(WmsLogTag::DMS, "[ANI] get main event handler failed!"); return; } - eventHandler_->PostTask(task, "dms:AniWindowListener::SizeChangeCallBack", 0, + eventHandler_->PostTask(std::move(task), "dms:AniWindowListener::SizeChangeCallBack", 0, AppExecFwk::EventQueue::Priority::IMMEDIATE); } } void DisplayAniListener::OnPrivateWindow(bool hasPrivate) { + TLOGI(WmsLogTag::DMS, "[ANI] called, hasPrivate: %{public}u", + static_cast(hasPrivate)); + auto thisListener = weakRef_.promote(); + if (thisListener == nullptr || env_ == nullptr) { + TLOGE(WmsLogTag::DMS, "[ANI] this listener or env is nullptr"); + return; + } + std::lock_guard lock(aniCallbackMtx_); + if (aniCallback_.empty()) { + TLOGE(WmsLogTag::DMS, "[ANI] OnPrivateWindow not register!"); + return; + } + if (aniCallback_.find(ANI_EVENT_PRIVATE_MODE_CHANGE) == aniCallback_.end()) { + TLOGE(WmsLogTag::DMS, "[ANI] OnPrivateWindow not this event, return"); + return; + } + if (env_ == nullptr) { + TLOGE(WmsLogTag::DMS, "[ANI] env is nullptr"); + return; + } + + auto it = aniCallback_.find(ANI_EVENT_PRIVATE_MODE_CHANGE); + for (auto oneAniCallback : it->second) { + auto task = [env = env_, oneAniCallback, hasPrivate] () { + DisplayAniUtils::CallAniFunctionVoid(env, "@ohos.display.display", "captureStatusChangedCallback", + nullptr, oneAniCallback, hasPrivate); + }; + if (!eventHandler_) { + TLOGE(WmsLogTag::DMS, "[ANI] get main event handler failed!"); + return; + } + eventHandler_->PostTask(task, "dms:AniDisplayListener::PrivateWindowCallback", 0, + AppExecFwk::EventQueue::Priority::IMMEDIATE); + } } void DisplayAniListener::OnFoldStatusChanged(FoldStatus foldStatus) { - TLOGI(WmsLogTag::DMS, "[ANI] OnFoldStatusChanged is called, foldStatus: %{public}u", + TLOGI(WmsLogTag::DMS, "[ANI] called, foldStatus: %{public}u", static_cast(foldStatus)); auto thisListener = weakRef_.promote(); if (thisListener == nullptr || env_ == nullptr) { TLOGE(WmsLogTag::DMS, "[ANI] this listener or env is nullptr"); return; } - std::lock_guard lock(aniCallBackMtx_); - if (aniCallBack_.empty()) { + std::lock_guard lock(aniCallbackMtx_); + if (aniCallback_.empty()) { TLOGE(WmsLogTag::DMS, "[ANI] OnFoldStatusChanged not register!"); return; } - if (aniCallBack_.find(EVENT_FOLD_STATUS_CHANGED) == aniCallBack_.end()) { + if (aniCallback_.find(ANI_EVENT_FOLD_STATUS_CHANGED) == aniCallback_.end()) { TLOGE(WmsLogTag::DMS, "[ANI] OnFoldStatusChanged not this event, return"); return; } + if (env_ == nullptr) { + TLOGE(WmsLogTag::DMS, "[ANI] env is nullptr"); + return; + } + auto it = aniCallback_.find(ANI_EVENT_FOLD_STATUS_CHANGED); + for (auto oneAniCallback : it->second) { + auto task = [env = env_, oneAniCallback, foldStatus] () { + DisplayAniUtils::CallAniFunctionVoid(env, "@ohos.display.display", "foldStatusCallback", + nullptr, oneAniCallback, static_cast(foldStatus)); + }; + if (!eventHandler_) { + TLOGE(WmsLogTag::DMS, "[ANI] get main event handler failed!"); + return; + } + eventHandler_->PostTask(task, "dms:AniDisplayListener::FoldStatusChangedCallback", 0, + AppExecFwk::EventQueue::Priority::IMMEDIATE); + } +} +void DisplayAniListener::OnFoldAngleChanged(std::vector foldAngles) +{ + TLOGI(WmsLogTag::DMS, "[ANI] called"); + auto thisListener = weakRef_.promote(); + if (thisListener == nullptr || env_ == nullptr) { + TLOGE(WmsLogTag::DMS, "[ANI] this listener or env is nullptr"); + return; + } + std::lock_guard lock(aniCallbackMtx_); + if (aniCallback_.empty()) { + TLOGE(WmsLogTag::DMS, "[ANI] OnFoldAngleChanged not register!"); + return; + } + if (aniCallback_.find(ANI_EVENT_FOLD_ANGLE_CHANGED) == aniCallback_.end()) { + TLOGE(WmsLogTag::DMS, "[ANI] OnFoldAngleChanged not this event, return"); + return; + } if (env_ != nullptr) { - auto it = aniCallBack_.find(EVENT_FOLD_STATUS_CHANGED); + auto it = aniCallback_.find(ANI_EVENT_FOLD_ANGLE_CHANGED); + ani_array_double cbArray; + DisplayAniUtils::CreateAniArrayDouble(env_, foldAngles.size(), &cbArray, foldAngles); for (auto oneAniCallback : it->second) { - auto task = [env = env_, oneAniCallback, foldStatus] () { - DisplayAniUtils::CallAniFunctionVoid(env, "L@ohos/display/display;", "foldStatusCallback", - nullptr, oneAniCallback, static_cast(foldStatus)); + auto task = [env = env_, oneAniCallback, cbArray] () { + DisplayAniUtils::CallAniFunctionVoid(env, "@ohos.display.display", "foldAngleChangeCallback", + nullptr, oneAniCallback, cbArray); }; if (!eventHandler_) { - TLOGE(WmsLogTag::DEFAULT, "get main event handler failed!"); + TLOGE(WmsLogTag::DMS, "[ANI] get main event handler failed!"); return; } - eventHandler_->PostTask(task, "dms:AniDisplayListener::FoldStatusChangedCallback", 0, + eventHandler_->PostTask(task, "dms:AniDisplayListener::FoldAngleChangeCallback", 0, AppExecFwk::EventQueue::Priority::IMMEDIATE); } } else { - TLOGE(WmsLogTag::DMS, "[ANI] OnCreate: env is nullptr"); + TLOGE(WmsLogTag::DMS, "[ANI] env is nullptr"); } } -void DisplayAniListener::OnFoldAngleChanged(std::vector foldAngles) -{ -} void DisplayAniListener::OnCaptureStatusChanged(bool isCapture) { + TLOGI(WmsLogTag::DMS, "[ANI] called"); + auto thisListener = weakRef_.promote(); + if (thisListener == nullptr || env_ == nullptr) { + TLOGE(WmsLogTag::DMS, "[ANI] this listener or env is nullptr"); + return; + } + std::lock_guard lock(aniCallbackMtx_); + if (aniCallback_.empty()) { + TLOGE(WmsLogTag::DMS, "[ANI] OnCaptureStatusChanged not register!"); + return; + } + if (aniCallback_.find(ANI_EVENT_CAPTURE_STATUS_CHANGED) == aniCallback_.end()) { + TLOGE(WmsLogTag::DMS, "[ANI] OnCaptureStatusChanged not this event, return"); + return; + } + if (env_ != nullptr) { + auto it = aniCallback_.find(ANI_EVENT_CAPTURE_STATUS_CHANGED); + for (auto oneAniCallback : it->second) { + auto task = [env = env_, oneAniCallback, isCapture] () { + DisplayAniUtils::CallAniFunctionVoid(env, "@ohos.display.display", "captureStatusChangedCallback", + nullptr, oneAniCallback, isCapture); + }; + if (!eventHandler_) { + TLOGE(WmsLogTag::DMS, "[ANI] get main event handler failed!"); + return; + } + eventHandler_->PostTask(task, "dms:AniDisplayListener::CaptureStatusChangedCallback", 0, + AppExecFwk::EventQueue::Priority::IMMEDIATE); + } + } else { + TLOGE(WmsLogTag::DMS, "[ANI] env is nullptr"); + } } void DisplayAniListener::OnDisplayModeChanged(FoldDisplayMode foldDisplayMode) { - TLOGI(WmsLogTag::DMS, "[ANI] OnDisplayModeChanged is called, foldDisplayMode: %{public}u", + TLOGI(WmsLogTag::DMS, "[ANI] called, foldDisplayMode: %{public}u", static_cast(foldDisplayMode)); auto thisListener = weakRef_.promote(); if (thisListener == nullptr || env_ == nullptr) { TLOGE(WmsLogTag::DMS, "[ANI] this listener or env is nullptr"); return; } - std::lock_guard lock(aniCallBackMtx_); - if (aniCallBack_.empty()) { + std::lock_guard lock(aniCallbackMtx_); + if (aniCallback_.empty()) { TLOGE(WmsLogTag::DMS, "[ANI] OnDisplayModeChanged not register!"); return; } - if (aniCallBack_.find(EVENT_DISPLAY_MODE_CHANGED) == aniCallBack_.end()) { + if (aniCallback_.find(ANI_EVENT_DISPLAY_MODE_CHANGED) == aniCallback_.end()) { TLOGE(WmsLogTag::DMS, "[ANI] OnDisplayModeChanged not this event, return"); return; } if (env_ != nullptr) { - auto it = aniCallBack_.find(EVENT_DISPLAY_MODE_CHANGED); + auto it = aniCallback_.find(ANI_EVENT_DISPLAY_MODE_CHANGED); for (auto oneAniCallback : it->second) { auto task = [env = env_, oneAniCallback, foldDisplayMode] () { - DisplayAniUtils::CallAniFunctionVoid(env, "L@ohos/display/display;", "foldDisplayModeCallback", + DisplayAniUtils::CallAniFunctionVoid(env, "@ohos.display.display", "foldDisplayModeCallback", nullptr, oneAniCallback, static_cast(foldDisplayMode)); }; if (!eventHandler_) { - TLOGE(WmsLogTag::DEFAULT, "get main event handler failed!"); + TLOGE(WmsLogTag::DMS, "[ANI] get main event handler failed!"); return; } eventHandler_->PostTask(task, "dms:AniDisplayListener::DisplayModeChangedCallback", 0, AppExecFwk::EventQueue::Priority::IMMEDIATE); } } else { - TLOGE(WmsLogTag::DMS, "[ANI] OnDisplayModeChanged: env is nullptr"); + TLOGE(WmsLogTag::DMS, "[ANI] env is nullptr"); } } void DisplayAniListener::OnAvailableAreaChanged(DMRect area) { + TLOGI(WmsLogTag::DMS, "[ANI] called"); + auto thisListener = weakRef_.promote(); + if (thisListener == nullptr || env_ == nullptr) { + TLOGE(WmsLogTag::DMS, "[ANI] this listener or env is nullptr"); + return; + } + std::lock_guard lock(aniCallbackMtx_); + if (aniCallback_.empty()) { + TLOGE(WmsLogTag::DMS, "[ANI] OnAvailableAreaChanged not register!"); + return; + } + if (aniCallback_.find(ANI_EVENT_AVAILABLE_AREA_CHANGED) == aniCallback_.end()) { + TLOGE(WmsLogTag::DMS, "[ANI] OnAvailableAreaChanged not this event, return"); + return; + } + if (env_ != nullptr) { + auto it = aniCallback_.find(ANI_EVENT_AVAILABLE_AREA_CHANGED); + for (auto oneAniCallback : it->second) { + auto task = [env = env_, oneAniCallback, area] () { + ani_object rectObj = DisplayAniUtils::CreateRectObject(env); + if (!rectObj) { + TLOGE(WmsLogTag::DMS, "[ANI] CreateRectObject failed"); + return; + } + DisplayAniUtils::ConvertRect(area, rectObj, env); + DisplayAniUtils::CallAniFunctionVoid(env, "L@ohos/display/display;", "availableAreaChangedCallback", + nullptr, oneAniCallback, rectObj); + }; + if (!eventHandler_) { + TLOGE(WmsLogTag::DMS, "[ANI] get main event handler failed!"); + return; + } + eventHandler_->PostTask(task, "dms:AniDisplayListener::AvailableAreaChangedCallback", 0, + AppExecFwk::EventQueue::Priority::IMMEDIATE); + } + } else { + TLOGE(WmsLogTag::DMS, "[ANI] env is nullptr"); + } } ani_status DisplayAniListener::CallAniMethodVoid(ani_object object, const char* cls, @@ -276,4 +456,4 @@ ani_status DisplayAniListener::CallAniMethodVoid(ani_object object, const char* return ret; } } -} \ No newline at end of file +} 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 d85c12d35fc0f6916663bb49678d5b795f616e6c..2fd1aba528384b0e57450dbc1410a61ce90d224a 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 @@ -36,11 +36,11 @@ DisplayManagerAni::DisplayManagerAni() { } -ani_status DisplayManagerAni::initDisplayManagerAni(ani_namespace displayNameSpace, ani_env* env) +ani_status DisplayManagerAni::InitDisplayManagerAni(ani_namespace displayNameSpace, ani_env* env) { TLOGI(WmsLogTag::DEFAULT, "[ANI]"); ani_function setObjFunc = nullptr; - ani_status ret = env->Namespace_FindFunction(displayNameSpace, "setDisplayMgrRef", "J:V", &setObjFunc); + ani_status ret = env->Namespace_FindFunction(displayNameSpace, "setDisplayMgrRef", "l:", &setObjFunc); if (ret != ANI_OK) { TLOGE(WmsLogTag::DEFAULT, "[ANI] find setNativeObj func fail %{public}u", ret); return ret; @@ -54,226 +54,275 @@ ani_status DisplayManagerAni::initDisplayManagerAni(ani_namespace displayNameSpa return ret; } -ani_int DisplayManagerAni::getFoldDisplayModeAni(ani_env* env) +ani_int DisplayManagerAni::GetFoldDisplayModeAni(ani_env* env) { auto mode = SingletonContainer::Get().GetFoldDisplayMode(); TLOGI(WmsLogTag::DMS, "[ANI]" PRIu64", getFoldDisplayMode = %{public}u", mode); return static_cast(mode); } -ani_boolean DisplayManagerAni::isFoldableAni(ani_env* env) +ani_boolean DisplayManagerAni::IsFoldableAni(ani_env* env) { bool foldable = SingletonContainer::Get().IsFoldable(); TLOGI(WmsLogTag::DMS, "[ANI]" PRIu64", isFoldable = %{public}u", foldable); return static_cast(foldable); } -ani_int DisplayManagerAni::getFoldStatus(ani_env* env) +ani_boolean DisplayManagerAni::IsCaptured(ani_env* env) +{ + bool isCapture = SingletonContainer::Get().IsCaptured(); + TLOGI(WmsLogTag::DMS, "[ANI]" PRIu64", isCapture = %{public}u", isCapture); + return static_cast(isCapture); +} + +ani_int DisplayManagerAni::GetFoldStatus(ani_env* env) { auto status = SingletonContainer::Get().GetFoldStatus(); - TLOGI(WmsLogTag::DMS, "[ANI]" PRIu64", getFoldStatus = %{public}u", status); + TLOGI(WmsLogTag::DMS, "[ANI]" PRIu64", GetFoldStatus = %{public}u", status); return static_cast(status); } -void DisplayManagerAni::getCurrentFoldCreaseRegion(ani_env* env, ani_object obj, ani_long nativeObj) +void DisplayManagerAni::GetCurrentFoldCreaseRegion(ani_env* env, ani_object obj, ani_long nativeObj) { DisplayManagerAni* displayManagerAni = reinterpret_cast(nativeObj); if (displayManagerAni != nullptr) { - displayManagerAni->onGetCurrentFoldCreaseRegion(env, obj); + displayManagerAni->OnGetCurrentFoldCreaseRegion(env, obj); } else { TLOGI(WmsLogTag::DMS, "[ANI] null ptr"); } } -void DisplayManagerAni::onGetCurrentFoldCreaseRegion(ani_env* env, ani_object obj) +void DisplayManagerAni::OnGetCurrentFoldCreaseRegion(ani_env* env, ani_object obj) { - TLOGI(WmsLogTag::DMS, "[ANI] getCurrentFoldCreaseRegion begin instance"); + TLOGI(WmsLogTag::DMS, "[ANI] begin"); sptr region = SingletonContainer::Get().GetCurrentFoldCreaseRegion(); if (region == nullptr) { return; } - TLOGI(WmsLogTag::DMS, "[ANI] SingletonContainer getCurrentFoldCreaseRegion"); + TLOGI(WmsLogTag::DMS, "[ANI] SingletonContainer GetCurrentFoldCreaseRegion"); uint64_t displayId = region->GetDisplayId(); std::vector rects = region->GetCreaseRects(); if (rects.size() == 0) { return; } - TLOGI(WmsLogTag::DMS, "[ANI] DisplayManager getCurrentFoldCreaseRegion success %{public}d", (int)displayId); - if (ANI_OK != env->Object_SetFieldByName_Double(obj, "displayId", (ani_double)displayId)) { + TLOGI(WmsLogTag::DMS, "[ANI] DisplayManager GetCurrentFoldCreaseRegion success %{public}d", (int)displayId); + if (ANI_OK != env->Object_SetFieldByName_Long(obj, "displayId", (ani_long)displayId)) { TLOGE(WmsLogTag::DMS, "[ANI] set displayId field fail"); } ani_ref creaseRectsObj{}; if (ANI_OK != env->Object_GetFieldByName_Ref(obj, "creaseRects", &creaseRectsObj)) { TLOGE(WmsLogTag::DMS, "[ANI] get ani_array len fail"); } - ani_double length; - if (ANI_OK != env->Object_GetPropertyByName_Double(static_cast(creaseRectsObj), "length", &length)) { + ani_int length; + if (ANI_OK != env->Object_GetPropertyByName_Int(static_cast(creaseRectsObj), "length", &length)) { TLOGE(WmsLogTag::DMS, "[ANI] get ani_array len fail"); } TLOGI(WmsLogTag::DMS, "[ANI] set CurrentFoldCreaseRegion property begin"); - for (size_t i = 0; i < std::min(int(length), static_cast(rects.size())); i++) { + for (int i = 0; i < std::min(int(length), static_cast(rects.size())); i++) { ani_ref currentCrease; if (ANI_OK != env->Object_CallMethodByName_Ref(static_cast(creaseRectsObj), - "$_get", "I:Lstd/core/Object;", ¤tCrease, (ani_int)i)) { + "$_get", "i:C{std.core.Object}", ¤tCrease, (ani_int)i)) { TLOGE(WmsLogTag::DMS, "[ANI] get ani_array index %{public}u fail", (ani_int)i); } - TLOGI(WmsLogTag::DMS, "current i: %{public}u", i); - DisplayAniUtils::convertRect(rects[i], static_cast(currentCrease), env); + TLOGI(WmsLogTag::DMS, "current i: %{public}d", i); + DisplayAniUtils::ConvertRect(rects[i], static_cast(currentCrease), env); } } -void DisplayManagerAni::getAllDisplaysAni(ani_env* env, ani_object arrayObj) +void DisplayManagerAni::GetAllDisplaysAni(ani_env* env, ani_object arrayObj) { - TLOGI(WmsLogTag::DMS, "[ANI] getAllDisplaysAni start"); + TLOGI(WmsLogTag::DMS, "[ANI] start"); std::vector> displays = SingletonContainer::Get().GetAllDisplays(); if (displays.empty()) { AniErrUtils::ThrowBusinessError(env, DmErrorCode::DM_ERROR_INVALID_SCREEN, ""); } - ani_double length; - if (ANI_OK != env->Object_GetPropertyByName_Double(arrayObj, "length", &length)) { + ani_int length; + if (ANI_OK != env->Object_GetPropertyByName_Int(arrayObj, "length", &length)) { TLOGE(WmsLogTag::DMS, "[ANI] get ani_array len fail"); } for (int i = 0; i < std::min(int(length), static_cast(displays.size())); i++) { ani_ref currentDisplay; - if (ANI_OK != env->Object_CallMethodByName_Ref(arrayObj, "$_get", "I:Lstd/core/Object;", + if (ANI_OK != env->Object_CallMethodByName_Ref(arrayObj, "$_get", "i:C{std.core.Object}", ¤tDisplay, (ani_int)i)) { TLOGE(WmsLogTag::DMS, "[ANI] get ani_array index %{public}u fail", (ani_int)i); } TLOGI(WmsLogTag::DMS, "current i: %{public}d", i); - DisplayAniUtils::cvtDisplay(displays[i], env, static_cast(currentDisplay)); + DisplayAniUtils::CvtDisplay(displays[i], env, static_cast(currentDisplay)); + DisplayAni::CreateDisplayAni(displays[i], static_cast(currentDisplay), env); } - TLOGI(WmsLogTag::DMS, "[ANI] getAllDisplaysAni end"); + TLOGI(WmsLogTag::DMS, "[ANI] GetAllDisplaysAni end"); } -void DisplayManagerAni::getDisplayByIdSyncAni(ani_env* env, ani_object obj, ani_double displayId) +void DisplayManagerAni::GetDisplayByIdSyncAni(ani_env* env, ani_object obj, ani_long displayId) { - TLOGE(WmsLogTag::DMS, "[ANI] getDisplayByIdSyncAni begin"); + TLOGI(WmsLogTag::DMS, "[ANI] begin"); if (displayId < 0) { TLOGE(WmsLogTag::DMS, "[ANI] Invalid displayId, less than 0"); + AniErrUtils::ThrowBusinessError(env, DmErrorCode::DM_ERROR_INVALID_PARAM, "Invalid displayId"); 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); + DisplayAniUtils::CvtDisplay(display, env, obj); + DisplayAni::CreateDisplayAni(display, static_cast(obj), env); } -void DisplayManagerAni::getDefaultDisplaySyncAni(ani_env* env, ani_object obj) +void DisplayManagerAni::GetDefaultDisplaySyncAni(ani_env* env, ani_object obj) { sptr display = SingletonContainer::Get().GetDefaultDisplaySync(true); if (display == nullptr) { TLOGE(WmsLogTag::DMS, "[ANI] Display null"); return; } - TLOGI(WmsLogTag::DMS, "[ANI] getDefaultDisplaySyncAni"); - DisplayAniUtils::cvtDisplay(display, env, obj); + TLOGI(WmsLogTag::DMS, "[ANI] GetDefaultDisplaySyncAni"); + DisplayAniUtils::CvtDisplay(display, env, obj); + DisplayAni::CreateDisplayAni(display, static_cast(obj), env); return; } -void DisplayManagerAni::registerCallback(ani_env* env, ani_string type, +void DisplayManagerAni::RegisterCallback(ani_env* env, ani_string type, ani_ref callback, ani_long nativeObj) { DisplayManagerAni* displayManagerAni = reinterpret_cast(nativeObj); if (displayManagerAni != nullptr) { - displayManagerAni->onRegisterCallback(env, type, callback); + displayManagerAni->OnRegisterCallback(env, type, callback); } else { TLOGI(WmsLogTag::DMS, "[ANI] null ptr"); } } -void DisplayManagerAni::onRegisterCallback(ani_env* env, ani_string type, ani_ref callback) +void DisplayManagerAni::OnRegisterCallback(ani_env* env, ani_string type, ani_ref callback) { - TLOGI(WmsLogTag::DMS, "[ANI] onRegisterCallback"); - 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; } displayAniListener->AddCallback(typeString, cbRef); displayAniListener->SetMainEventHandler(); - ret = processRegisterCallback(env, typeString, displayAniListener); + 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, DmErrorCode::DM_ERROR_INVALID_PARAM, errMsg); + AniErrUtils::ThrowBusinessError(env, ret, errMsg); return; } // add listener to map - jsCbMap_[typeString][callback] = displayAniListener; + jsCbMap_[typeString][cbRef] = displayAniListener; } -DmErrorCode DisplayManagerAni::processRegisterCallback(ani_env* env, std::string& typeStr, +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, sptr displayAniListener) { DmErrorCode ret = DmErrorCode::DM_ERROR_INVALID_PARAM; - if (typeStr == EVENT_ADD || typeStr == EVENT_REMOVE || typeStr == EVENT_CHANGE) { - TLOGI(WmsLogTag::DMS, "processRegisterCallback %{public}s", typeStr.c_str()); + if (typeStr == ANI_EVENT_ADD || typeStr == ANI_EVENT_REMOVE || typeStr == ANI_EVENT_CHANGE) { + TLOGI(WmsLogTag::DMS, "ProcessRegisterCallback %{public}s", typeStr.c_str()); ret = DM_JS_TO_ERROR_CODE_MAP.at( SingletonContainer::Get().RegisterDisplayListener(displayAniListener)); - } else if (typeStr == EVENT_FOLD_STATUS_CHANGED) { + } else if (typeStr == ANI_EVENT_FOLD_STATUS_CHANGED) { ret = DM_JS_TO_ERROR_CODE_MAP.at( SingletonContainer::Get().RegisterFoldStatusListener(displayAniListener)); - } else if (typeStr == EVENT_DISPLAY_MODE_CHANGED) { + } else if (typeStr == ANI_EVENT_DISPLAY_MODE_CHANGED) { ret = DM_JS_TO_ERROR_CODE_MAP.at( SingletonContainer::Get().RegisterDisplayModeListener(displayAniListener)); + } else if (typeStr == ANI_EVENT_AVAILABLE_AREA_CHANGED) { + ret = DM_JS_TO_ERROR_CODE_MAP.at( + SingletonContainer::Get().RegisterAvailableAreaListener(displayAniListener)); + } else if (typeStr == ANI_EVENT_FOLD_ANGLE_CHANGED) { + ret = DM_JS_TO_ERROR_CODE_MAP.at( + SingletonContainer::Get().RegisterFoldAngleListener(displayAniListener)); + } else if (typeStr == ANI_EVENT_CAPTURE_STATUS_CHANGED) { + ret = DM_JS_TO_ERROR_CODE_MAP.at( + SingletonContainer::Get().RegisterCaptureStatusListener(displayAniListener)); + } else if (typeStr == ANI_EVENT_PRIVATE_MODE_CHANGE) { + ret = DM_JS_TO_ERROR_CODE_MAP.at( + SingletonContainer::Get().RegisterPrivateWindowListener(displayAniListener)); } return ret; } -void DisplayManagerAni::unRegisterCallback(ani_env* env, ani_string type, +void DisplayManagerAni::UnRegisterCallback(ani_env* env, ani_string type, ani_long nativeObj, ani_ref callback) { - TLOGI(WmsLogTag::DMS, "[ANI] unRegisterCallback begin"); + TLOGI(WmsLogTag::DMS, "[ANI] begin"); DisplayManagerAni* displayManagerAni = reinterpret_cast(nativeObj); if (displayManagerAni != nullptr) { - displayManagerAni->onUnRegisterCallback(env, type, callback); + displayManagerAni->OnUnRegisterCallback(env, type, callback); } else { TLOGI(WmsLogTag::DMS, "[ANI] null ptr"); } } -void DisplayManagerAni::onUnRegisterCallback(ani_env* env, ani_string type, ani_ref callback) +void DisplayManagerAni::OnUnRegisterCallback(ani_env* env, ani_string type, ani_ref callback) { - TLOGI(WmsLogTag::DMS, "[ANI] onUnRegisterCallback begin"); + 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) { @@ -285,11 +334,12 @@ 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) { - TLOGI(WmsLogTag::DMS, "[ANI] UnRegisterDisplayListenerWithType begin"); + TLOGI(WmsLogTag::DMS, "[ANI] begin"); if (jsCbMap_.empty() || jsCbMap_.find(type) == jsCbMap_.end()) { TLOGI(WmsLogTag::DMS, "[ANI] methodName %{public}s not registered!", type.c_str()); return DMError::DM_OK; @@ -300,24 +350,35 @@ DMError DisplayManagerAni::UnRegisterDisplayListenerWithType(std::string type, a env->Reference_StrictEquals(callback, it->first, &isEquals); if (isEquals) { it->second->RemoveCallback(env, type, callback); - if (type == EVENT_ADD || type == EVENT_REMOVE || type == EVENT_CHANGE) { - TLOGI(WmsLogTag::DMS, "[ANI] start to unregis display event listener! event = %{public}s", - type.c_str()); + if (type == ANI_EVENT_ADD || type == ANI_EVENT_REMOVE || type == ANI_EVENT_CHANGE) { sptr thisListener(it->second); ret = SingletonContainer::Get().UnregisterDisplayListener(thisListener); - } else if (type == EVENT_FOLD_STATUS_CHANGED) { - TLOGI(WmsLogTag::DMS, "[ANI] start to unregis FoldStatusListener event listener! event = %{public}s", - type.c_str()); + } else if (type == ANI_EVENT_FOLD_STATUS_CHANGED) { sptr thisListener(it->second); ret = SingletonContainer::Get().UnregisterFoldStatusListener(thisListener); TLOGI(WmsLogTag::DMS, "[ANI] UnRegisterDisplayListener foldStatusChange success"); - } else if (type == EVENT_DISPLAY_MODE_CHANGED) { - TLOGI(WmsLogTag::DMS, "[ANI] start to unregis foldDisplayModeChange event listener! event = %{public}s", - type.c_str()); + } else if (type == ANI_EVENT_DISPLAY_MODE_CHANGED) { sptr thisListener(it->second); ret = SingletonContainer::Get().UnregisterDisplayModeListener(thisListener); TLOGI(WmsLogTag::DMS, "[ANI] UnRegisterDisplayListener foldDisplayModeChange success"); + } else if (type == ANI_EVENT_AVAILABLE_AREA_CHANGED) { + sptr thisListener(it->second); + ret = SingletonContainer::Get().UnregisterAvailableAreaListener(thisListener); + TLOGI(WmsLogTag::DMS, "[ANI] UnRegisterDisplayListener availableAreaListener success"); + } else if (type == ANI_EVENT_FOLD_ANGLE_CHANGED) { + sptr thisListener(it->second); + ret = SingletonContainer::Get().UnregisterFoldAngleListener(thisListener); + TLOGI(WmsLogTag::DMS, "[ANI] UnRegisterDisplayListener foldAngleListener success"); + } else if (type == ANI_EVENT_CAPTURE_STATUS_CHANGED) { + sptr thisListener(it->second); + SingletonContainer::Get().UnregisterCaptureStatusListener(thisListener); + TLOGI(WmsLogTag::DMS, "[ANI] UnRegisterDisplayListener captureStatusListener success"); + } else if (type == ANI_EVENT_PRIVATE_MODE_CHANGE) { + sptr thisListener(it->second); + ret = SingletonContainer::Get().UnregisterPrivateWindowListener(thisListener); + TLOGI(WmsLogTag::DMS, "[ANI] UnRegisterDisplayListener privateWindowListener success"); } + jsCbMap_[type].erase(it++); } } return ret; @@ -325,27 +386,80 @@ DMError DisplayManagerAni::UnRegisterDisplayListenerWithType(std::string type, a DMError DisplayManagerAni::UnregisterAllDisplayListenerWithType(std::string type) { - TLOGI(WmsLogTag::DMS, "[ANI] UnregisterAllDisplayListenerWithType begin"); + 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; } DMError ret = DMError::DM_OK; for (auto it = jsCbMap_[type].begin(); it != jsCbMap_[type].end();) { it->second->RemoveAllCallback(); - if (type == EVENT_ADD || type == EVENT_REMOVE || type == EVENT_CHANGE) { + if (type == ANI_EVENT_ADD || type == ANI_EVENT_REMOVE || type == ANI_EVENT_CHANGE) { sptr thisListener(it->second); ret = SingletonContainer::Get().UnregisterDisplayListener(thisListener); - } else if (type == EVENT_FOLD_STATUS_CHANGED) { + } else if (type == ANI_EVENT_FOLD_STATUS_CHANGED) { sptr thisListener(it->second); ret = SingletonContainer::Get().UnregisterFoldStatusListener(thisListener); - } else if (type == EVENT_DISPLAY_MODE_CHANGED) { + } else if (type == ANI_EVENT_DISPLAY_MODE_CHANGED) { sptr thisListener(it->second); ret = SingletonContainer::Get().UnregisterDisplayModeListener(thisListener); + } else if (type == ANI_EVENT_AVAILABLE_AREA_CHANGED) { + sptr thisListener(it->second); + ret = SingletonContainer::Get().UnregisterAvailableAreaListener(thisListener); + } else if (type == ANI_EVENT_FOLD_ANGLE_CHANGED) { + sptr thisListener(it->second); + ret = SingletonContainer::Get().UnregisterFoldAngleListener(thisListener); + } else if (type == ANI_EVENT_CAPTURE_STATUS_CHANGED) { + sptr thisListener(it->second); + ret = SingletonContainer::Get().UnregisterCaptureStatusListener(thisListener); + } else if (type == ANI_EVENT_PRIVATE_MODE_CHANGE) { + sptr thisListener(it->second); + ret = SingletonContainer::Get().UnregisterPrivateWindowListener(thisListener); } + jsCbMap_[type].erase(it++); } + jsCbMap_.erase(type); return ret; } + +ani_boolean DisplayManagerAni::HasPrivateWindow(ani_env* env, ani_long displayId) +{ + TLOGI(WmsLogTag::DMS, "[ANI] begin"); + bool hasPrivateWindow = false; + if (displayId < 0) { + TLOGE(WmsLogTag::DMS, "Invalid displayId: %{public}" PRId64, displayId); + AniErrUtils::ThrowBusinessError(env, DmErrorCode::DM_ERROR_INVALID_PARAM, "Invalid displayId"); + return hasPrivateWindow; + } + DmErrorCode errCode = DM_JS_TO_ERROR_CODE_MAP.at( + SingletonContainer::Get().HasPrivateWindow(static_cast(displayId), hasPrivateWindow)); + if (errCode != DmErrorCode::DM_OK) { + TLOGE(WmsLogTag::DMS, "Failed to convert parameter to displayId"); + AniErrUtils::ThrowBusinessError(env, errCode, "Failed to convert parameter to displayId"); + return hasPrivateWindow; + } + return hasPrivateWindow; +} + +void DisplayManagerAni::GetAllDisplayPhysicalResolution(ani_env* env, ani_object arrayObj, ani_long nativeObj) +{ + TLOGI(WmsLogTag::DMS, "[ANI] begin"); + DisplayManagerAni* displayManagerAni = reinterpret_cast(nativeObj); + displayManagerAni->OnGetAllDisplayPhysicalResolution(env, arrayObj); +} + +void DisplayManagerAni::OnGetAllDisplayPhysicalResolution(ani_env* env, ani_object arrayObj) +{ + TLOGI(WmsLogTag::DMS, "[ANI] begin"); + std::vector displayPhysicalArray = + SingletonContainer::Get().GetAllDisplayPhysicalResolution(); + if (displayPhysicalArray.empty()) { + AniErrUtils::ThrowBusinessError(env, DmErrorCode::DM_ERROR_SYSTEM_INNORMAL, + "JsDisplayManager::OnGetAllDisplayPhysicalResolution failed."); + } else { + DisplayAniUtils::ConvertDisplayPhysicalResolution(displayPhysicalArray, arrayObj, env); + } +} +} } -} \ No newline at end of file diff --git a/interfaces/kits/ani/display_runtime/display_ani/src/display_ani_utils.cpp b/interfaces/kits/ani/display_runtime/display_ani/src/display_ani_utils.cpp index 88673b05053e4d3723d0bb7c6132dffbebe34cad..d0365aaa9fa4524d2ec66f988d6e04c145524b3f 100644 --- a/interfaces/kits/ani/display_runtime/display_ani/src/display_ani_utils.cpp +++ b/interfaces/kits/ani/display_runtime/display_ani/src/display_ani_utils.cpp @@ -50,18 +50,17 @@ static const std::map NATIVE_TO_JS_DISPLAY_ }; -void DisplayAniUtils::convertRect(DMRect rect, ani_object rectObj, ani_env* env) +void DisplayAniUtils::ConvertRect(DMRect rect, ani_object rectObj, ani_env* env) { - TLOGI(WmsLogTag::DMS, "[ANI] rect area start"); TLOGI(WmsLogTag::DMS, "[ANI] rect area info: %{public}d, %{public}d, %{public}u, %{public}u", rect.posX_, rect.posY_, rect.width_, rect.height_); - env->Object_SetFieldByName_Double(rectObj, "left", rect.posX_); - env->Object_SetFieldByName_Double(rectObj, "width", rect.width_); - env->Object_SetFieldByName_Double(rectObj, "top", rect.posY_); - env->Object_SetFieldByName_Double(rectObj, "height", rect.height_); + env->Object_SetFieldByName_Long(rectObj, "left", rect.posX_); + env->Object_SetFieldByName_Long(rectObj, "width", rect.width_); + env->Object_SetFieldByName_Long(rectObj, "top", rect.posY_); + env->Object_SetFieldByName_Long(rectObj, "height", rect.height_); } -void DisplayAniUtils::convertWaterArea(WaterfallDisplayAreaRects waterfallDisplayAreaRects, +void DisplayAniUtils::ConvertWaterArea(WaterfallDisplayAreaRects waterfallDisplayAreaRects, ani_object waterfallObj, ani_env *env) { TLOGI(WmsLogTag::DMS, "[ANI] start convert WaterArea"); @@ -73,16 +72,51 @@ void DisplayAniUtils::convertWaterArea(WaterfallDisplayAreaRects waterfallDispla env->Object_GetFieldByName_Ref(waterfallObj, "right", &rightObj); env->Object_GetFieldByName_Ref(waterfallObj, "top", &topObj); env->Object_GetFieldByName_Ref(waterfallObj, "bottom", &bottomObj); - convertRect(waterfallDisplayAreaRects.left, static_cast(leftObj), env); - convertRect(waterfallDisplayAreaRects.right, static_cast(rightObj), env); - convertRect(waterfallDisplayAreaRects.top, static_cast(topObj), env); - convertRect(waterfallDisplayAreaRects.bottom, static_cast(bottomObj), env); + ConvertRect(waterfallDisplayAreaRects.left, static_cast(leftObj), env); + ConvertRect(waterfallDisplayAreaRects.right, static_cast(rightObj), env); + ConvertRect(waterfallDisplayAreaRects.top, static_cast(topObj), env); + ConvertRect(waterfallDisplayAreaRects.bottom, static_cast(bottomObj), env); } -ani_status DisplayAniUtils::cvtDisplay(sptr display, ani_env* env, ani_object obj) +void DisplayAniUtils::ConvertDisplayPhysicalResolution(std::vector& displayPhysicalArray, + ani_object arrayObj, ani_env *env) +{ + ani_int arrayObjLen; + env->Object_GetPropertyByName_Int(arrayObj, "length", &arrayObjLen); + + for (uint32_t i = 0; i < displayPhysicalArray.size() && i < static_cast(arrayObjLen); i++) { + ani_ref obj; + env->Object_CallMethodByName_Ref(arrayObj, "$_get", "i:C{std.core.Object}", &obj, (ani_int)i); + env->Object_SetFieldByName_Int(static_cast(obj), "foldDisplayMode_", + static_cast(displayPhysicalArray[i].foldDisplayMode_)); + env->Object_SetFieldByName_Long(static_cast(obj), "physicalWidth", + displayPhysicalArray[i].physicalWidth_); + env->Object_SetFieldByName_Long(static_cast(obj), "physicalHeight", + displayPhysicalArray[i].physicalHeight_); + } +} + +ani_enum_item DisplayAniUtils::CreateAniEnum(ani_env* env, const char* enum_descriptor, ani_size index) +{ + ani_enum enumType; + ani_status ret = env->FindEnum(enum_descriptor, &enumType); + if (ret != ANI_OK) { + TLOGE(WmsLogTag::DMS, "[ANI] Failed to find enum, %{public}s", enum_descriptor); + return nullptr; + } + ani_enum_item enumItem; + env->Enum_GetEnumItemByIndex(enumType, index, &enumItem); + return enumItem; +} + +ani_status DisplayAniUtils::CvtDisplay(sptr display, ani_env* env, ani_object obj) { sptr info = display->GetDisplayInfoWithCache(); - int setfieldid = env->Object_SetFieldByName_Double(obj, "id", info->GetDisplayId()); + if (info == nullptr) { + TLOGE(WmsLogTag::DMS, "[ANI] Failed to GetDisplayInfo"); + return ANI_ERROR; + } + int setfieldid = env->Object_SetFieldByName_Long(obj, "id", info->GetDisplayId()); if (ANI_OK != setfieldid) { TLOGE(WmsLogTag::DMS, "[ANI] set id failed: %{public}d", setfieldid); } @@ -94,45 +128,59 @@ ani_status DisplayAniUtils::cvtDisplay(sptr display, ani_env* env, ani_ env->Object_SetFieldByName_Ref(obj, "name", str); env->Object_SetFieldByName_Boolean(obj, "alive", info->GetAliveStatus()); if (NATIVE_TO_JS_DISPLAY_STATE_MAP.count(info->GetDisplayState()) != 0) { - env->Object_SetFieldByName_Int(obj, "state", static_cast(info->GetDisplayState())); + env->Object_SetFieldByName_Ref(obj, "state", DisplayAniUtils::CreateAniEnum( + env, "@ohos.display.display.DisplayState", static_cast(info->GetDisplayState()))); } else { - env->Object_SetFieldByName_Int(obj, "state", 0); + env->Object_SetFieldByName_Ref(obj, "state", DisplayAniUtils::CreateAniEnum( + env, "@ohos.display.display.DisplayState", static_cast(0))); } - env->Object_SetFieldByName_Double(obj, "refreshRate", info->GetRefreshRate()); - env->Object_SetFieldByName_Double(obj, "rotation", static_cast(info->GetRotation())); + env->Object_SetFieldByName_Int(obj, "refreshRate", info->GetRefreshRate()); + env->Object_SetFieldByName_Int(obj, "rotation", static_cast(info->GetRotation())); ani_status setfieldRes = env->Object_SetFieldByName_Double(obj, "width", static_cast(info->GetWidth())); if (ANI_OK != setfieldRes) { TLOGE(WmsLogTag::DMS, "[ANI] set failed: %{public}d, %{public}u", info->GetWidth(), setfieldRes); } - env->Object_SetFieldByName_Double(obj, "height", display->GetHeight()); - env->Object_SetFieldByName_Double(obj, "availableWidth", info->GetAvailableWidth()); - env->Object_SetFieldByName_Double(obj, "availableHeight", info->GetAvailableHeight()); + env->Object_SetFieldByName_Long(obj, "height", display->GetHeight()); + env->Object_SetFieldByName_Long(obj, "availableWidth", info->GetAvailableWidth()); + env->Object_SetFieldByName_Long(obj, "availableHeight", info->GetAvailableHeight()); env->Object_SetFieldByName_Double(obj, "densityDPI", info->GetVirtualPixelRatio() * DOT_PER_INCH); - env->Object_SetFieldByName_Double(obj, "orientation", - static_cast(info->GetDisplayOrientation())); + env->Object_SetFieldByName_Ref(obj, "orientation", DisplayAniUtils::CreateAniEnum( + env, "@ohos.display.display.Orientation", static_cast(info->GetDisplayOrientation()))); env->Object_SetFieldByName_Double(obj, "densityPixels", info->GetVirtualPixelRatio()); env->Object_SetFieldByName_Double(obj, "scaledDensity", info->GetVirtualPixelRatio()); env->Object_SetFieldByName_Double(obj, "xDPI", info->GetXDpi()); env->Object_SetFieldByName_Double(obj, "yDPI", info->GetYDpi()); + env->Object_SetFieldByName_Ref(obj, "screenShape", DisplayAniUtils::CreateAniEnum( + env, "@ohos.display.display.ScreenShape", static_cast(info->GetScreenShape()))); + if (info->GetDisplaySourceMode() == DisplaySourceMode::MAIN || + info->GetDisplaySourceMode() == DisplaySourceMode::EXTEND) { + env->Object_SetFieldByName_Long(obj, "x", info->GetX()); + env->Object_SetFieldByName_Long(obj, "y", info->GetY()); + } else { + env->Object_SetFieldByName_Ref(obj, "x", DisplayAniUtils::CreateAniUndefined(env)); + env->Object_SetFieldByName_Ref(obj, "y", DisplayAniUtils::CreateAniUndefined(env)); + } + env->Object_SetFieldByName_Ref(obj, "sourceMode", DisplayAniUtils::CreateAniEnum( + env, "@ohos.display.display.DisplaySourceMode", static_cast(info->GetDisplaySourceMode()))); auto colorSpaces = info->GetColorSpaces(); auto hdrFormats = info->GetHdrFormats(); - TLOGI(WmsLogTag::DMS, "[ANI] colorSpaces(0) %{public}u, %{public}u", colorSpaces.size(), colorSpaces[1]); + auto supportedRefreshRates = info->GetSupportedRefreshRate(); if (colorSpaces.size() != 0) { ani_array_int colorSpacesAni; CreateAniArrayInt(env, colorSpaces.size(), &colorSpacesAni, colorSpaces); - if (ANI_OK != env->Object_SetFieldByName_Ref(obj, "colorSpaces", - static_cast(colorSpacesAni))) { - TLOGE(WmsLogTag::DMS, "[ANI] Array set colorSpaces field error"); - } + env->Object_SetFieldByName_Ref(obj, "colorSpaces", static_cast(colorSpacesAni)); } if (hdrFormats.size() != 0) { ani_array_int hdrFormatsAni; CreateAniArrayInt(env, hdrFormats.size(), &hdrFormatsAni, hdrFormats); - if (ANI_OK != env->Object_SetFieldByName_Ref(obj, "hdrFormats", - static_cast(hdrFormatsAni))) { - TLOGE(WmsLogTag::DMS, "[ANI] Array set hdrFormats field error"); - } + env->Object_SetFieldByName_Ref(obj, "hdrFormats", static_cast(hdrFormatsAni)); + } + if (supportedRefreshRates.size() != 0) { + ani_array_int supportedRefreshRatesAni; + CreateAniArrayInt(env, hdrFormats.size(), &supportedRefreshRatesAni, supportedRefreshRates); + env->Object_SetFieldByName_Ref(obj, "supportedRefreshRates", + static_cast(supportedRefreshRatesAni)); } return ANI_OK; } @@ -148,6 +196,16 @@ void DisplayAniUtils::CreateAniArrayInt(ani_env* env, ani_size size, ani_array_i } } +void DisplayAniUtils::CreateAniArrayDouble(ani_env* env, ani_size size, + ani_array_double *aniArray, std::vector vec) +{ + env->Array_New_Double(size, aniArray); + std::vector vecDoubles; + std::copy(vec.begin(), vec.end(), std::back_inserter(vecDoubles)); + ani_double* aniArrayBuf = reinterpret_cast(vecDoubles.data()); + env->Array_SetRegion_Double(*aniArray, 0, size, aniArrayBuf); +} + ani_status DisplayAniUtils::GetStdString(ani_env *env, ani_string ani_str, std::string &result) { ani_size strSize; @@ -184,7 +242,7 @@ ani_status DisplayAniUtils::NewAniObject(ani_env* env, ani_class cls, const char ani_status DisplayAniUtils::NewAniObjectNoParams(ani_env* env, ani_class cls, ani_object* object) { ani_method aniCtor; - auto ret = env->Class_FindMethod(cls, "", ":V", &aniCtor); + auto ret = env->Class_FindMethod(cls, "", ":", &aniCtor); if (ret != ANI_OK) { TLOGE(WmsLogTag::DMS, "[ANI] find ctor method fail"); return ret; @@ -207,33 +265,56 @@ ani_status DisplayAniUtils::GetAniString(ani_env* env, const std::string& str, a ani_status DisplayAniUtils::CallAniFunctionVoid(ani_env *env, const char* ns, const char* fn, const char* signature, ...) { - TLOGI(WmsLogTag::DEFAULT, "[ANI]CallAniFunctionVoid begin"); + TLOGI(WmsLogTag::DMS, "[ANI]CallAniFunctionVoid begin"); ani_status ret = ANI_OK; ani_namespace aniNamespace{}; if ((ret = env->FindNamespace(ns, &aniNamespace)) != ANI_OK) { - TLOGE(WmsLogTag::DEFAULT, "[ANI]canot find ns %{public}d", ret); + TLOGE(WmsLogTag::DMS, "[ANI]canot find ns %{public}d", ret); return ret; } ani_function func{}; if ((ret = env->Namespace_FindFunction(aniNamespace, fn, signature, &func)) != ANI_OK) { - TLOGE(WmsLogTag::DEFAULT, "[ANI]canot find callBack %{public}d", ret); + TLOGE(WmsLogTag::DMS, "[ANI]canot find callBack %{public}d", ret); return ret; } - va_list args; - va_start(args, signature); - TLOGI(WmsLogTag::DEFAULT, "[ANI]CallAniFunctionVoid begin %{public}s", signature); if (func == nullptr) { - TLOGI(WmsLogTag::DEFAULT, "[ANI] null func ani"); + TLOGE(WmsLogTag::DMS, "[ANI] null func ani"); return ret; } + va_list args; + va_start(args, signature); + TLOGI(WmsLogTag::DMS, "[ANI]CallAniFunctionVoid begin %{public}s", signature); ret = env->Function_Call_Void_V(func, args); va_end(args); if (ret != ANI_OK) { - TLOGE(WmsLogTag::DEFAULT, "[ANI]canot run callBack %{public}d", ret); + TLOGE(WmsLogTag::DMS, "[ANI]canot run callBack %{public}d", ret); return ret; } return ret; } +ani_object DisplayAniUtils::CreateRectObject(ani_env *env) +{ + ani_class aniClass{}; + ani_status status = env->FindClass("@ohos.display.display.RectImpl", &aniClass); + if (status != ANI_OK) { + TLOGE(WmsLogTag::DMS, "[ANI] class not found, status:%{public}d", static_cast(status)); + return nullptr; + } + ani_method aniCtor; + auto ret = env->Class_FindMethod(aniClass, "", ":V", &aniCtor); + if (ret != ANI_OK) { + TLOGE(WmsLogTag::DMS, "[ANI] Class_FindMethod failed"); + return nullptr; + } + ani_object rectObj; + status = env->Object_New(aniClass, aniCtor, &rectObj); + if (status != ANI_OK) { + TLOGE(WmsLogTag::DMS, "[ANI] NewAniObject failed"); + return nullptr; + } + return rectObj; +} + +} } -} \ No newline at end of file diff --git a/interfaces/kits/ani/embeddable_window_stage/BUILD.gn b/interfaces/kits/ani/embeddable_window_stage/BUILD.gn index 39d4039f20507d44717b1ba08f8c8678717ff543..b549f887dafca1231fc4f310dbb88b6e742f27fc 100644 --- a/interfaces/kits/ani/embeddable_window_stage/BUILD.gn +++ b/interfaces/kits/ani/embeddable_window_stage/BUILD.gn @@ -81,9 +81,54 @@ ohos_shared_library("embeddablewindowstageani_kit") { subsystem_name = "window" } +# lib generate +ohos_shared_library("embeddablewindowstageani_module") { + branch_protector_ret = "pac_ret" + sanitize = { + cfi = true + cfi_cross_dso = true + cfi_vcall_icall_only = true + debug = false + } + sources = [ + "src/ani_embeddable_window_stage_module.cpp", + ] + + configs = [ + ":window_common_config", + ":windowstage_ani_public_config", + "../../../../resources/config/build:coverage_flags", + ] + + public_configs = [ ":windowstage_ani_public_config" ] + + deps = [ + "../../../../utils:libwmutil", + "../../../../utils:libwmutil_base", + "../../../../wm:libwm", + ":embeddablewindowstageani_kit", + ] + + external_deps = [ + "ability_runtime:ability_manager", + "ability_runtime:runtime", + "c_utils:utils", + "eventhandler:libeventhandler", + "hilog:libhilog", + "hitrace:hitrace_meter", + "napi:ace_napi", + "runtime_core:ani", + ] + + innerapi_tags = [ "platformsdk" ] + part_name = "window_manager" + subsystem_name = "window" +} + group("embeddable_window_stage_ani") { deps = [ ":embeddablewindowstageani_kit", + ":embeddablewindowstageani_module", "ets:extension_window_abc_ani_etc", "ets:extension_window_host_abc_ani_etc", ] diff --git a/interfaces/kits/ani/embeddable_window_stage/ets/@ohos.uiExtensionHost.ets b/interfaces/kits/ani/embeddable_window_stage/ets/@ohos.uiExtensionHost.ets index dadcbb29c62196c9e8c31d4ec7ab4268aa868676..d8f8bb2bbf32ad427ef20419eed47d1ff1af1485 100644 --- a/interfaces/kits/ani/embeddable_window_stage/ets/@ohos.uiExtensionHost.ets +++ b/interfaces/kits/ani/embeddable_window_stage/ets/@ohos.uiExtensionHost.ets @@ -35,20 +35,20 @@ namespace uiExtensionHost { const WMS_UIEXT: int = 0xC0420D; const WMS_UIEXT_TAG: string = "WMSUiext"; - function callBack(fn: object, fnArg: object): void { + function callback(fn: object, fnArg: object): void { let f = fn as (d: object) => void; f(fnArg); } class UIESize implements window.Size { - width: double; - height: double; + width: int; + height: int; } class UIERect implements window.Rect { - left: double; - top: double; - width: double; - height: double; + left: int; + top: int; + width: int; + height: int; }; class UIEAvoidArea implements window.AvoidArea { constructor() { @@ -76,7 +76,7 @@ namespace uiExtensionHost { // API implementation export class UIExtensionHostInternal implements UIExtensionHostWindowProxy { - static { loadLibrary("embeddablewindowstageani_kit.z") } + static { loadLibrary("embeddablewindowstageani_module.z") } private nativeObj: long = 0; private setNativeObj(nativeObj: long): void { this.nativeObj = nativeObj; diff --git a/interfaces/kits/ani/embeddable_window_stage/ets/uiExtensionHost_entry.ets b/interfaces/kits/ani/embeddable_window_stage/ets/uiExtensionHost_entry.ets index 12b1de92f9e78fc521beb82bcb55307771adef69..cea4b79096cbb9fc7c29d75e44863124b81881ca 100644 --- a/interfaces/kits/ani/embeddable_window_stage/ets/uiExtensionHost_entry.ets +++ b/interfaces/kits/ani/embeddable_window_stage/ets/uiExtensionHost_entry.ets @@ -2,7 +2,7 @@ import uiExtensionHost from '@ohos.uiExtensionHost'; import window from '@ohos.window'; function main() { - loadLibrary('embeddablewindowstageani_kit.z') + loadLibrary('embeddablewindowstageani_module.z') let win = uiExtensionHost.createExtentionWindow(0, 0); console.println('test uiExtensionHostWindowProxyRect'); diff --git a/interfaces/kits/ani/embeddable_window_stage/include/ani_embeddable_window_stage.h b/interfaces/kits/ani/embeddable_window_stage/include/ani_embeddable_window_stage.h index da848496bb0101b54221e05fb66c2a853a6fdcce..0736861dd0a75c1da70bd4e5b07ed3d18e8602e1 100644 --- a/interfaces/kits/ani/embeddable_window_stage/include/ani_embeddable_window_stage.h +++ b/interfaces/kits/ani/embeddable_window_stage/include/ani_embeddable_window_stage.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Copyright (c) 2025-2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at diff --git a/interfaces/kits/ani/embeddable_window_stage/include/ani_extension_window.h b/interfaces/kits/ani/embeddable_window_stage/include/ani_extension_window.h index 83dd7213e782447f71dc3f29476fabc79d460cf1..bd1f026580b6e1b2206859a56020aa2c4705cacf 100644 --- a/interfaces/kits/ani/embeddable_window_stage/include/ani_extension_window.h +++ b/interfaces/kits/ani/embeddable_window_stage/include/ani_extension_window.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Copyright (c) 2025-2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at diff --git a/interfaces/kits/ani/embeddable_window_stage/include/ani_extension_window_listener.h b/interfaces/kits/ani/embeddable_window_stage/include/ani_extension_window_listener.h index 4d280abf98cec23a84f03c9b35eb0edd0b427c70..8f7f5dcb89025be3f0bf7a3fb839f009370719ec 100644 --- a/interfaces/kits/ani/embeddable_window_stage/include/ani_extension_window_listener.h +++ b/interfaces/kits/ani/embeddable_window_stage/include/ani_extension_window_listener.h @@ -34,7 +34,7 @@ class AniExtensionWindowListener : public IWindowChangeListener, public IOccupiedAreaChangeListener { public: AniExtensionWindowListener(ani_env* env, ani_ref func, ani_ref data) - : env_(env), callBack_(func), callBackData_(data), weakRef_(wptr (this)) {} + : env_(env), callback_(func), callbackData_(data), weakRef_(wptr (this)) {} ~AniExtensionWindowListener(); void OnSizeChange(Rect rect, WindowSizeChangeReason reason, const std::shared_ptr& rsTransaction = nullptr) override; @@ -47,12 +47,12 @@ public: void SetSizeInfo(uint32_t width, uint32_t height); private: - void CallBack(); + void Callback(); uint32_t currentWidth_ = 0; uint32_t currentHeight_ = 0; ani_env* env_ = nullptr; - ani_ref callBack_; - ani_ref callBackData_; + ani_ref callback_; + ani_ref callbackData_; wptr weakRef_ = nullptr; std::shared_ptr eventHandler_ = nullptr; DEFINE_VAR_DEFAULT_FUNC_SET(bool, IsDeprecatedInterface, isDeprecatedInterface, false) diff --git a/interfaces/kits/ani/embeddable_window_stage/src/ani_embeddable_window_stage.cpp b/interfaces/kits/ani/embeddable_window_stage/src/ani_embeddable_window_stage.cpp index f61e4a3135bc2f56adc651ce51871d4f38aea004..31e50fcb785a10c794f15cc058019164e87476eb 100644 --- a/interfaces/kits/ani/embeddable_window_stage/src/ani_embeddable_window_stage.cpp +++ b/interfaces/kits/ani/embeddable_window_stage/src/ani_embeddable_window_stage.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Copyright (c) 2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -62,7 +62,7 @@ ani_object CreateAniEmbeddableWindowStage(ani_env* env, sptr wind ani_status ret; ani_class cls = nullptr; - if ((ret = env->FindClass("L@ohos/window/window/WindowStageInternal;", &cls)) != ANI_OK) { + if ((ret = env->FindClass("@ohos.window.window.WindowStageInternal", &cls)) != ANI_OK) { TLOGE(WmsLogTag::WMS_UIEXT, "[ANI] null env %{public}u", ret); return cls; } @@ -77,7 +77,7 @@ ani_object CreateAniEmbeddableWindowStage(ani_env* env, sptr wind } ani_method initFunc = nullptr; - if ((ret = env->Class_FindMethod(cls, "", ":V", &initFunc)) != ANI_OK) { + if ((ret = env->Class_FindMethod(cls, "", ":", &initFunc)) != ANI_OK) { TLOGE(WmsLogTag::WMS_UIEXT, "[ANI] get ctor fail %{public}u", ret); return nullptr; } @@ -87,7 +87,7 @@ ani_object CreateAniEmbeddableWindowStage(ani_env* env, sptr wind return nullptr; } ani_method setObjFunc = nullptr; - if ((ret = env->Class_FindMethod(cls, "setNativeObj", "J:V", &setObjFunc)) != ANI_OK) { + if ((ret = env->Class_FindMethod(cls, "setNativeObj", "l:", &setObjFunc)) != ANI_OK) { TLOGE(WmsLogTag::WMS_UIEXT, "[ANI] get ctor fail %{public}u", ret); return nullptr; } @@ -114,26 +114,3 @@ AniEmbeddableWindowStage* GetEmbeddableWindowStageFromEnv(ani_env* env, ani_clas } } // namespace Rosen } // namespace OHOS - -extern "C" { -ANI_EXPORT ani_status ExtensionWindow_ANI_Constructor(ani_vm *vm, uint32_t *result); -ANI_EXPORT ani_status ANI_Constructor(ani_vm *vm, uint32_t *result) -{ - using namespace OHOS::Rosen; - ani_status ret; - ani_env* env; - if ((ret = vm->GetEnv(ANI_VERSION_1, &env)) != ANI_OK) { - TLOGE(WmsLogTag::WMS_UIEXT, "[ANI] null env"); - return ANI_NOT_FOUND; - } - - ani_class cls = nullptr; - if ((ret = env->FindClass("L@ohos/window/window/WindowStage;", &cls)) != ANI_OK) { - TLOGE(WmsLogTag::WMS_UIEXT, "[ANI] null env %{public}u", ret); - return ANI_NOT_FOUND; - } - *result = ANI_VERSION_1; - - return ExtensionWindow_ANI_Constructor(vm, result); -} -} diff --git a/interfaces/kits/ani/embeddable_window_stage/src/ani_embeddable_window_stage_module.cpp b/interfaces/kits/ani/embeddable_window_stage/src/ani_embeddable_window_stage_module.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9ec69148589a04b21595f6ea5518269b38db9476 --- /dev/null +++ b/interfaces/kits/ani/embeddable_window_stage/src/ani_embeddable_window_stage_module.cpp @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ani.h" +#include "ani_embeddable_window_stage.h" +#include "window_manager_hilog.h" + +extern "C" { +ANI_EXPORT ani_status ExtensionWindow_ANI_Constructor(ani_vm *vm, uint32_t *result); +ANI_EXPORT ani_status ANI_Constructor(ani_vm *vm, uint32_t *result) +{ + using namespace OHOS::Rosen; + ani_status ret; + ani_env* env; + if ((ret = vm->GetEnv(ANI_VERSION_1, &env)) != ANI_OK) { + TLOGE(WmsLogTag::WMS_UIEXT, "[ANI] null env"); + return ANI_NOT_FOUND; + } + + ani_class cls = nullptr; + if ((ret = env->FindClass("@ohos.window.window.WindowStage", &cls)) != ANI_OK) { + TLOGE(WmsLogTag::WMS_UIEXT, "[ANI] null env %{public}u", ret); + return ANI_NOT_FOUND; + } + *result = ANI_VERSION_1; + + return ExtensionWindow_ANI_Constructor(vm, result); +} +} diff --git a/interfaces/kits/ani/embeddable_window_stage/src/ani_extension_window.cpp b/interfaces/kits/ani/embeddable_window_stage/src/ani_extension_window.cpp index 795c46bf37ba8f005b4ac05ec200ec36b133e0d9..49f0e25abc231390d3c69a35cfc2fb1a5f183718 100644 --- a/interfaces/kits/ani/embeddable_window_stage/src/ani_extension_window.cpp +++ b/interfaces/kits/ani/embeddable_window_stage/src/ani_extension_window.cpp @@ -49,7 +49,7 @@ ani_object AniExtensionWindow::CreateAniExtensionWindow(ani_env* env, sptrFindClass("L@ohos/uiExtensionHost/uiExtensionHost/UIExtensionHostInternal;", &cls)) != ANI_OK) { + if ((ret = env->FindClass("@ohos.uiExtensionHost.uiExtensionHost.UIExtensionHostInternal", &cls)) != ANI_OK) { TLOGE(WmsLogTag::WMS_UIEXT, "[ANI] null env %{public}u", ret); return cls; } @@ -65,7 +65,7 @@ ani_object AniExtensionWindow::CreateAniExtensionWindow(ani_env* env, sptrClass_FindMethod(cls, "", ":V", &initFunc)) != ANI_OK) { + if ((ret = env->Class_FindMethod(cls, "", ":", &initFunc)) != ANI_OK) { TLOGE(WmsLogTag::WMS_UIEXT, "[ANI] get ctor fail %{public}u", ret); return nullptr; } @@ -75,7 +75,7 @@ ani_object AniExtensionWindow::CreateAniExtensionWindow(ani_env* env, sptrClass_FindMethod(cls, "setNativeObj", "J:V", &setObjFunc)) != ANI_OK) { + if ((ret = env->Class_FindMethod(cls, "setNativeObj", "l:", &setObjFunc)) != ANI_OK) { TLOGE(WmsLogTag::WMS_UIEXT, "[ANI] get ctor fail %{public}u", ret); return nullptr; } @@ -318,21 +318,21 @@ ani_object createExtentionWindow(ani_env* env, ani_long win, ani_int hostId) extern "C" { using namespace OHOS::Rosen; std::array extensionWindowNativeMethods = { - ani_native_function {"getProperties", "JLstd/core/Object;:I", reinterpret_cast(ExtWindowGetProperties)}, - ani_native_function {"setProperties", "JLstd/core/Object;:I", reinterpret_cast(ExtWindowSetProperties)}, - ani_native_function {"getWindowAvoidArea", "JILstd/core/Object;:I", + ani_native_function {"getProperties", "lC{std.core.Object}:i", reinterpret_cast(ExtWindowGetProperties)}, + ani_native_function {"setProperties", "lC{std.core.Object}:i", reinterpret_cast(ExtWindowSetProperties)}, + ani_native_function {"getWindowAvoidArea", "liC{std.core.Object}:i", reinterpret_cast(ExtWindowGetWindowAvoidArea)}, - ani_native_function {"setWaterMarkFlag", "JZ:V", + ani_native_function {"setWaterMarkFlag", "lz:", reinterpret_cast(ExtWindowSetWaterMarkFlag)}, - ani_native_function {"hidePrivacyContentForHost", "JZ:V", + ani_native_function {"hidePrivacyContentForHost", "lz:", reinterpret_cast(ExtWindowHidePrivacyContentForHost)}, - ani_native_function {"onAvoidAreaChange", "JLstd/core/Object;Lstd/core/Object;:I", + ani_native_function {"onAvoidAreaChange", "lC{std.core.Object}C{std.core.Object}:i", reinterpret_cast(ExtWindowOnAvoidAreaChange)}, - ani_native_function {"onWindowSizeChange", "JLstd/core/Object;Lstd/core/Object;:I", + ani_native_function {"onWindowSizeChange", "lC{std.core.Object}C{std.core.Object}:i", reinterpret_cast(ExtWindowOnWindowSizeChange)}, - ani_native_function {"offAvoidAreaChange", "JLstd/core/Object;:I", + ani_native_function {"offAvoidAreaChange", "lC{std.core.Object}:i", reinterpret_cast(ExtWindowOffAvoidAreaChange)}, - ani_native_function {"offWindowSizeChange", "JLstd/core/Object;:I", + ani_native_function {"offWindowSizeChange", "lC{std.core.Object}:i", reinterpret_cast(ExtWindowOffWindowSizeChange)}, }; ANI_EXPORT ani_status ExtensionWindow_ANI_Constructor(ani_vm *vm, uint32_t *result) @@ -347,7 +347,7 @@ ANI_EXPORT ani_status ExtensionWindow_ANI_Constructor(ani_vm *vm, uint32_t *resu } ani_class cls = nullptr; - if ((ret = env->FindClass("L@ohos/uiExtensionHost/uiExtensionHost/UIExtensionHostInternal;", &cls)) != ANI_OK) { + if ((ret = env->FindClass("@ohos.uiExtensionHost.uiExtensionHost.UIExtensionHostInternal", &cls)) != ANI_OK) { TLOGE(WmsLogTag::WMS_UIEXT, "[ANI] null env %{public}u", ret); return ANI_NOT_FOUND; } @@ -361,7 +361,7 @@ ANI_EXPORT ani_status ExtensionWindow_ANI_Constructor(ani_vm *vm, uint32_t *resu // test ani_namespace ns; - if ((ret = env->FindNamespace("L@ohos/uiExtensionHost/uiExtensionHost;", &ns)) != ANI_OK) { + if ((ret = env->FindNamespace("@ohos.uiExtensionHost.uiExtensionHost", &ns)) != ANI_OK) { TLOGE(WmsLogTag::WMS_UIEXT, "[ANI] find ns %{public}u", ret); return ANI_NOT_FOUND; } diff --git a/interfaces/kits/ani/embeddable_window_stage/src/ani_extension_window_listener.cpp b/interfaces/kits/ani/embeddable_window_stage/src/ani_extension_window_listener.cpp index 96e81d96bef3994fc221c0541e94424baa8423f7..644960ed49c69d6fb03b556c7224aaabf7777954 100644 --- a/interfaces/kits/ani/embeddable_window_stage/src/ani_extension_window_listener.cpp +++ b/interfaces/kits/ani/embeddable_window_stage/src/ani_extension_window_listener.cpp @@ -34,11 +34,11 @@ const std::string KEYBOARD_HEIGHT_CHANGE_CB = "keyboardHeightChange"; AniExtensionWindowListener::~AniExtensionWindowListener() { - if (callBack_ != nullptr) { - env_->GlobalReference_Delete(callBack_); + if (callback_ != nullptr) { + env_->GlobalReference_Delete(callback_); } - if (callBackData_ != nullptr) { - env_->GlobalReference_Delete(callBackData_); + if (callbackData_ != nullptr) { + env_->GlobalReference_Delete(callbackData_); } TLOGI(WmsLogTag::WMS_UIEXT, "[ANI]~AniExtensionWindowListener"); } @@ -57,21 +57,21 @@ void AniExtensionWindowListener::SetMainEventHandler() eventHandler_ = std::make_shared(mainRunner); } -void AniExtensionWindowListener::CallBack() +void AniExtensionWindowListener::Callback() { ani_status ret {}; ani_function fn {}; ani_namespace ns {}; - if ((ret = env_->FindNamespace("L@ohos/uiExtensionHost/uiExtensionHost;", &ns)) != ANI_OK) { + if ((ret = env_->FindNamespace("@ohos.uiExtensionHost.uiExtensionHost", &ns)) != ANI_OK) { TLOGE(WmsLogTag::WMS_UIEXT, "[ANI]canot find ns %{public}d", ret); return; } - if ((ret = env_->Namespace_FindFunction(ns, "callBack", "Lstd/core/Object;Lstd/core/Object;:V", &fn)) != ANI_OK) { - TLOGE(WmsLogTag::WMS_UIEXT, "[ANI]canot find callBack %{public}d", ret); + if ((ret = env_->Namespace_FindFunction(ns, "callback", "C{std.core.Object}C{std.core.Object}:", &fn)) != ANI_OK) { + TLOGE(WmsLogTag::WMS_UIEXT, "[ANI]cannot find callback %{public}d", ret); return; } - if ((ret = env_->Function_Call_Void(fn, callBack_, callBackData_)) != ANI_OK) { - TLOGE(WmsLogTag::WMS_UIEXT, "[ANI]canot find callBack %{public}d", ret); + if ((ret = env_->Function_Call_Void(fn, callback_, callbackData_)) != ANI_OK) { + TLOGE(WmsLogTag::WMS_UIEXT, "[ANI]cannot find callback %{public}d", ret); return; } } @@ -79,12 +79,12 @@ void AniExtensionWindowListener::CallBack() void AniExtensionWindowListener::SetSizeInfo(uint32_t width, uint32_t height) { ani_status ret {}; - if ((ret = env_->Object_SetFieldByName_Double((ani_object)callBackData_, "width", + if ((ret = env_->Object_SetFieldByName_Double((ani_object)callbackData_, "width", (double)width)) != ANI_OK) { TLOGE(WmsLogTag::WMS_UIEXT, "[ANI]canot set width %{public}d", ret); return; }; - if ((ret = env_->Object_SetFieldByName_Double((ani_object)callBackData_, "height", + if ((ret = env_->Object_SetFieldByName_Double((ani_object)callbackData_, "height", (double)height)) != ANI_OK) { TLOGE(WmsLogTag::WMS_UIEXT, "[ANI]canot set height %{public}d", ret); return; @@ -108,7 +108,7 @@ void AniExtensionWindowListener::OnSizeChange(Rect rect, WindowSizeChangeReason return; } thisListener->SetSizeInfo(rect.width_, rect.height_); - thisListener->CallBack(); + thisListener->Callback(); }; if (reason == WindowSizeChangeReason::ROTATION) { aniCallback(); @@ -138,7 +138,7 @@ void AniExtensionWindowListener::OnSizeChange(const sptr static_cast(info->type_), info->rect_.posX_, info->rect_.posY_, info->rect_.width_, info->rect_.height_); // js callback should run in js thread - CallBack(); + Callback(); } } // namespace Rosen diff --git a/interfaces/kits/ani/embeddable_window_stage/src/ani_extension_window_register_manager.cpp b/interfaces/kits/ani/embeddable_window_stage/src/ani_extension_window_register_manager.cpp index 0724ed4c058133808b6d2b74f72a4f3d23ddc393..cb8243d68de6c41ab4ab9dd259a57e07ce90a6a6 100644 --- a/interfaces/kits/ani/embeddable_window_stage/src/ani_extension_window_register_manager.cpp +++ b/interfaces/kits/ani/embeddable_window_stage/src/ani_extension_window_register_manager.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023-2023 Huawei Device Co., Ltd. + * Copyright (c) 2025-2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at diff --git a/interfaces/kits/ani/screen_runtime/BUILD.gn b/interfaces/kits/ani/screen_runtime/BUILD.gn index fce48d6eaa6046d9c9dba79c56f14e77bf795aa0..fce77621398860322f30d2cc852fe35883c36cd0 100644 --- a/interfaces/kits/ani/screen_runtime/BUILD.gn +++ b/interfaces/kits/ani/screen_runtime/BUILD.gn @@ -24,6 +24,7 @@ config("screen_common_config") { "../../../innerkits/wm", "../../../innerkits/dm", "../../../../wm/include", + "../../napi/screen_runtime/napi", ] } @@ -35,6 +36,7 @@ config("screen_kit_public_config") { # lib generate ohos_shared_library("screenani_kit") { + shlib_type = "ani" branch_protector_ret = "pac_ret" sanitize = { cfi = true @@ -47,6 +49,7 @@ ohos_shared_library("screenani_kit") { "screen_ani/src/screen_ani_listener.cpp", "screen_ani/src/screen_ani_manager.cpp", "screen_ani/src/screen_ani_utils.cpp", + "screen_ani/src/screen_ani.cpp" ] configs = [ @@ -61,6 +64,7 @@ ohos_shared_library("screenani_kit") { "../../../../dm:libdm", "../../../../utils:libwmutil", "../../../../utils:libwmutil_base", + "../../../../interfaces/kits/napi/screen_runtime:screen_kit", ] external_deps = [ @@ -73,6 +77,8 @@ ohos_shared_library("screenani_kit") { "hilog:libhilog", "hitrace:hitrace_meter", "runtime_core:ani", + "napi:ace_napi", + "runtime_core:ani_helpers", ] innerapi_tags = [ "platformsdk" ] 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 d895f7f93d9db1ea100d52738cb0cc0c8d219263..fba60f91becb34c1a4c903594b1ec5ca3105b1b3 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 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Copyright (c) 2025-2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -14,30 +14,248 @@ */ import { AsyncCallback, Callback } from '@ohos.base'; +import { BusinessError } from '@ohos.base'; 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: long, mirrorScreen: Array, callback: AsyncCallback): void { + taskpool.execute((): long => { + let res: long = makeMirrorInternal(mainScreen, mirrorScreen); + return res; + }).then((ret: NullishType) => { + callback(null, ret as long); + }).catch((err: NullishType) => { + callback(err as BusinessError, -1); + }); +} + +export function makeMirror(mainScreen: long, mirrorScreen: Array): Promise { + return new Promise((resolve: (value: long) => void, reject: (error: BusinessError) => void ) => { + taskpool.execute((): long => { + let res: long = makeMirrorInternal(mainScreen, mirrorScreen); + return res; + }).then((ret: NullishType) => { + resolve(ret as long); + }).catch((err: NullishType) => { + reject(err as BusinessError); + }); + }) +} + +export native function makeMirrorInternal(mainScreen: long, mirrorScreen: Array): long; + +export function getAllScreens(callback: AsyncCallback>): void { + taskpool.execute((): Array => { + let screens: Array = new Array(10); + for (let i = 0; i < 10; i++) { + screens[i] = new ScreenImpl(); + } + getAllScreensInternal(screens); + minusScreens(screens); + return screens; + }).then((ret: NullishType) => { + callback(null, ret as Array); + }).catch((err: NullishType) => { + callback(err as BusinessError, new Array()); + }); +} + +export function getAllScreens(): Promise> { + return new Promise>((resolve: (value: Array) => void, + reject: (error: BusinessError) => void ) => { + taskpool.execute((): Array => { + let screens: Array = new Array(10); + for (let i = 0; i < 10; i++) { + screens[i] = new ScreenImpl(); + } + getAllScreensInternal(screens); + minusScreens(screens); + return screens; + }).then((ret: NullishType) => { + resolve(ret as Array); + }).catch((err: NullishType) => { + reject(err as BusinessError); + }); + } + ); +} + +function minusScreens(screens: Array) { + let i = 0; + for (; i < screens.length; i++) { + let currentScreen: ScreenImpl = screens[i] as ScreenImpl; + if (currentScreen.id < 0) { + break; + } + minusScreenModeInfo(currentScreen.supportedModeInfo); + } + screens.splice(i); +} + +function minusScreenModeInfo(screenModeInfo: Array) { + let i = 0; + for (; i < screenModeInfo.length; i++) { + let currentScreenMode: ScreenModeInfoImpl = screenModeInfo[i] as ScreenModeInfoImpl; + if (currentScreenMode.width <= 0) { + break; + } + } + screenModeInfo.splice(i); +} + +export native function getAllScreensInternal(screens: Array): void; + +export interface Screen { + + readonly id: long; + + readonly parent: long; + + readonly supportedModeInfo: Array; + + readonly activeModeIndex: long; + + readonly orientation: Orientation; + + readonly sourceMode: ScreenSourceMode; + + setDensityDpi(densityDpi: double, callback: AsyncCallback): void; + + setDensityDpi(densityDpi: double): Promise; +} + +class ScreenImpl implements Screen { + + static { loadLibrary("screenani_kit.z"); } + + constructor() { + this.id = -1; + this.supportedModeInfo = new Array(10); + for (let i = 0; i < this.supportedModeInfo.length;i++) { + this.supportedModeInfo[i] = new ScreenModeInfoImpl(); + } + } + + readonly id: long; + + readonly parent: long; + + readonly supportedModeInfo: Array; + + readonly activeModeIndex: long; + + readonly orientation: Orientation; + + readonly sourceMode: ScreenSourceMode; + + screenNativeObj: long; + + setDensityDpi(densityDpi: double, callback: AsyncCallback): void { + taskpool.execute((): void => { + this.setDensityDpiInternal(densityDpi); + }).then(() => { + callback(null, undefined); + }).catch((err: NullishType) => { + callback(err as BusinessError, undefined); + }); + } + + setDensityDpi(densityDpi: double): Promise { + return new Promise((resolve: (value: undefined) => void, reject: (error: BusinessError) => void ): void => { + taskpool.execute((): void => { + this.setDensityDpiInternal(densityDpi); + }).then(() => { + resolve(undefined); + }).catch((err: NullishType) => { + reject(err as BusinessError); + }); + }); + } + + static transferStatic(input: Any): Object { + let screen = new ScreenImpl(); + let screen_input: ESValue = ESValue.wrap(input); + let ret = false; + if (screen_input !== ESValue.Undefined) { + ret = ScreenImpl.nativeTransferStatic(screen_input, screen as Object); + minusScreenModeInfo(screen.supportedModeInfo); + } + if (!ret) { + return {}; + } + return screen as Object; + } + + static transferDynamic(input: Object): Any { + return ScreenImpl.nativeTransferDynamic((input as ScreenImpl).screenNativeObj).unwrap(); + } + + native setDensityDpiInternal(densityDpi: double): void; + native static nativeTransferStatic(input: ESValue, screen: Object): boolean; + native static nativeTransferDynamic(nativeObj: long): ESValue; +} + +export interface ScreenModeInfo { + id: long; + + width: long; + + height: long; + + refreshRate: int; +} + +class ScreenModeInfoImpl implements ScreenModeInfo{ + id: long; + + width: long; + + height: long; + + refreshRate: int; +} + +export enum ScreenSourceMode { + SCREEN_MAIN = 0, + + SCREEN_MIRROR = 1, + + SCREEN_EXTEND = 2, + + SCREEN_ALONE = 3 +} + +export enum Orientation { + UNSPECIFIED = 0, + + VERTICAL = 1, + + HORIZONTAL = 2, + + REVERSE_VERTICAL = 3, + + REVERSE_HORIZONTAL = 4 +} export let screenMgrRef: long; export function setScreenMgrRef(nativeObj: long): void{ screenMgrRef = nativeObj; } -export function screenEventCallBack(cb: object, cbArg: double): void { - const func = cb as (cbArg: double) => void; - func(cbArg as double); +export function screenEventCallBack(cb: object, cbArg: long): void { + const func = cb as (cbArg: long) => void; + func(cbArg as long); } } diff --git a/interfaces/kits/ani/screen_runtime/screen_ani/include/screen_ani.h b/interfaces/kits/ani/screen_runtime/screen_ani/include/screen_ani.h new file mode 100644 index 0000000000000000000000000000000000000000..4ed7082bb26136a7287274f5c2f41f8abb96b2db --- /dev/null +++ b/interfaces/kits/ani/screen_runtime/screen_ani/include/screen_ani.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OHOS_ANI_SCREEN_H +#define OHOS_ANI_SCREEN_H + +#include "ani.h" +#include "screen.h" + +namespace OHOS { +namespace Rosen { + +class ScreenAni { +public: + explicit ScreenAni(const sptr& screen); + static void SetDensityDpi(ani_env* env, ani_object obj, ani_double densityDpi); + void OnSetDensityDpi(ani_env* env, ani_object obj, ani_double densityDpi); + static ani_boolean TransferStatic(ani_env* env, ani_object obj, ani_object input, ani_object screenAniObj); + static ani_object TransferDynamic(ani_env* env, ani_object obj, ani_long nativeObj); + sptr GetScreen() const { return screen_; } + +private: + sptr screen_ = nullptr; +}; +} +} +#endif diff --git a/interfaces/kits/ani/screen_runtime/screen_ani/include/screen_ani_listener.h b/interfaces/kits/ani/screen_runtime/screen_ani/include/screen_ani_listener.h index 4284897185cc7b809dfdc28e294947188460fce1..23a283e5f4a2eb5e8e5aeb6e53bb14bc6d0768d3 100644 --- a/interfaces/kits/ani/screen_runtime/screen_ani/include/screen_ani_listener.h +++ b/interfaces/kits/ani/screen_runtime/screen_ani/include/screen_ani_listener.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Huawei Device Co., Ltd. + * Copyright (c) 2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -17,8 +17,10 @@ #define OHOS_ANI_SCREEN_LISTENER_H #include -#include "screen_manager.h" #include "ani.h" +#include "event_handler.h" +#include "screen_manager.h" +#include "refbase.h" namespace OHOS { namespace Rosen { @@ -35,16 +37,18 @@ public: void OnChange(ScreenId id) override; ani_status CallAniMethodVoid(ani_object object, const char* cls, const char* method, const char* signature, ...); + void SetMainEventHandler(); private: ani_env* env_; std::mutex mtx_; - std::map> aniCallBack_; + std::map> aniCallback_; wptr weakRef_; + std::shared_ptr eventHandler_ = nullptr; }; -const std::string EVENT_CONNECT = "connect"; -const std::string EVENT_DISCONNECT = "disconnect"; -const std::string EVENT_CHANGE = "change"; +const std::string ANI_EVENT_CONNECT = "connect"; +const std::string ANI_EVENT_DISCONNECT = "disconnect"; +const std::string ANI_EVENT_CHANGE = "change"; } // namespace Rosen } // namespace OHOS #endif /* OHOS_JS_SCREEN_LISTENER_H */ \ No newline at end of file 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 b1448b8a05811a3837df54e425fd92d5167af176..aa0d88198a21dabd9488237c15ebebc3558930d2 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 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Copyright (c) 2025-2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -29,18 +29,21 @@ namespace Rosen { class ScreenManagerAni { public: explicit ScreenManagerAni(); - static void registerCallback(ani_env* env, ani_string type, + static void RegisterCallback(ani_env* env, ani_string type, ani_ref callback, ani_long nativeObj); - static void unRegisterCallback(ani_env* env, ani_string type, + static void UnRegisterCallback(ani_env* env, ani_string type, ani_long nativeObj, ani_ref callback); - static ani_status initScreenManagerAni(ani_namespace screenNameSpace, ani_env* env); - DmErrorCode processRegisterCallback(ani_env* env, std::string& typeStr, + static ani_status InitScreenManagerAni(ani_namespace screenNameSpace, ani_env* env); + DmErrorCode ProcessRegisterCallback(ani_env* env, std::string& typeStr, sptr screenAniListener); + static ani_long MakeMirror(ani_env* env, ani_long mainScreen, ani_object mirrorScreen); + static void GetAllScreens(ani_env* env, ani_object screensAni); private: - void onRegisterCallback(ani_env* env, ani_string type, ani_ref callback); - void onUnRegisterCallback(ani_env* env, ani_string type, ani_ref callback); + void OnRegisterCallback(ani_env* env, ani_string type, ani_ref callback); + 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/include/screen_ani_utils.h b/interfaces/kits/ani/screen_runtime/screen_ani/include/screen_ani_utils.h index f5923bb245657d2944f11a819b8526dda2aa900e..352fcbffca52575df6b7580e6297fa260305ded8 100644 --- a/interfaces/kits/ani/screen_runtime/screen_ani/include/screen_ani_utils.h +++ b/interfaces/kits/ani/screen_runtime/screen_ani/include/screen_ani_utils.h @@ -17,6 +17,7 @@ #include #include "ani.h" +#include "screen.h" #include "singleton_container.h" namespace OHOS { @@ -32,6 +33,18 @@ static ani_status GetAniString(ani_env* env, const std::string& str, ani_string* static ani_status CallAniFunctionVoid(ani_env *env, const char* ns, const char* fn, const char* signature, ...); + +static ani_status ConvertScreen(ani_env *env, sptr screen, ani_object screenAni); + +static void ConvertScreenMode(ani_env* env, sptr mode, ani_object obj); + +static ani_status ConvertScreens(ani_env *env, std::vector> screen, ani_object& screensAni); + +static ani_object NewNativeObject(ani_env* env, const std::string& objName); + +static ani_array_ref NewNativeArray(ani_env* env, const std::string& objName, uint32_t size); + +static ani_enum_item CreateAniEnum(ani_env* env, const char* enum_descriptor, ani_size index); }; } } 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 6a1c64b45e42a1279d2dc70b2e5fa14d6080ca34..b73569d9492aaea6b684506eed26feaee187cdb6 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 @@ -118,13 +118,13 @@ ani_status AniErrUtils::CreateBusinessError(ani_env* env, int32_t error, std::st { TLOGI(WmsLogTag::DMS, "[ANI] in"); ani_class aniClass; - ani_status status = env->FindClass("L@ohos/base/BusinessError;", &aniClass); + ani_status status = env->FindClass("@ohos.base.BusinessError", &aniClass); if (status != ANI_OK) { TLOGE(WmsLogTag::DMS, "[ANI] class not found, status:%{public}d", static_cast(status)); return status; } ani_method aniCtor; - status = env->Class_FindMethod(aniClass, "", "Lstd/core/String;Lescompat/ErrorOptions;:V", &aniCtor); + status = env->Class_FindMethod(aniClass, "", "C{std.core.String}C{escompat.ErrorOptions}:", &aniCtor); if (status != ANI_OK) { TLOGE(WmsLogTag::DMS, "[ANI] ctor not found, status:%{public}d", static_cast(status)); return status; @@ -136,13 +136,11 @@ 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_Int(*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; } - status = env->Object_SetFieldByName_Int(*err, "code", static_cast(error)); - return ANI_OK; } -} // namespace OHOS::Rosen \ No newline at end of file +} // namespace OHOS::Rosen diff --git a/interfaces/kits/ani/screen_runtime/screen_ani/src/screen_ani.cpp b/interfaces/kits/ani/screen_runtime/screen_ani/src/screen_ani.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d1961350731e264feebb89d011511ea2e3f49938 --- /dev/null +++ b/interfaces/kits/ani/screen_runtime/screen_ani/src/screen_ani.cpp @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "screen_ani.h" + +#include "ani_err_utils.h" +#include "dm_common.h" +#include "interop_js/arkts_esvalue.h" +#include "interop_js/arkts_interop_js_api.h" +#include "interop_js/hybridgref_ani.h" +#include "interop_js/hybridgref_napi.h" +#include "js_screen.h" +#include "screen_ani_utils.h" +#include "window_manager_hilog.h" + + +namespace OHOS { +namespace Rosen { +ScreenAni::ScreenAni(const sptr& screen) : screen_(screen) +{ +} + +void ScreenAni::SetDensityDpi(ani_env* env, ani_object obj, ani_double densityDpi) +{ + ani_long screenNativeRef; + if (ANI_OK != env->Object_GetFieldByName_Long(obj, "screenNativeObj", &screenNativeRef)) { + TLOGE(WmsLogTag::DMS, "[ANI] screenAni native null ptr"); + return; + } + ScreenAni* screenAni = reinterpret_cast(screenNativeRef); + screenAni->OnSetDensityDpi(env, obj, densityDpi); +} + +void ScreenAni::OnSetDensityDpi(ani_env* env, ani_object obj, ani_double densityDpi) +{ + DmErrorCode ret = DM_JS_TO_ERROR_CODE_MAP.at(screen_->SetDensityDpi(static_cast(densityDpi))); + if (ret != DmErrorCode::DM_OK) { + TLOGE(WmsLogTag::DMS, "[ANI] OnSetDensityDpi fail"); + AniErrUtils::ThrowBusinessError(env, ret, "JsScreen::OnSetDensityDpi failed."); + } +} + +ani_boolean ScreenAni::TransferStatic(ani_env* env, ani_object obj, ani_object input, ani_object screenAniObj) +{ + TLOGI(WmsLogTag::DMS, "begin"); + void* unwrapResult = nullptr; + auto ret = arkts_esvalue_unwrap(env, input, &unwrapResult); + if (!ret) { + TLOGE(WmsLogTag::DMS, "[ANI] fail to unwrap input, ret: %{public}d", ret); + return false; + } + if (unwrapResult == nullptr) { + TLOGE(WmsLogTag::DMS, "[ANI] unwrapResult is nullptr"); + return false; + } + JsScreen* jsScreen = static_cast(unwrapResult); + if (jsScreen == nullptr) { + TLOGE(WmsLogTag::DMS, "[ANI] jsScreen is nullptr"); + return false; + } + + sptr screen = jsScreen->GetScreen(); + if (ScreenAniUtils::ConvertScreen(env, screen, screenAniObj) != ANI_OK) { + TLOGE(WmsLogTag::DMS, "[ANI] convert screen failed"); + return false; + } + return true; +} + +ani_object ScreenAni::TransferDynamic(ani_env* env, ani_object obj, ani_long nativeObj) +{ + TLOGI(WmsLogTag::DMS, "begin"); + ScreenAni* aniScreen = reinterpret_cast(nativeObj); + if (aniScreen == nullptr) { + TLOGE(WmsLogTag::DMS, "[ANI] aniScreen is nullptr"); + return nullptr; + } + napi_env napiEnv = {}; + if (!arkts_napi_scope_open(env, &napiEnv)) { + TLOGE(WmsLogTag::DMS, "arkts_napi_scope_open failed"); + return nullptr; + } + + sptr screen = aniScreen->GetScreen(); + napi_value jsScreen = CreateJsScreenObject(napiEnv, screen); + hybridgref ref = nullptr; + if (!hybridgref_create_from_napi(napiEnv, jsScreen, &ref)) { + TLOGE(WmsLogTag::DMS, "hybridgref_create_from_napi failed"); + return nullptr; + } + ani_object result = nullptr; + if (!hybridgref_get_esvalue(env, ref, &result)) { + hybridgref_delete_from_napi(napiEnv, ref); + TLOGE(WmsLogTag::DMS, "hybridgref_get_esvalue failed"); + return nullptr; + } + hybridgref_delete_from_napi(napiEnv, ref); + if (!arkts_napi_scope_close_n(napiEnv, 0, nullptr, nullptr)) { + TLOGE(WmsLogTag::DMS, "arkts_napi_scope_close_n failed"); + return nullptr; + } + return result; +} +} +} \ No newline at end of file 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 d542ecfd5fb3b188f33774061823291fa716a368..1debd618ce518e4ebca9e9f73c86ed6c23ef6b1f 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 @@ -23,34 +23,38 @@ ScreenAniListener::~ScreenAniListener() { TLOGI(WmsLogTag::DMS, "[ANI]~ScreenAniListener"); } + +void ScreenAniListener::SetMainEventHandler() +{ + auto mainRunner = AppExecFwk::EventRunner::GetMainEventRunner(); + if (mainRunner == nullptr) { + return; + } + eventHandler_ = std::make_shared(mainRunner); +} void ScreenAniListener::AddCallback(const std::string& type, ani_ref callback) { TLOGI(WmsLogTag::DMS, "[ANI] AddCallback is called, type = %{public}s", type.c_str()); if (env_ == nullptr) { - TLOGE(WmsLogTag::DMS, "env_ nullptr"); + TLOGE(WmsLogTag::DMS, "[ANI] env nullptr"); return; } std::lock_guard lock(mtx_); - ani_ref cbRef{}; - if (env_->GlobalReference_Create(callback, &cbRef) != ANI_OK) { - TLOGE(WmsLogTag::DEFAULT, "[ANI]create global ref fail"); - return; - }; - aniCallBack_[type].emplace_back(cbRef); - TLOGI(WmsLogTag::DMS, "[ANI] AddCallback success aniCallBack_ size: %{public}u!", - static_cast(aniCallBack_[type].size())); + aniCallback_[type].emplace_back(callback); + TLOGI(WmsLogTag::DMS, "[ANI] AddCallback success aniCallback_ size: %{public}u!", + static_cast(aniCallback_[type].size())); } void ScreenAniListener::RemoveAllCallback() { std::lock_guard lock(mtx_); - aniCallBack_.clear(); + aniCallback_.clear(); } void ScreenAniListener::RemoveCallback(ani_env* env, const std::string& type, ani_ref callback) { std::lock_guard lock(mtx_); - auto it = aniCallBack_.find(type); - if (it == aniCallBack_.end()) { + auto it = aniCallback_.find(type); + if (it == aniCallback_.end()) { TLOGE(WmsLogTag::DMS, "[ANI] Listener no callback to remove"); return; } @@ -69,55 +73,140 @@ void ScreenAniListener::RemoveCallback(ani_env* env, const std::string& type, an } void ScreenAniListener::OnConnect(ScreenId id) { + TLOGI(WmsLogTag::DMS, "[ANI] begin, displayId: %{public}" PRIu64, id); + std::lock_guard lock(mtx_); + auto thisListener = weakRef_.promote(); + if (thisListener == nullptr) { + TLOGE(WmsLogTag::DMS, "[ANI] this listener is nullptr"); + return; + } + if (aniCallback_.empty()) { + TLOGE(WmsLogTag::DMS, "[ANI] OnConnect not register!"); + return; + } + auto it = aniCallback_.find(ANI_EVENT_CONNECT); + if (it == aniCallback_.end()) { + TLOGE(WmsLogTag::DMS, "[ANI] OnConnect not this event, return"); + return; + } + std::vector vec = it->second; + TLOGI(WmsLogTag::DMS, "vec_callback size: %{public}d", vec.size()); + // find callbacks in vector + for (auto oneAniCallback : vec) { + if (env_ == nullptr) { + TLOGE(WmsLogTag::DMS, "[ANI] null env"); + return; + } + ani_boolean undefRes = 0; + env_->Reference_IsUndefined(oneAniCallback, &undefRes); + // judge is null or undefined + if (undefRes) { + TLOGE(WmsLogTag::DMS, "[ANI] oneAniCallback is undef"); + continue; + } + + auto task = [env = env_, oneAniCallback, id] { + ScreenAniUtils::CallAniFunctionVoid(env, "@ohos.screen.screen", "screenEventCallBack", + "C{std.core.Object}l:", oneAniCallback, static_cast(id)); + }; + if (!eventHandler_) { + TLOGE(WmsLogTag::DMS, "[ANI] get main event handler failed!"); + return; + } + eventHandler_->PostTask(std::move(task), "dms:AniScreenListener::ConnectCallBack", 0, + AppExecFwk::EventQueue::Priority::IMMEDIATE); + } } void ScreenAniListener::OnDisconnect(ScreenId id) { + TLOGI(WmsLogTag::DMS, "[ANI] begin"); + std::lock_guard lock(mtx_); + auto thisListener = weakRef_.promote(); + if (thisListener == nullptr) { + TLOGE(WmsLogTag::DMS, "[ANI] this listener is nullptr"); + return; + } + TLOGI(WmsLogTag::DMS, "[ANI] OnDisconnect is called, displayId: %{public}" PRIu64, id); + if (aniCallback_.empty()) { + TLOGE(WmsLogTag::DMS, "[ANI] OnDisconnect not register!"); + return; + } + auto it = aniCallback_.find(ANI_EVENT_DISCONNECT); + if (it == aniCallback_.end()) { + TLOGE(WmsLogTag::DMS, "[ANI] OnDisconnect not this event, return"); + return; + } + std::vector vec = it->second; + TLOGI(WmsLogTag::DMS, "vec_callback size: %{public}d", vec.size()); + // find callbacks in vector + for (auto oneAniCallback : vec) { + if (env_ == nullptr) { + TLOGE(WmsLogTag::DMS, "[ANI] null env"); + return; + } + ani_boolean undefRes = 0; + env_->Reference_IsUndefined(oneAniCallback, &undefRes); + // judge is null or undefined + if (undefRes) { + TLOGE(WmsLogTag::DMS, "[ANI] oneAniCallback is undef"); + continue; + } + + auto task = [env = env_, oneAniCallback, id] { + ScreenAniUtils::CallAniFunctionVoid(env, "@ohos.screen.screen", "screenEventCallBack", + "C{std.core.Object}l:", oneAniCallback, static_cast(id)); + }; + if (!eventHandler_) { + TLOGE(WmsLogTag::DMS, "[ANI] get main event handler failed!"); + return; + } + eventHandler_->PostTask(std::move(task), "dms:AniScreenListener::DisconnectCallBack", 0, + AppExecFwk::EventQueue::Priority::IMMEDIATE); + } } - -// need to implement + void ScreenAniListener::OnChange(ScreenId id) { - TLOGI(WmsLogTag::DMS, "[ANI] OnChange begin"); + TLOGI(WmsLogTag::DMS, "[ANI] begin"); std::lock_guard lock(mtx_); auto thisListener = weakRef_.promote(); if (thisListener == nullptr) { - TLOGE(WmsLogTag::DEFAULT, "[ANI] this listener is nullptr"); + TLOGE(WmsLogTag::DMS, "[ANI] this listener is nullptr"); return; } - TLOGI(WmsLogTag::DMS, "[ANI] OnChange is called, displayId: %{public}d", static_cast(id)); - if (aniCallBack_.empty()) { + TLOGI(WmsLogTag::DMS, "[ANI] OnChange is called, displayId: %{public}" PRIu64, id); + if (aniCallback_.empty()) { TLOGE(WmsLogTag::DMS, "[ANI] OnChange not register!"); return; } - auto it = aniCallBack_.find(EVENT_CHANGE); - if (it == aniCallBack_.end()) { + auto it = aniCallback_.find(ANI_EVENT_CHANGE); + if (it == aniCallback_.end()) { TLOGE(WmsLogTag::DMS, "[ANI] OnChange not this event, return"); return; } std::vector vec = it->second; - TLOGI(WmsLogTag::DMS, "vec_callback size: %{public}u", vec.size()); // find callbacks in vector for (auto oneAniCallback : vec) { if (env_ == nullptr) { - TLOGI(WmsLogTag::DMS, "OnDestroy: null env_"); + TLOGE(WmsLogTag::DMS, "[ANI] null env"); return; } - ani_boolean undefRes; - ani_boolean nullRes; + ani_boolean undefRes = 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, "@ohos.screen.screen", "screenEventCallBack", + "C{std.core.Object}l:", 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); } } @@ -141,4 +230,4 @@ ani_status ScreenAniListener::CallAniMethodVoid(ani_object object, const char* c return ret; } } -} \ No newline at end of file +} 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 aea2498c971bf7bf07bf4a879e2f7084221c02d0..a049799e2569e2886c77c96f087af1e00db94a10 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 @@ -12,18 +12,20 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#include "screen_ani_manager.h" + #include #include #include "ani.h" -#include "singleton_container.h" -#include "window_manager_hilog.h" +#include "ani_err_utils.h" #include "dm_common.h" #include "refbase.h" -#include "screen_ani_manager.h" +#include "screen_ani.h" #include "screen_ani_utils.h" #include "screen_ani_listener.h" -#include "ani_err_utils.h" +#include "singleton_container.h" +#include "window_manager_hilog.h" namespace OHOS { namespace Rosen { @@ -32,138 +34,167 @@ ScreenManagerAni::ScreenManagerAni() { } -void ScreenManagerAni::registerCallback(ani_env* env, ani_string type, ani_ref callback, ani_long nativeObj) +void ScreenManagerAni::RegisterCallback(ani_env* env, ani_string type, ani_ref callback, ani_long nativeObj) { - TLOGI(WmsLogTag::DMS, "[ANI] start to register screen callback: %{public}lld", nativeObj); + TLOGI(WmsLogTag::DMS, "[ANI] start to register screen callback: %{public}ld", (long)nativeObj); ScreenManagerAni* screenManagerAni = reinterpret_cast(nativeObj); if (screenManagerAni != nullptr) { - screenManagerAni->onRegisterCallback(env, type, callback); + screenManagerAni->OnRegisterCallback(env, type, callback); } else { TLOGE(WmsLogTag::DMS, "[ANI] screenManagerAni null ptr"); } } -void ScreenManagerAni::unRegisterCallback(ani_env* env, ani_string type, ani_long nativeObj, ani_ref callback) +void ScreenManagerAni::UnRegisterCallback(ani_env* env, ani_string type, ani_long nativeObj, ani_ref callback) { - TLOGI(WmsLogTag::DMS, "[ANI] unRegisterCallback begin"); + TLOGI(WmsLogTag::DMS, "[ANI] begin"); ScreenManagerAni* screenManagerAni = reinterpret_cast(nativeObj); if (screenManagerAni != nullptr) { - screenManagerAni->onUnRegisterCallback(env, type, callback); + screenManagerAni->OnUnRegisterCallback(env, type, callback); } else { TLOGI(WmsLogTag::DMS, "[ANI] null ptr"); } } -void ScreenManagerAni::onRegisterCallback(ani_env* env, ani_string type, ani_ref callback) +void ScreenManagerAni::OnRegisterCallback(ani_env* env, ani_string type, ani_ref callback) { - TLOGI(WmsLogTag::DMS, "[ANI] onRegisterCallback begin"); - std::lock_guard lock(mtx_); + TLOGI(WmsLogTag::DMS, "[ANI] begin"); + 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); - ret = processRegisterCallback(env, typeString, screenAniListener); + screenAniListener->SetMainEventHandler(); + 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, DmErrorCode::DM_ERROR_INVALID_PARAM, errMsg); + AniErrUtils::ThrowBusinessError(env, ret, errMsg); return; } // add listener to map - jsCbMap_[typeString][callback] = screenAniListener; - if (typeString == EVENT_CHANGE) { - screenAniListener->OnChange(0); - } + jsCbMap_[typeString][cbRef] = screenAniListener; } -DmErrorCode ScreenManagerAni::processRegisterCallback(ani_env* env, std::string& typeStr, +DmErrorCode ScreenManagerAni::ProcessRegisterCallback(ani_env* env, std::string& typeStr, sptr screenAniListener) { DmErrorCode ret = DmErrorCode::DM_ERROR_INVALID_PARAM; - if (typeStr == EVENT_CHANGE) { - TLOGI(WmsLogTag::DMS, "processRegisterCallback %{public}s", typeStr.c_str()); + if (typeStr == ANI_EVENT_CHANGE || typeStr == ANI_EVENT_CONNECT || typeStr == ANI_EVENT_DISCONNECT) { + TLOGI(WmsLogTag::DMS, "ProcessRegisterCallback %{public}s", typeStr.c_str()); ret = DM_JS_TO_ERROR_CODE_MAP.at( SingletonContainer::Get().RegisterScreenListener(screenAniListener)); } return ret; } -void ScreenManagerAni::onUnRegisterCallback(ani_env* env, ani_string type, ani_ref callback) +void ScreenManagerAni::OnUnRegisterCallback(ani_env* env, ani_string type, ani_ref callback) { - TLOGI(WmsLogTag::DMS, "[ANI] onUnRegisterCallback begin"); + TLOGI(WmsLogTag::DMS, "[ANI] begin"); 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) { - TLOGI(WmsLogTag::DMS, "[ANI] onUnRegisterCallback for all"); + if (callbackUndefined) { + TLOGI(WmsLogTag::DMS, "[ANI] OnUnRegisterCallback for all"); ret = DM_JS_TO_ERROR_CODE_MAP.at(UnRegisterAllScreenListenerWithType(typeString)); } else { - TLOGI(WmsLogTag::DMS, "[ANI] onUnRegisterCallback with type"); + TLOGI(WmsLogTag::DMS, "[ANI] OnUnRegisterCallback with type"); ret = DM_JS_TO_ERROR_CODE_MAP.at(UnRegisterScreenListenerWithType(typeString, env, callback)); } if (ret != DmErrorCode::DM_OK) { - DmErrorCode errCode = DmErrorCode::DM_ERROR_INVALID_PARAM; - if (ret == DmErrorCode::DM_ERROR_NOT_SYSTEM_APP) { - errCode = ret; - } std::string errMsg = "[ANI] failed to unregister screen listener with type"; TLOGE(WmsLogTag::DMS, "[ANI] failed to unregister screen listener with type"); - AniErrUtils::ThrowBusinessError(env, DMError::DM_ERROR_INVALID_PARAM, errMsg); + AniErrUtils::ThrowBusinessError(env, ret, errMsg); + } +} + +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] 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) { + if (type == ANI_EVENT_CONNECT || type == ANI_EVENT_DISCONNECT || type == ANI_EVENT_CHANGE) { TLOGI(WmsLogTag::DMS, "[ANI] start to unregis screen event listener! event = %{public}s", type.c_str()); 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; } DMError ScreenManagerAni::UnRegisterAllScreenListenerWithType(std::string type) { - TLOGI(WmsLogTag::DMS, "[ANI] UnregisterAllScreenListenerWithType begin"); + TLOGI(WmsLogTag::DMS, "[ANI] begin"); if (jsCbMap_.empty() || jsCbMap_.find(type) == jsCbMap_.end()) { TLOGI(WmsLogTag::DMS, "[ANI] UnregisterAllScreenListenerWithType methodName %{public}s not registered!", type.c_str()); @@ -172,7 +203,7 @@ DMError ScreenManagerAni::UnRegisterAllScreenListenerWithType(std::string type) DMError ret = DMError::DM_OK; for (auto it = jsCbMap_[type].begin(); it != jsCbMap_[type].end();) { it->second->RemoveAllCallback(); - if (type == EVENT_CHANGE) { + if (type == ANI_EVENT_CONNECT || type == ANI_EVENT_DISCONNECT || type == ANI_EVENT_CHANGE) { sptr thisListener(it->second); ret = SingletonContainer::Get().UnregisterScreenListener(thisListener); } @@ -180,12 +211,46 @@ DMError ScreenManagerAni::UnRegisterAllScreenListenerWithType(std::string type) return ret; } +ani_long ScreenManagerAni::MakeMirror(ani_env* env, ani_long mainScreen, ani_object mirrorScreen) +{ + ani_int length = 0; + std::vector screenIds; + env->Object_GetPropertyByName_Int(mirrorScreen, "length", &length); + TLOGI(WmsLogTag::DMS, "[ANI] length %{public}d", (ani_int)length); + for (int32_t i = 0; i < length; i++) { + ani_ref screenIdRef; + auto ret = env->Object_CallMethodByName_Ref(mirrorScreen, "$_get", "i:C{std.core.Object}", + &screenIdRef, (ani_int)i); + if (ANI_OK != ret) { + TLOGE(WmsLogTag::DMS, "[ANI] get ani_array index %{public}u fail, ret: %{public}u", (ani_int)i, ret); + AniErrUtils::ThrowBusinessError(env, DmErrorCode::DM_ERROR_INVALID_PARAM, "Failed to get screenId"); + return static_cast(INVALID_SCREEN_ID); + } + ani_long screenId; + ret = env->Object_CallMethodByName_Long(static_cast(screenIdRef), "unboxed", ":J", &screenId); + if (ANI_OK != ret) { + TLOGE(WmsLogTag::DMS, "[ANI] unboxed screenId failed, ret: %{public}u", ret); + AniErrUtils::ThrowBusinessError(env, DmErrorCode::DM_ERROR_INVALID_PARAM, "Failed to unboxed screenId"); + return static_cast(INVALID_SCREEN_ID); + } + screenIds.emplace_back(static_cast(screenId)); + } + ScreenId screenGroupId = INVALID_SCREEN_ID; + DmErrorCode ret = DM_JS_TO_ERROR_CODE_MAP.at( + SingletonContainer::Get().MakeMirror(static_cast(mainScreen), + screenIds, screenGroupId)); + if (ret != DmErrorCode::DM_OK) { + AniErrUtils::ThrowBusinessError(env, ret, "JsScreenManager::OnMakeMirror failed."); + return static_cast(INVALID_SCREEN_ID); + } + return static_cast(screenGroupId); +} -ani_status ScreenManagerAni::initScreenManagerAni(ani_namespace screenNameSpace, ani_env* env) +ani_status ScreenManagerAni::InitScreenManagerAni(ani_namespace screenNameSpace, ani_env* env) { - TLOGI(WmsLogTag::DEFAULT, "[ANI]"); + TLOGI(WmsLogTag::DEFAULT, "[ANI] begin"); ani_function setObjFunc = nullptr; - ani_status ret = env->Namespace_FindFunction(screenNameSpace, "setScreenMgrRef", "J:V", &setObjFunc); + ani_status ret = env->Namespace_FindFunction(screenNameSpace, "setScreenMgrRef", "l:", &setObjFunc); if (ret != ANI_OK) { TLOGE(WmsLogTag::DEFAULT, "[ANI] find setNativeObj func fail %{public}u", ret); return ret; @@ -199,6 +264,28 @@ ani_status ScreenManagerAni::initScreenManagerAni(ani_namespace screenNameSpace, return ret; } +void ScreenManagerAni::GetAllScreens(ani_env* env, ani_object screensAni) +{ + HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "JsScreenManager::OnGetAllScreens"); + TLOGI(WmsLogTag::DMS, "[ANI] start"); + std::vector> screens; + auto res = DM_JS_TO_ERROR_CODE_MAP.at(SingletonContainer::Get().GetAllScreens(screens)); + if (res != DmErrorCode::DM_OK) { + TLOGE(WmsLogTag::DMS, "[ANI] JsScreenManager::OnGetAllScreens failed."); + AniErrUtils::ThrowBusinessError(env, res, "JsScreenManager::OnGetAllScreens failed."); + } else if (!screens.empty()) { + TLOGI(WmsLogTag::DMS, "[ANI] JsScreenManager::OnGetAllScreens succeed. size = %{public}u", + static_cast(screens.size())); + if (ANI_OK != ScreenAniUtils::ConvertScreens(env, screens, screensAni)) { + TLOGE(WmsLogTag::DMS, "[ANI] ConvertScreens fail"); + } + } else { + TLOGE(WmsLogTag::DMS, "[ANI] JsScreenManager::OnGetAllScreens null."); + AniErrUtils::ThrowBusinessError(env, DmErrorCode::DM_ERROR_INVALID_SCREEN, + "JsScreenManager::OnGetAllScreens failed."); + } +} + extern "C" { ANI_EXPORT ani_status ANI_Constructor(ani_vm *vm, uint32_t *result) { @@ -211,21 +298,42 @@ ANI_EXPORT ani_status ANI_Constructor(ani_vm *vm, uint32_t *result) return ANI_NOT_FOUND; } ani_namespace nsp; - if ((ret = env->FindNamespace("L@ohos/screen/screen;", &nsp)) != ANI_OK) { + if ((ret = env->FindNamespace("@ohos.screen.screen", &nsp)) != ANI_OK) { TLOGE(WmsLogTag::DMS, "[ANI] null env %{public}u", ret); return ANI_NOT_FOUND; } - ScreenManagerAni::initScreenManagerAni(nsp, env); + ScreenManagerAni::InitScreenManagerAni(nsp, env); std::array funcs = { ani_native_function {"syncOn", nullptr, - reinterpret_cast(ScreenManagerAni::registerCallback)}, + reinterpret_cast(ScreenManagerAni::RegisterCallback)}, ani_native_function {"syncOff", nullptr, - reinterpret_cast(ScreenManagerAni::unRegisterCallback)} + reinterpret_cast(ScreenManagerAni::UnRegisterCallback)}, + ani_native_function {"makeMirrorInternal", nullptr, + reinterpret_cast(ScreenManagerAni::MakeMirror)}, + ani_native_function {"getAllScreensInternal", nullptr, + reinterpret_cast(ScreenManagerAni::GetAllScreens)} }; if ((ret = env->Namespace_BindNativeFunctions(nsp, funcs.data(), funcs.size()))) { TLOGE(WmsLogTag::DMS, "[ANI] bind namespace fail %{public}u", ret); return ANI_NOT_FOUND; } + ani_class screenCls = nullptr; + if ((ret = env->FindClass("@ohos.screen.screen.ScreenImpl", &screenCls)) != ANI_OK) { + TLOGE(WmsLogTag::DMS, "[ANI] null env %{public}u", ret); + return ANI_NOT_FOUND; + } + std::array methods = { + ani_native_function {"setDensityDpiInternal", "d:", + reinterpret_cast(ScreenAni::SetDensityDpi)}, + ani_native_function {"nativeTransferStatic", "C{std.interop.ESValue}C{std.core.Object}:z", + reinterpret_cast(ScreenAni::TransferStatic)}, + ani_native_function {"nativeTransferDynamic", "l:C{std.interop.ESValue}", + reinterpret_cast(ScreenAni::TransferDynamic)}, + }; + if ((ret = env->Class_BindNativeMethods(screenCls, methods.data(), methods.size())) != ANI_OK) { + TLOGE(WmsLogTag::DMS, "[ANI] bind screen class fail %{public}u", ret); + return ANI_NOT_FOUND; + } *result = ANI_VERSION_1; return ANI_OK; } diff --git a/interfaces/kits/ani/screen_runtime/screen_ani/src/screen_ani_utils.cpp b/interfaces/kits/ani/screen_runtime/screen_ani/src/screen_ani_utils.cpp index 99ff06c02783f1a15b7c316b706203ef207e102d..0ca827744baf5eb66849a00c3af9a77b6f1550ef 100644 --- a/interfaces/kits/ani/screen_runtime/screen_ani/src/screen_ani_utils.cpp +++ b/interfaces/kits/ani/screen_runtime/screen_ani/src/screen_ani_utils.cpp @@ -23,6 +23,8 @@ #include "window_manager_hilog.h" #include "dm_common.h" #include "refbase.h" +#include "screen_info.h" +#include "screen_ani.h" namespace OHOS { namespace Rosen { @@ -57,36 +59,148 @@ ani_status ScreenAniUtils::GetAniString(ani_env* env, const std::string& str, an return env->String_NewUTF8(str.c_str(), static_cast(str.size()), result); } +ani_status ScreenAniUtils::ConvertScreen(ani_env *env, sptr screen, ani_object obj) +{ + sptr info = screen->GetScreenInfo(); + TLOGI(WmsLogTag::DMS, "[ANI] convert screen id %{public}u", static_cast(info->GetScreenId())); + env->Object_SetFieldByName_Long(obj, "id", static_cast(info->GetScreenId())); + env->Object_SetFieldByName_Long(obj, "parent", static_cast(info->GetParentId())); + env->Object_SetFieldByName_Long(obj, "activeModeIndex", + static_cast(info->GetModeId())); + env->Object_SetFieldByName_Ref(obj, "orientation", ScreenAniUtils::CreateAniEnum(env, + "@ohos.screen.screen.Orientation", static_cast(info->GetOrientation()))); + env->Object_SetFieldByName_Ref(obj, "sourceMode", ScreenAniUtils::CreateAniEnum(env, + "@ohos.screen.screen.ScreenSourceMode", static_cast(info->GetSourceMode()))); + std::unique_ptr screenAni = std::make_unique(screen); + if (ANI_OK != env->Object_SetFieldByName_Long(obj, "screenNativeObj", + reinterpret_cast(screenAni.release()))) { + TLOGE(WmsLogTag::DMS, "[ANI] set screenNativeObj fail"); + return ANI_ERROR; + } + std::vector> modes = info->GetModes(); + ani_array_ref screenModeInfos = NewNativeArray(env, "@ohos.screen.screen.ScreenModeInfoImpl", + static_cast(modes.size())); + ani_size index = 0; + for (auto mode : modes) { + ani_object screenModeInfo = NewNativeObject(env, "@ohos.screen.screen.ScreenModeInfoImpl"); + ConvertScreenMode(env, mode, screenModeInfo); + if (ANI_OK != env->Array_Set_Ref(screenModeInfos, index, screenModeInfo)) { + TLOGE(WmsLogTag::DMS, "[ANI] Array_Set_Ref fail"); + return ANI_ERROR; + } + index++; + } + auto ret = env->Object_SetFieldByName_Ref(obj, "supportedModeInfo", + static_cast(screenModeInfos)); + if (ANI_OK != ret) { + TLOGE(WmsLogTag::DMS, "[ANI] get ScreenModeInfos fail, ret: %{public}d", ret); + return ANI_ERROR; + } + return ANI_OK; +} + +ani_array_ref ScreenAniUtils::NewNativeArray(ani_env* env, const std::string& objName, uint32_t size) +{ + ani_array_ref array = nullptr; + ani_class cls; + if (env->FindClass(objName.c_str(), &cls) != ANI_OK) { + TLOGE(WmsLogTag::DMS, "[ANI] class not found"); + return array; + } + if (env->Array_New_Ref(cls, size, CreateAniUndefined(env), &array) != ANI_OK) { + TLOGE(WmsLogTag::DMS, "[ANI] create array failed"); + } + return array; +} + +ani_object ScreenAniUtils::NewNativeObject(ani_env* env, const std::string& objName) +{ + ani_class cls; + if (env->FindClass(objName.c_str(), &cls) != ANI_OK) { + TLOGE(WmsLogTag::DMS, "[ANI] class not found"); + return CreateAniUndefined(env); + } + ani_method ctor; + if (env->Class_FindMethod(cls, "", nullptr, &ctor) != ANI_OK) { + TLOGE(WmsLogTag::DMS, "[ANI] ctor not found"); + return CreateAniUndefined(env); + } + ani_object obj; + if (env->Object_New(cls, ctor, &obj) != ANI_OK) { + TLOGE(WmsLogTag::DMS, "[ANI] fail to new obj"); + return CreateAniUndefined(env); + } + return obj; +} + +void ScreenAniUtils::ConvertScreenMode(ani_env* env, sptr mode, ani_object obj) +{ + env->Object_SetFieldByName_Long(obj, "id", static_cast(mode->id_)); + env->Object_SetFieldByName_Long(obj, "width", static_cast(mode->width_)); + env->Object_SetFieldByName_Long(obj, "height", static_cast(mode->height_)); + env->Object_SetFieldByName_Int(obj, "refreshRate", static_cast(mode->refreshRate_)); +} + +ani_status ScreenAniUtils::ConvertScreens(ani_env *env, std::vector> screens, ani_object& screensAni) +{ + TLOGI(WmsLogTag::DMS, "[ANI] screens size %{public}u", static_cast(screens.size())); + for (uint32_t i = 0; i < screens.size(); i++) { + ani_ref currentScreenAni; + if (ANI_OK != env->Object_CallMethodByName_Ref(screensAni, "$_get", "i:C{std.core.Object}", + ¤tScreenAni, (ani_int)i)) { + TLOGE(WmsLogTag::DMS, "[ANI] get ani_array index %{public}u fail", (ani_int)i); + return ANI_ERROR; + } + if (ANI_OK != ConvertScreen(env, screens[i], static_cast(currentScreenAni))) { + TLOGE(WmsLogTag::DMS, "[ANI] get convert screenAni index %{public}u fail", (ani_int)i); + return ANI_ERROR; + } + } + return ANI_OK; +} + ani_status ScreenAniUtils::CallAniFunctionVoid(ani_env *env, const char* ns, const char* fn, const char* signature, ...) { - TLOGI(WmsLogTag::DEFAULT, "[ANI]CallAniFunctionVoid begin"); + TLOGI(WmsLogTag::DMS, "[ANI] begin"); ani_status ret = ANI_OK; ani_namespace aniNamespace{}; if ((ret = env->FindNamespace(ns, &aniNamespace)) != ANI_OK) { - TLOGE(WmsLogTag::DEFAULT, "[ANI]canot find ns %{public}d", ret); + TLOGE(WmsLogTag::DMS, "[ANI]canot find ns %{public}d", ret); return ret; } ani_function func{}; if ((ret = env->Namespace_FindFunction(aniNamespace, fn, signature, &func)) != ANI_OK) { - TLOGE(WmsLogTag::DEFAULT, "[ANI]canot find callBack %{public}d", ret); + TLOGE(WmsLogTag::DMS, "[ANI]canot find callBack %{public}d", ret); return ret; } - va_list args; - va_start(args, signature); - TLOGI(WmsLogTag::DEFAULT, "[ANI]CallAniFunctionVoid begin %{public}s", signature); if (func == nullptr) { - TLOGI(WmsLogTag::DEFAULT, "[ANI] null func ani"); + TLOGE(WmsLogTag::DMS, "[ANI] null func ani"); return ret; } + va_list args; + va_start(args, signature); + TLOGI(WmsLogTag::DMS, "[ANI]CallAniFunctionVoid begin %{public}s", signature); ret = env->Function_Call_Void_V(func, args); va_end(args); if (ret != ANI_OK) { - TLOGE(WmsLogTag::DEFAULT, "[ANI]canot run callBack %{public}d", ret); + TLOGE(WmsLogTag::DMS, "[ANI]canot run callBack %{public}d", ret); return ret; } return ret; } +ani_enum_item ScreenAniUtils::CreateAniEnum(ani_env* env, const char* enum_descriptor, ani_size index) +{ + ani_enum enumType; + ani_status ret = env->FindEnum(enum_descriptor, &enumType); + if (ret != ANI_OK) { + TLOGE(WmsLogTag::DMS, "[ANI] Failed to find enum,%{public}s", enum_descriptor); + return nullptr; + } + ani_enum_item enumItem; + env->Enum_GetEnumItemByIndex(enumType, index, &enumItem); + return enumItem; +} } } \ No newline at end of file diff --git a/interfaces/kits/ani/screenshot_runtime/BUILD.gn b/interfaces/kits/ani/screenshot_runtime/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..93efca549c40d2a8a6280c9c8fbbb100232a7419 --- /dev/null +++ b/interfaces/kits/ani/screenshot_runtime/BUILD.gn @@ -0,0 +1,89 @@ +# Copyright (c) 2025-2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/ohos.gni") +import("../../../../windowmanager_aafwk.gni") + +config("screenshot_common_config") { + visibility = [ ":*" ] + + include_dirs = [ + "../common", + "../../../../utils/include", + "../../../innerkits/wm", + "../../../innerkits/dm", + "../../../../wm/include", + ] +} + +config("screenshot_kit_public_config") { + visibility = [ ":*" ] + + include_dirs = [ "screenshot_ani/include" ] +} + +# lib generate +ohos_shared_library("screenshotani_kit") { + branch_protector_ret = "pac_ret" + sanitize = { + cfi = true + cfi_cross_dso = true + cfi_vcall_icall_only = true + debug = false + } + sources = [ + "screenshot_ani/src/ani_err_utils.cpp", + "screenshot_ani/src/screenshot_ani_manager.cpp", + "screenshot_ani/src/screenshot_ani_utils.cpp", + ] + + configs = [ + ":screenshot_common_config", + ":screenshot_kit_public_config", + "../../../../resources/config/build:coverage_flags", + ] + + public_configs = [ ":screenshot_kit_public_config" ] + + deps = [ + "../../../../dm:libdm", + "../../../../utils:libwmutil", + "../../../../utils:libwmutil_base", + ] + + external_deps = [ + "ability_runtime:ability_manager", + "ability_runtime:runtime", + "c_utils:utils", + "eventhandler:libeventhandler", + "graphic_2d:librender_service_base", + "graphic_surface:surface", # use for SurfaceUtils + "hilog:libhilog", + "hitrace:hitrace_meter", + "image_framework:image", + "image_framework:image_taihe", + "image_framework:image_native", + "runtime_core:ani", + ] + + innerapi_tags = [ "platformsdk" ] + part_name = "window_manager" + subsystem_name = "window" +} + +group("screenshot_ani") { + deps = [ + ":screenshotani_kit", + "screenshot_ani:screenshot_etc", + ] +} \ No newline at end of file diff --git a/interfaces/kits/ani/screenshot_runtime/screenshot_ani/BUILD.gn b/interfaces/kits/ani/screenshot_runtime/screenshot_ani/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..46050bdff62498847f8c6d4ae2ec1271c2fd2de3 --- /dev/null +++ b/interfaces/kits/ani/screenshot_runtime/screenshot_ani/BUILD.gn @@ -0,0 +1,30 @@ +# Copyright (c) 2025-2025 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/config/components/ets_frontend/ets2abc_config.gni") + +# abc generate +generate_static_abc("screenshot_abc") { + base_url = "./ets" + files = [ "./ets/@ohos.screenshot.ets" ] + is_boot_abc = "True" + device_dst_file = "/system/framework/screenshot_abc.abc" +} + +ohos_prebuilt_etc("screenshot_etc") { + source = "$target_out_dir/screenshot_abc.abc" + deps = [ ":screenshot_abc" ] + part_name = "window_manager" + subsystem_name = "window" + module_install_dir = "framework" +} \ No newline at end of file diff --git a/interfaces/kits/ani/screenshot_runtime/screenshot_ani/arktsconfig.json b/interfaces/kits/ani/screenshot_runtime/screenshot_ani/arktsconfig.json new file mode 100644 index 0000000000000000000000000000000000000000..66342e474505845e622e841179fb0fe6edc278a0 --- /dev/null +++ b/interfaces/kits/ani/screenshot_runtime/screenshot_ani/arktsconfig.json @@ -0,0 +1,36 @@ +{ + "compilerOptions": { + "baseUrl": "./ets", + "paths": { + "std": [ + "../../../../../../../../../arkcompiler/runtime_core/static_core/plugins/ets/stdlib/std" + ], + "escompat": [ + "../../../../../../../../../arkcompiler/runtime_core/static_core/plugins/ets/stdlib/escompat" + ], + "@koalaui/common": [ + "../../../../../../../../../third_party/musl/temp_idlize/node_modules/@koalaui/common/src" + ], + "@koalaui/compat": [ + "../../../../../../../../../third_party/musl/temp_idlize/node_modules/@koalaui/compat/src/arkts" + ], + "@koalaui/interop": [ + "../../../../../../../../../third_party/musl/temp_idlize/node_modules/@koalaui/interop/src/arkts" + ], + "@koalaui/runtime": [ + "../../../../../../../../../third_party/musl/temp_idlize/node_modules/@koalaui/runtime/src" + ], + "@ohos.screenshot": [ + "./screenshot.ets" + ], + "@ohos.base": [ + "../../../../../../../../../interface/sdk-js/api/@ohos.base.d.ets" + ] + }, + "outDir": "../cache", + "package": "@ohos" + }, + "files": [ + "./ets/screenshot.ets" + ] + } \ No newline at end of file diff --git a/interfaces/kits/ani/screenshot_runtime/screenshot_ani/ets/@ohos.screenshot.ets b/interfaces/kits/ani/screenshot_runtime/screenshot_ani/ets/@ohos.screenshot.ets new file mode 100644 index 0000000000000000000000000000000000000000..f9d4ae7a902368c11c7c1c82c8ddba65dbf5014a --- /dev/null +++ b/interfaces/kits/ani/screenshot_runtime/screenshot_ani/ets/@ohos.screenshot.ets @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2025-2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { AsyncCallback, Callback } from '@ohos.base'; +import { BusinessError } from '@ohos.base'; +import image from '@ohos.multimedia.image'; + +export default namespace screenshot { + +loadLibrary('screenshotani_kit.z'); + +export function save(options: ScreenshotOptions, callback: AsyncCallback): void { + taskpool.execute((): image.PixelMap => { + let res: image.PixelMap = saveSync(options); + return res; + }).then((ret: NullishType) => { + callback(null, ret as image.PixelMap); + }).catch((err: NullishType) => { + callback(err as BusinessError, undefined); + }); +} + +export function save(callback: AsyncCallback): void { + taskpool.execute((): image.PixelMap => { + let res: image.PixelMap = saveSync(); + return res; + }).then((ret: NullishType) => { + callback(null, ret as image.PixelMap); + }).catch((err: NullishType) => { + callback(err as BusinessError, undefined); + }); +} + +export function save(options?: ScreenshotOptions): Promise { + return new Promise((resolve: (value: image.PixelMap) => void, reject: (error: BusinessError) => void ) => { + taskpool.execute((): image.PixelMap => { + let res: image.PixelMap = saveSync(options); + return res; + }).then((ret: NullishType) => { + resolve(ret as image.PixelMap); + }).catch((err: NullishType) => { + reject(err as BusinessError); + }); + }); +} + +native function saveSync(screenshotOptions?: ScreenshotOptions): image.PixelMap; + +export interface ScreenshotOptions { + screenRect?: Rect; + + imageSize?: Size; + + rotation?: int; + + displayId?: long; + + isNotificationNeeded?: boolean; + + isCaptureFullOfScreen?: boolean; +} + +export class ScreenshotOptionsImpl implements ScreenshotOptions{ + screenRect?: Rect; + + imageSize?: Size; + + rotation?: int; + + displayId?: long; + + isNotificationNeeded?: boolean; + + isCaptureFullOfScreen?: boolean; +} + +export interface Size { + width: long; + + height: long; +} + +export class SizeImpl implements Size { + width: long; + + height: long; +} + +export interface Rect { + left: long; + + top: long; + + width: long; + + height: long; +} + +export class RectImpl implements Rect { + left: long; + + top: long; + + width: long; + + height: long; +} + +} \ No newline at end of file diff --git a/interfaces/kits/ani/screenshot_runtime/screenshot_ani/include/ani_err_utils.h b/interfaces/kits/ani/screenshot_runtime/screenshot_ani/include/ani_err_utils.h new file mode 100644 index 0000000000000000000000000000000000000000..b026ac0eafe0a88edbef4010127211ddf9cb7753 --- /dev/null +++ b/interfaces/kits/ani/screenshot_runtime/screenshot_ani/include/ani_err_utils.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SCREENSHOT_ANI_ERROR_UTILS_H +#define SCREENSHOT_ANI_ERROR_UTILS_H + +#include "ani.h" +#include "dm_common.h" +#include "wm_common.h" + +namespace OHOS::Rosen { +class AniErrUtils { +public: + static ani_object CreateAniError(ani_env* env, const DMError& errorCode, std::string msg = ""); + static ani_object CreateAniError(ani_env* env, const DmErrorCode& errorCode, std::string msg = ""); + static ani_status ThrowBusinessError(ani_env* env, DMError error, std::string message); + static ani_status ThrowBusinessError(ani_env* env, DmErrorCode error, std::string message); + static ani_status CreateBusinessError(ani_env* env, int32_t error, std::string message, ani_object* err); + +private: + static std::string GetErrorMsg(const DMError& errorCode); + static std::string GetErrorMsg(const DmErrorCode& errorCode); +}; +} // namespace OHOS::Rosen + +#endif //WINDOW_WINDOW_MANAGER_ANI_ERROR_UTILS_H \ No newline at end of file diff --git a/interfaces/kits/ani/screenshot_runtime/screenshot_ani/include/screenshot_ani_manager.h b/interfaces/kits/ani/screenshot_runtime/screenshot_ani/include/screenshot_ani_manager.h new file mode 100644 index 0000000000000000000000000000000000000000..8a6ca3ed9e7ffd118ee3fa6ce94aac05c2064cc7 --- /dev/null +++ b/interfaces/kits/ani/screenshot_runtime/screenshot_ani/include/screenshot_ani_manager.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2025-2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef SCREENSHOT_MANAGER_ANI_H +#define SCREENSHOT_MANAGER_ANI_H + +#include +#include "dm_common.h" +#include "refbase.h" +#include "pixel_map.h" + +#include "ani.h" + +namespace OHOS::Rosen { + +struct Option { + Media::Rect rect; + Media::Size size; + int rotation = 0; + DisplayId displayId = 0; + bool isNeedNotify = true; + bool isCaptureFullOfScreen = true; +}; + +struct Param { + DmErrorCode wret; + Option option; + std::string errMessage; + bool useInputOption; + bool validInputParam; + std::shared_ptr image; + Media::Rect imageRect; + bool isPick; +}; + +class ScreenshotManagerAni { +public: + explicit ScreenshotManagerAni(); + static ani_object Save(ani_env* env, ani_object options); + static void InitScreenshotManagerAni(ani_namespace nsp, ani_env* env); + static void GetScreenshot(ani_env *env, std::unique_ptr ¶m); +}; +} +#endif \ No newline at end of file diff --git a/interfaces/kits/ani/screenshot_runtime/screenshot_ani/include/screenshot_ani_utils.h b/interfaces/kits/ani/screenshot_runtime/screenshot_ani/include/screenshot_ani_utils.h new file mode 100644 index 0000000000000000000000000000000000000000..99dad410438f8f5ec97ec8d6e7083ec5ebcb8484 --- /dev/null +++ b/interfaces/kits/ani/screenshot_runtime/screenshot_ani/include/screenshot_ani_utils.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef OHOS_ANI_SCREEN_UTILS_H +#define OHOS_ANI_SCREEN_UTILS_H +#include + +#include "ani.h" +#include "pixel_map.h" +#include "singleton_container.h" +#include "screenshot_ani_manager.h" + +namespace OHOS::Rosen { + +class ScreenshotAniUtils { +public: +static ani_status GetStdString(ani_env* env, ani_string ani_str, std::string& result); + +static ani_object CreateAniUndefined(ani_env* env); + +static ani_status GetAniString(ani_env* env, const std::string& str, ani_string* result); + +static ani_status CallAniFunctionVoid(ani_env* env, const char* ns, + const char* fn, const char* signature, ...); + +static void ConvertScreenshot(ani_env* env, std::shared_ptr image, ani_object obj); + +static ani_status GetScreenshotParam(ani_env* env, const std::unique_ptr& param, ani_object options); + +static ani_status GetScreenshotSize(ani_env* env, const std::unique_ptr& param, ani_object options); + +static ani_status GetScreenshotRect(ani_env* env, const std::unique_ptr& param, ani_object options); + +static ani_status ReadOptionalField(ani_env* env, ani_object obj, const char* fieldName, ani_ref& ref); +static ani_status ReadOptionalLongField(ani_env* env, ani_object obj, const char* fieldName, ani_long& value); +static ani_status ReadOptionalIntField(ani_env* env, ani_object obj, const char* fieldName, int& value); +static ani_status ReadOptionalBoolField(ani_env* env, ani_object obj, const char* fieldName, bool& value); +}; +} +#endif \ No newline at end of file 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 new file mode 100644 index 0000000000000000000000000000000000000000..ac86c8dbe5349f30a12599ecf5f175098a213414 --- /dev/null +++ b/interfaces/kits/ani/screenshot_runtime/screenshot_ani/src/ani_err_utils.cpp @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ani_err_utils.h" +#include "screenshot_ani_utils.h" +#include "window_manager_hilog.h" + +#include + +namespace OHOS::Rosen { +constexpr const char* DM_ERROR_MSG_OK = "ok"; +constexpr const char* DM_ERROR_MSG_INIT_DMS_PROXY_LOCKED = "init dms proxy locked"; +constexpr const char* DM_ERROR_MSG_IPC_FAILED = "ipc failed"; +constexpr const char* DM_ERROR_MSG_REMOTE_CREATE_FAILED = "remote create failed"; +constexpr const char* DM_ERROR_MSG_NULLPTR = "nullptr"; +constexpr const char* DM_ERROR_MSG_INVALID_PARAM = "invalid param"; +constexpr const char* DM_ERROR_MSG_WRITE_INTERFACE_TOKEN_FAILED = "write interface token failed"; +constexpr const char* DM_ERROR_MSG_DEATH_RECIPIENT = "death recipient"; +constexpr const char* DM_ERROR_MSG_INVALID_MODE_ID = "invalid mode id"; +constexpr const char* DM_ERROR_MSG_WRITE_DATA_FAILED = "write data failed"; +constexpr const char* DM_ERROR_MSG_RENDER_SERVICE_FAILED = "render service failed"; +constexpr const char* DM_ERROR_MSG_UNREGISTER_AGENT_FAILED = "unregister agent failed"; +constexpr const char* DM_ERROR_MSG_INVALID_CALLING = "invalid calling"; +constexpr const char* DM_ERROR_MSG_INVALID_PERMISSION = "invalid permission"; +constexpr const char* DM_ERROR_MSG_NOT_SYSTEM_APP = "not system app"; +constexpr const char* DM_ERROR_MSG_DEVICE_NOT_SUPPORT = "device not support"; +constexpr const char* DM_ERROR_MSG_UNKNOWN = "unknown"; + +static std::map DM_ERROR_TO_ERROR_MSG_MAP { + {DMError::DM_OK, DM_ERROR_MSG_OK }, + {DMError::DM_ERROR_INIT_DMS_PROXY_LOCKED, DM_ERROR_MSG_INIT_DMS_PROXY_LOCKED }, + {DMError::DM_ERROR_IPC_FAILED, DM_ERROR_MSG_IPC_FAILED }, + {DMError::DM_ERROR_REMOTE_CREATE_FAILED, DM_ERROR_MSG_REMOTE_CREATE_FAILED }, + {DMError::DM_ERROR_NULLPTR, DM_ERROR_MSG_NULLPTR }, + {DMError::DM_ERROR_INVALID_PARAM, DM_ERROR_MSG_INVALID_PARAM }, + {DMError::DM_ERROR_WRITE_INTERFACE_TOKEN_FAILED, DM_ERROR_MSG_WRITE_INTERFACE_TOKEN_FAILED }, + {DMError::DM_ERROR_DEATH_RECIPIENT, DM_ERROR_MSG_DEATH_RECIPIENT }, + {DMError::DM_ERROR_INVALID_MODE_ID, DM_ERROR_MSG_INVALID_MODE_ID }, + {DMError::DM_ERROR_WRITE_DATA_FAILED, DM_ERROR_MSG_WRITE_DATA_FAILED }, + {DMError::DM_ERROR_RENDER_SERVICE_FAILED, DM_ERROR_MSG_RENDER_SERVICE_FAILED }, + {DMError::DM_ERROR_UNREGISTER_AGENT_FAILED, DM_ERROR_MSG_UNREGISTER_AGENT_FAILED }, + {DMError::DM_ERROR_INVALID_CALLING, DM_ERROR_MSG_INVALID_CALLING }, + {DMError::DM_ERROR_INVALID_PERMISSION, DM_ERROR_MSG_INVALID_PERMISSION }, + {DMError::DM_ERROR_NOT_SYSTEM_APP, DM_ERROR_MSG_NOT_SYSTEM_APP }, + {DMError::DM_ERROR_DEVICE_NOT_SUPPORT, DM_ERROR_MSG_DEVICE_NOT_SUPPORT }, + {DMError::DM_ERROR_UNKNOWN, DM_ERROR_MSG_UNKNOWN }, +}; + +constexpr const char* DM_ERROR_CODE_MSG_OK = "ok"; +constexpr const char* DM_ERROR_CODE_MSG_NO_PERMISSION = "no permission"; +constexpr const char* DM_ERROR_CODE_MSG_NOT_SYSTEM_APP = "not system app"; +constexpr const char* DM_ERROR_CODE_MSG_INVALID_PARAM = "invalid param"; +constexpr const char* DM_ERROR_CODE_MSG_DEVICE_NOT_SUPPORT = "device not support"; +constexpr const char* DM_ERROR_CODE_MSG_INVALID_SCREEN = "invalid screen"; +constexpr const char* DM_ERROR_CODE_MSG_INVALID_CALLING = "invalid calling"; +constexpr const char* DM_ERROR_CODE_MSG_SYSTEM_INNORMAL = "system innormal"; + +static std::map DM_ERROR_CODE_TO_ERROR_MSG_MAP { + {DmErrorCode::DM_OK, DM_ERROR_CODE_MSG_OK }, + {DmErrorCode::DM_ERROR_NO_PERMISSION, DM_ERROR_CODE_MSG_NO_PERMISSION }, + {DmErrorCode::DM_ERROR_NOT_SYSTEM_APP, DM_ERROR_CODE_MSG_NOT_SYSTEM_APP }, + {DmErrorCode::DM_ERROR_INVALID_PARAM, DM_ERROR_CODE_MSG_INVALID_PARAM }, + {DmErrorCode::DM_ERROR_DEVICE_NOT_SUPPORT, DM_ERROR_CODE_MSG_DEVICE_NOT_SUPPORT }, + {DmErrorCode::DM_ERROR_INVALID_SCREEN, DM_ERROR_CODE_MSG_INVALID_SCREEN }, + {DmErrorCode::DM_ERROR_INVALID_CALLING, DM_ERROR_CODE_MSG_INVALID_CALLING }, + {DmErrorCode::DM_ERROR_SYSTEM_INNORMAL, DM_ERROR_CODE_MSG_SYSTEM_INNORMAL }, +}; + +std::string AniErrUtils::GetErrorMsg(const DMError& errorCode) +{ + return DM_ERROR_TO_ERROR_MSG_MAP.find(errorCode) != DM_ERROR_TO_ERROR_MSG_MAP.end() ? + DM_ERROR_TO_ERROR_MSG_MAP.at(errorCode) : ""; +} + +std::string AniErrUtils::GetErrorMsg(const DmErrorCode& errorCode) +{ + return DM_ERROR_CODE_TO_ERROR_MSG_MAP.find(errorCode) != DM_ERROR_CODE_TO_ERROR_MSG_MAP.end() ? + DM_ERROR_CODE_TO_ERROR_MSG_MAP.at(errorCode) : ""; +} + +ani_status AniErrUtils::ThrowBusinessError(ani_env* env, DMError error, std::string message) +{ + ani_object aniError; + CreateBusinessError(env, static_cast(error), message == "" ? GetErrorMsg(error) : message, &aniError); + ani_status status = env->ThrowError(static_cast(aniError)); + if (status != ANI_OK) { + TLOGE(WmsLogTag::DMS, "[ANI] fail to throw err, status:%{public}d", static_cast(status)); + return status; + } + return ANI_OK; +} + +ani_status AniErrUtils::ThrowBusinessError(ani_env* env, DmErrorCode error, std::string message) +{ + ani_object aniError; + CreateBusinessError(env, static_cast(error), message == "" ? GetErrorMsg(error) : message, &aniError); + ani_status status = env->ThrowError(static_cast(aniError)); + if (status != ANI_OK) { + TLOGE(WmsLogTag::DMS, "[ANI] fail to throw err, status:%{public}d", static_cast(status)); + return status; + } + return ANI_OK; +} + +ani_status AniErrUtils::CreateBusinessError(ani_env* env, int32_t error, std::string message, ani_object* err) +{ + TLOGI(WmsLogTag::DMS, "[ANI] in"); + ani_class aniClass; + ani_status status = env->FindClass("@ohos.base.BusinessError", &aniClass); + if (status != ANI_OK) { + TLOGE(WmsLogTag::DMS, "[ANI] class not found, status:%{public}d", static_cast(status)); + return status; + } + ani_method aniCtor; + status = env->Class_FindMethod(aniClass, "", "C{std.core.String}C{escompat.ErrorOptions}:", &aniCtor); + if (status != ANI_OK) { + TLOGE(WmsLogTag::DMS, "[ANI] ctor not found, status:%{public}d", static_cast(status)); + return status; + } + ani_string aniMsg; + ScreenshotAniUtils::GetAniString(env, message, &aniMsg); + status = env->Object_New(aniClass, aniCtor, err, aniMsg, ScreenshotAniUtils::CreateAniUndefined(env)); + if (status != ANI_OK) { + TLOGE(WmsLogTag::DMS, "[ANI] fail to new err, status:%{public}d", static_cast(status)); + return status; + } + 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; + } + return ANI_OK; +} +} // namespace OHOS::Rosen \ No newline at end of file diff --git a/interfaces/kits/ani/screenshot_runtime/screenshot_ani/src/screenshot_ani_manager.cpp b/interfaces/kits/ani/screenshot_runtime/screenshot_ani/src/screenshot_ani_manager.cpp new file mode 100644 index 0000000000000000000000000000000000000000..08d80a7595b3dccdbbeb3ed4572f8deb70203a06 --- /dev/null +++ b/interfaces/kits/ani/screenshot_runtime/screenshot_ani/src/screenshot_ani_manager.cpp @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "screenshot_ani_manager.h" + +#include +#include + +#include "ani.h" +#include "singleton_container.h" +#include "window_manager_hilog.h" +#include "display_manager.h" +#include "dm_common.h" +#include "pixel_map_taihe_ani.h" +#include "refbase.h" +#include "screenshot_ani_utils.h" +#include "ani_err_utils.h" + +namespace OHOS::Rosen { + +ScreenshotManagerAni::ScreenshotManagerAni() +{ +} + +void ScreenshotManagerAni::InitScreenshotManagerAni(ani_namespace nsp, ani_env* env) +{ +} + +ani_object ScreenshotManagerAni::Save(ani_env* env, ani_object options) +{ + TLOGI(WmsLogTag::DMS, "[ANI] begin"); + auto param = std::make_unique(); + if (param == nullptr) { + TLOGI(WmsLogTag::DMS, "Create param failed."); + return nullptr; + } + param->option.displayId = DisplayManager::GetInstance().GetDefaultDisplayId(); + ani_boolean optionsUndefined = 0; + env->Reference_IsUndefined(options, &optionsUndefined); + param->validInputParam = true; + if (!optionsUndefined) { + param->useInputOption = true; + ani_status ret = ScreenshotAniUtils::GetScreenshotParam(env, param, options); + if (ret != ANI_OK) { + AniErrUtils::ThrowBusinessError(env, DmErrorCode::DM_ERROR_INVALID_PARAM, "get screen shot param failed"); + return nullptr; + } + } + param->isPick = false; + GetScreenshot(env, param); + if (param->wret != DmErrorCode::DM_OK) { + if (param->wret == DmErrorCode::DM_ERROR_NO_PERMISSION || + param->wret == DmErrorCode::DM_ERROR_INVALID_PARAM || + param->wret == DmErrorCode::DM_ERROR_NOT_SYSTEM_APP || + param->wret == DmErrorCode::DM_ERROR_SYSTEM_INNORMAL) { + AniErrUtils::ThrowBusinessError(env, param->wret, param->errMessage); + } + return ScreenshotAniUtils::CreateAniUndefined(env); + } + if (param->image != nullptr) { + TLOGI(WmsLogTag::DMS, "save pixelMap, currentId = %{public}d", static_cast(param->image->currentId)); + } + auto nativePixelMap = Media::PixelMapTaiheAni::CreateEtsPixelMap(env, param->image); + return nativePixelMap; +} + +void ScreenshotManagerAni::GetScreenshot(ani_env *env, std::unique_ptr ¶m) +{ + TLOGI(WmsLogTag::DMS, "[ANI] begin"); + if (!param->validInputParam) { + TLOGI(WmsLogTag::DMS, "Get Screenshot invalidInputParam"); + param->image = nullptr; + param->wret = DmErrorCode::DM_ERROR_INVALID_PARAM; + param->errMessage = "Get Screenshot Failed: Invalid input param"; + return; + } + CaptureOption option = { param->option.displayId, param->option.isNeedNotify, true, + param->option.isCaptureFullOfScreen }; + if (!param->isPick && !option.isNeedNotify_) { + if (param->useInputOption) { + param->image = DisplayManager::GetInstance().GetScreenshotWithOption(option, + param->option.rect, param->option.size, param->option.rotation, ¶m->wret); + } else { + param->image = DisplayManager::GetInstance().GetScreenshotWithOption(option, ¶m->wret); + } + } else { + if (param->useInputOption) { + TLOGI(WmsLogTag::DMS, "Get Screenshot by input option"); + SnapShotConfig snapConfig; + snapConfig.displayId_ = param->option.displayId; + snapConfig.imageRect_ = param->option.rect; + snapConfig.imageSize_ = param->option.size; + snapConfig.rotation_ = param->option.rotation; + snapConfig.isCaptureFullOfScreen_ = param->option.isCaptureFullOfScreen; + param->image = DisplayManager::GetInstance().GetScreenshotwithConfig(snapConfig, ¶m->wret, true); + } else if (param->isPick) { + TLOGI(WmsLogTag::DMS, "Get Screenshot by picker"); + param->image = DisplayManager::GetInstance().GetSnapshotByPicker(param->imageRect, ¶m->wret); + } else { + TLOGI(WmsLogTag::DMS, "Get Screenshot by default option"); + param->image = DisplayManager::GetInstance().GetScreenshot(param->option.displayId, ¶m->wret, true, + param->option.isCaptureFullOfScreen); + } + } + if (param->image == nullptr && param->wret == DmErrorCode::DM_OK) { + TLOGI(WmsLogTag::DMS, "Get Screenshot failed!"); + param->wret = DmErrorCode::DM_ERROR_INVALID_SCREEN; + param->errMessage = "Get Screenshot failed: Screenshot image is nullptr"; + return; + } +} + +extern "C" { +ANI_EXPORT ani_status ANI_Constructor(ani_vm *vm, uint32_t *result) +{ + using namespace OHOS::Rosen; + TLOGI(WmsLogTag::DMS, "[ANI] start to ANI_Constructor"); + ani_status ret; + ani_env *env; + if ((ret = vm->GetEnv(ANI_VERSION_1, &env)) != ANI_OK) { + TLOGE(WmsLogTag::DMS, "[ANI] null env"); + return ANI_NOT_FOUND; + } + ani_namespace nsp; + if ((ret = env->FindNamespace("@ohos.screenshot.screenshot", &nsp)) != ANI_OK) { + TLOGE(WmsLogTag::DMS, "[ANI] null env %{public}u", ret); + return ANI_NOT_FOUND; + } + ScreenshotManagerAni::InitScreenshotManagerAni(nsp, env); + std::array funcs = { + ani_native_function {"saveSync", nullptr, + reinterpret_cast(ScreenshotManagerAni::Save)}, + }; + if ((ret = env->Namespace_BindNativeFunctions(nsp, funcs.data(), funcs.size()))) { + TLOGE(WmsLogTag::DMS, "[ANI] bind namespace fail %{public}u", ret); + return ANI_NOT_FOUND; + } + *result = ANI_VERSION_1; + return ANI_OK; +} +} + +} \ No newline at end of file diff --git a/interfaces/kits/ani/screenshot_runtime/screenshot_ani/src/screenshot_ani_utils.cpp b/interfaces/kits/ani/screenshot_runtime/screenshot_ani/src/screenshot_ani_utils.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a0e38e2c8006346c64af01fa4ff69db318d09ddb --- /dev/null +++ b/interfaces/kits/ani/screenshot_runtime/screenshot_ani/src/screenshot_ani_utils.cpp @@ -0,0 +1,262 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "ani.h" +#include "screenshot_ani_utils.h" +#include "singleton_container.h" +#include "window_manager_hilog.h" +#include "dm_common.h" +#include "refbase.h" + +namespace OHOS::Rosen { +ani_status ScreenshotAniUtils::GetStdString(ani_env* env, ani_string ani_str, std::string& result) +{ + ani_size strSize; + ani_status ret = env->String_GetUTF8Size(ani_str, &strSize); + if (ret != ANI_OK) { + return ret; + } + std::vector buffer(strSize + 1); + char* utf8_buffer = buffer.data(); + ani_size bytes_written = 0; + ret = env->String_GetUTF8(ani_str, utf8_buffer, strSize + 1, &bytes_written); + if (ret != ANI_OK) { + return ret; + } + utf8_buffer[bytes_written] = '\0'; + result = std::string(utf8_buffer); + return ret; +} + +ani_object ScreenshotAniUtils::CreateAniUndefined(ani_env* env) +{ + ani_ref aniRef; + env->GetUndefined(&aniRef); + return static_cast(aniRef); +} + +ani_status ScreenshotAniUtils::GetAniString(ani_env* env, const std::string& str, ani_string* result) +{ + return env->String_NewUTF8(str.c_str(), static_cast(str.size()), result); +} + +void ScreenshotAniUtils::ConvertScreenshot(ani_env* env, std::shared_ptr image, ani_object obj) +{ + return; +} + +ani_status ScreenshotAniUtils::CallAniFunctionVoid(ani_env* env, const char* ns, + const char* fn, const char* signature, ...) +{ + TLOGI(WmsLogTag::DEFAULT, "[ANI] begin"); + ani_status ret = ANI_OK; + ani_namespace aniNamespace{}; + if ((ret = env->FindNamespace(ns, &aniNamespace)) != ANI_OK) { + TLOGE(WmsLogTag::DEFAULT, "[ANI]canot find ns %{public}d", ret); + return ret; + } + ani_function func{}; + if ((ret = env->Namespace_FindFunction(aniNamespace, fn, signature, &func)) != ANI_OK) { + TLOGE(WmsLogTag::DEFAULT, "[ANI]canot find callBack %{public}d", ret); + return ret; + } + if (func == nullptr) { + TLOGI(WmsLogTag::DEFAULT, "[ANI] null func ani"); + return ret; + } + va_list args; + va_start(args, signature); + TLOGI(WmsLogTag::DEFAULT, "[ANI]CallAniFunctionVoid begin %{public}s", signature); + ret = env->Function_Call_Void_V(func, args); + va_end(args); + if (ret != ANI_OK) { + TLOGE(WmsLogTag::DEFAULT, "[ANI]canot run callBack %{public}d", ret); + return ret; + } + return ret; +} + +ani_status ScreenshotAniUtils::GetScreenshotParam(ani_env* env, const std::unique_ptr& param, + ani_object options) +{ + TLOGI(WmsLogTag::DMS, "[ANI] begin"); + if (param == nullptr) { + TLOGI(WmsLogTag::DMS, "[ANI] null param"); + return ANI_INVALID_ARGS; + } + ani_long displayId = 0; + ani_status ret = ReadOptionalLongField(env, options, "displayId", displayId); + if (ret != ANI_OK) { + TLOGE(WmsLogTag::DMS, "[ANI] get displayId failed"); + return ret; + } + param->option.displayId = static_cast(displayId); + + ret = ReadOptionalIntField(env, options, "rotation", param->option.rotation); + if (ret != ANI_OK) { + TLOGE(WmsLogTag::DMS, "[ANI] get rotation failed"); + return ret; + } + + ret = ReadOptionalBoolField(env, options, "isNotificationNeeded", param->option.isNeedNotify); + if (ret != ANI_OK) { + TLOGE(WmsLogTag::DMS, "[ANI] get isNotificationNeeded failed"); + return ret; + } + + ret = ReadOptionalBoolField(env, options, "isCaptureFullOfScreen", param->option.isCaptureFullOfScreen); + if (ret != ANI_OK) { + TLOGE(WmsLogTag::DMS, "[ANI] get isCaptureFullOfScreen failed"); + return ret; + } + + ret = GetScreenshotSize(env, param, options); + if (ret != ANI_OK) { + TLOGE(WmsLogTag::DMS, "[ANI] get screenshot size failed"); + return ret; + } + ret = GetScreenshotRect(env, param, options); + if (ret != ANI_OK) { + TLOGE(WmsLogTag::DMS, "[ANI] get screenshot rect failed"); + return ret; + } + return ANI_OK; +} + +ani_status ScreenshotAniUtils::GetScreenshotSize(ani_env* env, const std::unique_ptr& param, ani_object options) +{ + TLOGI(WmsLogTag::DMS, "[ANI] begin"); + ani_ref obj; + ani_status ret = env->Object_GetPropertyByName_Ref(options, "imageSize", &obj); + if (ret != ANI_OK) { + TLOGE(WmsLogTag::DMS, "[ANI] get imageSize failed"); + return ret; + } + ani_boolean isUndefRes = false; + ret = env->Reference_IsUndefined(obj, &isUndefRes); + if (ret != ANI_OK) { + TLOGE(WmsLogTag::DMS, "[ANI] check imageSize is undefined failed"); + return ret; + } + if (isUndefRes) { + TLOGI(WmsLogTag::DMS, "[ANI] imageSize is undefined"); + return ANI_OK; + } + ani_long width; + ani_long height; + env->Object_GetPropertyByName_Long(static_cast(obj), "width", &width); + env->Object_GetPropertyByName_Long(static_cast(obj), "height", &height); + param->option.size.width = static_cast(width); + param->option.size.height = static_cast(height); + TLOGI(WmsLogTag::DMS, "[ANI] get imageSize width = %{public}d, height = %{public}d", + param->option.size.width, param->option.size.height); + return ANI_OK; +} + +ani_status ScreenshotAniUtils::GetScreenshotRect(ani_env* env, const std::unique_ptr& param, ani_object options) +{ + TLOGI(WmsLogTag::DMS, "[ANI] begin"); + ani_ref obj; + ani_status ret = env->Object_GetPropertyByName_Ref(options, "screenRect", &obj); + if (ret != ANI_OK) { + TLOGE(WmsLogTag::DMS, "[ANI] get screenRect failed"); + return ret; + } + ani_boolean isUndefRes = false; + ret = env->Reference_IsUndefined(obj, &isUndefRes); + if (ret != ANI_OK) { + TLOGE(WmsLogTag::DMS, "[ANI] check screenRect is undefined failed"); + return ret; + } + if (isUndefRes) { + TLOGI(WmsLogTag::DMS, "[ANI] screenRect is undefined"); + return ANI_OK; + } + ani_long left = 0; + ani_long top = 0; + ani_long width = 0; + ani_long height = 0; + env->Object_GetPropertyByName_Long(static_cast(obj), "left", &left); + env->Object_GetPropertyByName_Long(static_cast(obj), "top", &top); + env->Object_GetPropertyByName_Long(static_cast(obj), "width", &width); + env->Object_GetPropertyByName_Long(static_cast(obj), "height", &height); + param->option.rect.left = static_cast(left); + param->option.rect.top = static_cast(top); + param->option.rect.width = static_cast(width); + param->option.rect.height = static_cast(height); + TLOGI(WmsLogTag::DMS, + "[ANI] get screenRect left = %{public}d, top = %{public}d, width = %{public}d, height = %{public}d", + param->option.rect.left, param->option.rect.top, param->option.rect.width, param->option.rect.height); + return ANI_OK; +} + +ani_status ScreenshotAniUtils::ReadOptionalField(ani_env* env, ani_object obj, const char* fieldName, ani_ref& ref) +{ + ani_status ret = env->Object_GetPropertyByName_Ref(obj, fieldName, &ref); + if (ret != ANI_OK) { + TLOGE(WmsLogTag::DMS, "Failed to get property %{public}s, ret %{public}d", fieldName, ret); + return ret; + } + ani_boolean isUndefRes; + ret = env->Reference_IsUndefined(ref, &isUndefRes); + if (ret != ANI_OK) { + TLOGE(WmsLogTag::DMS, "Failed to check ref is undefined, ret %{public}d", ret); + ref = nullptr; + return ret; + } + if (isUndefRes) { + ref = nullptr; + } + return ret; +} + +ani_status ScreenshotAniUtils::ReadOptionalLongField(ani_env* env, ani_object obj, const char* fieldName, + ani_long& value) +{ + ani_ref ref = nullptr; + ani_status result = ReadOptionalField(env, obj, fieldName, ref); + if (result == ANI_OK && ref != nullptr) { + result = env->Object_CallMethodByName_Long(reinterpret_cast(ref), "unboxed", ":l", &value); + } + return result; +} + + +ani_status ScreenshotAniUtils::ReadOptionalIntField(ani_env* env, ani_object obj, const char* fieldName, int& value) +{ + ani_ref ref = nullptr; + ani_status result = ReadOptionalField(env, obj, fieldName, ref); + if (result == ANI_OK && ref != nullptr) { + result = env->Object_CallMethodByName_Int(reinterpret_cast(ref), "unboxed", ":i", &value); + } + return result; +} + +ani_status ScreenshotAniUtils::ReadOptionalBoolField(ani_env* env, ani_object obj, const char* fieldName, bool& value) +{ + ani_ref ref = nullptr; + ani_status result = ReadOptionalField(env, obj, fieldName, ref); + if (result == ANI_OK && ref != nullptr) { + ani_boolean aniBool; + result = env->Object_CallMethodByName_Boolean(reinterpret_cast(ref), "unboxed", ":z", &aniBool); + if (result == ANI_OK) { + value = static_cast(aniBool); + } + } + return result; +} +} \ No newline at end of file diff --git a/interfaces/kits/ani/sdk/@ohos.display.d.ets b/interfaces/kits/ani/sdk/@ohos.display.d.ets index 09c4598f7066d102998a21f978233a2253ab2f02..43558637f06b1e5b9e70ed73387873a6bf3beefb 100644 --- a/interfaces/kits/ani/sdk/@ohos.display.d.ets +++ b/interfaces/kits/ani/sdk/@ohos.display.d.ets @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Copyright (c) 2025-2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at diff --git a/interfaces/kits/ani/sdk/@ohos.window.d.ets b/interfaces/kits/ani/sdk/@ohos.window.d.ets index dd9b3de67ef97304d6516a293a5346886aeb3b29..dd41a7206244ebac65dfae221bd643f6160fcda0 100644 --- a/interfaces/kits/ani/sdk/@ohos.window.d.ets +++ b/interfaces/kits/ani/sdk/@ohos.window.d.ets @@ -1,5 +1,5 @@ /* -* Copyright (c) 2021 Huawei Device Co., Ltd. +* Copyright (c) 2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at diff --git a/interfaces/kits/ani/window_runtime/BUILD.gn b/interfaces/kits/ani/window_runtime/BUILD.gn index ba3ad2c45f32278eaafdb651a075e1716b182be0..52d564af1d8fd96d2995cb7c58d6ed36bc95798f 100644 --- a/interfaces/kits/ani/window_runtime/BUILD.gn +++ b/interfaces/kits/ani/window_runtime/BUILD.gn @@ -63,6 +63,8 @@ ohos_shared_library("windowstageani_kit") { "../../../../utils:libwmutil", "../../../../utils:libwmutil_base", "../../../../wm:libwm", + "../../../../interfaces/kits/napi/window_runtime:windowstage_kit", + "../../../../interfaces/kits/napi/window_runtime:window_native_kit", ] external_deps = [ @@ -78,6 +80,63 @@ ohos_shared_library("windowstageani_kit") { "hilog:libhilog", "hitrace:hitrace_meter", "image_framework:image", + "image_framework:image_taihe", + "image_framework:image_native", + "ipc:ipc_napi", + "ipc:ipc_single", + "napi:ace_napi", + "runtime_core:ani", + "runtime_core:ani_helpers", + ] + + innerapi_tags = [ "platformsdk" ] + part_name = "window_manager" + subsystem_name = "window" +} + +# lib generate +ohos_shared_library("windowstageani_module") { + branch_protector_ret = "pac_ret" + sanitize = { + cfi = true + cfi_cross_dso = true + cfi_vcall_icall_only = true + debug = false + } + sources = [ + "window_stage_ani/src/ani_window_stage_module.cpp", + ] + + configs = [ + ":window_common_config", + ":windowstage_kit_public_config", + "../../../../resources/config/build:coverage_flags", + ] + + public_configs = [ ":windowstage_kit_public_config" ] + + deps = [ + "../../../../utils:libwmutil", + "../../../../utils:libwmutil_base", + "../../../../wm:libwm", + ":windowstageani_kit", + "../../../../interfaces/kits/napi/window_runtime:window_native_kit", + ] + + external_deps = [ + "ability_runtime:ability_context_native", + "ability_runtime:ability_manager", + "ability_runtime:abilitykit_native", + "ability_runtime:runtime", + "access_token:libaccesstoken_sdk", + "ace_engine:ace_uicontent", + "bundle_framework:appexecfwk_base", + "c_utils:utils", + "eventhandler:libeventhandler", + "hilog:libhilog", + "hitrace:hitrace_meter", + "image_framework:image", + "image_framework:image_ani", "image_framework:image_native", "ipc:ipc_napi", "ipc:ipc_single", @@ -93,6 +152,7 @@ ohos_shared_library("windowstageani_kit") { group("window_stage_ani_pack") { deps = [ ":windowstageani_kit", + ":windowstageani_module", "window_stage_ani:window_stage_etc", ] } 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 93f1a9972642c0aa9e4432f9914fce24bd55a101..c9ebcb9dd1e92c7f873e67b722408fcc1f872500 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 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Copyright (c) 2025-2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -12,30 +12,37 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import ConfigurationConstant from '@ohos.app.ability.ConfigurationConstant'; import { AsyncCallback, BusinessError, Callback } from '@ohos.base'; import { LocalStorage } from '@ohos.arkui.stateManagement'; import { UIContext } from '@ohos.arkui.UIContext'; +import image from '@ohos.multimedia.image'; import BaseContext from 'application.BaseContext'; +import hilog from '@ohos.hilog'; import { ColorMetrics } from '@ohos.arkui.node'; - export type AsyncCallbackVoid = (err: BusinessError) => void; export type WindowEventCallback = (data: window.WindowEventType) => void; +export type WindowRectCallback = (data: window.Rect) => void; export type WindowSizeCallback = (data: window.Size) => void; export type WindowStatusCallback = (data: window.WindowStatusType) => void; - +export type KeyboardHeightChangeCallback = (data: int) => void; +export type KeyboardDidShowOrHideCallback = (data: window.KeyboardInfo) => void; +export type WindowVoidCallback = () => void; +const DOMAIN = 0x4200; +const TAG = '[ANI]'; namespace window { export interface Size { /** * The width of the window. * - * @type { number } + * @type { int } * @syscap SystemCapability.WindowManager.WindowManager.Core * @since 7 */ /** * The width of the window. * - * @type { number } + * @type { int } * @syscap SystemCapability.WindowManager.WindowManager.Core * @crossplatform * @since 10 @@ -43,13 +50,13 @@ namespace window { /** * The width of the window. * - * @type { number } + * @type { int } * @syscap SystemCapability.WindowManager.WindowManager.Core * @crossplatform * @atomicservice * @since 11 */ - width: number; + width: int; /** * The height of the window. @@ -60,7 +67,7 @@ namespace window { /** * The height of the window. * - * @type { number } + * @type { int } * @syscap SystemCapability.WindowManager.WindowManager.Core * @crossplatform * @since 10 @@ -68,13 +75,13 @@ namespace window { /** * The height of the window. * - * @type { number } + * @type { int } * @syscap SystemCapability.WindowManager.WindowManager.Core * @crossplatform * @atomicservice * @since 11 */ - height: number; + height: int; } export enum AvoidAreaType { /** @@ -317,6 +324,118 @@ namespace window { bottomRect: Rect; } + /** + * System bar tint of region + * + * @interface SystemBarRegionTint + * @syscap SystemCapability.WindowManager.WindowManager.Core + * @systemapi Hide this for inner system use. + * @since 8 + */ + export interface SystemBarRegionTint { + /** + * System bar type + * + * @type { WindowType } + * @syscap SystemCapability.WindowManager.WindowManager.Core + * @systemapi Hide this for inner system use. + * @since 8 + */ + type: number; + + /** + * The visibility of system bar + * + * @type { ?boolean } + * @syscap SystemCapability.WindowManager.WindowManager.Core + * @systemapi Hide this for inner system use. + * @since 8 + */ + isEnable: boolean; + + /** + * The region of system bar + * + * @type { ?Rect } + * @syscap SystemCapability.WindowManager.WindowManager.Core + * @systemapi Hide this for inner system use. + * @since 8 + */ + region: Rect; + + /** + * The background color of the system bar. + * + * @type { ?string } + * @syscap SystemCapability.WindowManager.WindowManager.Core + * @systemapi Hide this for inner system use. + * @since 8 + */ + backgroundColor: string; + + /** + * The content color of the system bar. + * + * @type { ?string } + * @syscap SystemCapability.WindowManager.WindowManager.Core + * @systemapi Hide this for inner system use. + * @since 8 + */ + contentColor: string; + } + + export class SystemBarRegionTintInternal implements SystemBarRegionTint { + type: number; + isEnable: boolean; + region: Rect; + backgroundColor: string; + contentColor: string; + } + + /** + * System bar tint state for systemui + * + * @interface SystemBarTintState + * @syscap SystemCapability.WindowManager.WindowManager.Core + * @systemapi Hide this for inner system use. + * @since 8 + */ + export interface SystemBarTintState { + /** + * Id of display + * + * @type { long } + * @syscap SystemCapability.WindowManager.WindowManager.Core + * @systemapi Hide this for inner system use. + * @since 8 + */ + displayId: long; + /** + * Region tint of systembar + * + * @type { Array } + * @syscap SystemCapability.WindowManager.WindowManager.Core + * @systemapi Hide this for inner system use. + * @since 8 + */ + regionTint: Array; + } + + export class SystemBarTintStateInternal implements SystemBarTintState { + displayId: long; + regionTint: Array; + } + + export enum RectChangeReason { + UNDEFINED = 0, + MAXIMIZE = 1, + RECOVER = 2, + MOVE = 3, + DRAG = 4, + DRAG_START = 5, + DRAG_END = 6, + } + export interface Rect { /** * The left of the Rect. @@ -334,13 +453,13 @@ namespace window { /** * The left of the Rect. * - * @type { number } + * @type { int } * @syscap SystemCapability.WindowManager.WindowManager.Core * @crossplatform * @atomicservice * @since 11 */ - left: number; + left: int; /** * The top of the Rect. @@ -358,13 +477,13 @@ namespace window { /** * The top of the Rect. * - * @type { number } + * @type { int } * @syscap SystemCapability.WindowManager.WindowManager.Core * @crossplatform * @atomicservice * @since 11 */ - top: number; + top: int; /** * The width of the Rect. @@ -382,13 +501,13 @@ namespace window { /** * The width of the Rect. * - * @type { number } + * @type { int } * @syscap SystemCapability.WindowManager.WindowManager.Core * @crossplatform * @atomicservice * @since 11 */ - width: number; + width: int; /** * The height of the Rect. @@ -406,25 +525,30 @@ namespace window { /** * The height of the Rect. * - * @type { number } + * @type { int } * @syscap SystemCapability.WindowManager.WindowManager.Core * @crossplatform * @atomicservice * @since 11 */ - height: number; + height: int; } export class RectInternal implements Rect { - left: double; - top: double; - width: double; - height: double; + left: int; + top: int; + width: int; + height: int; + } + + export interface RectChangeOptions { + rect: Rect; + reason: RectChangeReason; } export class SizeInternal implements Size { - width: double; - height: double; + width: int; + height: int; } //enum WMError { @@ -583,6 +707,16 @@ export enum ModalityType { APPLICATION_MODALITY = 1 } +export enum RotationChangeType { + WINDOW_WILL_ROTATE = 0, + WINDOW_DID_ROTATE = 1 +} + +export enum RectType { + RELATIVE_TO_SCREEN = 0, + RELATIVE_TO_PARENT_WINDOW = 1 +} + export interface SystemBarProperties { /** * The color of the status bar. @@ -598,7 +732,7 @@ export interface SystemBarProperties { * @atomicservice * @since 12 */ - statusBarColor: string; + statusBarColor?: string; /** * The light icon of the status bar. @@ -614,7 +748,7 @@ export interface SystemBarProperties { * @atomicservice * @since 12 */ - isStatusBarLightIcon: boolean; + isStatusBarLightIcon?: boolean; /** * The content color of the status bar @@ -630,7 +764,7 @@ export interface SystemBarProperties { * @atomicservice * @since 12 */ - statusBarContentColor: string; + statusBarContentColor?: string; /** * The color of the navigation bar. @@ -646,7 +780,7 @@ export interface SystemBarProperties { * @atomicservice * @since 12 */ - navigationBarColor: string; + navigationBarColor?: string; /** * The light icon of the navigation bar. @@ -662,7 +796,7 @@ export interface SystemBarProperties { * @atomicservice * @since 12 */ - isNavigationBarLightIcon: boolean; + isNavigationBarLightIcon?: boolean; /** * The content color of the navigation bar @@ -678,7 +812,7 @@ export interface SystemBarProperties { * @atomicservice * @since 12 */ - navigationBarContentColor: string; + navigationBarContentColor?: string; /** * Enable the animation of the status bar. @@ -688,7 +822,7 @@ export interface SystemBarProperties { * @atomicservice * @since 12 */ - enableStatusBarAnimation: boolean; + enableStatusBarAnimation?: boolean; /** * Enable the animation of the navigation bar. @@ -698,18 +832,18 @@ export interface SystemBarProperties { * @atomicservice * @since 12 */ - enableNavigationBarAnimation: boolean; + enableNavigationBarAnimation?: boolean; } export class SystemBarPropertiesInternal implements SystemBarProperties { - statusBarColor: string = ""; - isStatusBarLightIcon: boolean; - statusBarContentColor: string = ""; - navigationBarColor: string = ""; - isNavigationBarLightIcon: boolean; - navigationBarContentColor: string = ""; - enableStatusBarAnimation: boolean; - enableNavigationBarAnimation: boolean; + statusBarColor?: string; + isStatusBarLightIcon?: boolean; + statusBarContentColor?: string; + navigationBarColor?: string; + isNavigationBarLightIcon?: boolean; + navigationBarContentColor?: string; + enableStatusBarAnimation?: boolean; + enableNavigationBarAnimation?: boolean; } /** @@ -874,7 +1008,7 @@ export interface WindowProperties { /** * Brightness value of window. * - * @type { number } + * @type { double } * @syscap SystemCapability.WindowManager.WindowManager.Core * @crossplatform * @since 10 @@ -882,13 +1016,13 @@ export interface WindowProperties { /** * Brightness value of window. * - * @type { number } + * @type { double } * @syscap SystemCapability.WindowManager.WindowManager.Core * @crossplatform * @atomicservice * @since 11 */ - brightness: number; + brightness: double; /** * The dimbehind value of window. @@ -972,29 +1106,39 @@ export interface WindowProperties { /** * Window id. * - * @type { number } + * @type { int } * @syscap SystemCapability.WindowManager.WindowManager.Core * @since 9 */ /** * Window id. * - * @type { number } + * @type { int } * @syscap SystemCapability.WindowManager.WindowManager.Core * @atomicservice * @since 12 */ - id: number; + id: int; /** * display id. * - * @type { ?number } + * @type { ?long } * @syscap SystemCapability.WindowManager.WindowManager.Core * @atomicservice * @since 12 */ - displayId: number; + displayId?: long; + + /** + * window name. + * + * @type { ?string } + * @syscap SystemCapability.WindowManager.WindowManager.Core + * @atomicservice + * @since 18 + */ + name?: string; } export class WindowPropertiesInternal implements WindowProperties { @@ -1005,25 +1149,162 @@ export class WindowPropertiesInternal implements WindowProperties { isLayoutFullScreen: boolean; focusable: boolean; touchable: boolean; - brightness: number; + brightness: double; dimBehindValue: number; isKeepScreenOn: boolean; isPrivacyMode: boolean; isRoundCorner: boolean; isTransparent: boolean; - id: number; - displayId: number; + id: int; + displayId?: long; + displayIdInternal: long; typeInternal: int; + name?: string; +} + +/** + * Configuration parameters for window creation. + * + * @interface Configuration + * @syscap SystemCapability.WindowManager.WindowManager.Core + * @since 9 + */ +/** + * Configuration parameters for window creation. + * + * @interface Configuration + * @syscap SystemCapability.WindowManager.WindowManager.Core + * @atomicservice + * @since 12 + */ +export interface Configuration { + /** + * Indicates window id. + * + * @syscap SystemCapability.WindowManager.WindowManager.Core + * @since 9 + */ + /** + * Indicates window id. + * + * @type { string } + * @syscap SystemCapability.WindowManager.WindowManager.Core + * @atomicservice + * @since 12 + */ + name: string; + + /** + * Indicates window type + * + * @type { WindowType } + * @syscap SystemCapability.WindowManager.WindowManager.Core + * @since 9 + */ + /** + * Indicates window type + * + * @type { WindowType } + * @syscap SystemCapability.WindowManager.WindowManager.Core + * @atomicservice + * @since 12 + */ + windowType: WindowType; + + /** + * Indicates window context. + * + * @type { ?BaseContext } + * @syscap SystemCapability.WindowManager.WindowManager.Core + * @since 9 + */ + /** + * Indicates window context. + * + * @type { ?BaseContext } + * @syscap SystemCapability.WindowManager.WindowManager.Core + * @atomicservice + * @since 12 + */ + ctx?: BaseContext; + + /** + * Indicates display ID. + * + * @type { ?number } + * @syscap SystemCapability.WindowManager.WindowManager.Core + * @since 9 + */ + /** + * Indicates display ID. + * + * @type { ?long } + * @syscap SystemCapability.WindowManager.WindowManager.Core + * @atomicservice + * @since 12 + */ + displayId?: long; + + /** + * Indicates Parent window id + * + * @type { ?int } + * @syscap SystemCapability.WindowManager.WindowManager.Core + * @since 9 + */ + /** + * Indicates Parent window id + * + * @type { ?int } + * @syscap SystemCapability.WindowManager.WindowManager.Core + * @atomicservice + * @since 12 + */ + parentId?: int; + + /** + * Indicates whether enable window decor, only support dialog, The default value is false. + * + * @type { ?boolean } + * @syscap SystemCapability.Window.SessionManager + * @atomicservice + * @since 12 + */ + decorEnabled?: boolean; + + /** + * Indicates dialog window title when decor enabled. + * + * @type { ?string } + * @syscap SystemCapability.Window.SessionManager + * @atomicservice + * @since 12 + */ + title?: string; +} + +export class ConfigurationInternal implements Configuration { + name: string; + windowType: WindowType; + ctx?: BaseContext; + displayId?: long; + parentId?: int; + decorEnabled?: boolean; + title?: string; } export interface MoveConfiguration { - displayId: number; + displayId: long; } export interface WindowDensityInfo { - systemDensity: number; - defaultDensity: number; - customDensity: number; + systemDensity: double; + defaultDensity: double; + customDensity: double; +} + +export interface SystemBarStyle { + statusBarContentColor?: string; } export interface AvoidAreaOptions { @@ -1061,110 +1342,642 @@ export interface WindowLimits { /** * The maximum width of the window. * - * @type { ?number } + * @type { ?int } * @syscap SystemCapability.Window.SessionManager * @since 11 */ /** * The maximum width of the window. * - * @type { ?number } + * @type { ?int } * @syscap SystemCapability.Window.SessionManager * @atomicservice * @since 12 */ - maxWidth: number; + maxWidth: int; /** * The maximum height of the window. * - * @type { ?number } + * @type { ?int } * @syscap SystemCapability.Window.SessionManager * @since 11 */ /** * The maximum height of the window. * - * @type { ?number } + * @type { ?int } * @syscap SystemCapability.Window.SessionManager * @atomicservice * @since 12 */ - maxHeight: number; + maxHeight: int; /** * The minimum width of the window. * - * @type { ?number } + * @type { ?int } * @syscap SystemCapability.Window.SessionManager * @since 11 */ /** * The minimum width of the window. * - * @type { ?number } + * @type { ?int } * @syscap SystemCapability.Window.SessionManager * @atomicservice * @since 12 */ - minWidth: number; + minWidth: int; /** * The minimum height of the window. * - * @type { ?number } + * @type { ?int } * @syscap SystemCapability.Window.SessionManager * @since 11 */ /** * The minimum height of the window. * - * @type { ?number } + * @type { ?int } * @syscap SystemCapability.Window.SessionManager * @atomicservice * @since 12 */ - minHeight: number; + minHeight: int; } -export class WindowStageInternal implements WindowStage { - static { loadLibrary('windowstageani_kit.z') } - - private nativeObj : long; - setNativeObj(nativeObj: long):void { - this.nativeObj = nativeObj; - } - - public native loadContent(nativeObj:long, path: String): int; - 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; - } - callback({code: WmErrorCode_WM_OK, message: ""} as BusinessError, undefined); - } +/** + * Rectangular area of the title buttons relative to the upper right corner of the window. + * + * @interface TitleButtonRect + * @syscap SystemCapability.Window.SessionManager + * @since 11 + */ + /** + * Rectangular area of the title buttons relative to the upper right corner of the window. + * + * @interface TitleButtonRect + * @syscap SystemCapability.Window.SessionManager + * @atomicservice + * @since 12 + */ + export interface TitleButtonRect { + + /** + * The right of the Rect. + * + * @type { number } + * @syscap SystemCapability.Window.SessionManager + * @since 11 + */ + /** + * The right of the Rect. + * + * @type { number } + * @syscap SystemCapability.Window.SessionManager + * @atomicservice + * @since 12 + */ + right: number; - public loadContentByName(name: string, callback: AsyncCallbackVoid): void { - let ret = this.loadContent(this.nativeObj, name); - } - - public disableWindowDecor(): void { - this.disableWindowDecorSync(this.nativeObj); - } + /** + * The top of the Rect. + * + * @type { number } + * @syscap SystemCapability.Window.SessionManager + * @since 11 + */ + /** + * The top of the Rect. + * + * @type { number } + * @syscap SystemCapability.Window.SessionManager + * @atomicservice + * @since 12 + */ + top: number; - public setShowOnLockScreen(showOnLockScreen: boolean): void { - this.setShowOnLockScreenSync(this.nativeObj, showOnLockScreen); - } + /** + * The width of the Rect. + * + * @type { number } + * @syscap SystemCapability.Window.SessionManager + * @since 11 + */ + /** + * The width of the Rect. + * + * @type { number } + * @syscap SystemCapability.Window.SessionManager + * @atomicservice + * @since 12 + */ + width: number; + + /** + * The height of the Rect. + * + * @type { number } + * @syscap SystemCapability.Window.SessionManager + * @since 11 + */ + /** + * The height of the Rect. + * + * @type { number } + * @syscap SystemCapability.Window.SessionManager + * @atomicservice + * @since 12 + */ + height: number; + } + +/** + * The decor button style of the window. + * + * @interface DecorButtonStyle + * @syscap SystemCapability.Window.SessionManager + * @atomicservice + * @since 14 + * @arkts 1.1&1.2 + */ +export interface DecorButtonStyle { + /** + * color mode. + * + * @type { ?colorMode } + * @syscap SystemCapability.Window.SessionManager + * @atomicservice + * @since 14 + */ + colorMode?: ConfigurationConstant.ColorMode; + + /** + * button background size when hover. + * + * @type { ?number } + * @syscap SystemCapability.Window.SessionManager + * @atomicservice + * @since 14 + */ + buttonBackgroundSize?: number; + + /** + * button spacing. + * + * @type { ?number } + * @syscap SystemCapability.Window.SessionManager + * @atomicservice + * @since 14 + */ + spacingBetweenButtons?: number; + + /** + * close button right margin. + * + * @type { ?number } + * @syscap SystemCapability.Window.SessionManager + * @atomicservice + * @since 14 + */ + closeButtonRightMargin?: number; +} + +export interface WindowTitleButtonVisibleParam { + isMaximizeButtonVisible: boolean; + isMinimizeButtonVisible: boolean; + isCloseButtonVisible: boolean; +} + +export interface TitleButtonVisibleParam { + isMaximizeVisible: boolean; + isMinimizeVisible: boolean; + isSplitVisible: boolean; + isCloseVisible: boolean; +} + +export interface GetWindowsByCoordinateParam { + displayId: number; + windowNumber: number; + x: number; + y: number; +} + +/** + * The information of keyboard + * + * @interface KeyboardInfo + * @syscap SystemCapability.Window.SessionManager + * @atomicservice + * @since 18 + */ +export interface KeyboardInfo { + /** + * The position and size of keyboard before animation. + * + * @type { Rect } + * @syscap SystemCapability.Window.SessionManager + * @atomicservice + * @since 18 + */ + beginRect: Rect; + + /** + * The position and size of keyboard after animation completed. + * + * @type { Rect } + * @syscap SystemCapability.Window.SessionManager + * @atomicservice + * @since 18 + */ + endRect: Rect; +} + +export class KeyboardInfoInternal implements KeyboardInfo { + beginRect: Rect; + endRect: Rect; +} + +/** + * Describes the scale Transition Options of window + * + * @interface ScaleOptions + * @syscap SystemCapability.WindowManager.WindowManager.Core + * @systemapi + * @since 9 + */ +export interface ScaleOptions { + /** + * The scale param of x direction. Default is 1.f + * + * @type { ?double } + * @syscap SystemCapability.WindowManager.WindowManager.Core + * @systemapi + * @since 9 + */ + x?: double; + + /** + * The scale param of y direction. Default is 1.f + * + * @type { ?double } + * @syscap SystemCapability.WindowManager.WindowManager.Core + * @systemapi + * @since 9 + */ + y?: double; + + /** + * The scale param of pivot point of x. Default is 0.5f, Interval is 0.f - 1.f + * + * @type { ?double } + * @syscap SystemCapability.WindowManager.WindowManager.Core + * @systemapi + * @since 9 + */ + pivotX?: double; + + /** + * The scale param of pivot point of y. Default is 0.5f, Interval is 0.f - 1.f + * + * @type { ?double } + * @syscap SystemCapability.WindowManager.WindowManager.Core + * @systemapi + * @since 9 + */ + pivotY?: double; +} + +export class ScaleOptionsInternal implements ScaleOptions { + x?: double; + y?: double; + pivotX?: double; + pivotY?: double; +} + +/** + * Describes the rotate Transition Options of window + * + * @interface RotateOptions + * @syscap SystemCapability.WindowManager.WindowManager.Core + * @systemapi + * @since 9 + */ +export interface RotateOptions { + /** + * The rotate degree of x direction. Default value is 0.f + * + * @type { ?double } + * @syscap SystemCapability.WindowManager.WindowManager.Core + * @systemapi + * @since 9 + */ + x?: double; + + /** + * The rotate degree of y direction. Default value is 0.f + * + * @type { ?double } + * @syscap SystemCapability.WindowManager.WindowManager.Core + * @systemapi + * @since 9 + */ + y?: double; + + /** + * The rotate degree of z direction. Default value is 0.f + * + * @type { ?double } + * @syscap SystemCapability.WindowManager.WindowManager.Core + * @systemapi + * @since 9 + */ + z?: double; + + /** + * The param of pivot point of x. Default is 0.5f, Interval is 0.f - 1.f + * + * @type { ?double } + * @syscap SystemCapability.WindowManager.WindowManager.Core + * @systemapi + * @since 9 + */ + pivotX?: double; + + /** + * The param of pivot point of y. Default is 0.5f, Interval is 0.f - 1.f + * + * @type { ?double } + * @syscap SystemCapability.WindowManager.WindowManager.Core + * @systemapi + * @since 9 + */ + pivotY?: double; +} + +export class RotateOptionsInternal implements RotateOptions { + x?: double; + y?: double; + z?: double; + pivotX?: double; + pivotY?: double; +} + +/** + * Describes the translate Transition Options of window + * + * @interface TranslateOptions + * @syscap SystemCapability.WindowManager.WindowManager.Core + * @systemapi + * @since 9 + */ +export interface TranslateOptions { + /** + * The translate pixel param of x direction. Default is 0.f + * + * @type { ?double } + * @syscap SystemCapability.WindowManager.WindowManager.Core + * @systemapi + * @since 9 + */ + x?: double; + + /** + * The translate pixel param of y direction. Default is 0.f + * + * @type { ?double } + * @syscap SystemCapability.WindowManager.WindowManager.Core + * @systemapi + * @since 9 + */ + y?: double; + + /** + * The translate pixel param of z direction. Default is 0.f + * + * @type { ?double } + * @syscap SystemCapability.WindowManager.WindowManager.Core + * @systemapi + * @since 9 + */ + z?: double; +} + +export class TranslateOptionsInternal implements TranslateOptions { + x?: double; + y?: double; + z?: double; +} + +/** + * Rotation change info + * + * @interface RotationChangeInfo + * @syscap SystemCapability.Window.SessionManager + * @atomicservice + * @since 19 + */ +export interface RotationChangeInfo { + /** + * Rotation change type + * + * @type { RotationChangeType } + * @syscap SystemCapability.Window.SessionManager + * @atomicservice + * @since 19 + */ + type: RotationChangeType; + /** + * window orientation + * + * @type { int } + * @syscap SystemCapability.Window.SessionManager + * @atomicservice + * @since 19 + */ + orientation: int; + /** + * Display id + * + * @type { long } + * @syscap SystemCapability.Window.SessionManager + * @atomicservice + * @since 19 + */ + displayId: long; + /** + * Display rect + * + * @type { Rect } + * @syscap SystemCapability.Window.SessionManager + * @atomicservice + * @since 19 + */ + displayRect: Rect; +} + +export class RotationChangeInfoInternal implements RotationChangeInfo { + type: RotationChangeType; + orientation: int; + displayId: long; + displayRect: Rect; +} + +/** + * Rotation change result + * + * @interface RotationChangeResult + * @syscap SystemCapability.Window.SessionManager + * @atomicservice + * @since 19 + */ +export interface RotationChangeResult { + /** + * Rect type + * + * @type { RectType } + * @syscap SystemCapability.Window.SessionManager + * @atomicservice + * @since 19 + */ + rectType: RectType; + /** + * Window Rect + * + * @type { Rect } + * @syscap SystemCapability.Window.SessionManager + * @atomicservice + * @since 19 + */ + windowRect: Rect; +} + +export class WindowStageInternal implements WindowStage { + static { loadLibrary('windowstageani_module.z') } + + private nativeObj: long = 0; + setNativeObj(nativeObj: long):void { + this.nativeObj = nativeObj; + } + + private static native nativeTransferStatic(input: ESValue): Object; + private static native nativeTransferDynamic(nativeObj: long): ESValue; + public native setWindowRectAutoSave(nativeObj: long, enabled: boolean, isSaveBySpecifiedFlag: boolean): void; + public native isWindowRectAutoSave(nativeObj: long): boolean; + public native removeStartingWindow(nativeObj: long): void; + 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 native createSubWindowSync(nativeObj: long, name: String): Window; + native onSync(nativeObj: long, eventType: 'windowStageEvent', callback: Object): void; + native offSync(nativeObj: long, eventType: 'windowStageEvent', callback?: Object): void; + + public static transferStatic(input: Any): Object { + hilog.info(DOMAIN, TAG, 'transfer static, input:' + input); + let windowStage: ESValue = ESValue.wrap(input).getPropertySafe('windowStage_'); + if (windowStage !== ESValue.Undefined) { + return WindowStageInternal.nativeTransferStatic(windowStage); + } else { + return WindowStageInternal.nativeTransferStatic(ESValue.wrap(input)); + } + } + + public static transferDynamic(input: Object): Any { + hilog.info(DOMAIN, TAG, 'transfer dynamic, input:' + input); + if (input instanceof WindowStageInternal) { + return WindowStageInternal.nativeTransferDynamic((input as WindowStageInternal).nativeObj).unwrap(); + } else { + return undefined; + } + } + + public setWindowRectAutoSave(enabled: boolean, isSaveBySpecifiedFlag: boolean): Promise { + return new Promise((resolve: (value: undefined) => void, reject: (error: BusinessError) => void): void => { + taskpool.execute((): void => { + this.setWindowRectAutoSave(this.nativeObj, enabled, isSaveBySpecifiedFlag); + }).then((ret: NullishType): void => { + resolve(undefined); + }).catch((err: NullishType): void => { + reject(err as BusinessError); + }); + }); + } + + public setWindowRectAutoSave(enabled: boolean): Promise { + return new Promise((resolve: (value: undefined) => void, reject: (error: BusinessError) => void): void => { + taskpool.execute((): void => { + this.setWindowRectAutoSave(this.nativeObj, enabled, false); + }).then((ret: NullishType): void => { + resolve(undefined); + }).catch((err: NullishType): void => { + reject(err as BusinessError); + }); + }); + } + + public isWindowRectAutoSave(): Promise { + return new Promise((resolve: (value: boolean) => void, reject: (error: BusinessError) => void): void => { + taskpool.execute((): boolean => { + return this.isWindowRectAutoSave(this.nativeObj); + }).then((ret: NullishType): void => { + resolve(ret as boolean); + }).catch((err: NullishType): void => { + reject(err as BusinessError); + }); + }); + } + + public removeStartingWindow(): Promise { + return new Promise((resolve: (value: undefined) => void, reject: (error: BusinessError) => void): void => { + taskpool.execute((): void => { + this.removeStartingWindow(this.nativeObj); + }).then((ret: NullishType): void => { + resolve(undefined); + }).catch((err: NullishType): void => { + reject(err 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); + } + }); + } + + 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 { + this.disableWindowDecorSync(this.nativeObj); + } + + public setShowOnLockScreen(showOnLockScreen: boolean): void { + this.setShowOnLockScreenSync(this.nativeObj, showOnLockScreen); + } public getMainWindowSync(): Window { let ret = this.getMainWindowSync(this.nativeObj); @@ -1172,7 +1985,7 @@ export class WindowStageInternal implements WindowStage { } public getMainWindow(): Promise { - return new Promise((resolve: (value: Window) => void, reject: (error: BusinessError) => void ) => { + return new Promise((resolve: (value: Window) => void, reject: (error: BusinessError) => void) => { taskpool.execute((): Window => { let window = this.getMainWindowSync(this.nativeObj); return window; @@ -1193,55 +2006,417 @@ export class WindowStageInternal implements WindowStage { }).catch((err: NullishType) => { }); } + + public createSubWindow(name: string): Promise { + return new Promise((resolve: (value: Window) => void, reject: (error: BusinessError) => void) => { + taskpool.execute((): Window => { + let window = this.createSubWindowSync(this.nativeObj, name); + return window; + }).then((ret: NullishType) => { + resolve(ret as Window); + }).catch((err: NullishType) => { + reject(err as BusinessError); + }); + }); + } + + public createSubWindow(name: string, callback: AsyncCallback): void { + taskpool.execute((): Window => { + let res = this.createSubWindowSync(this.nativeObj, name); + return res; + }).then((ret: NullishType) => { + callback(new BusinessError(), ret as Window); + }).catch((err: NullishType) => { + }); + } + + public on(eventType: 'windowStageEvent', callback: Callback): void { + this.onSync(this.nativeObj, eventType, callback); + } + + public off(eventType: 'windowStageEvent', callback?: Callback): void { + this.offSync(this.nativeObj, eventType, callback); + } } export interface WindowStage { + setWindowRectAutoSave(enabled: boolean): Promise; + isWindowRectAutoSave(): Promise; + setWindowRectAutoSave(enabled: boolean, isSaveBySpecifiedFlag: boolean): Promise; + removeStartingWindow(): Promise; + 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; + createSubWindow(name: string): Promise; + createSubWindow(name: string, callback: AsyncCallback): void; disableWindowDecor(): void; setShowOnLockScreen(showOnLockScreen: boolean): void; + on(eventType: 'windowStageEvent', callback: Callback): void; + off(eventType: 'windowStageEvent', callback?: Callback): void; } +export native function windowDestroyCallback(nativeObj: long): void; +let windowDestroyRegister = new FinalizationRegistry(windowDestroyCallback); + export class WindowInternal implements Window { static readonly DEFAULT_RET_VAL = 1; - static { loadLibrary('windowstageani_kit.z') } + static { loadLibrary('windowstageani_module.z') } private nativeObj: long; - public setNativeObj(nativeObj: long): void { - this.nativeObj = nativeObj; + public setNativeObj(nativeObject: long): void { + if (!this.nativeObj) { + windowDestroyRegister.register(this, nativeObject); + } + this.nativeObj = nativeObject; } - private native getWindowDecorHeight(nativeObj:long): double; + private static native nativeTransferStatic(input: ESValue): Object; + private static native nativeTransferDynamic(nativeObj: long): ESValue; + + private native setFollowParentWindowLayoutEnabled(nativeObj: long, enabled: boolean): void; + private native setWindowDelayRaiseOnDrag(nativeObj: long, isEnabled: boolean): void; + private native getParentWindow(nativeObj: long): Window; + private native getWindowDecorVisible(nativeObj: long): boolean; + private native stopMoving(nativeObj: long): void; + private native setParentWindow(nativeObj: long, windowId: double): void; + private native setWindowTitle(nativeObj: long, titleName: string): void; + private native getDecorButtonStyle(nativeObj: long): DecorButtonStyle; + private native getTitleButtonRect(nativeObj: long): TitleButtonRect; + private native setTitleButtonVisible(nativeObj: long, visibleParam: TitleButtonVisibleParam): void; + private native setWindowTitleMoveEnabled(nativeObj: long, enabled: boolean): void; + private native setWindowTopmost(nativeObj: long, isWindowTopmost: boolean): void; + private native setTitleAndDockHoverShown(nativeObj: long, isTitleHoverShown: boolean, isDockHoverShown: boolean): void; + private native restore(nativeObj: long): void; + + private native startMoving(nativeObj: long): void; + private native startMoveWindowWithCoordinate(nativeObj: long, offsetX: int, offsetY: int): void; + private native setWindowTitleButtonVisible(nativeObj: long, visibleParam: WindowTitleButtonVisibleParam): void; + private native setDecorButtonStyle(nativeObj: long, decorStyle: DecorButtonStyle): void; + private native getWindowStatus(nativeObj: long): int; + private native minimize(nativeObj: long): void; + private native maximize(nativeObj: long, presentation: int): void; + private native resize(nativeObj: long, width: int, height: int): void; + private native moveWindowTo(nativeObj: long, x: int, y: int): void; + private native getGlobalRect(nativeObj:long): Rect; + + private native getWindowDecorHeight(nativeObj:long): int; private native setWindowBackgroundColor(nativeObj: long, color: string): int; private native setImmersiveModeEnabledState(nativeObj: long, enable: boolean): int; private native setWindowDecorVisible(nativeObj: long, isVisible: boolean): int; - private native setWindowDecorHeight(nativeObj: long, height: double): int; + private native setWindowDecorHeight(nativeObj: long, height: int): int; private native getWindowProperties(nativeObj: long): WindowProperties; private native getProperties(nativeObj: long): WindowProperties; private native isWindowSupportWideGamut(nativeObj: long): boolean; private native setWindowLayoutFullScreen(nativeObj: long, isLayoutFullScreen: boolean): int; private native setWindowSystemBarProperties(nativeObj: long, systemBarProperties: SystemBarProperties): int; private native setSpecificSystemBarEnabled(nativeObj: long, name: String, enable: boolean, enableAnimation: boolean): int; + private native snapshot(nativeObj: long): image.PixelMap; + private native hideNonSystemFloatingWindows(nativeObj: long, shouldHide: boolean): void; + private native opacity(nativeObj: long, opacity: double): void; + private native scale(nativeObj: long, scaleOptions: ScaleOptions): void; + private native translate(nativeObj: long, translateOptions: TranslateOptions): void; + private native rotate(nativeObj: long, rotateOptions: RotateOptions): void; + private native setShadow(nativeObj: long, radius: double, color?: string, + offsetX?: double, offsetY?: double): void; + + private native setWindowColorSpaceSync(nativeObj: long, colorSpace: int): void; + private native setPreferredOrientationSync(nativeObj: long, orientation: int): void; + 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 setWindowKeepScreenOnSync(nativeObj: long, isKeepScreenOn: boolean): void; + private native setWindowSystemBarEnableSync(nativeObj: long, names: Array<'status' | 'navigation'>): void; + private native getUIContextSync(nativeObj: long): UIContext; + private native getWindowAvoidAreaSync(nativeObj: long, type: int): AvoidArea; + private native setWaterMarkFlagSync(nativeObj: long, enable: boolean): void; + private native showWindowSync(nativeObj: long): void; + private native destroyWindowSync(nativeObj: long): void; + private native isWindowShowingSync(nativeObj: long): boolean; + private native hideWithAnimationSync(nativeObj: long): void; + private native showWithAnimationSync(nativeObj: long): void; + private native setWindowFocusableSync(nativeObj: long, isFocusable: boolean): void; + + private native setWindowTouchableSync(nativeObj: long, isTouchable: boolean): void; + private native onNoInteractionDetected(nativeObj: long, type: string, timeout: long, callback: Object): void; + private native keepKeyboardOnFocusSync(nativeObj: long, enable: boolean): void; + private native onSync(nativeObj: long, type: string, callback: object): void; + private native offSync(nativeObj: long, type: string, callback?: object): void; + + public static transferStatic(input: Any): Object { + hilog.info(DOMAIN, TAG, 'window transfer static, input:' + input); + return WindowInternal.nativeTransferStatic(ESValue.wrap(input)); + } + + public static transferDynamic(input: Object): Any { + hilog.info(DOMAIN, TAG, 'window transfer dynamic, input:' + input); + return WindowInternal.nativeTransferDynamic((input as WindowInternal).nativeObj).unwrap(); + } + + public setFollowParentWindowLayoutEnabled(enabled: boolean): Promise { + return new Promise((resolve: (value: undefined) => void, reject: (error: BusinessError) => void ): void => { + taskpool.execute((): void => { + this.setFollowParentWindowLayoutEnabled(this.nativeObj, enabled); + }).then((ret: NullishType): void => { + resolve(undefined); + }).catch((err: NullishType): void => { + reject(err as BusinessError); + }); + }); + } + + public setWindowDelayRaiseOnDrag(isEnabled: boolean): void { + this.setWindowDelayRaiseOnDrag(this.nativeObj, isEnabled); + } + + public getParentWindow(): Window { + return this.getParentWindow(this.nativeObj); + } + + public getWindowDecorVisible(): boolean { + return this.getWindowDecorVisible(this.nativeObj); + } + + public stopMoving(): Promise { + return new Promise((resolve: (value: undefined) => void, reject: (error: BusinessError) => void ): void => { + taskpool.execute((): void => { + this.stopMoving(this.nativeObj); + }).then((ret: NullishType): void => { + resolve(undefined); + }).catch((err: NullishType): void => { + reject(err as BusinessError); + }); + }); + } + + public setParentWindow(windowId: number): Promise { + return new Promise((resolve: (value: undefined) => void, reject: (error: BusinessError) => void ): void => { + taskpool.execute((): void => { + this.setParentWindow(this.nativeObj, windowId); + }).then((ret: NullishType): void => { + resolve(undefined); + }).catch((err: NullishType): void => { + reject(err as BusinessError); + }); + }); + } + + public setWindowTitle(titleName: string): Promise { + return new Promise((resolve: (value: undefined) => void, reject: (error: BusinessError) => void ): void => { + taskpool.execute((): void => { + this.setWindowTitle(this.nativeObj, titleName); + }).then((ret: NullishType): void => { + resolve(undefined); + }).catch((err: NullishType): void => { + reject(err as BusinessError); + }); + }); + } + + public getDecorButtonStyle(): DecorButtonStyle { + return this.getDecorButtonStyle(this.nativeObj); + } + + public getTitleButtonRect(): TitleButtonRect { + return this.getTitleButtonRect(this.nativeObj); + } + + public setTitleButtonVisible(isMaximizeVisible: boolean, isMinimizeVisible: boolean, + isSplitVisible: boolean): void { + let visibleParam: window.TitleButtonVisibleParam = { + isMaximizeVisible: isMaximizeVisible, + isMinimizeVisible: isMinimizeVisible, + isSplitVisible: isSplitVisible, + isCloseVisible: true, + }; + this.setTitleButtonVisible(this.nativeObj, visibleParam); + } + + public setWindowTitleMoveEnabled(enabled: boolean): void { + this.setWindowTitleMoveEnabled(this.nativeObj, enabled); + } + + public setWindowTopmost(isWindowTopmost: boolean): Promise { + return new Promise((resolve: (value: undefined) => void, reject: (error: BusinessError) => void ): void => { + taskpool.execute((): void => { + this.setWindowTopmost(this.nativeObj, isWindowTopmost); + }).then((ret: NullishType): void => { + resolve(undefined); + }).catch((err: NullishType): void => { + reject(err as BusinessError); + }); + }); + } + + public setTitleAndDockHoverShown(isTitleHoverShown?: boolean, isDockHoverShown?: boolean): Promise { + return new Promise((resolve: (value: undefined) => void, reject: (error: BusinessError) => void ): void => { + taskpool.execute((): void => { + let titleShow: boolean = true; + if (isTitleHoverShown != undefined) { + titleShow = isTitleHoverShown; + } + let dockShow: boolean = true; + if (isDockHoverShown != undefined) { + dockShow = isDockHoverShown; + } + this.setTitleAndDockHoverShown(this.nativeObj, titleShow, dockShow); + }).then((ret: NullishType): void => { + resolve(undefined); + }).catch((err: NullishType): void => { + reject(err as BusinessError); + }); + }); + } + + public restore(): Promise { + return new Promise((resolve: (value: undefined) => void, reject: (error: BusinessError) => void ): void => { + taskpool.execute((): void => { + this.restore(this.nativeObj); + }).then((ret: NullishType): void => { + resolve(undefined); + }).catch((err: NullishType): void => { + reject(err as BusinessError); + }); + }); + } + + public startMoving(): Promise { + return new Promise((resolve: (value: undefined) => void, reject: (error: BusinessError) => void ) :void => { + taskpool.execute((): void => { + this.startMoving(this.nativeObj); + }).then((ret: NullishType) :void => { + resolve(undefined); + }).catch((err: NullishType) :void => { + reject(err as BusinessError); + }); + }); + } + + public startMoving(offsetX: int, offsetY: int): Promise { + return new Promise((resolve: (value: undefined) => void, reject: (error: BusinessError) => void ) :void => { + taskpool.execute((): void => { + this.startMoveWindowWithCoordinate(this.nativeObj, offsetX, offsetY); + }).then((ret: NullishType) :void => { + resolve(undefined); + }).catch((err: NullishType) :void => { + reject(err as BusinessError); + }); + }); + } + + public setWindowTitleButtonVisible(isMaximizeButtonVisible: boolean, isMinimizeButtonVisible: boolean, + isCloseButtonVisible?: boolean): void { + let visibleParam: window.WindowTitleButtonVisibleParam = { + isMaximizeButtonVisible: isMaximizeButtonVisible, + isMinimizeButtonVisible: isMinimizeButtonVisible, + isCloseButtonVisible: true + }; + if (isCloseButtonVisible != undefined) { + visibleParam.isCloseButtonVisible = isCloseButtonVisible; + } + this.setWindowTitleButtonVisible(this.nativeObj, visibleParam); + } + + public setDecorButtonStyle(decorStyle: DecorButtonStyle): void { + this.setDecorButtonStyle(this.nativeObj, decorStyle); + } + + public getWindowStatus(): WindowStatusType { + return this.getWindowStatus(this.nativeObj) as WindowStatusType; + } + + public minimize(): Promise { + return new Promise((resolve: (value: undefined) => void, reject: (error: BusinessError) => void ) :void => { + taskpool.execute((): void => { + this.minimize(this.nativeObj); + }).then((ret: NullishType) :void => { + resolve(undefined); + }).catch((err: NullishType) :void => { + reject(err as BusinessError); + }); + }); + } + + public minimize(callback: AsyncCallback): void { + taskpool.execute((): void => { + this.minimize(this.nativeObj); + }).then((ret: NullishType) => { + callback(new BusinessError(), undefined); + }).catch((err: NullishType) => { + callback(err as BusinessError, undefined); + }); + } + + public maximize(presentation?: MaximizePresentation): Promise { + return new Promise((resolve: (value: undefined) => void, reject: (error: BusinessError) => void ) :void => { + taskpool.execute((): void => { + if (presentation == undefined) { + this.maximize(this.nativeObj, MaximizePresentation.ENTER_IMMERSIVE as int); + } + else { + this.maximize(this.nativeObj, presentation as int); + } + }).then((ret: NullishType) :void => { + resolve(undefined); + }).catch((err: NullishType) :void => { + reject(err as BusinessError); + }); + }); + } + + public resize(width: int, height: int): Promise { + return new Promise((resolve: (value: undefined) => void, reject: (error: BusinessError) => void) :void => { + taskpool.execute((): void => { + this.resize(this.nativeObj, width, height); + }).then((ret: NullishType) :void => { + resolve(undefined); + }).catch((err: NullishType) :void => { + reject(err as BusinessError); + }); + }); + } + + public moveWindowTo(x: int, y: int): Promise { + return new Promise((resolve: (value: undefined) => void, reject: (error: BusinessError) => void) :void => { + taskpool.execute((): void => { + this.moveWindowTo(this.nativeObj, x, y); + }).then((ret: NullishType) :void => { + resolve(undefined); + }).catch((err: NullishType) :void => { + reject(err as BusinessError); + }); + }); + } + + public resize(width: int, height: int, callback: AsyncCallback): void { + taskpool.execute((): void => { + this.resize(this.nativeObj, width, height); + }).then((ret: NullishType) => { + callback(new BusinessError(), undefined); + }).catch((err: NullishType) => { + callback(err as BusinessError, undefined); + }); + } - private native setWindowColorSpaceSync(nativeObj: long, colorSpace: int): void; - private native setPreferredOrientationSync(nativeObj: long, orientation: int): void; - 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 setWindowKeepScreenOnSync(nativeObj: long, isKeepScreenOn: boolean): void; - private native setWindowSystemBarEnableSync(nativeObj: long, names: Array<'status' | 'navigation'>): void; - private native getUIContextSync(nativeObj: long): UIContext; - private native getWindowAvoidAreaSync(nativeObj: long, type: int): AvoidArea; - private native setWaterMarkFlagSync(nativeObj: long, enable: boolean): void; - private native onSync(nativeObj: long, type: string, callback: object): void; - private native offSync(nativeObj: long, type: string, callback?: object): void; + public moveWindowTo(x: int, y: int, callback: AsyncCallback): void { + taskpool.execute((): void => { + this.moveWindowTo(this.nativeObj, x, y); + }).then((ret: NullishType) => { + callback(new BusinessError(), undefined); + }).catch((err: NullishType) => { + callback(err as BusinessError, undefined); + }); + } - public getWindowDecorHeight(): number { + public getGlobalRect(): Rect { + let ret = this.getGlobalRect(this.nativeObj); + return ret; + } + + public getWindowDecorHeight(): int { let ret = this.getWindowDecorHeight(this.nativeObj); return ret; } @@ -1253,7 +2428,7 @@ export class WindowInternal implements Window { } public setBackgroundColor(color: string): Promise { - return new Promise((resolve: (value: undefined) => void, reject: (error: BusinessError) => void ) :void => { + return new Promise((resolve: (value: undefined) => void, reject: (error: BusinessError) => void) :void => { taskpool.execute((): void => { this.setWindowBackgroundColor(this.nativeObj, color); }).then((ret: NullishType) :void => { @@ -1282,22 +2457,24 @@ export class WindowInternal implements Window { this.setWindowDecorVisible(this.nativeObj, isVisible); } - public setWindowDecorHeight(height: number): void { + public setWindowDecorHeight(height: int): void { this.setWindowDecorHeight(this.nativeObj, height); } public getWindowProperties(): WindowProperties { let windowProperties = this.getWindowProperties(this.nativeObj) as WindowPropertiesInternal; windowProperties.type = windowProperties.typeInternal as WindowType; + windowProperties.displayId = windowProperties.displayIdInternal; return windowProperties; } public getProperties(): Promise { return new Promise((resolve: (value: WindowProperties) => void, - reject: (error: BusinessError) => void ) => { + reject: (error: BusinessError) => void) => { taskpool.execute((): WindowProperties => { let res = this.getProperties(this.nativeObj) as WindowPropertiesInternal; res.type = res.typeInternal as WindowType; + res.displayId = res.displayIdInternal; return res; }).then((ret: NullishType) => { resolve(ret as WindowProperties); @@ -1309,7 +2486,9 @@ export class WindowInternal implements Window { public getProperties(callback: AsyncCallback): void { taskpool.execute((): WindowProperties => { - let res = this.getProperties(this.nativeObj); + let res = this.getProperties(this.nativeObj) as WindowPropertiesInternal; + res.type = res.typeInternal as WindowType; + res.displayId = res.displayIdInternal; return res; }).then((ret: NullishType) => { callback(new BusinessError(), ret as WindowProperties); @@ -1319,7 +2498,7 @@ export class WindowInternal implements Window { } public isWindowSupportWideGamut(): Promise { - return new Promise((resolve: (value: boolean) => void, reject: (error: BusinessError) => void ) => { + return new Promise((resolve: (value: boolean) => void, reject: (error: BusinessError) => void) => { taskpool.execute((): boolean => { let res = this.isWindowSupportWideGamut(this.nativeObj); return res; @@ -1402,6 +2581,50 @@ export class WindowInternal implements Window { }); } + public snapshot(): Promise { + return new Promise((resolve: (value: image.PixelMap) => void, reject: (error: BusinessError) => void) => { + taskpool.execute(() => { + return this.snapshot(this.nativeObj); + }).then((ret: NullishType) => { + resolve(ret as image.PixelMap); + }).catch((err: NullishType) => { + reject(err as BusinessError); + }); + }); + } + + public snapshot(callback: AsyncCallback): void { + taskpool.execute(() => { + return this.snapshot(this.nativeObj); + }).then((ret: NullishType) => { + callback(new BusinessError(), ret as image.PixelMap); + }).catch((err: NullishType) => { + callback(err as BusinessError, undefined); + }); + } + + public hideNonSystemFloatingWindows(shouldHide: boolean): Promise { + return new Promise((resolve: (value: undefined) => void, reject: (error: BusinessError) => void): void => { + taskpool.execute(() => { + this.hideNonSystemFloatingWindows(this.nativeObj, shouldHide); + }).then(() => { + resolve(undefined); + }).catch((err: NullishType) => { + reject(err as BusinessError); + }); + }); + } + + public hideNonSystemFloatingWindows(shouldHide: boolean, callback: AsyncCallback): void { + taskpool.execute((): void => { + this.hideNonSystemFloatingWindows(this.nativeObj, shouldHide); + }).then(() => { + callback(new BusinessError(), undefined); + }).catch((err: NullishType) => { + callback(err as BusinessError, undefined); + }); + } + public setWindowColorSpace(colorSpace: ColorSpace): Promise { return new Promise((resolve: (value: undefined) => void, reject: (error: BusinessError) => void): void => { taskpool.execute((): void => { @@ -1563,7 +2786,7 @@ export class WindowInternal implements Window { } public setWindowSystemBarEnable(names: Array<'status' | 'navigation'>): Promise { - return new Promise((resolve: (value: undefined) => void, reject: (error: BusinessError) => void ) :void => { + return new Promise((resolve: (value: undefined) => void, reject: (error: BusinessError) => void) :void => { taskpool.execute((): void => { this.setWindowSystemBarEnableSync(this.nativeObj, names); }).then((ret: NullishType) => { @@ -1614,23 +2837,216 @@ export class WindowInternal implements Window { }); } + public setWindowFocusable(isFocusable: boolean): Promise { + return new Promise((resolve: (value: undefined) => void, reject: (error: BusinessError) => void): void => { + taskpool.execute((): void => { + this.setWindowFocusableSync(this.nativeObj, isFocusable); + }).then((ret: NullishType) => { + resolve(undefined); + }).catch((err: NullishType) => { + reject(err as BusinessError); + }); + }); + } + + public setWindowFocusable(isFocusable: boolean, callback: AsyncCallback): void { + taskpool.execute((): void => { + this.setWindowFocusableSync(this.nativeObj, isFocusable); + }).then((ret: NullishType) => { + callback(new BusinessError(), undefined); + }).catch((err: NullishType) => { + callback(err as BusinessError, undefined); + }); + } + + public keepKeyboardOnFocus(keepKeyboardFlag: boolean): void { + this.keepKeyboardOnFocusSync(this.nativeObj, keepKeyboardFlag); + } + + public setWindowTouchable(isTouchable: boolean): Promise { + return new Promise((resolve: (value: undefined) => void, reject: (error: BusinessError) => void): void => { + taskpool.execute((): void => { + this.setWindowTouchableSync(this.nativeObj, isTouchable); + }).then((ret: NullishType) => { + resolve(undefined); + }).catch((err: NullishType) => { + reject(err as BusinessError); + }); + }); + } + + public setWindowTouchable(isTouchable: boolean, callback: AsyncCallback): void { + taskpool.execute((): void => { + this.setWindowTouchableSync(this.nativeObj, isTouchable); + }).then((ret: NullishType) => { + callback(new BusinessError(), undefined); + }).catch((err: NullishType) => { + callback(err as BusinessError, undefined); + }); + } + + public opacity(opacity: double): void { + this.opacity(this.nativeObj, opacity); + } + + public scale(scaleOptions: ScaleOptions): void { + this.scale(this.nativeObj, scaleOptions); + } + + public translate(translateOptions: TranslateOptions): void { + this.translate(this.nativeObj, translateOptions); + } + + public rotate(rotateOptions: RotateOptions): void { + this.rotate(this.nativeObj, rotateOptions); + } + + public setShadow(radius: double, color?: string, offsetX?: double, offsetY?: double): void { + this.setShadow(this.nativeObj, radius, color, offsetX, offsetY); + } + public on(type: string, callback: Callback): void { this.onSync(this.nativeObj, type, callback); } + public on(type: 'noInteractionDetected', timeout: long, callback: Callback): void { + this.onNoInteractionDetected(this.nativeObj, type, timeout, callback as WindowVoidCallback); + } + public off(type: string, callback?: Callback): void { this.offSync(this.nativeObj, type, callback); } + + public showWindow(callback: AsyncCallback): void { + taskpool.execute((): void => { + this.showWindowSync(this.nativeObj); + }).then((ret: NullishType) => { + callback(new BusinessError(), undefined); + }).catch((err: NullishType) => { + callback(err as BusinessError, undefined); + }); + } + + public showWindow(): Promise { + return new Promise((resolve: (value: undefined) => void, reject: (error: BusinessError) => void): void => { + taskpool.execute((): void => { + this.showWindowSync(this.nativeObj); + }).then((ret: NullishType) => { + resolve(undefined); + }).catch((err: NullishType) => { + reject(err as BusinessError); + }); + }); + } + + public destroyWindow(callback: AsyncCallback): void { + taskpool.execute((): void => { + this.destroyWindowSync(this.nativeObj); + }).then((ret: NullishType) => { + callback(new BusinessError(), undefined); + }).catch((err: NullishType) => { + callback(err as BusinessError, undefined); + }); + } + + public destroyWindow(): Promise { + return new Promise((resolve: (value: undefined) => void, reject: (error: BusinessError) => void): void => { + taskpool.execute((): void => { + this.destroyWindowSync(this.nativeObj); + }).then((ret: NullishType) => { + resolve(undefined); + }).catch((err: NullishType) => { + reject(err as BusinessError); + }); + }); + } + + public isWindowShowing(): boolean { + return this.isWindowShowingSync(this.nativeObj); + } + + public hideWithAnimation(callback: AsyncCallback): void { + taskpool.execute((): void => { + this.hideWithAnimationSync(this.nativeObj); + }).then((ret: NullishType) => { + callback(new BusinessError(), undefined); + }).catch((err: NullishType) => { + callback(err as BusinessError, undefined); + }); + } + + public hideWithAnimation(): Promise { + return new Promise((resolve: (value: undefined) => void, reject: (error: BusinessError) => void): void => { + taskpool.execute((): void => { + this.hideWithAnimationSync(this.nativeObj); + }).then((ret: NullishType) => { + resolve(undefined); + }).catch((err: NullishType) => { + reject(err as BusinessError); + }); + }); + } + + public showWithAnimation(callback: AsyncCallback): void { + taskpool.execute((): void => { + this.showWithAnimationSync(this.nativeObj); + }).then((ret: NullishType) => { + callback(new BusinessError(), undefined); + }).catch((err: NullishType) => { + callback(err as BusinessError, undefined); + }); + } + + public showWithAnimation(): Promise { + return new Promise((resolve: (value: undefined) => void, reject: (error: BusinessError) => void): void => { + taskpool.execute((): void => { + this.showWithAnimationSync(this.nativeObj); + }).then((ret: NullishType) => { + resolve(undefined); + }).catch((err: NullishType) => { + reject(err as BusinessError); + }); + }); + } } export interface Window { - getWindowDecorHeight(): double; + setFollowParentWindowLayoutEnabled(enabled: boolean): Promise; + setWindowDelayRaiseOnDrag(isEnabled: boolean): void; + getParentWindow(): Window; + getWindowDecorVisible(): boolean; + stopMoving(): Promise; + setParentWindow(windowId: number): Promise; + setWindowTitle(titleName: string): Promise; + getDecorButtonStyle(): DecorButtonStyle; + getTitleButtonRect(): TitleButtonRect; + setTitleButtonVisible(isMaximizeVisible: boolean, isMinimizeVisible: boolean, isSplitVisible: boolean): void; + setWindowTitleMoveEnabled(enabled: boolean): void; + setWindowTopmost(isWindowTopmost: boolean): Promise; + setTitleAndDockHoverShown(isTitleHoverShown?: boolean, isDockHoverShown?: boolean): Promise; + restore(): Promise; + + startMoving(): Promise; + startMoving(offsetX: int, offsetY: int): Promise; + setWindowTitleButtonVisible(isMaximizeButtonVisible: boolean, isMinimizeButtonVisible: boolean, + isCloseButtonVisible?: boolean): void; + setDecorButtonStyle(dectorStyle: DecorButtonStyle): void; + getWindowStatus(): WindowStatusType; + minimize(callback: AsyncCallback): void; + minimize(): Promise; + maximize(presentation?: MaximizePresentation): Promise; + resize(width: int, height: int): Promise; + moveWindowTo(x: int, y: int): Promise; + resize(width: int, height: int, callback: AsyncCallback): void; + moveWindowTo(x: int, y: int, callback: AsyncCallback): void; + getGlobalRect(): Rect; + getWindowDecorHeight(): int; setWindowBackgroundColor(color: string | ColorMetrics): void; setBackgroundColor(color: string): Promise; setBackgroundColor(color: string, callback: AsyncCallback): void; setImmersiveModeEnabledState(enable: boolean): void; setWindowDecorVisible(isVisible: boolean): void; - setWindowDecorHeight(height: number): void; + setWindowDecorHeight(height: int): void; getWindowProperties(): WindowProperties; getProperties(): Promise; getProperties(callback: AsyncCallback): void; @@ -1641,6 +3057,10 @@ export interface Window { setWindowSystemBarProperties(systemBarProperties: SystemBarProperties): Promise; setWindowSystemBarProperties(systemBarProperties: SystemBarProperties, callback: AsyncCallback): void; setSpecificSystemBarEnabled(name: String, enable: boolean, enableAnimation?: boolean): Promise; + snapshot(): Promise; + snapshot(callback: AsyncCallback): void; + hideNonSystemFloatingWindows(shouldHide: boolean): Promise; + hideNonSystemFloatingWindows(shouldHide: boolean, callback: AsyncCallback): void; setWindowColorSpace(colorSpace: ColorSpace): Promise; setWindowColorSpace(colorSpace: ColorSpace, callback: AsyncCallback): void; setPreferredOrientation(orientation: Orientation): Promise; @@ -1662,7 +3082,27 @@ export interface Window { getWindowAvoidArea(type: AvoidAreaType): AvoidArea; setWaterMarkFlag(enable: boolean): Promise; setWaterMarkFlag(enable: boolean, callback: AsyncCallback): void; + showWindow(callback: AsyncCallback): void; + showWindow(): Promise; + destroyWindow(callback: AsyncCallback): void; + destroyWindow(): Promise; + isWindowShowing(): boolean; + hideWithAnimation(callback: AsyncCallback): void; + hideWithAnimation(): Promise; + showWithAnimation(callback: AsyncCallback): void; + showWithAnimation(): Promise; + setWindowFocusable(isFocusable: boolean): Promise; + setWindowFocusable(isFocusable: boolean, callback: AsyncCallback): void; + keepKeyboardOnFocus(enable: boolean): void; + setWindowTouchable(isTouchable: boolean): Promise + setWindowTouchable(isTouchable: boolean, callback: AsyncCallback): void + opacity(opacity: double): void; + scale(scaleOptions: ScaleOptions): void; + translate(translateOptions: TranslateOptions): void; + rotate(rotateOptions: RotateOptions): void; + setShadow(radius: double, color?: string, offsetX?: double, offsetY?: double): void; on(type: string, callback: Callback): void; + on(type: 'noInteractionDetected', timeout: long, callback: Callback): void; off(type: string, callback?: Callback): void; } @@ -1671,15 +3111,24 @@ 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 { + hilog.info(DOMAIN, TAG, 'setNativeObj, nativeObject:' + nativeObject); + nativeObj = nativeObject; } +native function getWindowsByCoordinate(nativeObj: long, param: window.GetWindowsByCoordinateParam): Array; native function getLastWindowSync(nativeObj: long, ctx: BaseContext): Window; +native function minimizeAllSync(nativeObj: long, id: long): void; +native function findWindowSync(nativeObj: long, name: string): Window; +native function onSync(nativeObj: long, type: string, callback: object): void; +native function offSync(nativeObj: long, type: string, callback?: object): void; +native function shiftAppWindowFocusSync(nativeObj: long, sourceWindowId: int, targetWindowId: int): void; +native function createWindowSync(nativeObj: long, config: Configuration): Window; export function getLastWindow(ctx: BaseContext): Promise { - return new Promise((resolve: (value: Window) => void, reject: (error: BusinessError) => void ) => { + return new Promise((resolve: (value: Window) => void, reject: (error: BusinessError) => void) => { taskpool.execute((): Window => { + hilog.info(DOMAIN, TAG, 'getLastWindow, ctx:' + ctx); return getLastWindowSync(nativeObj, ctx); }).then((ret: NullishType) => { resolve(ret as Window); @@ -1691,6 +3140,7 @@ export function getLastWindow(ctx: BaseContext): Promise { export function getLastWindow(ctx: BaseContext, callback: AsyncCallback): void { taskpool.execute((): Window => { + hilog.info(DOMAIN, TAG, 'getLastWindow, ctx:' + ctx); return getLastWindowSync(nativeObj, ctx); }).then((ret: NullishType) => { callback(new BusinessError(), ret as Window); @@ -1699,20 +3149,187 @@ export function getLastWindow(ctx: BaseContext, callback: AsyncCallback) }); } -function runWindowEventCallBack(cb: object, cbArg: int): void { +export function createWindow(config: Configuration): Promise { + return new Promise((resolve: (value: Window) => void, reject: (error: BusinessError) => void ) => { + taskpool.execute((): Window => { + return createWindowSync(nativeObj, config); + }).then((ret: NullishType) => { + resolve(ret as Window); + }).catch((err: NullishType) => { + reject(err as BusinessError); + }); + }); +} + +export function createWindow(config: Configuration, callback: AsyncCallback): void { + taskpool.execute((): Window => { + return createWindowSync(nativeObj, config); + }).then((ret: NullishType) => { + callback(new BusinessError(), ret as Window); + }).catch((err: NullishType) => { + callback(err as BusinessError, new WindowInternal()); + }); +} + +export function minimizeAll(id: long): Promise { + return new Promise((resolve: (value: undefined) => void, reject: (error: BusinessError) => void): void => { + taskpool.execute((): void => { + minimizeAllSync(nativeObj, id); + }).then((ret: NullishType) => { + resolve(undefined); + }).catch((err: NullishType) => { + reject(err as BusinessError); + }); + }); +} + +export function minimizeAll(id: long, callback: AsyncCallback): void { + taskpool.execute((): void => { + minimizeAllSync(nativeObj, id); + }).then((ret: NullishType) => { + callback(new BusinessError(), undefined); + }).catch((err: NullishType) => { + callback(err as BusinessError, undefined); + }); +} + +export function getWindowsByCoordinate(displayId: number, windowNumber?: number, + x?: number, y?: number): Promise> { + return new Promise>((resolve: (value: Array) => void, + reject: (error: BusinessError) => void): void => { + taskpool.execute((): Array => { + let param: window.GetWindowsByCoordinateParam = { + displayId: displayId, + windowNumber: 0, + x: -1, + y: -1 + }; + if (windowNumber != undefined) { + param.windowNumber = windowNumber; + } + if (x != undefined) { + param.x = x; + } + if (y != undefined) { + param.y = y; + } + return getWindowsByCoordinate(nativeObj, param); + }).then((ret: NullishType) => { + resolve(ret as Array); + }).catch((err: NullishType) => { + reject(err as BusinessError); + }); + }); +} + +export function findWindow(name: string): Window { + return findWindowSync(nativeObj, name); +} + +export function on(type: string, callback: Callback): void { + onSync(nativeObj, type, callback); +} + +export function off(type: string, callback?: Callback): void { + offSync(nativeObj, type, callback); +} + +function runWindowListenerVoidArgCallback(cb: object): void { + const func = cb as () => void; + func(); +} + +function runWindowListenerBooleanArgCallback(cb: object, cbArg: boolean): void { + const func = cb as (cbArg: boolean) => void; + func(cbArg); +} + +function runSystemDensityChangeCallback(cb: object, density: double): void { + const func = cb as (density: double) => void; + func(density as double); +} + +function runDisplayIdChangeCallback(cb: object, displayId: long): void { + const func = cb as (displayId: long) => void; + func(displayId as long); +} + +function runSystemBarTintChangeCallback(cb: object, tint: object): void { + const func = cb as (tint: SystemBarTintState) => void; + func(tint as SystemBarTintState); +} + +function runAvoidAreaChangeCallback(cb: object, area: object, type: int): void { + const func = cb as (data: AvoidAreaOptions) => void; + func({type: type as AvoidAreaType, area: area as AvoidArea}); +} + +export function shiftAppWindowFocus(sourceWindowId: int, targetWindowId: int): Promise { + return new Promise((resolve: (value: undefined) => void, reject: (error: BusinessError) => void ) : void => { + taskpool.execute((): void => { + return shiftAppWindowFocusSync(nativeObj, sourceWindowId, targetWindowId); + }).then((ret: NullishType) => { + resolve(undefined); + }).catch((err: NullishType) => { + reject(err as BusinessError); + }); + }); +} + +function runWindowDialogTargetCallback(cb: object): void { + const func = cb as () => void; + func(); +} + +function runWindowEventCallback(cb: object, cbArg: int): void { const func = cb as (cbArg: WindowEventType) => void; func(cbArg as WindowEventType); } -function runWindowSizeCallBack(cb: object, cbArg: object): void { +function runWindowStageEventCallback(cb: object, cbArg: int): void { + const func = cb as (cbArg: WindowStageEventType) => void; + func(cbArg as WindowStageEventType); +} + +function runWindowTouchOutCallback(cb: object): void { + const func = cb as () => void; + func(); +} + +function runWindowSizeCallback(cb: object, cbArg: object): void { const func = cb as (cbArg: Size) => void; func(cbArg as Size); } -function runWindowStatusCallBack(cb: object, cbArg: int): void { +function runWindowRectChangeCallback(cb: object, rect: object, reason: int): void { + const func = cb as (data: RectChangeOptions) => void; + func({rect: rect as Rect, reason: reason as RectChangeReason}); +} + +function runKeyboardHeightChangeCallback(cb: object, cbArg: int): void { + const func = cb as (cbArg: int) => void; + func(cbArg as int); +} + +function runKeyboardDidShowCallback(cb: object, cbArg: object): void { + const func = cb as (cbArg: KeyboardInfo) => void; + func(cbArg as KeyboardInfo); +} + +function runKeyboardDidHideCallback(cb: object, cbArg: object): void { + const func = cb as (cbArg: KeyboardInfo) => void; + func(cbArg as KeyboardInfo); +} + +function runWindowStatusCallback(cb: object, cbArg: int): void { const func = cb as (cbArg: WindowStatusType) => void; func(cbArg as WindowStatusType); } + +function runWindowNoInteractionCallback(cb: object): void { + const func = cb as () => void; + func(); +} } export default window; \ No newline at end of file diff --git a/interfaces/kits/ani/window_runtime/window_stage_ani/ets/window_entry.ets b/interfaces/kits/ani/window_runtime/window_stage_ani/ets/window_entry.ets index a1a88fc7f056a72a8344d2f1aa29c2603fc7e741..57edc7ca213ba8bd9e0e330d54e450e8442c2d1e 100644 --- a/interfaces/kits/ani/window_runtime/window_stage_ani/ets/window_entry.ets +++ b/interfaces/kits/ani/window_runtime/window_stage_ani/ets/window_entry.ets @@ -9,7 +9,7 @@ import { } from '@ohos.window'; function main() { - loadLibrary('windowstageani_kit.z') + loadLibrary('windowstageani_module.z') let ws = window.CreateWindowStage(0); let callback:AsyncCallbackVoid = (err) => { @@ -119,6 +119,24 @@ function main() { w.on('windowStatusChange', cb3); w.off('windowStatusChange', cb3); + let cb4 = (): void => { + console.println(`dialogTargetTouch event`); + }; + w.on('dialogTargetTouch', cb4); + w.off('dialogTargetTouch', cb4); + + let cb5 = (): void => { + console.println(`touchOutside event`); + }; + w.on('touchOutside', cb5); + w.off('touchOutside', cb5); + + let cb6 = (): void => { + console.println(`noInteractionDetected event`); + }; + w.on('noInteractionDetected', cb6); + w.off('noInteractionDetected', cb6); + w.setImmersiveModeEnabledState(false); w.setWindowDecorVisible(false); w.setWindowDecorHeight(100); 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 7c0f0b0b61747baf8355253bbefda08e4cad0f99..6e8281d6488da0bd7128d7273c910fe057115677 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,12 @@ 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; } + + // transfer + static ani_object NativeTransferStatic(ani_env* aniEnv, ani_class cls, ani_object input); + static ani_object NativeTransferDynamic(ani_env* aniEnv, ani_class cls, ani_long nativeObj); /* window obj stored in ANI */ static AniWindow* GetWindowObjectFromEnv(ani_env* env, ani_object obj); @@ -45,44 +51,107 @@ 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 SetWindowFocusable(ani_env* env, ani_object obj, ani_long nativeObj, ani_boolean isFocusable); + static void SetWindowTouchable(ani_env* env, ani_object obj, ani_long nativeObj, ani_boolean isTouchable); + 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); static ani_object GetWindowAvoidArea(ani_env* env, ani_object obj, ani_long nativeObj, ani_int type); + static void RegisterNoInteractionDetectedCallback(ani_env* env, ani_object obj, ani_long nativeObj, + ani_string type, ani_long timeout, ani_ref callback); static void RegisterWindowCallback(ani_env* env, ani_object obj, ani_long nativeObj, ani_string type, ani_ref callback); static void UnregisterWindowCallback(ani_env* env, ani_object obj, ani_long nativeObj, ani_string type, ani_ref callback); + static void ShowWindow(ani_env* env, ani_object obj, ani_long nativeObj); + static void DestroyWindow(ani_env* env, ani_object obj, ani_long nativeObj); + static ani_boolean IsWindowShowing(ani_env* env, ani_object obj, ani_long nativeObj); + static void HideWithAnimation(ani_env* env, ani_object obj, ani_long nativeObj); + static void ShowWithAnimation(ani_env* env, ani_object obj, ani_long nativeObj); + static void KeepKeyboardOnFocus(ani_env* env, ani_object obj, ani_long nativeObj, ani_boolean keepKeyboardFlag); + static void Opacity(ani_env* env, ani_object obj, ani_long nativeObj, ani_double opacity); + static void Scale(ani_env* env, ani_object obj, ani_long nativeObj, ani_object scaleOptions); + static void Translate(ani_env* env, ani_object obj, ani_long nativeObj, ani_object translateOptions); + static void Rotate(ani_env* env, ani_object obj, ani_long nativeObj, ani_object rotateOptions); + static void SetShadow(ani_env* env, ani_object obj, ani_long nativeObj, ani_double radius, + ani_string color, ani_object offsetX, ani_object offsetY); + static void Finalizer(ani_env* env, ani_long nativeObj); + + void SetFollowParentWindowLayoutEnabled(ani_env* env, ani_boolean enabled); + void SetWindowDelayRaiseOnDrag(ani_env* env, ani_boolean isEnabled); + ani_ref GetParentWindow(ani_env* env); + ani_boolean GetWindowDecorVisible(ani_env* env); + void StopMoving(ani_env* env); + void SetParentWindow(ani_env* env, ani_double windowId); + void SetWindowTitle(ani_env* env, ani_string titleName); + ani_object GetDecorButtonStyle(ani_env* env); + ani_object GetTitleButtonRect(ani_env* env); + void SetTitleButtonVisible(ani_env* env, ani_object titleButtonVisibleParam); + void SetWindowTitleMoveEnabled(ani_env* env, ani_boolean enabled); + void SetWindowTopmost(ani_env* env, ani_boolean isWindowTopmost); + void SetTitleAndDockHoverShown(ani_env* env, ani_boolean isTitleHoverShown, ani_boolean isDockHoverShown); + void Restore(ani_env* env); + void StartMoving(ani_env* env); + void StartMoveWindowWithCoordinate(ani_env* env, ani_int offsetX, ani_int offsetY); + void SetWindowTitleButtonVisible(ani_env* env, ani_object visibleParam); + void SetDecorButtonStyle(ani_env* env, ani_object decorStyle); + ani_int GetWindowStatus(ani_env* env); + void Minimize(ani_env* env); + void HideWindowFunction(ani_env* env, WmErrorCode errCode); + void Maximize(ani_env* env, ani_int presentation); + + /* + * Window Layout + */ + void Resize(ani_env* env, ani_int width, ani_int height); + void MoveWindowTo(ani_env* env, ani_int x, ani_int y); + ani_object GetGlobalRect(ani_env* env); - ani_double GetWindowDecorHeight(ani_env* env); + ani_int GetWindowDecorHeight(ani_env* env); ani_object SetWindowBackgroundColor(ani_env* env, const std::string& color); ani_object SetImmersiveModeEnabledState(ani_env* env, bool enable); ani_object SetWindowDecorVisible(ani_env* env, bool isVisible); - ani_object SetWindowDecorHeight(ani_env* env, ani_double height); + ani_object SetWindowDecorHeight(ani_env* env, ani_int height); ani_object GetWindowPropertiesSync(ani_env* env); ani_boolean IsWindowSupportWideGamut(ani_env* env); ani_object SetWindowLayoutFullScreen(ani_env* env, ani_boolean isLayoutFullScreen); void SetSystemBarProperties(ani_env* env, ani_object aniSystemBarProperties); ani_object SetSpecificSystemBarEnabled(ani_env* env, ani_string, ani_boolean enable, ani_boolean enableAnimation); + ani_object Snapshot(ani_env* env); + void HideNonSystemFloatingWindows(ani_env* env, ani_boolean shouldHide); private: void OnSetWindowColorSpace(ani_env* env, ani_int colorSpace); void OnSetPreferredOrientation(ani_env* env, ani_int orientation); void OnSetWindowPrivacyMode(ani_env* env, ani_boolean isPrivacyMode); + void OnSetWindowTouchable(ani_env* env, ani_boolean isTouchable); void OnRecover(ani_env* env); 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 OnSetWindowFocusable(ani_env* env, ani_boolean isFocusable); 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); ani_object OnGetWindowAvoidArea(ani_env* env, ani_int type); - void OnRegisterWindowCallback(ani_env* env, ani_string type, ani_ref callback); + void OnRegisterWindowCallback(ani_env* env, ani_string type, ani_ref callback, ani_long timeout); void OnUnregisterWindowCallback(ani_env* env, ani_string type, ani_ref callback); + void OnShowWindow(ani_env* env); + void OnDestroyWindow(ani_env* env); + ani_boolean OnIsWindowShowing(ani_env* env); + void OnHideWithAnimation(ani_env* env); + void OnShowWithAnimation(ani_env* env); + void OnKeepKeyboardOnFocus(ani_env* env, ani_boolean keepKeyboardFlag); + void OnOpacity(ani_env* env, ani_double opacity); + void OnScale(ani_env* env, ani_object scaleOptions); + void OnTranslate(ani_env* env, ani_object translateOptions); + void OnRotate(ani_env* env, ani_object rotateOptions); + void OnSetShadow(ani_env* env, ani_double radius, ani_string color, ani_object offsetX, ani_object offsetY); + static bool ParseScaleOption(ani_env* env, ani_object scaleOptions, Transform& trans); + static bool ParseTranslateOption(ani_env* env, ani_object translateOptions, Transform& trans); + static bool ParseRotateOption(ani_env* env, ani_object rotateOptions, Transform& trans); bool GetSystemBarStatus(std::map& systemBarProperties, std::map& systemBarpropertyFlags, const std::vector& names, sptr& window); @@ -93,11 +162,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 cc8befc89a3e94496a40af471a1879c6daac73bf..1f460261af1f59c9b31aee5217649f04300c64aa 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 @@ -29,33 +29,14 @@ namespace OHOS { namespace Rosen { -const std::string WINDOW_SIZE_CHANGE_CB = "windowSizeChange"; -const std::string SYSTEM_BAR_TINT_CHANGE_CB = "systemBarTintChange"; -const std::string SYSTEM_AVOID_AREA_CHANGE_CB = "systemAvoidAreaChange"; -const std::string AVOID_AREA_CHANGE_CB = "avoidAreaChange"; -const std::string LIFECYCLE_EVENT_CB = "lifeCycleEvent"; -const std::string WINDOW_STAGE_EVENT_CB = "windowStageEvent"; -const std::string WINDOW_EVENT_CB = "windowEvent"; -const std::string KEYBOARD_HEIGHT_CHANGE_CB = "keyboardHeightChange"; -const std::string TOUCH_OUTSIDE_CB = "touchOutside"; -const std::string SCREENSHOT_EVENT_CB = "screenshot"; -const std::string DIALOG_TARGET_TOUCH_CB = "dialogTargetTouch"; -const std::string DIALOG_DEATH_RECIPIENT_CB = "dialogDeathRecipient"; -const std::string GESTURE_NAVIGATION_ENABLED_CHANGE_CB = "gestureNavigationEnabledChange"; -const std::string WATER_MARK_FLAG_CHANGE_CB = "waterMarkFlagChange"; -const std::string WINDOW_VISIBILITY_CHANGE_CB = "windowVisibilityChange"; -const std::string WINDOW_STATUS_CHANGE_CB = "windowStatusChange"; -const std::string WINDOW_TITLE_BUTTON_RECT_CHANGE_CB = "windowTitleButtonRectChange"; -const std::string WINDOW_NO_INTERACTION_DETECT_CB = "noInteractionDetected"; -const std::string WINDOW_RECT_CHANGE_CB = "windowRectChange"; -const std::string SUB_WINDOW_CLOSE_CB = "subWindowClose"; -const std::string WINDOW_STAGE_CLOSE_CB = "windowStageClose"; class AniWindowListener : public IWindowChangeListener, public ISystemBarChangedListener, public IAvoidAreaChangedListener, public IWindowLifeCycle, public IOccupiedAreaChangeListener, + public IKeyboardDidShowListener, + public IKeyboardDidHideListener, public ITouchOutsideListener, public IScreenshotListener, public IDialogTargetTouchListener, @@ -68,12 +49,18 @@ class AniWindowListener : public IWindowChangeListener, public IWindowNoInteractionListener, public IWindowRectChangeListener, public IMainWindowCloseListener, - public ISubWindowCloseListener { + public ISubWindowCloseListener, + public IWindowHighlightChangeListener, + public ISystemDensityChangeListener, + public IDisplayIdChangeListener, + public IWindowRotationChangeListener { public: AniWindowListener(ani_env* env, ani_ref callback, CaseType caseType) - : env_(env), aniCallBack_(callback), caseType_(caseType), + : env_(env), aniCallback_(callback), caseType_(caseType), weakRef_(wptr (this)) {} ~AniWindowListener(); + ani_ref GetAniCallback() const { return aniCallback_; } + void SetAniCallback(ani_ref aniCallback) { aniCallback_ = aniCallback; } void OnSystemBarPropertyChange(DisplayId displayId, const SystemBarRegionTints& tints) override; void OnSizeChange(Rect rect, WindowSizeChangeReason reason, const std::shared_ptr& rsTransaction = nullptr) override; @@ -88,7 +75,9 @@ public: void AfterPaused() override; void AfterDestroyed() override; void OnSizeChange(const sptr& info, - const std::shared_ptr& rsTransaction = nullptr) override; + const std::shared_ptr& rsTransaction = nullptr) override; + void OnKeyboardDidShow(const KeyboardPanelInfo& keyboardPanelInfo) override; + void OnKeyboardDidHide(const KeyboardPanelInfo& keyboardPanelInfo) override; void OnTouchOutside() const override; void OnScreenshot() override; void OnDialogTargetTouch() const override; @@ -97,22 +86,30 @@ public: void OnWaterMarkFlagUpdate(bool showWaterMark) override; void SetMainEventHandler(); void OnWindowVisibilityChangedCallback(const bool isVisible) override; + void OnSystemDensityChanged(float density) override; + void OnDisplayIdChanged(DisplayId displayId) override; void OnWindowStatusChange(WindowStatus status) override; void OnWindowNoInteractionCallback() override; void OnWindowTitleButtonRectChanged(const TitleButtonRect& titleButtonRect) override; void OnRectChange(Rect rect, WindowSizeChangeReason reason) override; void OnSubWindowClose(bool& terminateCloseProcess) override; + void OnWindowHighlightChange(bool isHighlight) override; void OnMainWindowClose(bool& terminateCloseProcess) override; + void SetTimeout(int64_t timeout) override; + int64_t GetTimeout() const override; + void OnRotationChange(const RotationChangeInfo& rotationChangeInfo, + RotationChangeResult& rotationChangeResult) override; private: void OnLastStrongRef(const void *) override; Rect currRect_ = {0, 0, 0, 0}; WindowState state_ {WindowState::STATE_INITIAL}; - void LifeCycleCallBack(LifeCycleEventType eventType); + void LifeCycleCallback(LifeCycleEventType eventType); + int64_t noInteractionTimeout_ = 0; ani_env* env_ = nullptr; - ani_ref aniCallBack_; + ani_ref aniCallback_; CaseType caseType_ = CaseType::CASE_WINDOW; wptr weakRef_ = nullptr; std::shared_ptr eventHandler_ = nullptr; 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..7ac8139371fef7d735209d9ab8b070206c0fa4c9 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 @@ -30,11 +30,31 @@ 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); + explicit AniWindowManager(); + + static ani_status AniWindowManagerInit(ani_env* env); + static ani_object WindowStageCreate(ani_env* env, ani_long scene); + static ani_object GetWindowsByCoordinate(ani_env* env, ani_long nativeObj, ani_object getWindowsParam); + static ani_ref GetLastWindow(ani_env* env, ani_long nativeObj, ani_object context); + static ani_ref FindWindow(ani_env* env, ani_long nativeObj, ani_string windowName); + static ani_ref CreateWindow(ani_env* env, ani_long nativeObj, ani_object configuration); + static void MinimizeAll(ani_env* env, ani_long nativeObj, ani_long displayId); + static void RegisterWindowManagerCallback(ani_env* env, ani_long nativeObj, ani_string type, ani_ref callback); + static void UnregisterWindowManagerCallback(ani_env* env, ani_long nativeObj, ani_string type, ani_ref callback); + static void ShiftAppWindowFocus(ani_env* env, ani_long nativeObj, + ani_int sourceWindowId, ani_int targetWindowId); private: - ani_object OnGetLastWindow(ani_env* env, ani_object context); + ani_object OnGetWindowsByCoordinate(ani_env* env, ani_object getWindowsParam); + ani_ref OnGetLastWindow(ani_env* env, ani_object context); + ani_ref OnFindWindow(ani_env* env, ani_string windowName); + ani_ref OnCreateWindow(ani_env* env, ani_object configuration); + void OnMinimizeAll(ani_env* env, ani_long displayId); + void OnShiftAppWindowFocus(ani_env* env, ani_int sourceWindowId, ani_int targetWindowId); ani_object GetTopWindowTask(ani_env* env, void* contextPtr, bool newApi); + void OnRegisterWindowManagerCallback(ani_env* env, ani_string type, ani_ref callback); + void OnUnregisterWindowManagerCallback(ani_env* env, ani_string type, ani_ref callback); + + std::unique_ptr registerManager_ = nullptr; }; } // namespace Rosen } // namespace OHOS 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 9f9648e7e41e88a9f5f446f91f7255f51fe3bb51..33090b5584441532e49ce5217db1737a494c9f4d 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 @@ -24,38 +24,14 @@ namespace OHOS { namespace Rosen { -enum class RegisterListenerType : uint32_t { - SYSTEM_BAR_TINT_CHANGE_CB, - GESTURE_NAVIGATION_ENABLED_CHANGE_CB, - WATER_MARK_FLAG_CHANGE_CB, - WINDOW_SIZE_CHANGE_CB, - SYSTEM_AVOID_AREA_CHANGE_CB, - AVOID_AREA_CHANGE_CB, - LIFECYCLE_EVENT_CB, - WINDOW_EVENT_CB, - KEYBOARD_HEIGHT_CHANGE_CB, - TOUCH_OUTSIDE_CB, - SCREENSHOT_EVENT_CB, - DIALOG_TARGET_TOUCH_CB, - DIALOG_DEATH_RECIPIENT_CB, - WINDOW_STATUS_CHANGE_CB, - WINDOW_TITLE_BUTTON_RECT_CHANGE_CB, - WINDOW_VISIBILITY_CHANGE_CB, - WINDOW_NO_INTERACTION_DETECT_CB, - WINDOW_RECT_CHANGE_CB, - SUB_WINDOW_CLOSE_CB, - WINDOW_STAGE_EVENT_CB, - WINDOW_STAGE_CLOSE_CB, -}; - class AniWindowRegisterManager { public: AniWindowRegisterManager(); ~AniWindowRegisterManager(); - WmErrorCode RegisterListener(sptr window, std::string type, - CaseType caseType, ani_env* env, ani_ref callback); - WmErrorCode UnregisterListener(sptr window, std::string type, - CaseType caseType, ani_env* env, ani_ref callback); + WmErrorCode RegisterListener(sptr window, const std::string& type, + CaseType caseType, ani_env* env, ani_ref callback, ani_long timeout); + 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); WmErrorCode ProcessWindowChangeRegister(sptr listener, sptr window, bool isRegister, @@ -68,6 +44,10 @@ private: ani_env* env); WmErrorCode ProcessOccupiedAreaChangeRegister(sptr listener, sptr window, bool isRegister, ani_env* env); + WmErrorCode ProcessKeyboardDidShowRegister(sptr listener, sptr window, + bool isRegister, ani_env* env); + WmErrorCode ProcessKeyboardDidHideRegister(sptr listener, sptr window, + bool isRegister, ani_env* env); WmErrorCode ProcessSystemBarChangeRegister(sptr listener, sptr window, bool isRegister, ani_env* env); WmErrorCode ProcessTouchOutsideRegister(sptr listener, sptr window, bool isRegister, @@ -84,8 +64,12 @@ private: sptr window, bool isRegister, ani_env* env); WmErrorCode ProcessWindowVisibilityChangeRegister(sptr listener, sptr window, bool isRegister, ani_env* env); - WmErrorCode ProcessWindowNoInteractionRegister(sptr listener, sptr window, + WmErrorCode ProcessSystemDensityChangeRegister(sptr listener, sptr window, + bool isRegister, ani_env* env); + WmErrorCode ProcessDisplayIdChangeRegister(sptr listener, sptr window, bool isRegister, ani_env* env); + WmErrorCode ProcessWindowNoInteractionRegister(sptr listener, sptr window, + bool isRegister, ani_env* env, ani_long timeout); WmErrorCode ProcessWindowStatusChangeRegister(sptr listener, sptr window, bool isRegister, ani_env* env); WmErrorCode ProcessWindowTitleButtonRectChangeRegister(sptr listener, sptr window, @@ -94,20 +78,15 @@ private: bool isRegister, ani_env* env); WmErrorCode ProcessSubWindowCloseRegister(sptr listener, sptr window, bool isRegister, ani_env* env); + WmErrorCode ProcessWindowHighlightChangeRegister(sptr listener, sptr window, + bool isRegister, ani_env* env); WmErrorCode ProcessMainWindowCloseRegister(const sptr& listener, const sptr& window, bool isRegister, ani_env* env); - WmErrorCode ProcessWindowStageListener(RegisterListenerType registerListenerType, - const sptr& windowManagerListener, const sptr& window, bool isRegister, - ani_env* env); - WmErrorCode ProcessWindowListener(RegisterListenerType registerListenerType, - const sptr& windowManagerListener, const sptr& window, bool isRegister, - ani_env* env); - WmErrorCode ProcessWindowManagerListener(RegisterListenerType registerListenerType, - const sptr& windowManagerListener, const sptr& window, bool isRegister, - ani_env* env); + WmErrorCode ProcessWindowRotationChangeRegister(const sptr& listener, const sptr& window, + bool isRegister, ani_env* env); WmErrorCode ProcessListener(RegisterListenerType registerListenerType, CaseType caseType, const sptr& windowManagerListener, const sptr& window, bool isRegister, - ani_env* env); + ani_env* env, ani_long timeout); std::map>> jsCbMap_; std::mutex mtx_; }; 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..6edf8f9cbae23338961c71ea2ef2e2d6ab51d8e9 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 @@ -17,6 +17,7 @@ #define OHOS_ANI_WINDOW_STAGE_H #include "ani.h" +#include "ani_window_register_manager.h" #include "window_scene.h" namespace OHOS { @@ -31,17 +32,32 @@ class AniWindowStage { public: explicit AniWindowStage(const std::shared_ptr& windowScene); ~AniWindowStage(); + static ani_object NativeTransferStatic(ani_env* aniEnv, ani_class cls, ani_object input); + static ani_object NativeTransferDynamic(ani_env* aniEnv, ani_class cls, ani_long nativeObj); + 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); + static void RegisterWindowCallback(ani_env* env, ani_object obj, ani_long nativeObj, ani_string type, + ani_ref callback); + static void UnregisterWindowCallback(ani_env* env, ani_object obj, ani_long nativeObj, ani_string type, + ani_ref callback); - void LoadContent(ani_env* env, const std::string& content); + void SetWindowRectAutoSave(ani_env* env, ani_boolean enabled, ani_boolean isSaveBySpecifiedFlag); + ani_boolean IsWindowRectAutoSave(ani_env* env); + void RemoveStartingWindow(ani_env* env); 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); + ani_ref OnCreateSubWindow(ani_env *env, ani_string name); 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); + void OnRegisterWindowCallback(ani_env* env, ani_string type, ani_ref callback); + void OnUnregisterWindowCallback(ani_env* env, ani_string type, ani_ref callback); std::weak_ptr windowScene_; + std::unique_ptr registerManager_ = nullptr; }; ani_object CreateAniWindowStage(ani_env* env, std::shared_ptr& windowScene); diff --git a/interfaces/kits/ani/window_runtime/window_stage_ani/include/ani_window_utils.h b/interfaces/kits/ani/window_runtime/window_stage_ani/include/ani_window_utils.h index 5c80902662cb955a944746207aed176ea74c155d..8c6dec6e19373892a35263c5ce4526a2ff7c13f2 100644 --- a/interfaces/kits/ani/window_runtime/window_stage_ani/include/ani_window_utils.h +++ b/interfaces/kits/ani/window_runtime/window_stage_ani/include/ani_window_utils.h @@ -13,10 +13,11 @@ * limitations under the License. */ -#ifndef OHOS_JS_WINDOW_UTILS_H -#define OHOS_JS_WINDOW_UTILS_H +#ifndef OHOS_ANI_WINDOW_UTILS_H +#define OHOS_ANI_WINDOW_UTILS_H #include #include "ani.h" +#include "js_window.h" #include "native_engine/native_engine.h" #include "native_engine/native_value.h" #include "window.h" @@ -33,243 +34,37 @@ namespace OHOS { namespace Rosen { -constexpr int32_t RGB_LENGTH = 6; -constexpr int32_t RGBA_LENGTH = 8; constexpr Rect g_emptyRect = {0, 0, 0, 0}; - -enum class ApiWindowType : uint32_t { - TYPE_BASE, - TYPE_APP = TYPE_BASE, - TYPE_SYSTEM_ALERT, - TYPE_INPUT_METHOD, - TYPE_STATUS_BAR, - TYPE_PANEL, - TYPE_KEYGUARD, - TYPE_VOLUME_OVERLAY, - TYPE_NAVIGATION_BAR, - TYPE_FLOAT, - TYPE_WALLPAPER, - TYPE_DESKTOP, - TYPE_LAUNCHER_RECENT, - TYPE_LAUNCHER_DOCK, - TYPE_VOICE_INTERACTION, - TYPE_POINTER, - TYPE_FLOAT_CAMERA, - TYPE_DIALOG, - TYPE_SCREENSHOT, - TYPE_SYSTEM_TOAST, - TYPE_DIVIDER, - TYPE_GLOBAL_SEARCH, - TYPE_HANDWRITE, - TYPE_END -}; - -enum class LifeCycleEventType : uint32_t { - FOREGROUND = 1, - ACTIVE, - INACTIVE, - BACKGROUND, - RESUMED, - PAUSED, - DESTROYED, -}; - -const std::map NATIVE_JS_TO_WINDOW_TYPE_MAP { - { WindowType::WINDOW_TYPE_APP_SUB_WINDOW, ApiWindowType::TYPE_APP }, - { WindowType::WINDOW_TYPE_DIALOG, ApiWindowType::TYPE_DIALOG }, - { WindowType::WINDOW_TYPE_SYSTEM_ALARM_WINDOW, ApiWindowType::TYPE_SYSTEM_ALERT }, - { WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT, ApiWindowType::TYPE_INPUT_METHOD }, - { WindowType::WINDOW_TYPE_STATUS_BAR, ApiWindowType::TYPE_STATUS_BAR }, - { WindowType::WINDOW_TYPE_PANEL, ApiWindowType::TYPE_PANEL }, - { WindowType::WINDOW_TYPE_KEYGUARD, ApiWindowType::TYPE_KEYGUARD }, - { WindowType::WINDOW_TYPE_VOLUME_OVERLAY, ApiWindowType::TYPE_VOLUME_OVERLAY }, - { WindowType::WINDOW_TYPE_NAVIGATION_BAR, ApiWindowType::TYPE_NAVIGATION_BAR }, - { WindowType::WINDOW_TYPE_FLOAT, ApiWindowType::TYPE_FLOAT }, - { WindowType::WINDOW_TYPE_FLOAT_CAMERA, ApiWindowType::TYPE_FLOAT_CAMERA }, - { WindowType::WINDOW_TYPE_WALLPAPER, ApiWindowType::TYPE_WALLPAPER }, - { WindowType::WINDOW_TYPE_DESKTOP, ApiWindowType::TYPE_DESKTOP }, - { WindowType::WINDOW_TYPE_LAUNCHER_RECENT, ApiWindowType::TYPE_LAUNCHER_RECENT }, - { WindowType::WINDOW_TYPE_LAUNCHER_DOCK, ApiWindowType::TYPE_LAUNCHER_DOCK }, - { WindowType::WINDOW_TYPE_VOICE_INTERACTION, ApiWindowType::TYPE_VOICE_INTERACTION }, - { WindowType::WINDOW_TYPE_POINTER, ApiWindowType::TYPE_POINTER }, - { WindowType::WINDOW_TYPE_SCREENSHOT, ApiWindowType::TYPE_SCREENSHOT }, - { WindowType::WINDOW_TYPE_SYSTEM_TOAST, ApiWindowType::TYPE_SYSTEM_TOAST }, - { WindowType::WINDOW_TYPE_DOCK_SLICE, ApiWindowType::TYPE_DIVIDER }, - { WindowType::WINDOW_TYPE_GLOBAL_SEARCH, ApiWindowType::TYPE_GLOBAL_SEARCH }, - { WindowType::WINDOW_TYPE_HANDWRITE, ApiWindowType::TYPE_HANDWRITE }, -}; - -const std::map JS_TO_NATIVE_WINDOW_TYPE_MAP { - { ApiWindowType::TYPE_APP, WindowType::WINDOW_TYPE_APP_SUB_WINDOW }, - { ApiWindowType::TYPE_DIALOG, WindowType::WINDOW_TYPE_DIALOG }, - { ApiWindowType::TYPE_SYSTEM_ALERT, WindowType::WINDOW_TYPE_SYSTEM_ALARM_WINDOW }, - { ApiWindowType::TYPE_INPUT_METHOD, WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT }, - { ApiWindowType::TYPE_STATUS_BAR, WindowType::WINDOW_TYPE_STATUS_BAR }, - { ApiWindowType::TYPE_PANEL, WindowType::WINDOW_TYPE_PANEL }, - { ApiWindowType::TYPE_KEYGUARD, WindowType::WINDOW_TYPE_KEYGUARD }, - { ApiWindowType::TYPE_VOLUME_OVERLAY, WindowType::WINDOW_TYPE_VOLUME_OVERLAY }, - { ApiWindowType::TYPE_NAVIGATION_BAR, WindowType::WINDOW_TYPE_NAVIGATION_BAR }, - { ApiWindowType::TYPE_FLOAT, WindowType::WINDOW_TYPE_FLOAT }, - { ApiWindowType::TYPE_FLOAT_CAMERA, WindowType::WINDOW_TYPE_FLOAT_CAMERA }, - { ApiWindowType::TYPE_WALLPAPER, WindowType::WINDOW_TYPE_WALLPAPER }, - { ApiWindowType::TYPE_DESKTOP, WindowType::WINDOW_TYPE_DESKTOP }, - { ApiWindowType::TYPE_LAUNCHER_RECENT, WindowType::WINDOW_TYPE_LAUNCHER_RECENT }, - { ApiWindowType::TYPE_LAUNCHER_DOCK, WindowType::WINDOW_TYPE_LAUNCHER_DOCK }, - { ApiWindowType::TYPE_VOICE_INTERACTION, WindowType::WINDOW_TYPE_VOICE_INTERACTION }, - { ApiWindowType::TYPE_POINTER, WindowType::WINDOW_TYPE_POINTER }, - { ApiWindowType::TYPE_SCREENSHOT, WindowType::WINDOW_TYPE_SCREENSHOT }, - { ApiWindowType::TYPE_SYSTEM_TOAST, WindowType::WINDOW_TYPE_SYSTEM_TOAST }, - { ApiWindowType::TYPE_DIVIDER, WindowType::WINDOW_TYPE_DOCK_SLICE }, - { ApiWindowType::TYPE_GLOBAL_SEARCH, WindowType::WINDOW_TYPE_GLOBAL_SEARCH }, - { ApiWindowType::TYPE_HANDWRITE, WindowType::WINDOW_TYPE_HANDWRITE }, -}; - -enum class ApiWindowMode : uint32_t { - UNDEFINED = 1, - FULLSCREEN, - PRIMARY, - SECONDARY, - FLOATING, - MODE_END = FLOATING -}; - -const std::map NATIVE_TO_JS_WINDOW_MODE_MAP { - { WindowMode::WINDOW_MODE_UNDEFINED, ApiWindowMode::UNDEFINED }, - { WindowMode::WINDOW_MODE_FULLSCREEN, ApiWindowMode::FULLSCREEN }, - { WindowMode::WINDOW_MODE_SPLIT_PRIMARY, ApiWindowMode::PRIMARY }, - { WindowMode::WINDOW_MODE_SPLIT_SECONDARY, ApiWindowMode::SECONDARY }, - { WindowMode::WINDOW_MODE_FLOATING, ApiWindowMode::FLOATING }, -}; - -const std::map JS_TO_NATIVE_WINDOW_MODE_MAP { - {ApiWindowMode::UNDEFINED, WindowMode::WINDOW_MODE_UNDEFINED }, - {ApiWindowMode::FULLSCREEN, WindowMode::WINDOW_MODE_FULLSCREEN }, - {ApiWindowMode::PRIMARY, WindowMode::WINDOW_MODE_SPLIT_PRIMARY }, - {ApiWindowMode::SECONDARY, WindowMode::WINDOW_MODE_SPLIT_SECONDARY }, - {ApiWindowMode::FLOATING, WindowMode::WINDOW_MODE_FLOATING }, -}; - -enum class ApiOrientation : uint32_t { - BEGIN = 0, - UNSPECIFIED = BEGIN, - PORTRAIT = 1, - LANDSCAPE = 2, - PORTRAIT_INVERTED = 3, - LANDSCAPE_INVERTED = 4, - AUTO_ROTATION = 5, - AUTO_ROTATION_PORTRAIT = 6, - AUTO_ROTATION_LANDSCAPE = 7, - AUTO_ROTATION_RESTRICTED = 8, - AUTO_ROTATION_PORTRAIT_RESTRICTED = 9, - AUTO_ROTATION_LANDSCAPE_RESTRICTED = 10, - LOCKED = 11, - AUTO_ROTATION_UNSPECIFIED = 12, - USER_ROTATION_PORTRAIT = 13, - USER_ROTATION_LANDSCAPE = 14, - USER_ROTATION_PORTRAIT_INVERTED = 15, - USER_ROTATION_LANDSCAPE_INVERTED = 16, - FOLLOW_DESKTOP = 17, - END = FOLLOW_DESKTOP, -}; - -const std::map JS_TO_NATIVE_ORIENTATION_MAP { - {ApiOrientation::UNSPECIFIED, Orientation::UNSPECIFIED }, - {ApiOrientation::PORTRAIT, Orientation::VERTICAL }, - {ApiOrientation::LANDSCAPE, Orientation::HORIZONTAL }, - {ApiOrientation::PORTRAIT_INVERTED, Orientation::REVERSE_VERTICAL }, - {ApiOrientation::LANDSCAPE_INVERTED, Orientation::REVERSE_HORIZONTAL }, - {ApiOrientation::AUTO_ROTATION, Orientation::SENSOR }, - {ApiOrientation::AUTO_ROTATION_PORTRAIT, Orientation::SENSOR_VERTICAL }, - {ApiOrientation::AUTO_ROTATION_LANDSCAPE, Orientation::SENSOR_HORIZONTAL }, - {ApiOrientation::AUTO_ROTATION_RESTRICTED, Orientation::AUTO_ROTATION_RESTRICTED }, - {ApiOrientation::AUTO_ROTATION_PORTRAIT_RESTRICTED, Orientation::AUTO_ROTATION_PORTRAIT_RESTRICTED }, - {ApiOrientation::AUTO_ROTATION_LANDSCAPE_RESTRICTED, Orientation::AUTO_ROTATION_LANDSCAPE_RESTRICTED }, - {ApiOrientation::LOCKED, Orientation::LOCKED }, - {ApiOrientation::AUTO_ROTATION_UNSPECIFIED, Orientation::AUTO_ROTATION_UNSPECIFIED }, - {ApiOrientation::USER_ROTATION_PORTRAIT, Orientation::USER_ROTATION_PORTRAIT }, - {ApiOrientation::USER_ROTATION_LANDSCAPE, Orientation::USER_ROTATION_LANDSCAPE }, - {ApiOrientation::USER_ROTATION_PORTRAIT_INVERTED, Orientation::USER_ROTATION_PORTRAIT_INVERTED }, - {ApiOrientation::USER_ROTATION_LANDSCAPE_INVERTED, Orientation::USER_ROTATION_LANDSCAPE_INVERTED }, - {ApiOrientation::FOLLOW_DESKTOP, Orientation::FOLLOW_DESKTOP }, -}; - -const std::map NATIVE_TO_JS_ORIENTATION_MAP { - {Orientation::UNSPECIFIED, ApiOrientation::UNSPECIFIED }, - {Orientation::VERTICAL, ApiOrientation::PORTRAIT }, - {Orientation::HORIZONTAL, ApiOrientation::LANDSCAPE }, - {Orientation::REVERSE_VERTICAL, ApiOrientation::PORTRAIT_INVERTED }, - {Orientation::REVERSE_HORIZONTAL, ApiOrientation::LANDSCAPE_INVERTED }, - {Orientation::SENSOR, ApiOrientation::AUTO_ROTATION }, - {Orientation::SENSOR_VERTICAL, ApiOrientation::AUTO_ROTATION_PORTRAIT }, - {Orientation::SENSOR_HORIZONTAL, ApiOrientation::AUTO_ROTATION_LANDSCAPE }, - {Orientation::AUTO_ROTATION_RESTRICTED, ApiOrientation::AUTO_ROTATION_RESTRICTED }, - {Orientation::AUTO_ROTATION_PORTRAIT_RESTRICTED, ApiOrientation::AUTO_ROTATION_PORTRAIT_RESTRICTED }, - {Orientation::AUTO_ROTATION_LANDSCAPE_RESTRICTED, ApiOrientation::AUTO_ROTATION_LANDSCAPE_RESTRICTED }, - {Orientation::LOCKED, ApiOrientation::LOCKED }, - {Orientation::FOLLOW_RECENT, ApiOrientation::UNSPECIFIED }, - {Orientation::AUTO_ROTATION_UNSPECIFIED, ApiOrientation::AUTO_ROTATION_UNSPECIFIED }, - {Orientation::USER_ROTATION_PORTRAIT, ApiOrientation::USER_ROTATION_PORTRAIT }, - {Orientation::USER_ROTATION_LANDSCAPE, ApiOrientation::USER_ROTATION_LANDSCAPE }, - {Orientation::USER_ROTATION_PORTRAIT_INVERTED, ApiOrientation::USER_ROTATION_PORTRAIT_INVERTED }, - {Orientation::USER_ROTATION_LANDSCAPE_INVERTED, ApiOrientation::USER_ROTATION_LANDSCAPE_INVERTED }, - {Orientation::FOLLOW_DESKTOP, ApiOrientation::FOLLOW_DESKTOP }, -}; - -enum class RectChangeReason : uint32_t { - UNDEFINED = 0, - MAXIMIZE, - RECOVER, - MOVE, - DRAG, - DRAG_START, - DRAG_END, -}; - -const std::map JS_SIZE_CHANGE_REASON { - { WindowSizeChangeReason::UNDEFINED, RectChangeReason::UNDEFINED }, - { WindowSizeChangeReason::MAXIMIZE, RectChangeReason::MAXIMIZE }, - { WindowSizeChangeReason::RECOVER, RectChangeReason::RECOVER }, - { WindowSizeChangeReason::ROTATION, RectChangeReason::UNDEFINED }, - { WindowSizeChangeReason::DRAG, RectChangeReason::DRAG }, - { WindowSizeChangeReason::DRAG_START, RectChangeReason::DRAG_START }, - { WindowSizeChangeReason::DRAG_END, RectChangeReason::DRAG_END }, - { WindowSizeChangeReason::RESIZE, RectChangeReason::UNDEFINED }, - { WindowSizeChangeReason::MOVE, RectChangeReason::MOVE }, - { WindowSizeChangeReason::HIDE, RectChangeReason::UNDEFINED }, - { WindowSizeChangeReason::TRANSFORM, RectChangeReason::UNDEFINED }, - { WindowSizeChangeReason::CUSTOM_ANIMATION_SHOW, RectChangeReason::UNDEFINED }, - { WindowSizeChangeReason::FULL_TO_SPLIT, RectChangeReason::UNDEFINED }, - { WindowSizeChangeReason::SPLIT_TO_FULL, RectChangeReason::UNDEFINED }, - { WindowSizeChangeReason::FULL_TO_FLOATING, RectChangeReason::UNDEFINED }, - { WindowSizeChangeReason::FLOATING_TO_FULL, RectChangeReason::UNDEFINED }, - { WindowSizeChangeReason::END, RectChangeReason::UNDEFINED }, -}; - -enum class ApiModalityType : uint32_t { - BEGIN = 0, - WINDOW_MODALITY = BEGIN, - APPLICATION_MODALITY, - END = APPLICATION_MODALITY, -}; - -inline const std::map JS_TO_NATIVE_MODALITY_TYPE_MAP { - { ApiModalityType::WINDOW_MODALITY, ModalityType::WINDOW_MODALITY }, - { ApiModalityType::APPLICATION_MODALITY, ModalityType::APPLICATION_MODALITY }, -}; - class AniWindowUtils { public: static ani_status GetStdString(ani_env* env, ani_string ani_str, std::string& result); static ani_status GetStdStringVector(ani_env* env, ani_object ary, std::vector& result); + static ani_status GetPropertyIntObject(ani_env* env, const char* propertyName, ani_object object, int32_t& result); + static ani_status GetPropertyDoubleObject(ani_env* env, const char* propertyName, + ani_object object, double& result); + static bool GetPropertyRectObject(ani_env* env, const char* propertyName, + ani_object object, Rect& result); + static bool GetIntObject(ani_env* env, const char* propertyName, ani_object object, int32_t& result); + static ani_status GetDoubleObject(ani_env* env, ani_object double_object, double& result); static ani_status NewAniObjectNoParams(ani_env* env, const char* cls, ani_object* object); static ani_status NewAniObject(ani_env* env, const char* cls, const char* signature, ani_object* result, ...); static ani_object CreateAniUndefined(ani_env* env); static ani_object AniThrowError(ani_env* env, WMError errorCode, std::string msg = ""); static ani_object AniThrowError(ani_env* env, WmErrorCode errorCode, std::string msg = ""); + static ani_object CreateAniDecorButtonStyle(ani_env* env, const DecorButtonStyle& decorButtonStyle); + static ani_object CreateAniTitleButtonRect(ani_env* env, const TitleButtonRect& titleButtonRect); + static ani_object CreateAniWindowArray(ani_env* env, std::vector& windows); static ani_object CreateAniSize(ani_env* env, int32_t width, int32_t height); static ani_object CreateAniRect(ani_env* env, const Rect& rect); static ani_object CreateAniAvoidArea(ani_env* env, const AvoidArea& avoidArea, AvoidAreaType type); + static ani_object CreateAniKeyboardInfo(ani_env* env, const KeyboardPanelInfo& keyboardPanelInfo); + static ani_object CreateAniSystemBarTintState(ani_env* env, DisplayId displayId, const SystemBarRegionTints& tints); + static ani_object CreateAniSystemBarRegionTint(ani_env* env, const SystemBarRegionTint& tint); + static ani_object CreateAniRotationChangeInfo(ani_env* env, const RotationChangeInfo& info); + static void ParseRotationChangeResult(ani_env* env, ani_object obj, RotationChangeResult& rotationChangeResult); static ani_status CallAniFunctionVoid(ani_env *env, const char* ns, const char* func, const char* signature, ...); + static ani_status CallAniFunctionRef(ani_env *env, ani_ref& result, ani_ref ani_callback, + const int32_t args_num, ...); static ani_status CallAniMethodVoid(ani_env* env, ani_object object, const char* cls, const char* method, const char* signature, ...); static ani_status CallAniMethodVoid(ani_env* env, ani_object object, ani_class cls, @@ -291,6 +86,8 @@ public: std::map& windowPropertyFlags, const ani_object& aniProperties, const sptr& window); + static bool SetDecorButtonStyleFromAni(ani_env* env, DecorButtonStyle& decorButtonStyle, + const ani_object& decorStyle); static void GetSystemBarPropertiesFromAni(sptr& window, std::map& newProperties, std::map& newPropertyFlags, @@ -307,6 +104,17 @@ public: std::map& newSystemBarProperties, std::map& systemBarProperties); + /** + * @brief Convert a WMError to its corresponding WmErrorCode. + * + * If the WMError is not found in the mapping, returns the given default code. + * + * @param error WMError value to convert. + * @param defaultCode Value to return if mapping is not found (default: WM_ERROR_STATE_ABNORMALLY). + * @return Corresponding WmErrorCode or defaultCode if unmapped. + */ + static WmErrorCode ToErrorCode(WMError error, WmErrorCode defaultCode = WmErrorCode::WM_ERROR_STATE_ABNORMALLY); + private: static void SetSystemPropertiesWindowRect(ani_env* env, const sptr& window, ani_object& systemProperties, const char* clsName); @@ -330,13 +138,15 @@ private: ani_object& systemProperties, const char* clsName); static void SetSystemPropertiesWindowIsTransparent(ani_env* env, const sptr& window, ani_object& systemProperties, const char* clsName); - static void SetSystemPropertieswindowIsRoundCorner(ani_env* env, const sptr& window, + static void SetSystemPropertiesWindowIsRoundCorner(ani_env* env, const sptr& window, ani_object& systemProperties, const char* clsName); static void SetSystemPropertiesWindowDimBehindValue(ani_env* env, const sptr& window, ani_object& systemProperties, const char* clsName); - static void SetSystemPropertieswindowId(ani_env* env, const sptr& window, + static void SetSystemPropertiesWindowId(ani_env* env, const sptr& window, + ani_object& systemProperties, const char* clsName); + static void SetSystemPropertiesDisplayId(ani_env* env, const sptr& window, ani_object& systemProperties, const char* clsName); - static void SetSystemPropertiesdisplayId(ani_env* env, const sptr& window, + static void SetSystemPropertiesWindowName(ani_env* env, const sptr& window, ani_object& systemProperties, const char* clsName); }; } diff --git a/interfaces/kits/ani/window_runtime/window_stage_ani/include/idl_window_common.h b/interfaces/kits/ani/window_runtime/window_stage_ani/include/idl_window_common.h index 2ceb7cebbd4d6c8ea61f7e9ed0839965efab6f0f..394a95487e87facb4c8707f33160156083d5eb66 100644 --- a/interfaces/kits/ani/window_runtime/window_stage_ani/include/idl_window_common.h +++ b/interfaces/kits/ani/window_runtime/window_stage_ani/include/idl_window_common.h @@ -16,6 +16,7 @@ #ifndef OHOS_IDL_WINDOW_COMMOH_H #define OHOS_IDL_WINDOW_COMMOH_H +#include "../generated/native/window.h" #include "window.h" class IdlWindowCommon { 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 e30755d2d046a792cc8eb4e9bbbeed3d8b9fdd2f..945f76da8d48082725cbfb3d1526e2de210e4e7f 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 @@ -214,38 +214,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("@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, "", "C{std.core.String}C{escompat.ErrorOptions}:", &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_Int(*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 d0e39bc03927e3926456c060883aea60a3b4f58b..308f3fb9c44ce15805dbeead82ddf1bce5f79cf8 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 @@ -18,15 +18,24 @@ #include #include +#include #include "ani.h" #include "ani_err_utils.h" #include "ani_window_utils.h" +#include "interop_js/arkts_esvalue.h" +#include "interop_js/arkts_interop_js_api.h" +#include "interop_js/hybridgref_ani.h" +#include "interop_js/hybridgref_napi.h" +#include "permission.h" +#include "pixel_map.h" +#include "pixel_map_taihe_ani.h" #include "window_helper.h" #include "window_scene.h" #include "window_manager.h" #include "window_manager_hilog.h" #include "wm_common.h" +#include "wm_math.h" using OHOS::Rosen::WindowScene; @@ -36,8 +45,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()) @@ -48,7 +58,7 @@ AniWindow* AniWindow::GetWindowObjectFromEnv(ani_env* env, ani_object obj) { ani_class cls = nullptr; ani_status ret; - if ((ret = env->FindClass("L@ohos/window/window/Window;", &cls)) != ANI_OK) { + if ((ret = env->FindClass("@ohos.window.window.Window", &cls)) != ANI_OK) { TLOGE(WmsLogTag::DEFAULT, "[ANI]null env %{public}u", ret); return nullptr; } @@ -65,14 +75,77 @@ AniWindow* AniWindow::GetWindowObjectFromEnv(ani_env* env, ani_object obj) return reinterpret_cast(nativeObj); } +ani_object AniWindow::NativeTransferStatic(ani_env* aniEnv, ani_class cls, ani_object input) +{ + TLOGI(WmsLogTag::DEFAULT, "[ANI]"); + void *unwrapResult = nullptr; + if (!arkts_esvalue_unwrap(aniEnv, input, &unwrapResult)) { + TLOGE(WmsLogTag::DEFAULT, "[ANI] fail to unwrap input"); + return AniWindowUtils::CreateAniUndefined(aniEnv); + } + if (unwrapResult == nullptr) { + TLOGE(WmsLogTag::DEFAULT, "[ANI] unwrapResult is nullptr"); + return AniWindowUtils::CreateAniUndefined(aniEnv); + } + JsWindow* jsWindow = static_cast(unwrapResult); + sptr windowToken = jsWindow->GetWindow(); + ani_ref aniWindowObj = CreateAniWindowObject(aniEnv, windowToken); + if (aniWindowObj == nullptr) { + TLOGE(WmsLogTag::DEFAULT, "[ANI] ani window object is nullptr"); + return AniWindowUtils::CreateAniUndefined(aniEnv); + } + return static_cast(aniWindowObj); +} + +ani_object AniWindow::NativeTransferDynamic(ani_env* aniEnv, ani_class cls, ani_long nativeObj) +{ + TLOGI(WmsLogTag::DEFAULT, "[ANI]"); + AniWindow* aniWindow = reinterpret_cast(nativeObj); + if (aniWindow == nullptr) { + TLOGE(WmsLogTag::DEFAULT, "[ANI] aniWindow is nullptr"); + return AniWindowUtils::CreateAniUndefined(aniEnv); + } + napi_env napiEnv {}; + if (!arkts_napi_scope_open(aniEnv, &napiEnv)) { + TLOGE(WmsLogTag::DEFAULT, "[ANI] napi scope open fail"); + return AniWindowUtils::CreateAniUndefined(aniEnv); + } + sptr windowToken = aniWindow->GetWindow(); + napi_value jsWindow = CreateJsWindowObject(napiEnv, windowToken); + hybridgref ref {}; + if (!hybridgref_create_from_napi(napiEnv, jsWindow, &ref)) { + TLOGE(WmsLogTag::DEFAULT, "[ANI] create hybridgref fail"); + arkts_napi_scope_close_n(napiEnv, 0, nullptr, nullptr); + return AniWindowUtils::CreateAniUndefined(aniEnv); + } + ani_object result {}; + if (!hybridgref_get_esvalue(aniEnv, ref, &result)) { + TLOGE(WmsLogTag::DEFAULT, "[ANI] get esvalue fail"); + hybridgref_delete_from_napi(napiEnv, ref); + arkts_napi_scope_close_n(napiEnv, 0, nullptr, nullptr); + return AniWindowUtils::CreateAniUndefined(aniEnv); + } + if (!hybridgref_delete_from_napi(napiEnv, ref)) { + arkts_napi_scope_close_n(napiEnv, 0, nullptr, nullptr); + TLOGE(WmsLogTag::DEFAULT, "[ANI] delete hybridgref fail"); + return AniWindowUtils::CreateAniUndefined(aniEnv); + } + if (!arkts_napi_scope_close_n(napiEnv, 0, nullptr, nullptr)) { + TLOGE(WmsLogTag::DEFAULT, "[ANI] napi close scope fail"); + return AniWindowUtils::CreateAniUndefined(aniEnv); + } + return result; +} + void AniWindow::SetWindowColorSpace(ani_env* env, ani_object obj, ani_long nativeObj, ani_int colorSpace) { - TLOGI(WmsLogTag::DEFAULT, "[ANI] colorSpace:%{public}d", static_cast(colorSpace)); + TLOGI(WmsLogTag::WMS_ATTRIBUTE, "[ANI] colorSpace:%{public}d", static_cast(colorSpace)); AniWindow* aniWindow = reinterpret_cast(nativeObj); if (aniWindow != nullptr) { aniWindow->OnSetWindowColorSpace(env, colorSpace); } else { - TLOGE(WmsLogTag::DEFAULT, "[ANI] aniWindow is nullptr"); + TLOGE(WmsLogTag::WMS_ATTRIBUTE, "[ANI] aniWindow is nullptr"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); } } @@ -80,66 +153,465 @@ void AniWindow::OnSetWindowColorSpace(ani_env* env, ani_int colorSpace) { if (static_cast(colorSpace) > static_cast(ColorSpace::COLOR_SPACE_WIDE_GAMUT) || static_cast(colorSpace) < static_cast(ColorSpace::COLOR_SPACE_DEFAULT)) { - TLOGE(WmsLogTag::DEFAULT, "ColorSpace %{public}u invalid!", static_cast(colorSpace)); + TLOGE(WmsLogTag::WMS_ATTRIBUTE, "ColorSpace %{public}u invalid!", static_cast(colorSpace)); AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_INVALID_PARAM); return; } - TLOGI(WmsLogTag::DEFAULT, "[ANI] colorSpace:%{public}d", static_cast(colorSpace)); + TLOGI(WmsLogTag::WMS_ATTRIBUTE, "[ANI] colorSpace:%{public}d", static_cast(colorSpace)); auto window = GetWindow(); if (window == nullptr) { - TLOGE(WmsLogTag::DEFAULT, "[ANI]window is nullptr"); + TLOGE(WmsLogTag::WMS_ATTRIBUTE, "[ANI]window is nullptr"); AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); return; } window->SetColorSpace(static_cast(colorSpace)); - TLOGI(WmsLogTag::DEFAULT, "[ANI] SetWindowColorSpace end"); + TLOGI(WmsLogTag::WMS_ATTRIBUTE, "[ANI] SetWindowColorSpace end"); } void AniWindow::SetPreferredOrientation(ani_env* env, ani_object obj, ani_long nativeObj, ani_int orientation) { - TLOGI(WmsLogTag::DEFAULT, "[ANI] orientation:%{public}d", static_cast(orientation)); + TLOGI(WmsLogTag::WMS_ROTATION, "[ANI] orientation:%{public}d", static_cast(orientation)); AniWindow* aniWindow = reinterpret_cast(nativeObj); if (aniWindow != nullptr) { aniWindow->OnSetPreferredOrientation(env, orientation); } else { - TLOGE(WmsLogTag::DEFAULT, "[ANI] aniWindow is nullptr"); + TLOGE(WmsLogTag::WMS_ROTATION, "[ANI] aniWindow is nullptr"); } } void AniWindow::OnSetPreferredOrientation(ani_env* env, ani_int orientation) { - TLOGI(WmsLogTag::DEFAULT, "[ANI] orientation:%{public}d", static_cast(orientation)); + int32_t orientationValue = static_cast(orientation); + TLOGI(WmsLogTag::WMS_ROTATION, "[ANI] orientation:%{public}d", orientationValue); + WmErrorCode errCode = WmErrorCode::WM_OK; + Orientation requestedOrientation = Orientation::UNSPECIFIED; auto window = GetWindow(); if (window == nullptr) { - TLOGE(WmsLogTag::DEFAULT, "[ANI] window is nullptr"); + TLOGE(WmsLogTag::WMS_ROTATION, "[ANI] window is nullptr"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); + return; + } + + auto apiOrientation = static_cast(orientationValue); + if (apiOrientation < ApiOrientation::BEGIN || apiOrientation > ApiOrientation::END) { + TLOGE(WmsLogTag::WMS_ROTATION, "[ANI] Orientation %{public}u invalid!", + static_cast(apiOrientation)); + errCode = WmErrorCode::WM_ERROR_INVALID_PARAM; + } else { + requestedOrientation = JS_TO_NATIVE_ORIENTATION_MAP.at(apiOrientation); + } + window->SetRequestedOrientation(requestedOrientation); + window->NotifyPreferredOrientationChange(requestedOrientation); + TLOGNI(WmsLogTag::WMS_ROTATION, + "[ANI] SetPreferredOrientation end, window [%{public}u, %{public}s] orientation=%{public}u", + window->GetWindowId(), window->GetWindowName().c_str(), orientationValue); +} + +void AniWindow::Opacity(ani_env* env, ani_object obj, ani_long nativeObj, ani_double opacity) +{ + TLOGI(WmsLogTag::WMS_ANIMATION, "[ANI] opacity: %{public}f", static_cast(opacity)); + AniWindow* aniWindow = reinterpret_cast(nativeObj); + if (aniWindow != nullptr) { + aniWindow->OnOpacity(env, opacity); + } else { + TLOGE(WmsLogTag::WMS_ANIMATION, "[ANI] aniWindow is nullptr"); + } +} + +void AniWindow::OnOpacity(ani_env* env, ani_double opacity) +{ + TLOGI(WmsLogTag::WMS_ANIMATION, "[ANI] OnOpacity in"); + auto window = GetWindow(); + if (window == nullptr) { + TLOGE(WmsLogTag::WMS_ANIMATION, "[ANI] window is nullptr"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); + return; + } + + if (!WindowHelper::IsSystemWindow(windowToken_->GetType())) { + TLOGE(WmsLogTag::WMS_ANIMATION, "[ANI] Opacity is not allowed since window is not system window"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_INVALID_CALLING); + return; + } + + if (MathHelper::LessNotEqual(static_cast(opacity), 0.0) || + MathHelper::GreatNotEqual(static_cast(opacity), 1.0)) { + TLOGE(WmsLogTag::WMS_ANIMATION, "[ANI] Opacity should greater than 0 or smaller than 1.0"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_INVALID_PARAM); + return; + } + + WmErrorCode ret = WM_JS_TO_ERROR_CODE_MAP.at(window->SetAlpha(static_cast(opacity))); + if (ret != WmErrorCode::WM_OK) { + TLOGE(WmsLogTag::WMS_ANIMATION, "[ANI] Window Opacity failed"); + AniWindowUtils::AniThrowError(env, ret); + return; + } + TLOGNI(WmsLogTag::WMS_ANIMATION, "[ANI] window [%{public}u, %{public}s] Opacity end, opacity=%{public}f", + window->GetWindowId(), window->GetWindowName().c_str(), static_cast(opacity)); +} + +void AniWindow::Scale(ani_env* env, ani_object obj, ani_long nativeObj, ani_object scaleOptions) +{ + TLOGI(WmsLogTag::WMS_ANIMATION, "[ANI] Set window Scale in"); + AniWindow* aniWindow = reinterpret_cast(nativeObj); + if (aniWindow != nullptr) { + aniWindow->OnScale(env, scaleOptions); + } else { + TLOGE(WmsLogTag::WMS_ANIMATION, "[ANI] aniWindow is nullptr"); + } +} + +static bool IsPivotValid(double data) +{ + if (MathHelper::LessNotEqual(data, 0.0) || (MathHelper::GreatNotEqual(data, 1.0))) { + return false; + } + return true; +} + +static bool IsScaleValid(double data) +{ + if (!MathHelper::GreatNotEqual(data, 0.0)) { + return false; + } + return true; +} + +bool AniWindow::ParseScaleOption(ani_env* env, ani_object scaleOptions, Transform& trans) +{ + double scaleX; + ani_double retScaleX = AniWindowUtils::GetPropertyDoubleObject(env, "x", scaleOptions, scaleX); + if (retScaleX == ANI_OK) { + if (!IsScaleValid(scaleX)) { + return false; + } + trans.scaleX_ = scaleX; + } + + double scaleY; + ani_double retScaleY = AniWindowUtils::GetPropertyDoubleObject(env, "y", scaleOptions, scaleY); + if (retScaleY == ANI_OK) { + if (!IsScaleValid(scaleY)) { + return false; + } + trans.scaleY_ = scaleY; + } + + double pivotX; + ani_double retPivotX = AniWindowUtils::GetPropertyDoubleObject(env, "pivotX", scaleOptions, pivotX); + if (retPivotX == ANI_OK) { + if (!IsPivotValid(pivotX)) { + return false; + } + trans.pivotX_ = pivotX; + } + + double pivotY; + ani_double retPivotY = AniWindowUtils::GetPropertyDoubleObject(env, "pivotY", scaleOptions, pivotY); + if (retPivotY == ANI_OK) { + if (!IsPivotValid(pivotY)) { + return false; + } + trans.pivotY_ = pivotY; + } + TLOGE(WmsLogTag::WMS_ANIMATION, "[ANI] ParseScaleOption end"); + return true; +} + +void AniWindow::OnScale(ani_env* env, ani_object scaleOptions) +{ + TLOGI(WmsLogTag::WMS_ANIMATION, "[ANI] OnScale in"); + if (!Permission::IsSystemCalling()) { + TLOGE(WmsLogTag::WMS_ANIMATION, "[ANI] not system app, permission denied!"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_NOT_SYSTEM_APP); + return; + } + + auto window = GetWindow(); + if (window == nullptr) { + TLOGE(WmsLogTag::WMS_ANIMATION, "[ANI] window is nullptr"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); + return; + } + + if (!WindowHelper::IsSystemWindow(window->GetType())) { + TLOGE(WmsLogTag::WMS_ANIMATION, "[ANI] Scale is not allowed since window is not system window"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_INVALID_CALLING); + return; + } + + auto trans = window->GetTransform(); + if (!ParseScaleOption(env, scaleOptions, trans)) { + TLOGE(WmsLogTag::WMS_ANIMATION, + "[ANI] PivotX or PivotY should between 0.0 ~ 1.0, scale should greater than 0.0"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_INVALID_PARAM); + return; + } + WmErrorCode ret = WM_JS_TO_ERROR_CODE_MAP.at(window->SetTransform(trans)); + if (ret != WmErrorCode::WM_OK) { + TLOGE(WmsLogTag::WMS_ANIMATION, "[ANI] Window Scale failed"); + AniWindowUtils::AniThrowError(env, ret); + return; + } + TLOGNI(WmsLogTag::WMS_ANIMATION, "[ANI] Window [%{public}u, %{public}s] Scale end", + window->GetWindowId(), window->GetWindowName().c_str()); + TLOGNI(WmsLogTag::WMS_ANIMATION, + "[ANI] scaleX=%{public}f, scaleY=%{public}f, pivotX=%{public}f pivotY=%{public}f", + trans.scaleX_, trans.scaleY_, trans.pivotX_, trans.pivotY_); +} + +void AniWindow::Translate(ani_env* env, ani_object obj, ani_long nativeObj, ani_object translateOptions) +{ + TLOGI(WmsLogTag::WMS_ANIMATION, "[ANI] Set window Translate in"); + AniWindow* aniWindow = reinterpret_cast(nativeObj); + if (aniWindow != nullptr) { + aniWindow->OnTranslate(env, translateOptions); + } else { + TLOGE(WmsLogTag::WMS_ANIMATION, "[ANI] aniWindow is nullptr"); + } +} + +bool AniWindow::ParseTranslateOption(ani_env* env, ani_object translateOptions, Transform& trans) +{ + double translateX; + ani_double retTranslateX = AniWindowUtils::GetPropertyDoubleObject(env, "x", translateOptions, translateX); + if (retTranslateX == ANI_OK) { + trans.translateX_ = translateX; + } + + double translateY; + ani_double retTranslateY = AniWindowUtils::GetPropertyDoubleObject(env, "y", translateOptions, translateY); + if (retTranslateY == ANI_OK) { + trans.translateY_ = translateY; + } + + double translateZ; + ani_double retTranslateZ = AniWindowUtils::GetPropertyDoubleObject(env, "z", translateOptions, translateZ); + if (retTranslateZ == ANI_OK) { + trans.translateZ_ = translateZ; + } + TLOGE(WmsLogTag::WMS_ANIMATION, "[ANI] ParseTranslateOption end"); + return true; +} + +void AniWindow::OnTranslate(ani_env* env, ani_object translateOptions) +{ + TLOGI(WmsLogTag::WMS_ANIMATION, "[ANI] Translate in"); + if (!Permission::IsSystemCalling()) { + TLOGE(WmsLogTag::WMS_ANIMATION, "[ANI] not system app, permission denied!"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_NOT_SYSTEM_APP); + return; + } + + auto window = GetWindow(); + if (window == nullptr) { + TLOGE(WmsLogTag::WMS_ANIMATION, "[ANI] window is nullptr"); AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); return; } - window->SetRequestedOrientation(static_cast(orientation)); + + if (!WindowHelper::IsSystemWindow(window->GetType())) { + TLOGE(WmsLogTag::WMS_ANIMATION, "[ANI] Translate is not allowed since window is not system window"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_INVALID_CALLING); + return; + } + + auto trans = window->GetTransform(); + if (!ParseTranslateOption(env, translateOptions, trans)) { + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_INVALID_PARAM); + return; + } + WmErrorCode ret = WM_JS_TO_ERROR_CODE_MAP.at(window->SetTransform(trans)); + if (ret != WmErrorCode::WM_OK) { + TLOGE(WmsLogTag::WMS_ANIMATION, "[ANI] Window Translate failed"); + AniWindowUtils::AniThrowError(env, ret); + return; + } + TLOGNI(WmsLogTag::WMS_ANIMATION, "[ANI] Window [%{public}u, %{public}s] Translate end, " + "translateX=%{public}f, translateY=%{public}f, translateZ=%{public}f", + window->GetWindowId(), window->GetWindowName().c_str(), + trans.translateX_, trans.translateY_, trans.translateZ_); +} + +void AniWindow::Rotate(ani_env* env, ani_object obj, ani_long nativeObj, ani_object rotateOptions) +{ + TLOGI(WmsLogTag::WMS_ANIMATION, "[ANI] Set window Rotate in"); + AniWindow* aniWindow = reinterpret_cast(nativeObj); + if (aniWindow != nullptr) { + aniWindow->OnRotate(env, rotateOptions); + } else { + TLOGE(WmsLogTag::WMS_ANIMATION, "[ANI] aniWindow is nullptr"); + } +} + +bool AniWindow::ParseRotateOption(ani_env* env, ani_object rotateOptions, Transform& trans) +{ + double pivotX; + ani_double retPivotX = AniWindowUtils::GetPropertyDoubleObject(env, "pivotX", rotateOptions, pivotX); + if (retPivotX == ANI_OK) { + if (!IsPivotValid(pivotX)) { + return false; + } + trans.pivotX_ = pivotX; + } + + double pivotY; + ani_double retPivotY = AniWindowUtils::GetPropertyDoubleObject(env, "pivotY", rotateOptions, pivotY); + if (retPivotY == ANI_OK) { + if (!IsPivotValid(pivotY)) { + return false; + } + trans.pivotY_ = pivotY; + } + + double rotationX; + ani_double retRotationX = AniWindowUtils::GetPropertyDoubleObject(env, "x", rotateOptions, rotationX); + if (retRotationX == ANI_OK) { + trans.rotationX_ = rotationX; + } + + double rotationY; + ani_double retRotationY = AniWindowUtils::GetPropertyDoubleObject(env, "y", rotateOptions, rotationY); + if (retRotationY == ANI_OK) { + trans.rotationY_ = rotationY; + } + + double rotationZ; + ani_double retRotationZ = AniWindowUtils::GetPropertyDoubleObject(env, "z", rotateOptions, rotationZ); + if (retRotationZ == ANI_OK) { + trans.rotationZ_ = rotationZ; + } + TLOGE(WmsLogTag::WMS_ANIMATION, "[ANI] ParseScaleOption end"); + return true; +} + +void AniWindow::OnRotate(ani_env* env, ani_object rotateOptions) +{ + TLOGI(WmsLogTag::WMS_ANIMATION, "[ANI] OnRotate in"); + if (!Permission::IsSystemCalling()) { + TLOGE(WmsLogTag::WMS_ANIMATION, "[ANI] not system app, permission denied!"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_NOT_SYSTEM_APP); + return; + } + + auto window = GetWindow(); + if (window == nullptr) { + TLOGE(WmsLogTag::WMS_ANIMATION, "[ANI] window is nullptr"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); + return; + } + + if (!WindowHelper::IsSystemWindow(window->GetType())) { + TLOGE(WmsLogTag::WMS_ANIMATION, "[ANI] Rotate is not allowed since window is not system window"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_INVALID_CALLING); + return; + } + + // cannot use sync task since next transform base on current transform + auto trans = window->GetTransform(); + if (!ParseRotateOption(env, rotateOptions, trans)) { + TLOGE(WmsLogTag::WMS_ANIMATION, "[ANI] PivotX or PivotY should between 0.0 ~ 1.0"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_INVALID_PARAM); + return; + } + WmErrorCode ret = WM_JS_TO_ERROR_CODE_MAP.at(window->SetTransform(trans)); + if (ret != WmErrorCode::WM_OK) { + TLOGE(WmsLogTag::WMS_ANIMATION, "[ANI] Window Translate failed"); + AniWindowUtils::AniThrowError(env, ret); + return; + } + TLOGNI(WmsLogTag::WMS_ANIMATION, "[ANI] Window [%{public}u, %{public}s] Rotate end", + window->GetWindowId(), window->GetWindowName().c_str()); + TLOGNI(WmsLogTag::WMS_ANIMATION, + "[ANI] rotateX=%{public}f, rotateY=%{public}f, rotateZ=%{public}f pivotX=%{public}f pivotY=%{public}f", + trans.rotationX_, trans.rotationY_, trans.rotationZ_, trans.pivotX_, trans.pivotY_); +} + +void AniWindow::SetShadow(ani_env* env, ani_object obj, ani_long nativeObj, ani_double radius, + ani_string color, ani_object offsetX, ani_object offsetY) +{ + TLOGI(WmsLogTag::WMS_ANIMATION, "[ANI] Set window Shadow in"); + AniWindow* aniWindow = reinterpret_cast(nativeObj); + if (aniWindow != nullptr) { + aniWindow->OnSetShadow(env, radius, color, offsetX, offsetY); + } else { + TLOGE(WmsLogTag::WMS_ANIMATION, "[ANI] aniWindow is nullptr"); + } +} + +void AniWindow::OnSetShadow(ani_env* env, ani_double radius, ani_string color, ani_object offsetX, ani_object offsetY) +{ + TLOGI(WmsLogTag::WMS_ANIMATION, "[ANI] OnSetShadow in"); + WmErrorCode ret = WmErrorCode::WM_OK; + auto window = GetWindow(); + if (window == nullptr) { + TLOGE(WmsLogTag::WMS_ANIMATION, "[ANI] window is nullptr"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); + return; + } + if (!WindowHelper::IsSystemWindow(window->GetType()) && + !WindowHelper::IsSubWindow(window->GetType())) { + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_INVALID_CALLING); + return; + } + + double radiusValue = static_cast(radius); + if (MathHelper::LessNotEqual(radiusValue, 0.0)) { + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_INVALID_PARAM); + return; + } + ret = WM_JS_TO_ERROR_CODE_MAP.at(window->SetShadowRadius(radiusValue)); + std::string colorValue = ""; + if (ret == WmErrorCode::WM_OK && ANI_OK == AniWindowUtils::GetStdString(env, color, colorValue)) { + ret = WM_JS_TO_ERROR_CODE_MAP.at(window->SetShadowColor(colorValue)); + } + + double offsetXValue = 0.0; + if (ret == WmErrorCode::WM_OK && ANI_OK == AniWindowUtils::GetDoubleObject(env, offsetX, offsetXValue)) { + ret = WM_JS_TO_ERROR_CODE_MAP.at(window->SetShadowOffsetX(offsetXValue)); + } + + double offsetYValue = 0.0; + if (ret == WmErrorCode::WM_OK && ANI_OK == AniWindowUtils::GetDoubleObject(env, offsetY, offsetYValue)) { + ret = WM_JS_TO_ERROR_CODE_MAP.at(window->SetShadowOffsetY(offsetYValue)); + } + if (ret != WmErrorCode::WM_OK) { + TLOGE(WmsLogTag::WMS_ANIMATION, "[ANI] Set Window Shadow failed"); + AniWindowUtils::AniThrowError(env, ret); + } + TLOGNI(WmsLogTag::WMS_ANIMATION, "[ANI] Window [%{public}u, %{public}s] Set Window Shadow end, " + "radius=%{public}f, color=%{public}s, offsetX=%{public}f offsetY=%{public}f", + window->GetWindowId(), window->GetWindowName().c_str(), + radiusValue, colorValue.c_str(), offsetXValue, offsetYValue); } void AniWindow::SetWindowPrivacyMode(ani_env* env, ani_object obj, ani_long nativeObj, ani_boolean isPrivacyMode) { - TLOGI(WmsLogTag::DEFAULT, "[ANI]"); + TLOGI(WmsLogTag::WMS_ATTRIBUTE, "[ANI]"); AniWindow* aniWindow = reinterpret_cast(nativeObj); if (aniWindow != nullptr) { aniWindow->OnSetWindowPrivacyMode(env, isPrivacyMode); } else { - TLOGE(WmsLogTag::DEFAULT, "[ANI] aniWindow is nullptr"); + TLOGE(WmsLogTag::WMS_ATTRIBUTE, "[ANI] aniWindow is nullptr"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); } } void AniWindow::OnSetWindowPrivacyMode(ani_env* env, ani_boolean isPrivacyMode) { - TLOGI(WmsLogTag::DEFAULT, "[ANI]"); + TLOGI(WmsLogTag::WMS_ATTRIBUTE, "[ANI]"); auto window = GetWindow(); if (window == nullptr) { - TLOGE(WmsLogTag::DEFAULT, "[ANI] window is nullptr"); + TLOGE(WmsLogTag::WMS_ATTRIBUTE, "[ANI] windowToken_ is nullptr"); AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); return; } - auto ret = window->SetPrivacyMode(static_cast(isPrivacyMode)); - TLOGI(WmsLogTag::DEFAULT, "[ANI] ret:%{public}d", static_cast(ret)); + auto ret = WM_JS_TO_ERROR_CODE_MAP.at(window->SetPrivacyMode(static_cast(isPrivacyMode))); + if (ret != WmErrorCode::WM_OK) { + TLOGE(WmsLogTag::WMS_ATTRIBUTE, "[ANI] ret:%{public}d", static_cast(ret)); + AniWindowUtils::AniThrowError(env, ret); + } } void AniWindow::Recover(ani_env* env, ani_object obj, ani_long nativeObj) @@ -198,22 +670,23 @@ void AniWindow::OnSetUIContent(ani_env* env, ani_string path) void AniWindow::SetWindowKeepScreenOn(ani_env* env, ani_object obj, ani_long nativeObj, ani_boolean isKeepScreenOn) { - TLOGI(WmsLogTag::DEFAULT, "[ANI]"); + TLOGI(WmsLogTag::WMS_ATTRIBUTE, "[ANI]"); AniWindow* aniWindow = reinterpret_cast(nativeObj); if (aniWindow == nullptr) { - TLOGE(WmsLogTag::DEFAULT, "[ANI] aniWindow is nullptr"); + TLOGE(WmsLogTag::WMS_ATTRIBUTE, "[ANI] aniWindow is nullptr"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); return; } aniWindow->OnSetWindowKeepScreenOn(env, isKeepScreenOn); - TLOGI(WmsLogTag::DEFAULT, "[ANI] SetWindowKeepScreenOn end"); + TLOGI(WmsLogTag::WMS_ATTRIBUTE, "[ANI] SetWindowKeepScreenOn end"); } void AniWindow::OnSetWindowKeepScreenOn(ani_env* env, ani_boolean isKeepScreenOn) { - TLOGI(WmsLogTag::DEFAULT, "[ANI]"); + TLOGI(WmsLogTag::WMS_ATTRIBUTE, "[ANI]"); auto window = GetWindow(); if (window == nullptr) { - TLOGE(WmsLogTag::DEFAULT, "[ANI] window is nullptr"); + TLOGE(WmsLogTag::WMS_ATTRIBUTE, "[ANI] window is nullptr"); AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); return; } @@ -225,21 +698,22 @@ void AniWindow::OnSetWindowKeepScreenOn(ani_env* env, ani_boolean isKeepScreenOn void AniWindow::SetWaterMarkFlag(ani_env* env, ani_object obj, ani_long nativeObj, ani_boolean enable) { - TLOGI(WmsLogTag::DEFAULT, "[ANI]"); + TLOGI(WmsLogTag::WMS_ATTRIBUTE, "[ANI]"); AniWindow* aniWindow = reinterpret_cast(nativeObj); if (aniWindow != nullptr) { aniWindow->OnSetWaterMarkFlag(env, enable); } else { - TLOGE(WmsLogTag::DEFAULT, "[ANI] aniWindow is nullptr"); + TLOGE(WmsLogTag::WMS_ATTRIBUTE, "[ANI] aniWindow is nullptr"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); } } void AniWindow::OnSetWaterMarkFlag(ani_env* env, ani_boolean enable) { - TLOGI(WmsLogTag::DEFAULT, "[ANI]"); + TLOGI(WmsLogTag::WMS_ATTRIBUTE, "[ANI]"); auto window = GetWindow(); if (window == nullptr) { - TLOGE(WmsLogTag::DEFAULT, "[ANI] window is nullptr"); + TLOGE(WmsLogTag::WMS_ATTRIBUTE, "[ANI] window is nullptr"); AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); return; } @@ -254,18 +728,18 @@ void AniWindow::OnSetWaterMarkFlag(ani_env* env, ani_boolean enable) } } -void AniWindow::LoadContent(ani_env* env, ani_object obj, ani_long nativeObj, ani_string path) +void AniWindow::SetWindowFocusable(ani_env* env, ani_object obj, ani_long nativeObj, ani_boolean isFocusable) { TLOGI(WmsLogTag::DEFAULT, "[ANI]"); AniWindow* aniWindow = reinterpret_cast(nativeObj); if (aniWindow != nullptr) { - aniWindow->OnLoadContent(env, path); + aniWindow->OnSetWindowFocusable(env, isFocusable); } else { TLOGE(WmsLogTag::DEFAULT, "[ANI] aniWindow is nullptr"); } } -void AniWindow::OnLoadContent(ani_env* env, ani_string path) +void AniWindow::OnSetWindowFocusable(ani_env* env, ani_boolean isFocusable) { TLOGI(WmsLogTag::DEFAULT, "[ANI]"); auto window = GetWindow(); @@ -274,16 +748,40 @@ void AniWindow::OnLoadContent(ani_env* env, ani_string path) 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)); + WmErrorCode ret = WM_JS_TO_ERROR_CODE_MAP.at(window->SetFocusable(isFocusable)); if (ret != WmErrorCode::WM_OK) { - AniWindowUtils::AniThrowError(env, ret, "Window load content failed"); + AniWindowUtils::AniThrowError(env, ret, "SetWindowFocusable failed."); + } +} + +void AniWindow::SetWindowTouchable(ani_env* env, ani_object obj, ani_long nativeObj, ani_boolean isTouchable) +{ + TLOGI(WmsLogTag::WMS_EVENT, "[ANI] in"); + AniWindow* aniWindow = reinterpret_cast(nativeObj); + if (aniWindow == nullptr) { + TLOGE(WmsLogTag::WMS_EVENT, "[ANI] aniWindow is nullptr"); + return; + } + aniWindow->OnSetWindowTouchable(env, isTouchable); + TLOGI(WmsLogTag::WMS_EVENT, "[ANI] end"); +} + +void AniWindow::OnSetWindowTouchable(ani_env* env, ani_boolean isTouchable) +{ + TLOGI(WmsLogTag::WMS_EVENT, "[ANI] in"); + auto window = GetWindow(); + if (window == nullptr) { + TLOGE(WmsLogTag::WMS_EVENT, "[ANI] window is nullptr"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); + return; + } + WmErrorCode ret = WM_JS_TO_ERROR_CODE_MAP.at(window->SetTouchable(static_cast(isTouchable))); + if (ret != WmErrorCode::WM_OK) { + AniWindowUtils::AniThrowError(env, ret, "Window set touchable on 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]"); @@ -306,8 +804,9 @@ 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)); + TLOGI(WmsLogTag::WMS_LIFE, "[ANI] Window [%{public}u, %{public}s] load content end, ret=%{public}d", + window->GetWindowId(), window->GetWindowName().c_str(), ret); if (ret != WmErrorCode::WM_OK) { AniWindowUtils::AniThrowError(env, ret, "Window load content failed"); } @@ -315,22 +814,24 @@ void AniWindow::OnLoadContent(ani_env* env, ani_string path, ani_object storage) void AniWindow::SetWindowSystemBarEnable(ani_env* env, ani_object obj, ani_long nativeObj, ani_object nameAry) { - TLOGI(WmsLogTag::WMS_MAIN, "[ANI]"); + TLOGI(WmsLogTag::WMS_IMMS, "[ANI]"); AniWindow* aniWindow = reinterpret_cast(nativeObj); if (aniWindow != nullptr) { aniWindow->OnSetWindowSystemBarEnable(env, nameAry); } else { - TLOGE(WmsLogTag::WMS_MAIN, "[ANI] aniWindow is nullptr"); + TLOGE(WmsLogTag::WMS_IMMS, "[ANI] aniWindow is nullptr"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); + return; } - TLOGI(WmsLogTag::WMS_MAIN, "[ANI] SetWindowSystemBarEnable end"); + TLOGI(WmsLogTag::WMS_IMMS, "[ANI] SetWindowSystemBarEnable end"); } void AniWindow::OnSetWindowSystemBarEnable(ani_env* env, ani_object nameAry) { - TLOGI(WmsLogTag::WMS_MAIN, "[ANI]"); + TLOGI(WmsLogTag::WMS_IMMS, "[ANI]"); auto window = GetWindow(); if (window == nullptr) { - TLOGE(WmsLogTag::DEFAULT, "[ANI] window is nullptr"); + TLOGE(WmsLogTag::WMS_IMMS, "[ANI] window is nullptr"); AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); return; } @@ -446,23 +947,23 @@ 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) { - TLOGI(WmsLogTag::DEFAULT, "[ANI] type:%{public}d", static_cast(type)); + TLOGI(WmsLogTag::WMS_IMMS, "[ANI] type:%{public}d", static_cast(type)); AniWindow* aniWindow = reinterpret_cast(nativeObj); - return aniWindow != nullptr ? aniWindow->OnGetWindowAvoidArea(env, type) : nullptr; + return aniWindow != nullptr ? aniWindow->OnGetWindowAvoidArea(env, type) : + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); } ani_object AniWindow::OnGetWindowAvoidArea(ani_env* env, ani_int type) { - TLOGI(WmsLogTag::DEFAULT, "[ANI]"); + TLOGI(WmsLogTag::WMS_IMMS, "[ANI]"); auto window = GetWindow(); if (window == nullptr) { - TLOGE(WmsLogTag::DEFAULT, "[ANI] window is nullptr"); + TLOGE(WmsLogTag::WMS_IMMS, "[ANI] window is nullptr"); return AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); } AvoidArea avoidArea; @@ -470,9 +971,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; } @@ -481,32 +982,40 @@ 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) { + if ((ret = env->FindClass("@ohos.window.window.WindowInternal", &cls)) != ANI_OK) { TLOGE(WmsLogTag::DEFAULT, "[ANI] null env %{public}u", ret); return nullptr; } std::unique_ptr aniWindow = std::make_unique(window); + TLOGD(WmsLogTag::DEFAULT, "[ANI] native obj %{public}p", aniWindow.get()); ani_method initFunc = nullptr; - if ((ret = env->Class_FindMethod(cls, "", ":V", &initFunc)) != ANI_OK) { + if ((ret = env->Class_FindMethod(cls, "", ":", &initFunc)) != ANI_OK) { TLOGE(WmsLogTag::DEFAULT, "[ANI] get ctor fail %{public}u", ret); return nullptr; } @@ -516,286 +1025,1486 @@ __attribute__((no_sanitize("cfi"))) return nullptr; } 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); + if ((ret = env->Class_FindMethod(cls, "setNativeObj", "l:", &setObjFunc)) != ANI_OK) { + TLOGE(WmsLogTag::DEFAULT, "[ANI] get setNativeObj 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); + localObjs.insert(std::pair(ref, aniWindow.release())); + g_aniWindowMap[windowName] = ref; return obj; } -ani_double AniWindow::GetWindowDecorHeight(ani_env* env) +void AniWindow::SetFollowParentWindowLayoutEnabled(ani_env* env, ani_boolean enabled) { - int32_t height { 0 }; - wptr weakToken(windowToken_); - auto window = weakToken.promote(); - if (window == nullptr) { - TLOGE(WmsLogTag::DEFAULT, "[ANI] window is nullptr"); + if (windowToken_ == nullptr) { + TLOGE(WmsLogTag::WMS_SUB, "[ANI] windowToken_ is null"); AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); - return ANI_ERROR; + return; } - WMError ret = windowToken_->GetDecorHeight(height); - if (ret != WMError::WM_OK) { - if (ret == WMError::WM_ERROR_DEVICE_NOT_SUPPORT) { - AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_DEVICE_NOT_SUPPORT); - return ANI_ERROR; - } + if (!WindowHelper::IsSubWindow(windowToken_->GetType()) && !WindowHelper::IsDialogWindow(windowToken_->GetType())) { + TLOGE(WmsLogTag::WMS_SUB, "[ANI] Only sub window and dialog is valid"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_INVALID_CALLING); + return; + } + WmErrorCode ret = WM_JS_TO_ERROR_CODE_MAP.at(windowToken_->SetFollowParentWindowLayoutEnabled(enabled)); + if (ret != WmErrorCode::WM_OK) { + TLOGE(WmsLogTag::WMS_SUB, "[ANI] Set follow parent layout failed, ret %{public}d", ret); + AniWindowUtils::AniThrowError(env, ret); + } +} + +void AniWindow::SetWindowDelayRaiseOnDrag(ani_env* env, ani_boolean isEnabled) +{ + if (windowToken_ == nullptr) { + TLOGE(WmsLogTag::WMS_FOCUS, "[ANI] windowToken is nullptr"); AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); - return 0; + return; + } + auto result = windowToken_->SetWindowDelayRaiseEnabled(isEnabled); + if (result != WMError::WM_OK) { + TLOGE(WmsLogTag::WMS_FOCUS, "[ANI] failed"); + AniWindowUtils::AniThrowError(env, WM_JS_TO_ERROR_CODE_MAP.at(result)); } - TLOGI(WmsLogTag::DEFAULT, "[ANI] Window [%{public}u, %{public}s] OnGetDecorHeight end, height = %{public}d", - windowToken_->GetWindowId(), windowToken_->GetWindowName().c_str(), height); - return static_cast(height); } -ani_object AniWindow::SetWindowBackgroundColor(ani_env* env, const std::string& color) +ani_ref AniWindow::GetParentWindow(ani_env* env) { - WmErrorCode ret = WM_JS_TO_ERROR_CODE_MAP.at(windowToken_->SetBackgroundColor(color)); + if (windowToken_ == nullptr) { + TLOGE(WmsLogTag::WMS_SUB, "[ANI] windowToken_ is nullptr"); + return AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); + } + sptr parentWindow = nullptr; + WmErrorCode ret = WM_JS_TO_ERROR_CODE_MAP.at(windowToken_->GetParentWindow(parentWindow)); + if (ret != WmErrorCode::WM_OK) { + TLOGE(WmsLogTag::WMS_SUB, "[ANI] get failed, result=%{public}d", ret); + return AniWindowUtils::AniThrowError(env, ret); + } + if (parentWindow == nullptr) { + TLOGE(WmsLogTag::WMS_SUB, "[ANI] parentWindow is nullptr"); + return AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_INVALID_PARENT); + } + return CreateAniWindowObject(env, parentWindow); +} + +ani_boolean AniWindow::GetWindowDecorVisible(ani_env* env) +{ + if (windowToken_ == nullptr) { + TLOGE(WmsLogTag::WMS_DECOR, "[ANI] windowToken_ is nullptr"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); + return ani_boolean(false); + } + bool isVisible = false; + WmErrorCode ret = WM_JS_TO_ERROR_CODE_MAP.at(windowToken_->GetDecorVisible(isVisible)); + if (ret != WmErrorCode::WM_OK) { + TLOGE(WmsLogTag::WMS_DECOR, "[ANI] Get window decor visibility failed"); + AniWindowUtils::AniThrowError(env, ret); + return ani_boolean(false); + } + TLOGI(WmsLogTag::WMS_DECOR, "[ANI] end, window [%{public}u, %{public}s] isVisible=%{public}d", + windowToken_->GetWindowId(), windowToken_->GetWindowName().c_str(), isVisible); + return ani_boolean(isVisible); +} + +void AniWindow::StopMoving(ani_env* env) +{ + if (windowToken_ == nullptr) { + TLOGE(WmsLogTag::WMS_LAYOUT_PC, "[ANI] WindowToken is nullptr"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); + return; + } + if (!WindowHelper::IsSystemWindow(windowToken_->GetType()) && + !WindowHelper::IsMainWindow(windowToken_->GetType()) && + !WindowHelper::IsSubWindow(windowToken_->GetType())) { + TLOGE(WmsLogTag::WMS_LAYOUT_PC, "[ANI] This is not valid window."); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_INVALID_CALLING); + return; + } + WmErrorCode ret = windowToken_->StopMoveWindow(); + if (ret != WmErrorCode::WM_OK) { + TLOGE(WmsLogTag::WMS_LAYOUT_PC, "[ANI] Stop moving window failed"); + AniWindowUtils::AniThrowError(env, ret); + } +} + +void AniWindow::SetParentWindow(ani_env* env, ani_double windowId) +{ + if (windowToken_ == nullptr) { + TLOGE(WmsLogTag::WMS_SUB, "[ANI] window is nullptr"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); + return; + } + int32_t newParentWindowId = static_cast(windowId); + WMError ret = windowToken_->SetParentWindow(newParentWindowId); + if (ret != WMError::WM_OK) { + WmErrorCode wmErrorCode = WM_JS_TO_ERROR_CODE_MAP.at(ret); + TLOGE(WmsLogTag::WMS_SUB, "[ANI] Set parent window failed"); + AniWindowUtils::AniThrowError(env, wmErrorCode); + } else { + TLOGI(WmsLogTag::WMS_SUB, "[ANI] window id: %{public}u set parent window id: %{public}u end", + windowToken_->GetWindowId(), newParentWindowId); + } +} + +void AniWindow::SetWindowTitle(ani_env* env, ani_string titleName) +{ + if (windowToken_ == nullptr) { + TLOGE(WmsLogTag::WMS_DECOR, "[ANI] Window is nullptr"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); + return; + } + std::string title; + if (AniWindowUtils::GetStdString(env, titleName, title) != ANI_OK) { + TLOGE(WmsLogTag::WMS_DECOR, "[ANI] Failed to convert parameter to title"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_INVALID_PARAM); + return; + } + WmErrorCode ret = WM_JS_TO_ERROR_CODE_MAP.at(windowToken_->SetWindowTitle(title)); if (ret == WmErrorCode::WM_OK) { - TLOGI(WmsLogTag::DEFAULT, "Window [%{public}u, %{public}s] set background color end", - windowToken_->GetWindowId(), windowToken_->GetWindowName().c_str()); - return AniWindowUtils::CreateAniUndefined(env); + TLOGI(WmsLogTag::WMS_DECOR, "[ANI] Window [%{public}u] end", windowToken_->GetWindowId()); } else { + TLOGE(WmsLogTag::WMS_DECOR, "[ANI] Window set title failed"); + AniWindowUtils::AniThrowError(env, ret); + } +} + +ani_object AniWindow::GetDecorButtonStyle(ani_env* env) +{ + if (windowToken_ == nullptr) { + TLOGE(WmsLogTag::WMS_DECOR, "[ANI] window is nullptr"); + return AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); + } + if (!windowToken_->IsPcOrPadFreeMultiWindowMode()) { + TLOGE(WmsLogTag::WMS_DECOR, "[ANI] device not support"); + return AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_DEVICE_NOT_SUPPORT); + } + DecorButtonStyle decorButtonStyle; + WMError errCode = windowToken_->GetDecorButtonStyle(decorButtonStyle); + WmErrorCode ret = WM_JS_TO_ERROR_CODE_MAP.at(errCode); + if (ret != WmErrorCode::WM_OK) { + TLOGE(WmsLogTag::WMS_DECOR, "[ANI] get decorButtonStyle fail"); return AniWindowUtils::AniThrowError(env, ret); } + return AniWindowUtils::CreateAniDecorButtonStyle(env, decorButtonStyle); } -void AniWindow::RegisterWindowCallback(ani_env* env, ani_object obj, ani_long nativeObj, ani_string type, - ani_ref callback) +ani_object AniWindow::GetTitleButtonRect(ani_env* env) { - TLOGI(WmsLogTag::DEFAULT, "[ANI]"); - AniWindow* aniWindow = reinterpret_cast(nativeObj); - if (aniWindow != nullptr) { - aniWindow->OnRegisterWindowCallback(env, type, callback); - } else { - TLOGE(WmsLogTag::DEFAULT, "[ANI] aniWindow is nullptr"); + if (windowToken_ == nullptr) { + TLOGE(WmsLogTag::WMS_DECOR, "[ANI] window is nullptr"); + return AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); + } + TitleButtonRect titleButtonRect; + WmErrorCode ret = WM_JS_TO_ERROR_CODE_MAP.at(windowToken_->GetTitleButtonArea(titleButtonRect)); + if (ret != WmErrorCode::WM_OK) { + TLOGE(WmsLogTag::WMS_DECOR, "[ANI] get titleButtonRect fail"); + return AniWindowUtils::AniThrowError(env, ret); } + TLOGI(WmsLogTag::WMS_DECOR, "Window [%{public}u, %{public}s] end", + windowToken_->GetWindowId(), windowToken_->GetWindowName().c_str()); + return AniWindowUtils::CreateAniTitleButtonRect(env, titleButtonRect); } -void AniWindow::OnRegisterWindowCallback(ani_env* env, ani_string type, ani_ref callback) +void AniWindow::SetTitleButtonVisible(ani_env* env, ani_object titleButtonVisibleParam) { - TLOGI(WmsLogTag::DEFAULT, "[ANI]"); - auto window = GetWindow(); - if (window == nullptr) { - TLOGE(WmsLogTag::DEFAULT, "[ANI] window is nullptr"); + if (!Permission::IsSystemCalling()) { + TLOGE(WmsLogTag::WMS_DECOR, "[ANI] set title button visible permission denied!"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_NOT_SYSTEM_APP); + return; + } + ani_boolean isMaximizeVisible = true; + if (ANI_OK != env->Object_GetPropertyByName_Boolean(titleButtonVisibleParam, + "isMaximizeVisible", &isMaximizeVisible)) { + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_INVALID_PARAM); + return; + } + ani_boolean isMinimizeVisible = true; + if (ANI_OK != env->Object_GetPropertyByName_Boolean(titleButtonVisibleParam, + "isMinimizeVisible", &isMinimizeVisible)) { + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_INVALID_PARAM); + return; + } + ani_boolean isSplitVisible = true; + if (ANI_OK != env->Object_GetPropertyByName_Boolean(titleButtonVisibleParam, + "isSplitVisible", &isSplitVisible)) { + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_INVALID_PARAM); + return; + } + ani_boolean isCloseVisible = true; + if (ANI_OK != env->Object_GetPropertyByName_Boolean(titleButtonVisibleParam, + "isCloseVisible", &isCloseVisible)) { + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_INVALID_PARAM); + return; + } + if (windowToken_ == nullptr) { + TLOGE(WmsLogTag::WMS_DECOR, "[ANI] windowToken is nullptr"); AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); return; } - std::string cbType; - AniWindowUtils::GetStdString(env, type, cbType); - TLOGI(WmsLogTag::DEFAULT, "[ANI] type:%{public}s", cbType.c_str()); - WmErrorCode ret = registerManager_->RegisterListener(window, cbType, CaseType::CASE_WINDOW, env, callback); + WMError errCode = windowToken_->SetTitleButtonVisible(isMaximizeVisible, isMinimizeVisible, isSplitVisible, + isCloseVisible); + WmErrorCode ret = WM_JS_TO_ERROR_CODE_MAP.at(errCode); if (ret != WmErrorCode::WM_OK) { + TLOGE(WmsLogTag::WMS_DECOR, "[ANI] set title button visible failed!"); AniWindowUtils::AniThrowError(env, ret); return; } + TLOGI(WmsLogTag::WMS_DECOR, + "[ANI] window [%{public}u, %{public}s] end [%{public}d, %{public}d, %{public}d, %{public}d]", + windowToken_->GetWindowId(), windowToken_->GetWindowName().c_str(), isMaximizeVisible, isMinimizeVisible, + isSplitVisible, isCloseVisible); } -void AniWindow::UnregisterWindowCallback(ani_env* env, ani_object obj, ani_long nativeObj, ani_string type, - ani_ref callback) +void AniWindow::SetWindowTitleMoveEnabled(ani_env* env, ani_boolean enabled) { - TLOGI(WmsLogTag::DEFAULT, "[ANI]"); - AniWindow* aniWindow = reinterpret_cast(nativeObj); - if (aniWindow != nullptr) { - aniWindow->OnUnregisterWindowCallback(env, type, callback); - } else { - TLOGE(WmsLogTag::DEFAULT, "[ANI] aniWindow is nullptr"); + if (windowToken_ == nullptr) { + TLOGE(WmsLogTag::WMS_DECOR, "[ANI] WindowToken is nullptr"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); + return; + } + WmErrorCode ret = WM_JS_TO_ERROR_CODE_MAP.at(windowToken_->SetWindowTitleMoveEnabled(enabled)); + if (ret != WmErrorCode::WM_OK) { + TLOGE(WmsLogTag::WMS_DECOR, "[ANI] Window set title move enable failed"); + AniWindowUtils::AniThrowError(env, ret); + return; } + TLOGI(WmsLogTag::WMS_DECOR, "[ANI] Window [%{public}u, %{public}s] end", + windowToken_->GetWindowId(), windowToken_->GetWindowName().c_str()); } -void AniWindow::OnUnregisterWindowCallback(ani_env* env, ani_string type, ani_ref callback) +void AniWindow::SetWindowTopmost(ani_env* env, ani_boolean isWindowTopmost) { - TLOGI(WmsLogTag::DEFAULT, "[ANI]"); - auto window = GetWindow(); - if (window == nullptr) { - TLOGE(WmsLogTag::DEFAULT, "[ANI] window is nullptr"); + if (windowToken_ == nullptr) { + TLOGE(WmsLogTag::WMS_HIERARCHY, "[ANI] windowToken is nullptr"); AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); return; } - std::string cbType; - AniWindowUtils::GetStdString(env, type, cbType); - TLOGI(WmsLogTag::DEFAULT, "[ANI] type:%{public}s", cbType.c_str()); - WmErrorCode ret = registerManager_->UnregisterListener(window, cbType, CaseType::CASE_WINDOW, env, callback); + if (!windowToken_->IsPcOrPadFreeMultiWindowMode()) { + TLOGE(WmsLogTag::WMS_HIERARCHY, "[ANI] device not support"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_DEVICE_NOT_SUPPORT); + return; + } + if (!WindowHelper::IsMainWindow(windowToken_->GetType())) { + TLOGE(WmsLogTag::WMS_HIERARCHY, "[ANI] not allowed since window is not main window"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_INVALID_CALLING); + return; + } + auto ret = WM_JS_TO_ERROR_CODE_MAP.at(windowToken_->SetMainWindowTopmost(isWindowTopmost)); + if (ret != WmErrorCode::WM_OK) { + TLOGE(WmsLogTag::WMS_HIERARCHY, "[ANI] Window set main window topmost failed"); + AniWindowUtils::AniThrowError(env, ret); + return; + } + TLOGI(WmsLogTag::WMS_HIERARCHY, + "[ANI] id: %{public}u, name: %{public}s, isWindowTopmost: %{public}d", + windowToken_->GetWindowId(), windowToken_->GetWindowName().c_str(), isWindowTopmost); +} + +void AniWindow::SetTitleAndDockHoverShown(ani_env* env, ani_boolean isTitleHoverShown, ani_boolean isDockHoverShown) +{ + if (windowToken_ == nullptr) { + TLOGE(WmsLogTag::WMS_LAYOUT_PC, "[ANI] window is nullptr"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); + return; + } + WMError errCode = windowToken_->SetTitleAndDockHoverShown(isTitleHoverShown, isDockHoverShown); + WmErrorCode ret = WM_JS_TO_ERROR_CODE_MAP.at(errCode); + if (ret != WmErrorCode::WM_OK) { + TLOGE(WmsLogTag::WMS_LAYOUT_PC, "[ANI] set title and dock hover show failed!"); + AniWindowUtils::AniThrowError(env, ret); + return; + } + TLOGI(WmsLogTag::WMS_LAYOUT_PC, "[ANI] window [%{public}u, %{public}s] [%{public}d, %{public}d]", + windowToken_->GetWindowId(), windowToken_->GetWindowName().c_str(), isTitleHoverShown, isDockHoverShown); +} + +void AniWindow::Restore(ani_env* env) +{ + if (windowToken_ == nullptr) { + TLOGE(WmsLogTag::WMS_LAYOUT_PC, "[ANI] Window is nullptr"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); + return; + } + if (!WindowHelper::IsMainWindow(windowToken_->GetType())) { + TLOGE(WmsLogTag::WMS_LAYOUT_PC, "[ANI] Restore fail, not main window"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_INVALID_CALLING); + return; + } + WmErrorCode ret = WM_JS_TO_ERROR_CODE_MAP.at(windowToken_->Restore()); + if (ret != WmErrorCode::WM_OK) { + TLOGE(WmsLogTag::WMS_LAYOUT_PC, "[ANI] Window restore failed"); + AniWindowUtils::AniThrowError(env, ret); + } +} + +void AniWindow::StartMoving(ani_env* env) +{ + if (windowToken_ == nullptr) { + TLOGE(WmsLogTag::WMS_LAYOUT_PC, "[ANI] windowToken_ is null"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); + return; + } + if (!WindowHelper::IsSystemWindow(windowToken_->GetType()) && + !WindowHelper::IsMainWindow(windowToken_->GetType()) && + !WindowHelper::IsSubWindow(windowToken_->GetType())) { + TLOGE(WmsLogTag::WMS_LAYOUT, "[ANI] This is not valid window."); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_INVALID_CALLING); + return; + } + WmErrorCode err = windowToken_->StartMoveWindow(); + if (err != WmErrorCode::WM_OK) { + TLOGE(WmsLogTag::WMS_LAYOUT, "[ANI] Move system window failed."); + AniWindowUtils::AniThrowError(env, err); + } +} + +void AniWindow::StartMoveWindowWithCoordinate(ani_env* env, ani_int offsetX, ani_int offsetY) +{ + if (windowToken_ == nullptr) { + TLOGE(WmsLogTag::WMS_LAYOUT_PC, "[ANI] WindowToken is null."); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); + return; + } + WindowType windowType = windowToken_->GetType(); + if (!WindowHelper::IsSystemWindow(windowType) && !WindowHelper::IsAppWindow(windowType)) { + TLOGE(WmsLogTag::WMS_LAYOUT_PC, "[ANI] Invalid window type:%{public}u", windowType); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_INVALID_CALLING); + return; + } + WmErrorCode ret = windowToken_->StartMoveWindowWithCoordinate(static_cast(offsetX), static_cast(offsetY)); + if (ret != WmErrorCode::WM_OK) { + TLOGE(WmsLogTag::WMS_LAYOUT_PC, "[ANI] Move window failed."); + AniWindowUtils::AniThrowError(env, ret); + } +} + +void AniWindow::SetWindowTitleButtonVisible(ani_env* env, ani_object visibleParam) +{ + if (windowToken_ == nullptr) { + TLOGE(WmsLogTag::WMS_DECOR, "[ANI] WindowToken is null"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); + return; + } + ani_boolean isMaximizeButtonVisible = false; + if (ANI_OK != env->Object_GetPropertyByName_Boolean(visibleParam, + "isMaximizeButtonVisible", &isMaximizeButtonVisible)) { + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_INVALID_PARAM); + return; + } + ani_boolean isMinimizeButtonVisible = false; + if (ANI_OK != env->Object_GetPropertyByName_Boolean(visibleParam, + "isMinimizeButtonVisible", &isMinimizeButtonVisible)) { + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_INVALID_PARAM); + return; + } + ani_boolean isCloseButtonVisible = false; + if (ANI_OK != env->Object_GetPropertyByName_Boolean(visibleParam, + "isCloseButtonVisible", &isCloseButtonVisible)) { + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_INVALID_PARAM); + return; + } + TLOGI(WmsLogTag::WMS_DECOR, "[ANI] Window [%{public}u, %{public}s] [%{public}d, %{public}d, %{public}d]", + windowToken_->GetWindowId(), windowToken_->GetWindowName().c_str(), + isMaximizeButtonVisible, isMinimizeButtonVisible, isCloseButtonVisible); + WMError errCode = windowToken_->SetTitleButtonVisible(isMaximizeButtonVisible, isMinimizeButtonVisible, + isMaximizeButtonVisible, isCloseButtonVisible); + WmErrorCode ret = WM_JS_TO_ERROR_CODE_MAP.at(errCode); + if (ret != WmErrorCode::WM_OK) { + TLOGE(WmsLogTag::WMS_DECOR, "[ANI] set title button visible failed!"); + AniWindowUtils::AniThrowError(env, ret); + } +} + +void AniWindow::SetDecorButtonStyle(ani_env* env, ani_object decorStyle) +{ + if (windowToken_ == nullptr) { + TLOGE(WmsLogTag::WMS_DECOR, "[ANI] WindowToken is null"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); + return; + } + if (!windowToken_->IsPcOrPadFreeMultiWindowMode()) { + TLOGE(WmsLogTag::WMS_DECOR, "[ANI] device not support"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_DEVICE_NOT_SUPPORT); + return; + } + + DecorButtonStyle decorButtonStyle; + WMError res = windowToken_->GetDecorButtonStyle(decorButtonStyle); + if (res != WMError::WM_OK) { + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_INVALID_CALLING); + return; + } + if (!AniWindowUtils::SetDecorButtonStyleFromAni(env, decorButtonStyle, decorStyle)) { + TLOGE(WmsLogTag::WMS_DECOR, "[ANI] Argc is invalid"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_INVALID_PARAM); + return; + } + TLOGI(WmsLogTag::WMS_DECOR, "[ANI] param [%{public}d, %{public}d, %{public}d, %{public}d] to be updated", + decorButtonStyle.colorMode, decorButtonStyle.spacingBetweenButtons, + decorButtonStyle.closeButtonRightMargin, decorButtonStyle.buttonBackgroundSize); + if (!WindowHelper::CheckButtonStyleValid(decorButtonStyle)) { + TLOGE(WmsLogTag::WMS_DECOR, "[ANI] out of range params"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_INVALID_PARAM); + return; + } + WMError errCode = windowToken_->SetDecorButtonStyle(decorButtonStyle); + WmErrorCode ret = WM_JS_TO_ERROR_CODE_MAP.at(errCode); if (ret != WmErrorCode::WM_OK) { + TLOGE(WmsLogTag::WMS_DECOR, "[ANI] set decor button fail"); AniWindowUtils::AniThrowError(env, ret); + } +} + +ani_int AniWindow::GetWindowStatus(ani_env* env) +{ + if (windowToken_ == nullptr) { + TLOGE(WmsLogTag::WMS_PC, "[ANI] window is null"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); + return ANI_ERROR; + } + WindowStatus windowStatus; + WmErrorCode ret = WM_JS_TO_ERROR_CODE_MAP.at(windowToken_->GetWindowStatus(windowStatus)); + if (ret != WmErrorCode::WM_OK) { + TLOGE(WmsLogTag::WMS_PC, "[ANI] Get window status failed, ret=%{public}d", ret); + AniWindowUtils::AniThrowError(env, ret); + return ANI_ERROR; + } + TLOGI(WmsLogTag::WMS_PC, "[ANI] window [%{public}u, %{public}s] end", + windowToken_->GetWindowId(), windowToken_->GetWindowName().c_str()); + return static_cast(windowStatus); +} + +void AniWindow::Minimize(ani_env* env) +{ + if (windowToken_ == nullptr) { + TLOGE(WmsLogTag::WMS_LAYOUT, "[ANI] window is null"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); + return; + } + + if (WindowHelper::IsFloatOrSubWindow(windowToken_->GetType())) { + TLOGI(WmsLogTag::WMS_LAYOUT, "[ANI] subWindow or float window use hide"); + HideWindowFunction(env, WmErrorCode::WM_OK); + return; + } + + WMError ret = windowToken_->Minimize(); + TLOGNI(WmsLogTag::WMS_PC, "[ANI] Window [%{public}u, %{public}s] minimize end, ret=%{public}d", + windowToken_->GetWindowId(), windowToken_->GetWindowName().c_str(), ret); + if (ret != WMError::WM_OK) { + WmErrorCode wmErrorCode = WM_JS_TO_ERROR_CODE_MAP.at(ret); + AniWindowUtils::AniThrowError(env, wmErrorCode); + } +} + +void AniWindow::HideWindowFunction(ani_env* env, WmErrorCode errCode) +{ + if (errCode != WmErrorCode::WM_OK) { + AniWindowUtils::AniThrowError(env, errCode); + return; + } + if (windowToken_ == nullptr) { + TLOGE(WmsLogTag::WMS_LIFE, "[ANI] window is null"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); + return; + } + if (WindowHelper::IsMainWindow(windowToken_->GetType())) { + TLOGW(WmsLogTag::WMS_LIFE, "[ANI] window type %{public}u is not supported, [%{public}u, %{public}s]", + static_cast(windowToken_->GetType()), + windowToken_->GetWindowId(), windowToken_->GetWindowName().c_str()); + return; + } + WmErrorCode ret = WM_JS_TO_ERROR_CODE_MAP.at(windowToken_->Hide(0, false, false)); + TLOGI(WmsLogTag::WMS_LIFE, "[ANI] end, window [%{public}u] ret=%{public}d", + windowToken_->GetWindowId(), ret); + if (ret != WmErrorCode::WM_OK) { + AniWindowUtils::AniThrowError(env, ret); + } +} + +void AniWindow::Maximize(ani_env* env, ani_int presentation) +{ + if (windowToken_ == nullptr) { + TLOGE(WmsLogTag::WMS_LAYOUT_PC, "[ANI] WindowToken is null"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); + return; + } + if (!(WindowHelper::IsMainWindow(windowToken_->GetType()) || + windowToken_->IsSubWindowMaximizeSupported())) { + TLOGE(WmsLogTag::WMS_LAYOUT_PC, "[ANI] only support main or sub Window"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_INVALID_CALLING); + return; + } + if (presentation < static_cast(MaximizePresentation::FOLLOW_APP_IMMERSIVE_SETTING) || + presentation > static_cast(MaximizePresentation::ENTER_IMMERSIVE_DISABLE_TITLE_AND_DOCK_HOVER)) { + TLOGE(WmsLogTag::WMS_LAYOUT_PC, "[ANI] Failed to convert parameter to presentationValue"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_INVALID_PARAM); + return; + } + MaximizePresentation presentationValue = static_cast(presentation); + WMError ret = windowToken_->Maximize(presentationValue); + if (ret != WMError::WM_OK) { + TLOGE(WmsLogTag::WMS_LAYOUT_PC, "[ANI] maximize failed"); + WmErrorCode wmErrorCode = WM_JS_TO_ERROR_CODE_MAP.at(ret); + AniWindowUtils::AniThrowError(env, wmErrorCode); + } +} + +/** @note @window.layout */ +void AniWindow::Resize(ani_env* env, ani_int width, ani_int height) +{ + if (windowToken_ == nullptr) { + TLOGE(WmsLogTag::WMS_LAYOUT, "[ANI] window is null"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); + return; + } + + const uint32_t w = static_cast(width); + const uint32_t h = static_cast(height); + const WMError ret = windowToken_->Resize(w, h); + const WmErrorCode errorCode = AniWindowUtils::ToErrorCode(ret); + + const uint32_t windowId = windowToken_->GetWindowId(); + if (errorCode != WmErrorCode::WM_OK) { + TLOGE(WmsLogTag::WMS_LAYOUT, + "[ANI] Resize failed, windowId: %{public}u, width: %{public}u, height: %{public}u, ret: %{public}d", + windowId, w, h, static_cast(ret)); + AniWindowUtils::AniThrowError(env, errorCode); + return; + } + + TLOGD(WmsLogTag::WMS_LAYOUT, "[ANI] Resize success, windowId: %{public}u, width: %{public}u, height: %{public}u", + windowId, w, h); + return; +} + +/** @note @window.layout */ +void AniWindow::MoveWindowTo(ani_env* env, ani_int x, ani_int y) +{ + if (windowToken_ == nullptr) { + TLOGE(WmsLogTag::WMS_LAYOUT, "[ANI] window is null"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); + return; + } + + const int32_t targetX = static_cast(x); + const int32_t targetY = static_cast(y); + const WMError ret = windowToken_->MoveTo(targetX, targetY); + const WmErrorCode errorCode = AniWindowUtils::ToErrorCode(ret); + + const uint32_t windowId = windowToken_->GetWindowId(); + if (errorCode != WmErrorCode::WM_OK) { + TLOGE(WmsLogTag::WMS_LAYOUT, + "[ANI] MoveWindowTo failed, windowId: %{public}u, x: %{public}d, y: %{public}d, ret: %{public}d", + windowId, targetX, targetY, static_cast(ret)); + AniWindowUtils::AniThrowError(env, errorCode); + return; + } + + TLOGD(WmsLogTag::WMS_LAYOUT, "[ANI] MoveWindowTo success, windowId: %{public}u, x: %{public}d, y: %{public}d", + windowId, targetX, targetY); + return; +} + +/** @note @window.layout */ +ani_object AniWindow::GetGlobalRect(ani_env* env) +{ + if (windowToken_ == nullptr) { + TLOGE(WmsLogTag::WMS_LAYOUT, "[ANI] window is null"); + return AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); + } + + Rect globalScaledRect = Rect::EMPTY_RECT; + const WMError ret = windowToken_->GetGlobalScaledRect(globalScaledRect); + const WmErrorCode errorCode = AniWindowUtils::ToErrorCode(ret); + + const uint32_t windowId = windowToken_->GetWindowId(); + if (errorCode != WmErrorCode::WM_OK) { + TLOGE(WmsLogTag::WMS_LAYOUT, "[ANI] GetGlobalRect failed, windowId: %{public}u, ret: %{public}d", + windowId, static_cast(ret)); + return AniWindowUtils::AniThrowError(env, errorCode); + } + + TLOGD(WmsLogTag::WMS_LAYOUT, "[ANI] Window [%{public}u, %{public}s], globalScaledRect: %{public}s", + windowId, windowToken_->GetWindowName().c_str(), globalScaledRect.ToString().c_str()); + return AniWindowUtils::CreateAniRect(env, globalScaledRect); +} + +ani_int AniWindow::GetWindowDecorHeight(ani_env* env) +{ + int32_t height { 0 }; + wptr weakToken(windowToken_); + auto window = weakToken.promote(); + if (window == nullptr) { + TLOGE(WmsLogTag::DEFAULT, "[ANI] window is nullptr"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); + return ANI_ERROR; + } + WMError ret = windowToken_->GetDecorHeight(height); + if (ret != WMError::WM_OK) { + if (ret == WMError::WM_ERROR_DEVICE_NOT_SUPPORT) { + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_DEVICE_NOT_SUPPORT); + return ANI_ERROR; + } + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); + return 0; + } + TLOGI(WmsLogTag::DEFAULT, "[ANI] Window [%{public}u, %{public}s] OnGetDecorHeight end, height = %{public}d", + windowToken_->GetWindowId(), windowToken_->GetWindowName().c_str(), height); + return static_cast(height); +} + +ani_object AniWindow::SetWindowBackgroundColor(ani_env* env, const std::string& color) +{ + if (windowToken_ == nullptr) { + TLOGE(WmsLogTag::WMS_ATTRIBUTE, "[ANI] windowToken_ is nullptr"); + return AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); + } + WmErrorCode ret = WM_JS_TO_ERROR_CODE_MAP.at(windowToken_->SetBackgroundColor(color)); + if (ret == WmErrorCode::WM_OK) { + TLOGI(WmsLogTag::WMS_ATTRIBUTE, "Window [%{public}u, %{public}s] set background color end", + windowToken_->GetWindowId(), windowToken_->GetWindowName().c_str()); + return AniWindowUtils::CreateAniUndefined(env); + } else { + return AniWindowUtils::AniThrowError(env, ret); + } +} + +void AniWindow::RegisterWindowCallback(ani_env* env, ani_object obj, ani_long nativeObj, ani_string type, + ani_ref callback) +{ + TLOGI(WmsLogTag::DEFAULT, "[ANI]"); + AniWindow* aniWindow = reinterpret_cast(nativeObj); + ani_long timeOut = 0; + if (aniWindow != nullptr) { + aniWindow->OnRegisterWindowCallback(env, type, callback, timeOut); + } else { + TLOGE(WmsLogTag::DEFAULT, "[ANI] aniWindow is nullptr"); + } +} + +void AniWindow::RegisterNoInteractionDetectedCallback(ani_env* env, ani_object obj, ani_long nativeObj, ani_string type, + ani_long timeOut, ani_ref callback) +{ + TLOGI(WmsLogTag::DEFAULT, "[ANI]"); + AniWindow* aniWindow = reinterpret_cast(nativeObj); + if (aniWindow != nullptr) { + aniWindow->OnRegisterWindowCallback(env, type, callback, timeOut); + } else { + TLOGE(WmsLogTag::DEFAULT, "[ANI] aniWindow is nullptr"); + } +} + +void AniWindow::OnRegisterWindowCallback(ani_env* env, ani_string type, ani_ref callback, ani_long timeOut) +{ + 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 cbType; + AniWindowUtils::GetStdString(env, type, cbType); + TLOGI(WmsLogTag::DEFAULT, "[ANI] type:%{public}s", cbType.c_str()); + WmErrorCode ret = registerManager_->RegisterListener(window, cbType, CaseType::CASE_WINDOW, env, callback, timeOut); + if (ret != WmErrorCode::WM_OK) { + AniWindowUtils::AniThrowError(env, ret); + return; + } +} + +void AniWindow::UnregisterWindowCallback(ani_env* env, ani_object obj, ani_long nativeObj, ani_string type, + ani_ref callback) +{ + TLOGI(WmsLogTag::DEFAULT, "[ANI]"); + AniWindow* aniWindow = reinterpret_cast(nativeObj); + if (aniWindow != nullptr) { + aniWindow->OnUnregisterWindowCallback(env, type, callback); + } else { + TLOGE(WmsLogTag::DEFAULT, "[ANI] aniWindow is nullptr"); + } +} + +void AniWindow::OnUnregisterWindowCallback(ani_env* env, ani_string type, ani_ref callback) +{ + 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 cbType; + AniWindowUtils::GetStdString(env, type, cbType); + TLOGI(WmsLogTag::DEFAULT, "[ANI] type:%{public}s", cbType.c_str()); + WmErrorCode ret = registerManager_->UnregisterListener(window, cbType, CaseType::CASE_WINDOW, env, callback); + if (ret != WmErrorCode::WM_OK) { + AniWindowUtils::AniThrowError(env, ret); + return; + } +} + +void AniWindow::ShowWindow(ani_env* env, ani_object obj, ani_long nativeObj) +{ + TLOGI(WmsLogTag::DEFAULT, "[ANI]"); + AniWindow* aniWindow = reinterpret_cast(nativeObj); + if (aniWindow != nullptr) { + aniWindow->OnShowWindow(env); + } else { + TLOGE(WmsLogTag::DEFAULT, "[ANI] aniWindow is nullptr"); + } +} + +void AniWindow::OnShowWindow(ani_env* env) +{ + 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; + } + if (WindowHelper::IsMainWindowAndNotShown(window->GetType(), window->GetWindowState())) { + TLOGW(WmsLogTag::WMS_LIFE, + "window Type %{public}u and window state %{public}u is not supported, [%{public}u, %{public}s]", + static_cast(window->GetType()), static_cast(window->GetWindowState()), + window->GetWindowId(), window->GetWindowName().c_str()); + return; + } + WmErrorCode ret = WM_JS_TO_ERROR_CODE_MAP.at(window->Show(0, false, true)); + TLOGI(WmsLogTag::WMS_LIFE, "Window [%{public}u, %{public}s] show with ret=%{public}d", + window->GetWindowId(), window->GetWindowName().c_str(), ret); + if (ret != WmErrorCode::WM_OK) { + AniWindowUtils::AniThrowError(env, ret, "Window show failed"); + return; + } +} + +void AniWindow::DestroyWindow(ani_env* env, ani_object obj, ani_long nativeObj) +{ + TLOGI(WmsLogTag::DEFAULT, "[ANI]"); + AniWindow* aniWindow = reinterpret_cast(nativeObj); + if (aniWindow != nullptr) { + aniWindow->OnDestroyWindow(env); + } else { + TLOGE(WmsLogTag::DEFAULT, "[ANI] aniWindow is nullptr"); + } +} + +void AniWindow::OnDestroyWindow(ani_env* env) +{ + 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; + } + if (WindowHelper::IsMainWindow(window->GetType())) { + TLOGW(WmsLogTag::WMS_LIFE, "window Type %{public}u is not supported, [%{public}u, %{public}s]", + static_cast(window->GetType()), + window->GetWindowId(), window->GetWindowName().c_str()); + return; + } + WmErrorCode ret = WM_JS_TO_ERROR_CODE_MAP.at(window->Destroy()); + TLOGI(WmsLogTag::WMS_LIFE, "window [%{public}u, %{public}s] ret=%{public}d", + window->GetWindowId(), window->GetWindowName().c_str(), ret); + if (ret != WmErrorCode::WM_OK) { + AniWindowUtils::AniThrowError(env, ret, "Window destroy failed"); + return; + } + windowToken_ = nullptr; +} + +ani_boolean AniWindow::IsWindowShowing(ani_env* env, ani_object obj, ani_long nativeObj) +{ + TLOGI(WmsLogTag::DEFAULT, "[ANI]"); + AniWindow* aniWindow = reinterpret_cast(nativeObj); + if (aniWindow != nullptr) { + return aniWindow->OnIsWindowShowing(env); + } else { + TLOGE(WmsLogTag::DEFAULT, "[ANI] aniWindow is nullptr"); + return ani_boolean(false); + } +} + +ani_boolean AniWindow::OnIsWindowShowing(ani_env* env) +{ + 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 ani_boolean(false); + } + return ani_boolean(window->GetWindowState() == WindowState::STATE_SHOWN); +} + +void AniWindow::HideWithAnimation(ani_env* env, ani_object obj, ani_long nativeObj) +{ + TLOGI(WmsLogTag::DEFAULT, "[ANI]"); + AniWindow* aniWindow = reinterpret_cast(nativeObj); + if (aniWindow != nullptr) { + aniWindow->OnHideWithAnimation(env); + } else { + TLOGE(WmsLogTag::DEFAULT, "[ANI] aniWindow is nullptr"); + } +} + +void AniWindow::OnHideWithAnimation(ani_env* env) +{ + TLOGI(WmsLogTag::DEFAULT, "[ANI]"); + if (!Permission::IsSystemCallingOrStartByHdcd(true)) { + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_NOT_SYSTEM_APP); + return; + } + auto window = GetWindow(); + if (window == nullptr) { + TLOGE(WmsLogTag::DEFAULT, "[ANI] window is nullptr"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); + return; + } + auto winType = window->GetType(); + if (!WindowHelper::IsSystemWindow(winType)) { + TLOGE(WmsLogTag::WMS_LIFE, + "window Type %{public}u is not supported", static_cast(winType)); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_INVALID_CALLING); + return; + } + WmErrorCode ret = WM_JS_TO_ERROR_CODE_MAP.at(window->Hide(0, true, false)); + if (ret != WmErrorCode::WM_OK) { + AniWindowUtils::AniThrowError(env, ret, "Window show failed"); + return; + } +} + +void AniWindow::ShowWithAnimation(ani_env* env, ani_object obj, ani_long nativeObj) +{ + TLOGI(WmsLogTag::DEFAULT, "[ANI]"); + AniWindow* aniWindow = reinterpret_cast(nativeObj); + if (aniWindow != nullptr) { + aniWindow->OnShowWithAnimation(env); + } else { + TLOGE(WmsLogTag::DEFAULT, "[ANI] aniWindow is nullptr"); + } +} + +void AniWindow::OnShowWithAnimation(ani_env* env) +{ + TLOGI(WmsLogTag::DEFAULT, "[ANI]"); + if (!Permission::IsSystemCallingOrStartByHdcd(true)) { + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_NOT_SYSTEM_APP); + return; + } + auto window = GetWindow(); + if (window == nullptr) { + TLOGE(WmsLogTag::DEFAULT, "[ANI] window is nullptr"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); + return; + } + auto winType = window->GetType(); + if (!WindowHelper::IsSystemWindow(winType)) { + TLOGE(WmsLogTag::WMS_LIFE, + "window Type %{public}u is not supported", static_cast(winType)); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_INVALID_CALLING); + return; + } + WmErrorCode ret = WM_JS_TO_ERROR_CODE_MAP.at(window->Show(0, true, true)); + if (ret != WmErrorCode::WM_OK) { + AniWindowUtils::AniThrowError(env, ret, "Window show failed"); + return; + } +} + +void AniWindow::KeepKeyboardOnFocus(ani_env* env, ani_object obj, ani_long nativeObj, ani_boolean keepKeyboardFlag) +{ + TLOGI(WmsLogTag::WMS_KEYBOARD, "[ANI]In"); + AniWindow* aniWindow = reinterpret_cast(nativeObj); + if (aniWindow != nullptr) { + aniWindow->OnKeepKeyboardOnFocus(env, keepKeyboardFlag); + } else { + TLOGE(WmsLogTag::DEFAULT, "[ANI] aniWindow is nullptr"); + } +} + +void AniWindow::OnKeepKeyboardOnFocus(ani_env* env, ani_boolean keepKeyboardFlag) +{ + if (windowToken_ == nullptr) { + TLOGE(WmsLogTag::WMS_KEYBOARD, "WindowToken_ is nullptr"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); + return; + } + if (!WindowHelper::IsSystemWindow(windowToken_->GetType()) && + !WindowHelper::IsSubWindow(windowToken_->GetType())) { + TLOGE(WmsLogTag::WMS_KEYBOARD, "not allowed since window is not system window or app subwindow"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_INVALID_CALLING); + return; + } + + WmErrorCode ret = windowToken_->KeepKeyboardOnFocus(keepKeyboardFlag); + if (ret != WmErrorCode::WM_OK) { + TLOGE(WmsLogTag::WMS_KEYBOARD, "failed"); + AniWindowUtils::AniThrowError(env, ret); + } + TLOGE(WmsLogTag::WMS_KEYBOARD, "end, window [%{public}u, %{public}s] keepKeyboardFlag=%{public}d", + windowToken_->GetWindowId(), windowToken_->GetWindowName().c_str(), keepKeyboardFlag); +} + +ani_object AniWindow::SetImmersiveModeEnabledState(ani_env* env, bool enable) +{ + if (windowToken_ == nullptr) { + TLOGE(WmsLogTag::WMS_IMMS, "WindowToken_ is nullptr"); + return AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); + } + if (!WindowHelper::IsMainWindow(windowToken_->GetType()) && + !WindowHelper::IsSubWindow(windowToken_->GetType())) { + TLOGE(WmsLogTag::WMS_IMMS, "[ANI] OnSetImmersiveModeEnabledState is not allowed since invalid window type"); + return AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_INVALID_CALLING); + } + + if (windowToken_->IsPcOrPadFreeMultiWindowMode()) { + TLOGE(WmsLogTag::WMS_IMMS, "[ANI] device not support"); + return AniWindowUtils::CreateAniUndefined(env); + } + + TLOGI(WmsLogTag::WMS_IMMS, "[ANI] OnSetImmersiveModeEnabledState to %{public}d", static_cast(enable)); + WmErrorCode ret = WM_JS_TO_ERROR_CODE_MAP.at(windowToken_->SetImmersiveModeEnabledState(static_cast(enable))); + if (ret != WmErrorCode::WM_OK) { + TLOGE(WmsLogTag::WMS_IMMS, "[ANI] Window immersive mode set enabled failed, ret = %{public}d", ret); + return AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_SYSTEM_ABNORMALLY); + } + + TLOGI(WmsLogTag::WMS_IMMS, "[ANI] window [%{public}u, %{public}s] OnSetImmersiveModeEnabledState end", + windowToken_->GetWindowId(), windowToken_->GetWindowName().c_str()); + return AniWindowUtils::CreateAniUndefined(env); +} + +ani_object AniWindow::SetWindowDecorVisible(ani_env* env, bool isVisible) +{ + WmErrorCode ret = WM_JS_TO_ERROR_CODE_MAP.at(windowToken_->SetDecorVisible(static_cast(isVisible))); + TLOGI(WmsLogTag::WMS_IMMS, "[ANI] OnSetWindowDecorVisible to %{public}d", static_cast(isVisible)); + if (ret != WmErrorCode::WM_OK) { + TLOGE(WmsLogTag::DEFAULT, "[ANI] Window decor set visible failed"); + return AniWindowUtils::AniThrowError(env, ret); + } + TLOGI(WmsLogTag::DEFAULT, "[ANI] Window [%{public}u, %{public}s] OnSetWindowDecorVisible end", + windowToken_->GetWindowId(), windowToken_->GetWindowName().c_str()); + return AniWindowUtils::CreateAniUndefined(env); +} + +ani_object AniWindow::SetWindowDecorHeight(ani_env* env, ani_int height) +{ + if (height < MIN_DECOR_HEIGHT || height > MAX_DECOR_HEIGHT) { + TLOGE(WmsLogTag::DEFAULT, "[ANI] height should greater than 37 or smaller than 112"); + return AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_INVALID_PARAM); + } + + WmErrorCode ret = WM_JS_TO_ERROR_CODE_MAP.at(windowToken_->SetDecorHeight(static_cast(height))); + if (ret != WmErrorCode::WM_OK) { + TLOGE(WmsLogTag::DEFAULT, "[ANI] Set window decor height failed"); + return AniWindowUtils::AniThrowError(env, ret); + } + TLOGI(WmsLogTag::DEFAULT, "[ANI] Window [%{public}u, %{public}s] OnSetDecorHeight end, height = %{public}d", + windowToken_->GetWindowId(), windowToken_->GetWindowName().c_str(), static_cast(height)); + return AniWindowUtils::CreateAniUndefined(env); +} + +ani_object AniWindow::GetWindowPropertiesSync(ani_env* env) +{ + TLOGI(WmsLogTag::WMS_ATTRIBUTE, "[ANI]"); + if (windowToken_ == nullptr) { + TLOGE(WmsLogTag::WMS_ATTRIBUTE, "[ANI] windowToken_ is nullptr"); + return AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); + } + auto objValue = AniWindowUtils::CreateWindowsProperties(env, windowToken_); + if (objValue == nullptr) { + return AniWindowUtils::AniThrowError(env, WMError::WM_ERROR_NULLPTR, "[ANI] Window get properties failed"); + } + TLOGI(WmsLogTag::WMS_ATTRIBUTE, "[ANI] Window [%{public}u, %{public}s] get properties end", + windowToken_->GetWindowId(), windowToken_->GetWindowName().c_str()); + return objValue; +} + +ani_boolean AniWindow::IsWindowSupportWideGamut(ani_env* env) +{ + TLOGI(WmsLogTag::DEFAULT, "[ANI]"); + if (windowToken_ == nullptr) { + TLOGE(WmsLogTag::WMS_ATTRIBUTE, "windowToken_ is nullptr"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); + return false; + } + ani_boolean res = static_cast(windowToken_->IsSupportWideGamut()); + return res; +} + +ani_object AniWindow::SetWindowLayoutFullScreen(ani_env* env, ani_boolean isLayoutFullScreen) +{ + if (windowToken_ == nullptr) { + TLOGE(WmsLogTag::WMS_IMMS, "windowToken_ is nullptr"); + return AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); + } + + if (windowToken_->IsPcOrPadFreeMultiWindowMode()) { + TLOGE(WmsLogTag::WMS_IMMS, "[ANI] device not support"); + return AniWindowUtils::CreateAniUndefined(env); + } + + WMError ret = windowToken_->SetLayoutFullScreen(static_cast(isLayoutFullScreen)); + if (ret != WMError::WM_OK) { + TLOGE(WmsLogTag::WMS_IMMS, "[ANI] fullscreen set error"); + return AniWindowUtils::CreateAniUndefined(env); + } + return 0; +} + +void AniWindow::SetSystemBarProperties(ani_env* env, ani_object aniSystemBarProperties) +{ + if (windowToken_ == nullptr) { + TLOGE(WmsLogTag::WMS_IMMS, "[ANI] windowToken_ is nullptr"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); + return; + } + std::map aniProperties; + std::map aniSystemBarPropertyFlags; + + if (!AniWindowUtils::SetSystemBarPropertiesFromAni(env, aniProperties, aniSystemBarPropertyFlags, + aniSystemBarProperties, windowToken_)) { + TLOGE(WmsLogTag::WMS_IMMS, "[ANI] Failed to convert parameter to systemBarProperties"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_INVALID_PARAM); + return; + } + + std::map systemBarProperties; + std::map systemBarPropertyFlags; + AniWindowUtils::GetSystemBarPropertiesFromAni(windowToken_, aniProperties, aniSystemBarPropertyFlags, + systemBarProperties, systemBarPropertyFlags); + AniWindowUtils::UpdateSystemBarProperties(systemBarProperties, systemBarPropertyFlags, windowToken_); + WMError ret = SetSystemBarPropertiesByFlags( + systemBarPropertyFlags, systemBarProperties, windowToken_); + if (ret != WMError::WM_OK) { + AniWindowUtils::AniThrowError(env, WMError::WM_ERROR_NULLPTR, "[ANI] Window SetSystemBarProperties failed"); + return; + } + + TLOGI(WmsLogTag::WMS_IMMS, "[ANI] Succeed in setting systemBarProperties"); +} + +ani_object AniWindow::SetSpecificSystemBarEnabled(ani_env* env, ani_string name, ani_boolean enable, + ani_boolean enableAnimation) +{ + TLOGI(WmsLogTag::WMS_IMMS, "[ANI]"); + std::map aniSystemBarProperties; + if (!AniWindowUtils::SetSpecificSystemBarEnabled(env, aniSystemBarProperties, name, enable, enableAnimation)) { + TLOGE(WmsLogTag::WMS_IMMS, "[ANI] invalid param or argc"); + return AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_INVALID_PARAM); + } + std::map systemBarProperties; + std::string barName; + ani_status ret = AniWindowUtils::GetStdString(env, name, barName); + if (ret != ANI_OK) { + TLOGE(WmsLogTag::WMS_IMMS, "[ANI] invalid param of name"); + return AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_INVALID_PARAM); + } + if (windowToken_ == nullptr) { + TLOGE(WmsLogTag::WMS_IMMS, "[ANI] windowToken_ is nullptr"); + return AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); + } + AniWindowUtils::GetSpecificBarStatus(windowToken_, barName, aniSystemBarProperties, systemBarProperties); + WmErrorCode err = WmErrorCode::WM_OK; + if (barName.compare("status") == 0) { + err = WM_JS_TO_ERROR_CODE_MAP.at(windowToken_->SetSpecificBarProperty( + WindowType::WINDOW_TYPE_STATUS_BAR, systemBarProperties.at(WindowType::WINDOW_TYPE_STATUS_BAR))); + } else if (barName.compare("navigation") == 0) { + err = WM_JS_TO_ERROR_CODE_MAP.at(windowToken_->SetSpecificBarProperty(WindowType::WINDOW_TYPE_NAVIGATION_BAR, + systemBarProperties.at(WindowType::WINDOW_TYPE_NAVIGATION_BAR))); + } else if (barName.compare("navigationIndicator") == 0) { + err = WM_JS_TO_ERROR_CODE_MAP.at(windowToken_->SetSpecificBarProperty( + WindowType::WINDOW_TYPE_NAVIGATION_INDICATOR, + systemBarProperties.at(WindowType::WINDOW_TYPE_NAVIGATION_INDICATOR))); + } + + if (err == WmErrorCode::WM_OK) { + return AniWindowUtils::CreateAniUndefined(env); + } + + 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]; +} + +ani_object AniWindow::Snapshot(ani_env* env) +{ + if (windowToken_ == nullptr) { + TLOGE(WmsLogTag::WMS_ATTRIBUTE, "[ANI] windowToken_ is nullptr"); + return AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); + } + std::shared_ptr pixelMap = windowToken_->Snapshot(); + if (pixelMap == nullptr) { + return AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); + } + auto nativePixelMap = Media::PixelMapTaiheAni::CreateEtsPixelMap(env, pixelMap); + if (nativePixelMap == nullptr) { + return AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); + } + TLOGI(WmsLogTag::WMS_ATTRIBUTE, "Window [%{public}u, %{public}s], WxH=%{public}dx%{public}d", + windowToken_->GetWindowId(), windowToken_->GetWindowName().c_str(), + pixelMap->GetWidth(), pixelMap->GetHeight()); + return nativePixelMap; +} + +void AniWindow::HideNonSystemFloatingWindows(ani_env* env, ani_boolean shouldHide) +{ + if (windowToken_ == nullptr) { + TLOGE(WmsLogTag::WMS_ATTRIBUTE, "windowToken_ is nullptr"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); + return; + } + if (windowToken_->IsFloatingWindowAppType()) { + TLOGE(WmsLogTag::WMS_ATTRIBUTE, "window is app floating window"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_INVALID_CALLING, + "HideNonSystemFloatingWindows is not allowed since window is app floating window"); + return; + } + WMError ret = windowToken_->HideNonSystemFloatingWindows(shouldHide); + if (ret != WMError::WM_OK) { + TLOGE(WmsLogTag::WMS_ATTRIBUTE, "failed"); + AniWindowUtils::AniThrowError(env, WM_JS_TO_ERROR_CODE_MAP.at(ret), + "Hide non-system floating windows failed"); + return; + } + TLOGI(WmsLogTag::WMS_ATTRIBUTE, + "end. Window [%{public}u, %{public}s]", + windowToken_->GetWindowId(), windowToken_->GetWindowName().c_str()); +} + +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 + +static void SetFollowParentWindowLayoutEnabled(ani_env* env, ani_object obj, ani_long nativeObj, ani_boolean enabled) +{ + using namespace OHOS::Rosen; + TLOGI(WmsLogTag::WMS_SUB, "[ANI] start"); + AniWindow* aniWindow = reinterpret_cast(nativeObj); + if (aniWindow == nullptr || aniWindow->GetWindow() == nullptr) { + TLOGE(WmsLogTag::WMS_SUB, "[ANI] windowToken is null"); + return; + } + aniWindow->SetFollowParentWindowLayoutEnabled(env, enabled); +} + +static void SetWindowDelayRaiseOnDrag(ani_env* env, ani_object obj, ani_long nativeObj, ani_boolean isEnabled) +{ + using namespace OHOS::Rosen; + TLOGI(WmsLogTag::WMS_FOCUS, "[ANI] start"); + AniWindow* aniWindow = reinterpret_cast(nativeObj); + if (aniWindow == nullptr || aniWindow->GetWindow() == nullptr) { + TLOGE(WmsLogTag::WMS_FOCUS, "[ANI] windowToken is null"); + return; + } + aniWindow->SetWindowDelayRaiseOnDrag(env, isEnabled); +} + +static ani_ref GetParentWindow(ani_env* env, ani_object obj, ani_long nativeObj) +{ + using namespace OHOS::Rosen; + TLOGI(WmsLogTag::WMS_SUB, "[ANI] start"); + AniWindow* aniWindow = reinterpret_cast(nativeObj); + if (aniWindow == nullptr || aniWindow->GetWindow() == nullptr) { + TLOGE(WmsLogTag::WMS_SUB, "[ANI] windowToken is null"); + return AniWindowUtils::CreateAniUndefined(env); + } + return aniWindow->GetParentWindow(env); +} + +static ani_boolean GetWindowDecorVisible(ani_env* env, ani_object obj, ani_long nativeObj) +{ + using namespace OHOS::Rosen; + TLOGI(WmsLogTag::WMS_DECOR, "[ANI] start"); + AniWindow* aniWindow = reinterpret_cast(nativeObj); + if (aniWindow == nullptr || aniWindow->GetWindow() == nullptr) { + TLOGE(WmsLogTag::WMS_DECOR, "[ANI] windowToken is null"); + return ani_boolean(false); + } + return aniWindow->GetWindowDecorVisible(env); +} + +static void StopMoving(ani_env* env, ani_object obj, ani_long nativeObj) +{ + using namespace OHOS::Rosen; + TLOGI(WmsLogTag::WMS_LAYOUT_PC, "[ANI] start"); + AniWindow* aniWindow = reinterpret_cast(nativeObj); + if (aniWindow == nullptr || aniWindow->GetWindow() == nullptr) { + TLOGE(WmsLogTag::WMS_LAYOUT_PC, "[ANI] windowToken is null"); + return; + } + aniWindow->StopMoving(env); +} + +static void SetParentWindow(ani_env* env, ani_object obj, ani_long nativeObj, ani_double windowId) +{ + using namespace OHOS::Rosen; + TLOGI(WmsLogTag::WMS_SUB, "[ANI] start"); + AniWindow* aniWindow = reinterpret_cast(nativeObj); + if (aniWindow == nullptr || aniWindow->GetWindow() == nullptr) { + TLOGE(WmsLogTag::WMS_SUB, "[ANI] windowToken is null"); return; } + aniWindow->SetParentWindow(env, windowId); } -ani_object AniWindow::SetImmersiveModeEnabledState(ani_env* env, bool enable) +static void SetWindowTitle(ani_env* env, ani_object obj, ani_long nativeObj, ani_string titleName) { - if (!WindowHelper::IsMainWindow(windowToken_->GetType()) && - !WindowHelper::IsSubWindow(windowToken_->GetType())) { - TLOGE(WmsLogTag::WMS_IMMS, "[ANI] OnSetImmersiveModeEnabledState is not allowed since invalid window type"); - return AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_INVALID_CALLING); + using namespace OHOS::Rosen; + TLOGI(WmsLogTag::WMS_DECOR, "[ANI] start"); + AniWindow* aniWindow = reinterpret_cast(nativeObj); + if (aniWindow == nullptr || aniWindow->GetWindow() == nullptr) { + TLOGE(WmsLogTag::WMS_DECOR, "[ANI] windowToken is null"); + return; } + aniWindow->SetWindowTitle(env, titleName); +} - if (windowToken_->IsPcOrPadFreeMultiWindowMode()) { - TLOGE(WmsLogTag::WMS_IMMS, "[ANI] device not support"); +static ani_object GetDecorButtonStyle(ani_env* env, ani_object obj, ani_long nativeObj) +{ + using namespace OHOS::Rosen; + TLOGI(WmsLogTag::WMS_DECOR, "[ANI] start"); + AniWindow* aniWindow = reinterpret_cast(nativeObj); + if (aniWindow == nullptr || aniWindow->GetWindow() == nullptr) { + TLOGE(WmsLogTag::WMS_DECOR, "[ANI] windowToken is null"); return AniWindowUtils::CreateAniUndefined(env); } + return aniWindow->GetDecorButtonStyle(env); +} - TLOGI(WmsLogTag::WMS_IMMS, "[ANI] OnSetImmersiveModeEnabledState to %{public}d", static_cast(enable)); - WmErrorCode ret = WM_JS_TO_ERROR_CODE_MAP.at(windowToken_->SetImmersiveModeEnabledState(static_cast(enable))); - if (ret != WmErrorCode::WM_OK) { - TLOGE(WmsLogTag::WMS_IMMS, "[ANI] Window immersive mode set enabled failed, ret = %{public}d", ret); - return AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_SYSTEM_ABNORMALLY); +static ani_object GetTitleButtonRect(ani_env* env, ani_object obj, ani_long nativeObj) +{ + using namespace OHOS::Rosen; + TLOGI(WmsLogTag::WMS_DECOR, "[ANI] start"); + AniWindow* aniWindow = reinterpret_cast(nativeObj); + if (aniWindow == nullptr || aniWindow->GetWindow() == nullptr) { + TLOGE(WmsLogTag::WMS_DECOR, "[ANI] windowToken is null"); + return AniWindowUtils::CreateAniUndefined(env); } - - TLOGI(WmsLogTag::WMS_IMMS, "[ANI] window [%{public}u, %{public}s] OnSetImmersiveModeEnabledState end", - windowToken_->GetWindowId(), windowToken_->GetWindowName().c_str()); - return AniWindowUtils::CreateAniUndefined(env); + return aniWindow->GetTitleButtonRect(env); } -ani_object AniWindow::SetWindowDecorVisible(ani_env* env, bool isVisible) +static void SetTitleButtonVisible(ani_env* env, ani_object obj, ani_long nativeObj, ani_object titleButtonVisibleParam) { - WmErrorCode ret = WM_JS_TO_ERROR_CODE_MAP.at(windowToken_->SetDecorVisible(static_cast(isVisible))); - TLOGI(WmsLogTag::WMS_IMMS, "[ANI] OnSetWindowDecorVisible to %{public}d", static_cast(isVisible)); - if (ret != WmErrorCode::WM_OK) { - TLOGE(WmsLogTag::DEFAULT, "[ANI] Window decor set visible failed"); - return AniWindowUtils::AniThrowError(env, ret); + using namespace OHOS::Rosen; + TLOGI(WmsLogTag::WMS_DECOR, "[ANI] start"); + AniWindow* aniWindow = reinterpret_cast(nativeObj); + if (aniWindow == nullptr || aniWindow->GetWindow() == nullptr) { + TLOGE(WmsLogTag::WMS_DECOR, "[ANI] windowToken is null"); + return; } - TLOGI(WmsLogTag::DEFAULT, "[ANI] Window [%{public}u, %{public}s] OnSetWindowDecorVisible end", - windowToken_->GetWindowId(), windowToken_->GetWindowName().c_str()); - return AniWindowUtils::CreateAniUndefined(env); + aniWindow->SetTitleButtonVisible(env, titleButtonVisibleParam); } -ani_object AniWindow::SetWindowDecorHeight(ani_env* env, ani_double height) +static void SetWindowTitleMoveEnabled(ani_env* env, ani_object obj, ani_long nativeObj, ani_boolean enabled) { - if (height < MIN_DECOR_HEIGHT || height > MAX_DECOR_HEIGHT) { - TLOGE(WmsLogTag::DEFAULT, "[ANI] height should greater than 37 or smaller than 112"); - return AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_INVALID_PARAM); + using namespace OHOS::Rosen; + TLOGI(WmsLogTag::WMS_DECOR, "[ANI] start"); + AniWindow* aniWindow = reinterpret_cast(nativeObj); + if (aniWindow == nullptr || aniWindow->GetWindow() == nullptr) { + TLOGE(WmsLogTag::WMS_DECOR, "[ANI] windowToken is null"); + return; } + aniWindow->SetWindowTitleMoveEnabled(env, enabled); +} - WmErrorCode ret = WM_JS_TO_ERROR_CODE_MAP.at(windowToken_->SetDecorHeight(static_cast(height))); - if (ret != WmErrorCode::WM_OK) { - TLOGE(WmsLogTag::DEFAULT, "[ANI] Set window decor height failed"); - return AniWindowUtils::AniThrowError(env, ret); +static void SetWindowTopmost(ani_env* env, ani_object obj, ani_long nativeObj, ani_boolean isWindowTopmost) +{ + using namespace OHOS::Rosen; + TLOGI(WmsLogTag::WMS_HIERARCHY, "[ANI] start"); + AniWindow* aniWindow = reinterpret_cast(nativeObj); + if (aniWindow == nullptr || aniWindow->GetWindow() == nullptr) { + TLOGE(WmsLogTag::WMS_HIERARCHY, "[ANI] windowToken is null"); + return; } - TLOGI(WmsLogTag::DEFAULT, "[ANI] Window [%{public}u, %{public}s] OnSetDecorHeight end, height = %{public}d", - windowToken_->GetWindowId(), windowToken_->GetWindowName().c_str(), static_cast(height)); - return AniWindowUtils::CreateAniUndefined(env); + aniWindow->SetWindowTopmost(env, isWindowTopmost); } -ani_object AniWindow::GetWindowPropertiesSync(ani_env* env) +static void SetTitleAndDockHoverShown(ani_env* env, ani_object obj, ani_long nativeObj, + ani_boolean isTitleHoverShown, ani_boolean isDockHoverShown) { - wptr weakToken(windowToken_); - TLOGI(WmsLogTag::WMS_IMMS, "[ANI]"); - auto weakWindow = weakToken.promote(); - if (weakWindow == nullptr) { - TLOGE(WmsLogTag::WMS_IMMS, "[ANI] windowToken_ is nullptr"); - return AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_INVALID_PARAM); + using namespace OHOS::Rosen; + TLOGI(WmsLogTag::WMS_LAYOUT_PC, "[ANI] start"); + AniWindow* aniWindow = reinterpret_cast(nativeObj); + if (aniWindow == nullptr || aniWindow->GetWindow() == nullptr) { + TLOGE(WmsLogTag::WMS_LAYOUT_PC, "[ANI] windowToken is null"); + return; } + aniWindow->SetTitleAndDockHoverShown(env, isTitleHoverShown, isDockHoverShown); +} - auto objValue = AniWindowUtils::CreateWindowsProperties(env, weakWindow); - if (objValue == nullptr) { - return AniWindowUtils::AniThrowError(env, WMError::WM_ERROR_NULLPTR, "[ANI] Window get properties failed"); +static void Restore(ani_env* env, ani_object obj, ani_long nativeObj) +{ + using namespace OHOS::Rosen; + TLOGI(WmsLogTag::WMS_LAYOUT_PC, "[ANI] start"); + AniWindow* aniWindow = reinterpret_cast(nativeObj); + if (aniWindow == nullptr || aniWindow->GetWindow() == nullptr) { + TLOGE(WmsLogTag::WMS_LAYOUT_PC, "[ANI] windowToken is null"); + return; } - TLOGI(WmsLogTag::WMS_IMMS, "[ANI] Window [%{public}u, %{public}s] get properties end", - weakWindow->GetWindowId(), weakWindow->GetWindowName().c_str()); - return objValue; + aniWindow->Restore(env); } -ani_boolean AniWindow::IsWindowSupportWideGamut(ani_env* env) +static void StartMoving(ani_env* env, ani_object obj, ani_long nativeObj) { - TLOGI(WmsLogTag::DEFAULT, "[ANI]"); - ani_boolean res = static_cast(windowToken_->IsSupportWideGamut()); - TLOGI(WmsLogTag::DEFAULT, "[ANI] Window IsWindowSupportWideGamut end"); - return res; + using namespace OHOS::Rosen; + TLOGI(WmsLogTag::WMS_LAYOUT, "[ANI] start"); + AniWindow* aniWindow = reinterpret_cast(nativeObj); + if (aniWindow == nullptr || aniWindow->GetWindow() == nullptr) { + TLOGE(WmsLogTag::WMS_LAYOUT, "[ANI] windowToken is null"); + return; + } + aniWindow->StartMoving(env); } -ani_object AniWindow::SetWindowLayoutFullScreen(ani_env* env, ani_boolean isLayoutFullScreen) +static void StartMoveWindowWithCoordinate(ani_env* env, ani_object obj, ani_long nativeObj, + ani_int offsetX, ani_int offsetY) { - if (windowToken_ == nullptr) { - return AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); + using namespace OHOS::Rosen; + TLOGI(WmsLogTag::WMS_LAYOUT, "[ANI] start"); + AniWindow* aniWindow = reinterpret_cast(nativeObj); + if (aniWindow == nullptr || aniWindow->GetWindow() == nullptr) { + TLOGE(WmsLogTag::WMS_LAYOUT, "[ANI] windowToken is null"); + return; } + aniWindow->StartMoveWindowWithCoordinate(env, offsetX, offsetY); +} - if (windowToken_->IsPcOrPadFreeMultiWindowMode()) { - TLOGE(WmsLogTag::WMS_IMMS, "[ANI] device not support"); - return AniWindowUtils::CreateAniUndefined(env); +static void SetWindowTitleButtonVisible(ani_env* env, ani_object obj, ani_long nativeObj, + ani_object visibleParam) +{ + using namespace OHOS::Rosen; + TLOGI(WmsLogTag::WMS_DECOR, "[ANI] start"); + AniWindow* aniWindow = reinterpret_cast(nativeObj); + if (aniWindow == nullptr || aniWindow->GetWindow() == nullptr) { + TLOGE(WmsLogTag::WMS_DECOR, "[ANI] windowToken is null"); + return; } + aniWindow->SetWindowTitleButtonVisible(env, visibleParam); +} - WMError ret = windowToken_->SetLayoutFullScreen(static_cast(isLayoutFullScreen)); - if (ret != WMError::WM_OK) { - TLOGE(WmsLogTag::WMS_IMMS, "[ANI] fullscreen set error"); - return AniWindowUtils::CreateAniUndefined(env); +static void SetDecorButtonStyle(ani_env* env, ani_object obj, ani_long nativeObj, ani_object decorStyle) +{ + using namespace OHOS::Rosen; + TLOGI(WmsLogTag::WMS_DECOR, "[ANI] start"); + AniWindow* aniWindow = reinterpret_cast(nativeObj); + if (aniWindow == nullptr || aniWindow->GetWindow() == nullptr) { + TLOGE(WmsLogTag::WMS_DECOR, "[ANI] windowToken is null"); + return; } - return 0; + aniWindow->SetDecorButtonStyle(env, decorStyle); } -void AniWindow::SetSystemBarProperties(ani_env* env, ani_object aniSystemBarProperties) +static ani_int GetWindowStatus(ani_env* env, ani_object obj, ani_long nativeObj) { - if (windowToken_ == nullptr) { - TLOGE(WmsLogTag::WMS_IMMS, "[ANI] windowToken_ is nullptr"); - return; + using namespace OHOS::Rosen; + TLOGI(WmsLogTag::WMS_PC, "[ANI] start"); + AniWindow* aniWindow = reinterpret_cast(nativeObj); + if (aniWindow == nullptr || aniWindow->GetWindow() == nullptr) { + TLOGE(WmsLogTag::WMS_PC, "[ANI] windowToken is null"); + return ANI_ERROR; } - std::map aniProperties; - std::map aniSystemBarPropertyFlags; + return aniWindow->GetWindowStatus(env); +} - if (!AniWindowUtils::SetSystemBarPropertiesFromAni(env, aniProperties, aniSystemBarPropertyFlags, - aniSystemBarProperties, windowToken_)) { - TLOGE(WmsLogTag::WMS_IMMS, "[ANI] Failed to convert parameter to systemBarProperties"); +static void Minimize(ani_env* env, ani_object obj, ani_long nativeObj) +{ + using namespace OHOS::Rosen; + TLOGI(WmsLogTag::WMS_LAYOUT_PC, "[ANI] start"); + AniWindow* aniWindow = reinterpret_cast(nativeObj); + if (aniWindow == nullptr || aniWindow->GetWindow() == nullptr) { + TLOGE(WmsLogTag::WMS_LAYOUT_PC, "[ANI] windowToken is null"); return; } + aniWindow->Minimize(env); +} - std::map systemBarProperties; - std::map systemBarPropertyFlags; - AniWindowUtils::GetSystemBarPropertiesFromAni(windowToken_, aniProperties, aniSystemBarPropertyFlags, - systemBarProperties, systemBarPropertyFlags); - AniWindowUtils::UpdateSystemBarProperties(systemBarProperties, systemBarPropertyFlags, windowToken_); - WMError ret = SetSystemBarPropertiesByFlags( - systemBarPropertyFlags, systemBarProperties, windowToken_); - if (ret != WMError::WM_OK) { - AniWindowUtils::AniThrowError(env, WMError::WM_ERROR_NULLPTR, "[ANI] Window SetSystemBarProperties failed"); +static void Maximize(ani_env* env, ani_object obj, ani_long nativeObj, ani_int presentation) +{ + using namespace OHOS::Rosen; + TLOGI(WmsLogTag::WMS_LAYOUT_PC, "[ANI] start"); + AniWindow* aniWindow = reinterpret_cast(nativeObj); + if (aniWindow == nullptr || aniWindow->GetWindow() == nullptr) { + TLOGE(WmsLogTag::WMS_LAYOUT_PC, "[ANI] windowToken is null"); return; } - - TLOGI(WmsLogTag::WMS_IMMS, "[ANI] Succeed in setting systemBarProperties"); + aniWindow->Maximize(env, presentation); } -ani_object AniWindow::SetSpecificSystemBarEnabled(ani_env* env, ani_string name, ani_boolean enable, - ani_boolean enableAnimation) +static void WindowResize(ani_env* env, ani_object obj, ani_long nativeObj, ani_int width, ani_int height) { - TLOGI(WmsLogTag::DEFAULT, "[ANI] SetSystemBarEnable"); - std::map aniSystemBarProperties; - if (!AniWindowUtils::SetSpecificSystemBarEnabled(env, aniSystemBarProperties, name, enable, enableAnimation)) { - TLOGE(WmsLogTag::WMS_IMMS, "[ANI] invalid param or argc"); - return AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_INVALID_PARAM); - } - std::map systemBarProperties; - std::string barName; - ani_status ret = AniWindowUtils::GetStdString(env, name, barName); - if (ret != ANI_OK) { - TLOGE(WmsLogTag::WMS_IMMS, "[ANI] invalid param of name"); - return AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_INVALID_PARAM); + using namespace OHOS::Rosen; + TLOGI(WmsLogTag::WMS_LAYOUT, "[ANI]"); + AniWindow* aniWindow = reinterpret_cast(nativeObj); + if (aniWindow == nullptr || aniWindow->GetWindow() == nullptr) { + TLOGE(WmsLogTag::WMS_LAYOUT, "[ANI] windowToken is nullptr"); + AniWindowUtils::CreateAniUndefined(env); + return; } + aniWindow->Resize(env, width, height); +} - AniWindowUtils::GetSpecificBarStatus(windowToken_, barName, systemBarProperties, systemBarProperties); - WmErrorCode err = (windowToken_ == nullptr) ? WmErrorCode::WM_ERROR_STATE_ABNORMALLY : WmErrorCode::WM_OK; - if (barName.compare("status") == 0) { - err = WM_JS_TO_ERROR_CODE_MAP.at(windowToken_->SetSpecificBarProperty( - WindowType::WINDOW_TYPE_STATUS_BAR, systemBarProperties.at(WindowType::WINDOW_TYPE_STATUS_BAR))); - } else if (barName.compare("navigation") == 0) { - err = WM_JS_TO_ERROR_CODE_MAP.at(windowToken_->SetSpecificBarProperty(WindowType::WINDOW_TYPE_NAVIGATION_BAR, - systemBarProperties.at(WindowType::WINDOW_TYPE_NAVIGATION_BAR))); - } else if (barName.compare("navigationIndicator") == 0) { - err = WM_JS_TO_ERROR_CODE_MAP.at(windowToken_->SetSpecificBarProperty( - WindowType::WINDOW_TYPE_NAVIGATION_INDICATOR, - systemBarProperties.at(WindowType::WINDOW_TYPE_NAVIGATION_INDICATOR))); +static void WindowMoveWindowTo(ani_env* env, ani_object obj, ani_long nativeObj, ani_int x, ani_int y) +{ + using namespace OHOS::Rosen; + TLOGI(WmsLogTag::WMS_LAYOUT, "[ANI]"); + AniWindow* aniWindow = reinterpret_cast(nativeObj); + if (aniWindow == nullptr || aniWindow->GetWindow() == nullptr) { + TLOGE(WmsLogTag::WMS_LAYOUT, "[ANI] windowToken is nullptr"); + AniWindowUtils::CreateAniUndefined(env); + return; } + aniWindow->MoveWindowTo(env, x, y); +} - if (err == WmErrorCode::WM_OK) { +static ani_object WindowGetGlobalRect(ani_env* env, ani_object obj, ani_long nativeObj) +{ + using namespace OHOS::Rosen; + TLOGI(WmsLogTag::WMS_LAYOUT, "[ANI]"); + AniWindow* aniWindow = reinterpret_cast(nativeObj); + if (aniWindow == nullptr || aniWindow->GetWindow() == nullptr) { + TLOGE(WmsLogTag::WMS_LAYOUT, "[ANI] windowToken is nullptr"); return AniWindowUtils::CreateAniUndefined(env); } - - TLOGE(WmsLogTag::WMS_IMMS, "SetSpecificSystemBarEnabled failed, ret = %{public}d", err); - return AniWindowUtils::AniThrowError(env, err); + return aniWindow->GetGlobalRect(env); } -} // namespace Rosen -} // namespace OHOS -static ani_double WindowGetWindowDecorHeight(ani_env* env, ani_object obj, ani_long nativeObj) +static ani_int WindowGetWindowDecorHeight(ani_env* env, ani_object obj, ani_long nativeObj) { using namespace OHOS::Rosen; TLOGI(WmsLogTag::DEFAULT, "[ANI]"); @@ -811,17 +2520,17 @@ static ani_int WindowSetWindowBackgroundColor(ani_env* env, ani_object obj, ani_ ani_string color) { using namespace OHOS::Rosen; - TLOGI(WmsLogTag::DEFAULT, "[ANI]"); std::string colorStr; OHOS::Rosen::AniWindowUtils::GetStdString(env, color, colorStr); - TLOGD(WmsLogTag::DEFAULT, "[ANI] SetWindowBackgroundColor %{public}s", colorStr.c_str()); + TLOGD(WmsLogTag::WMS_ATTRIBUTE, "[ANI] SetWindowBackgroundColor %{public}s", colorStr.c_str()); AniWindow* aniWindow = reinterpret_cast(nativeObj); - if (aniWindow == nullptr || aniWindow->GetWindow() == nullptr) { - TLOGE(WmsLogTag::DEFAULT, "[ANI] windowToken_ is nullptr"); + if (aniWindow == nullptr) { + TLOGE(WmsLogTag::WMS_ATTRIBUTE, "[ANI] aniWindow is nullptr"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); return ANI_ERROR; } aniWindow->SetWindowBackgroundColor(env, colorStr); - TLOGI(WmsLogTag::DEFAULT, "[ANI] SetWindowBackgroundColor end"); + TLOGI(WmsLogTag::WMS_ATTRIBUTE, "[ANI] SetWindowBackgroundColor end"); return ANI_OK; } @@ -832,8 +2541,9 @@ static ani_int WindowSetImmersiveModeEnabledState(ani_env* env, ani_object obj, using namespace OHOS::Rosen; TLOGI(WmsLogTag::WMS_IMMS, "[ANI]"); AniWindow* aniWindow = reinterpret_cast(nativeObj); - if (aniWindow == nullptr || aniWindow->GetWindow() == nullptr) { - TLOGE(WmsLogTag::WMS_IMMS, "[ANI] windowToken_ is nullptr"); + if (aniWindow == nullptr) { + TLOGE(WmsLogTag::WMS_IMMS, "[ANI] aniWindow is nullptr"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); return ANI_ERROR; } aniWindow->SetImmersiveModeEnabledState(env, static_cast(enable)); @@ -853,7 +2563,7 @@ static ani_int WindowSetWindowDecorVisible(ani_env* env, ani_object obj, ani_lon return ANI_OK; } -static ani_int WindowSetWindowDecorHeight(ani_env* env, ani_object obj, ani_long nativeObj, ani_double height) +static ani_int WindowSetWindowDecorHeight(ani_env* env, ani_object obj, ani_long nativeObj, ani_int height) { using namespace OHOS::Rosen; TLOGI(WmsLogTag::DEFAULT, "[ANI]"); @@ -869,11 +2579,11 @@ static ani_int WindowSetWindowDecorHeight(ani_env* env, ani_object obj, ani_long static ani_object WindowGetWindowProperties(ani_env* env, ani_object obj, ani_long nativeObj) { using namespace OHOS::Rosen; - TLOGI(WmsLogTag::DEFAULT, "[ANI]"); + TLOGI(WmsLogTag::WMS_ATTRIBUTE, "[ANI]"); AniWindow* aniWindow = reinterpret_cast(nativeObj); - if (aniWindow == nullptr || aniWindow->GetWindow() == nullptr) { - TLOGE(WmsLogTag::DEFAULT, "[ANI] windowToken_ is nullptr"); - return AniWindowUtils::CreateAniUndefined(env); + if (aniWindow == nullptr) { + TLOGE(WmsLogTag::WMS_ATTRIBUTE, "[ANI] windowToken_ is nullptr"); + return AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); } return aniWindow->GetWindowPropertiesSync(env); } @@ -881,13 +2591,13 @@ static ani_object WindowGetWindowProperties(ani_env* env, ani_object obj, ani_lo static ani_boolean WindowIsWindowSupportWideGamut(ani_env* env, ani_object obj, ani_long nativeObj) { using namespace OHOS::Rosen; - TLOGI(WmsLogTag::DEFAULT, "[ANI]"); + TLOGI(WmsLogTag::WMS_ATTRIBUTE, "[ANI]"); AniWindow* aniWindow = reinterpret_cast(nativeObj); - if (aniWindow == nullptr || aniWindow->GetWindow() == nullptr) { - TLOGE(WmsLogTag::DEFAULT, "[ANI] windowToken_ is nullptr"); + if (aniWindow == nullptr) { + TLOGE(WmsLogTag::WMS_ATTRIBUTE, "[ANI] aniWindow is nullptr"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); return false; } - TLOGI(WmsLogTag::WMS_IMMS, "[ANI] WindowIsWindowSupportWideGamut end"); return aniWindow->IsWindowSupportWideGamut(env); } @@ -897,8 +2607,9 @@ static ani_int WindowSetWindowLayoutFullScreen(ani_env* env, ani_object obj, using namespace OHOS::Rosen; TLOGI(WmsLogTag::WMS_IMMS, "[ANI]"); AniWindow* aniWindow = reinterpret_cast(nativeObj); - if (aniWindow == nullptr || aniWindow->GetWindow() == nullptr) { - TLOGE(WmsLogTag::DEFAULT, "[ANI] windowToken_ is nullptr"); + if (aniWindow == nullptr) { + TLOGE(WmsLogTag::WMS_IMMS, "[ANI] aniWindow is nullptr"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); return ANI_ERROR; } aniWindow->SetWindowLayoutFullScreen(env, isLayoutFullScreen); @@ -912,8 +2623,9 @@ static ani_int WindowSetSystemBarProperties(ani_env* env, ani_object obj, using namespace OHOS::Rosen; TLOGI(WmsLogTag::WMS_IMMS, "[ANI]"); AniWindow* aniWindow = reinterpret_cast(nativeObj); - if (aniWindow == nullptr || aniWindow->GetWindow() == nullptr) { - TLOGE(WmsLogTag::WMS_IMMS, "[ANI] windowToken_ is nullptr"); + if (aniWindow == nullptr) { + TLOGE(WmsLogTag::WMS_IMMS, "[ANI] aniWindow is nullptr"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); return ANI_ERROR; } aniWindow->SetSystemBarProperties(env, aniSystemBarProperties); @@ -924,17 +2636,43 @@ static ani_int WindowSetSpecificSystemBarEnabled(ani_env* env, ani_object obj, a ani_string name, ani_boolean enable, ani_boolean enableAnimation) { using namespace OHOS::Rosen; - TLOGI(WmsLogTag::DEFAULT, "[ANI]"); + TLOGI(WmsLogTag::WMS_IMMS, "[ANI]"); AniWindow* aniWindow = reinterpret_cast(nativeObj); - if (aniWindow == nullptr || aniWindow->GetWindow() == nullptr) { - TLOGE(WmsLogTag::DEFAULT, "[ANI] windowToken_ is nullptr"); + if (aniWindow == nullptr) { + TLOGE(WmsLogTag::WMS_IMMS, "[ANI] windowToken_ is nullptr"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); return ANI_ERROR; } aniWindow->SetSpecificSystemBarEnabled(env, name, enable, enableAnimation); - TLOGI(WmsLogTag::DEFAULT, "[ANI] SetSpecificSystemBarEnabled end"); + TLOGI(WmsLogTag::WMS_IMMS, "[ANI] SetSpecificSystemBarEnabled end"); return ANI_OK; } +static ani_object Snapshot(ani_env* env, ani_object obj, ani_long nativeObj) +{ + using namespace OHOS::Rosen; + TLOGI(WmsLogTag::WMS_ATTRIBUTE, "[ANI]"); + AniWindow* aniWindow = reinterpret_cast(nativeObj); + if (aniWindow == nullptr) { + TLOGE(WmsLogTag::WMS_ATTRIBUTE, "[ANI] aniWindow is nullptr"); + return AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); + } + return aniWindow->Snapshot(env); +} + +static void HideNonSystemFloatingWindows(ani_env* env, ani_object obj, ani_long nativeObj, ani_boolean shouldHide) +{ + using namespace OHOS::Rosen; + TLOGI(WmsLogTag::WMS_ATTRIBUTE, "[ANI]"); + AniWindow* aniWindow = reinterpret_cast(nativeObj); + if (aniWindow == nullptr) { + TLOGE(WmsLogTag::WMS_ATTRIBUTE, "[ANI] aniWindow is nullptr"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); + return; + } + aniWindow->HideNonSystemFloatingWindows(env, shouldHide); +} + ani_object CreateAniWindow(ani_env* env, OHOS::sptr& window) __attribute__((no_sanitize("cfi"))) { @@ -947,12 +2685,13 @@ __attribute__((no_sanitize("cfi"))) ani_status ret; ani_class cls = nullptr; - if ((ret = env->FindClass("L@ohos/window/window/WindowInternal;", &cls)) != ANI_OK) { + if ((ret = env->FindClass("@ohos.window.window.WindowInternal", &cls)) != ANI_OK) { TLOGE(WmsLogTag::DEFAULT, "[ANI] null env %{public}u", ret); return cls; } std::unique_ptr uniqueWindow = std::make_unique(window); + TLOGD(WmsLogTag::WMS_IMMS, "[ANI] native obj %{public}p", uniqueWindow.get()); ani_field contextField; if ((ret = env->Class_FindField(cls, "nativeObj", &contextField)) != ANI_OK) { @@ -961,7 +2700,7 @@ __attribute__((no_sanitize("cfi"))) } ani_method initFunc = nullptr; - if ((ret = env->Class_FindMethod(cls, "", ":V", &initFunc)) != ANI_OK) { + if ((ret = env->Class_FindMethod(cls, "", ":", &initFunc)) != ANI_OK) { TLOGD(WmsLogTag::DEFAULT, "[ANI] get ctor fail %{public}u", ret); return nullptr; } @@ -971,19 +2710,22 @@ __attribute__((no_sanitize("cfi"))) return nullptr; } ani_method setObjFunc = nullptr; - if ((ret = env->Class_FindMethod(cls, "setNativeObj", "J:V", &setObjFunc)) != ANI_OK) { + if ((ret = env->Class_FindMethod(cls, "setNativeObj", "l:", &setObjFunc)) != ANI_OK) { TLOGD(WmsLogTag::DEFAULT, "[ANI] get ctor fail %{public}u", ret); return nullptr; } env->Object_CallMethod_Void(obj, setObjFunc, reinterpret_cast(uniqueWindow.get())); localObjs.insert(std::pair(obj, uniqueWindow.release())); + TLOGD(WmsLogTag::DEFAULT, "[ANI] window stage created %{public}p", reinterpret_cast(obj)); return obj; } static ani_object WindowCreate(ani_env* env, ani_long window) { using namespace OHOS::Rosen; + TLOGD(WmsLogTag::DEFAULT, "[ANI] create window with scene 0x%{public}p %{public}d", + reinterpret_cast(env), (int32_t)window); Rect baseWindowRect = { 150, 150, 400, 600 }; OHOS::sptr baseOp = new WindowOption(); SystemBarProperty barProperty = SystemBarProperty(); @@ -1007,80 +2749,165 @@ ani_status OHOS::Rosen::ANI_Window_Constructor(ani_vm *vm, uint32_t *result) } ani_class cls = nullptr; - if ((ret = env->FindClass("L@ohos/window/window/WindowInternal;", &cls)) != ANI_OK) { + if ((ret = env->FindClass("@ohos.window.window.WindowInternal", &cls)) != ANI_OK) { TLOGD(WmsLogTag::DEFAULT, "[ANI] null env %{public}u", ret); return ANI_NOT_FOUND; } std::array methods = { - ani_native_function {"getWindowDecorHeight", "J:D", + ani_native_function {"setFollowParentWindowLayoutEnabled", "lz:", + reinterpret_cast(SetFollowParentWindowLayoutEnabled)}, + ani_native_function {"setWindowDelayRaiseOnDrag", "lz:", + reinterpret_cast(SetWindowDelayRaiseOnDrag)}, + ani_native_function {"getParentWindow", "l:C{@ohos.window.window.Window}", + reinterpret_cast(GetParentWindow)}, + ani_native_function {"getWindowDecorVisible", "l:z", + reinterpret_cast(GetWindowDecorVisible)}, + ani_native_function {"stopMoving", "l:", + reinterpret_cast(StopMoving)}, + ani_native_function {"setParentWindow", "ld:", + reinterpret_cast(SetParentWindow)}, + ani_native_function {"setWindowTitle", "lC{std.core.String}:", + reinterpret_cast(SetWindowTitle)}, + ani_native_function {"getDecorButtonStyle", "l:C{@ohos.window.window.DecorButtonStyle}", + reinterpret_cast(GetDecorButtonStyle)}, + ani_native_function {"getTitleButtonRect", "l:C{@ohos.window.window.TitleButtonRect}", + reinterpret_cast(GetTitleButtonRect)}, + ani_native_function {"setTitleButtonVisible", "lC{@ohos.window.window.TitleButtonVisibleParam}:", + reinterpret_cast(SetTitleButtonVisible)}, + ani_native_function {"setWindowTitleMoveEnabled", "lz:", + reinterpret_cast(SetWindowTitleMoveEnabled)}, + ani_native_function {"setWindowTopmost", "lz:", + reinterpret_cast(SetWindowTopmost)}, + ani_native_function {"setTitleAndDockHoverShown", "lzz:", + reinterpret_cast(SetTitleAndDockHoverShown)}, + ani_native_function {"restore", "l:", + reinterpret_cast(Restore)}, + ani_native_function {"startMoving", "l:", + reinterpret_cast(StartMoving)}, + ani_native_function {"startMoveWindowWithCoordinate", "lii:", + reinterpret_cast(StartMoveWindowWithCoordinate)}, + ani_native_function {"setWindowTitleButtonVisible", "lC{@ohos.window.window.WindowTitleButtonVisibleParam}:", + reinterpret_cast(SetWindowTitleButtonVisible)}, + ani_native_function {"setDecorButtonStyle", "lC{@ohos.window.window.DecorButtonStyle}:", + reinterpret_cast(SetDecorButtonStyle)}, + ani_native_function {"getWindowStatus", "l:i", + reinterpret_cast(GetWindowStatus)}, + ani_native_function {"minimize", "l:", + reinterpret_cast(Minimize)}, + ani_native_function {"maximize", "li:", + reinterpret_cast(Maximize)}, + ani_native_function {"resize", "lii:", + reinterpret_cast(WindowResize)}, + ani_native_function {"moveWindowTo", "lii:", + reinterpret_cast(WindowMoveWindowTo)}, + ani_native_function {"getGlobalRect", "l:C{@ohos.window.window.Rect}", + reinterpret_cast(WindowGetGlobalRect)}, + ani_native_function {"getWindowDecorHeight", "l:i", reinterpret_cast(WindowGetWindowDecorHeight)}, - ani_native_function {"setWindowBackgroundColor", "JLstd/core/String;:I", + ani_native_function {"setWindowBackgroundColor", "lC{std.core.String}:i", reinterpret_cast(WindowSetWindowBackgroundColor)}, - ani_native_function {"setImmersiveModeEnabledState", "JZ:I", + ani_native_function {"setImmersiveModeEnabledState", "lz:i", reinterpret_cast(WindowSetImmersiveModeEnabledState)}, - ani_native_function {"setWindowDecorVisible", "JZ:I", + ani_native_function {"setWindowDecorVisible", "lz:i", reinterpret_cast(WindowSetWindowDecorVisible)}, - ani_native_function {"setWindowDecorHeight", "JD:I", + ani_native_function {"setWindowDecorHeight", "li:i", reinterpret_cast(WindowSetWindowDecorHeight)}, - ani_native_function {"getWindowProperties", "J:L@ohos/window/window/WindowProperties;", + ani_native_function {"getWindowProperties", "l:C{@ohos.window.window.WindowProperties}", reinterpret_cast(WindowGetWindowProperties)}, - ani_native_function {"getProperties", "J:L@ohos/window/window/WindowProperties;", + ani_native_function {"getProperties", "l:C{@ohos.window.window.WindowProperties}", reinterpret_cast(WindowGetWindowProperties)}, - ani_native_function {"isWindowSupportWideGamut", "J:Z", + ani_native_function {"isWindowSupportWideGamut", "l:z", reinterpret_cast(WindowIsWindowSupportWideGamut)}, - ani_native_function {"setWindowLayoutFullScreen", "JZ:I", + ani_native_function {"setWindowLayoutFullScreen", "lz:i", reinterpret_cast(WindowSetWindowLayoutFullScreen)}, - ani_native_function {"setWindowSystemBarProperties", "JL@ohos/window/window/SystemBarProperties;:I", + ani_native_function {"setWindowSystemBarProperties", "lC{@ohos.window.window.SystemBarProperties}:i", reinterpret_cast(WindowSetSystemBarProperties)}, - ani_native_function {"setSpecificSystemBarEnabled", "JLstd/core/String;ZZ:I", + ani_native_function {"setSpecificSystemBarEnabled", "lC{std.core.String}zz:i", reinterpret_cast(WindowSetSpecificSystemBarEnabled)}, - ani_native_function {"setWindowColorSpaceSync", "JI:V", + ani_native_function {"snapshot", "l:C{@ohos.multimedia.image.image.PixelMap}", + reinterpret_cast(Snapshot)}, + ani_native_function {"hideNonSystemFloatingWindows", "lz:", + reinterpret_cast(HideNonSystemFloatingWindows)}, + ani_native_function {"setWindowColorSpaceSync", "li:", reinterpret_cast(AniWindow::SetWindowColorSpace)}, - ani_native_function {"setPreferredOrientationSync", "JI:V", + ani_native_function {"setPreferredOrientationSync", "li:", reinterpret_cast(AniWindow::SetPreferredOrientation)}, - ani_native_function {"setWindowPrivacyModeSync", "JZ:V", + ani_native_function {"setWindowPrivacyModeSync", "lz:", reinterpret_cast(AniWindow::SetWindowPrivacyMode)}, - ani_native_function {"recoverSync", "J:V", + ani_native_function {"recoverSync", "l:", reinterpret_cast(AniWindow::Recover)}, - ani_native_function {"setUIContentSync", "JLstd/core/String;:V", + ani_native_function {"setUIContentSync", "lC{std.core.String}:", 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)}, - ani_native_function {"setWindowKeepScreenOnSync", "JZ:V", + "lC{std.core.String}C{arkui.stateManagement.storage.localStorage.LocalStorage}:", + reinterpret_cast(AniWindow::LoadContent)}, + ani_native_function {"setWindowKeepScreenOnSync", "lz:", reinterpret_cast(AniWindow::SetWindowKeepScreenOn)}, - ani_native_function {"setWindowSystemBarEnableSync", "JLescompat/Array;:V", + ani_native_function {"setWindowSystemBarEnableSync", "lC{escompat.Array}:", reinterpret_cast(AniWindow::SetWindowSystemBarEnable)}, - ani_native_function {"getUIContextSync", "J:L@ohos/arkui/UIContext/UIContext;", + ani_native_function {"getUIContextSync", "l:C{@ohos.arkui.UIContext.UIContext}", reinterpret_cast(AniWindow::GetUIContext)}, - ani_native_function {"getWindowAvoidAreaSync", "JI:L@ohos/window/window/AvoidArea;", + ani_native_function {"getWindowAvoidAreaSync", "li:C{@ohos.window.window.AvoidArea}", reinterpret_cast(AniWindow::GetWindowAvoidArea)}, - ani_native_function {"setWaterMarkFlagSync", "JZ:V", + ani_native_function {"setWaterMarkFlagSync", "lz:", reinterpret_cast(AniWindow::SetWaterMarkFlag)}, + ani_native_function {"setWindowFocusableSync", "lz:", + reinterpret_cast(AniWindow::SetWindowFocusable)}, + ani_native_function {"keepKeyboardOnFocusSync", "lz:", + reinterpret_cast(AniWindow::KeepKeyboardOnFocus)}, + ani_native_function {"setWindowTouchableSync", "lz:", + reinterpret_cast(AniWindow::SetWindowTouchable)}, + ani_native_function {"onNoInteractionDetected", nullptr, + reinterpret_cast(AniWindow::RegisterNoInteractionDetectedCallback)}, + ani_native_function {"opacity", "ld:", + reinterpret_cast(AniWindow::Opacity)}, + ani_native_function {"scale", "lC{@ohos.window.window.ScaleOptions}:", + reinterpret_cast(AniWindow::Scale)}, + ani_native_function {"translate", "lC{@ohos.window.window.TranslateOptions}:", + reinterpret_cast(AniWindow::Translate)}, + ani_native_function {"rotate", "lC{@ohos.window.window.RotateOptions}:", + reinterpret_cast(AniWindow::Rotate)}, + ani_native_function {"setShadow", "ldC{std.core.String}C{std.core.Double}C{std.core.Double}:", + reinterpret_cast(AniWindow::SetShadow)}, ani_native_function {"onSync", nullptr, reinterpret_cast(AniWindow::RegisterWindowCallback)}, ani_native_function {"offSync", nullptr, reinterpret_cast(AniWindow::UnregisterWindowCallback)}, + ani_native_function {"showWindowSync", nullptr, + reinterpret_cast(AniWindow::ShowWindow)}, + ani_native_function {"destroyWindowSync", nullptr, + reinterpret_cast(AniWindow::DestroyWindow)}, + ani_native_function {"isWindowShowingSync", nullptr, + reinterpret_cast(AniWindow::IsWindowShowing)}, + ani_native_function {"hideWithAnimationSync", nullptr, + reinterpret_cast(AniWindow::HideWithAnimation)}, + ani_native_function {"showWithAnimationSync", nullptr, + reinterpret_cast(AniWindow::ShowWithAnimation)}, + ani_native_function {"nativeTransferStatic", "Lstd/interop/ESValue;:Lstd/core/Object;", + reinterpret_cast(AniWindow::NativeTransferStatic)}, + ani_native_function {"nativeTransferDynamic", "J:Lstd/interop/ESValue;", + reinterpret_cast(AniWindow::NativeTransferDynamic)}, }; - if ((ret = env->Class_BindNativeMethods(cls, methods.data(), methods.size())) != ANI_OK) { - TLOGE(WmsLogTag::DEFAULT, "[ANI] bind window method fail %{public}u", ret); - return ANI_NOT_FOUND; + for (auto method : methods) { + if ((ret = env->Class_BindNativeMethods(cls, &method, 1u)) != ANI_OK) { + TLOGE(WmsLogTag::DEFAULT, "[ANI] bind window method fail %{public}u, %{public}s, %{public}s", + ret, method.name, method.signature); + return ANI_NOT_FOUND; + } } *result = ANI_VERSION_1; ani_namespace ns; - if ((ret = env->FindNamespace("L@ohos/window/window;", &ns)) != ANI_OK) { + if ((ret = env->FindNamespace("@ohos.window.window", &ns)) != ANI_OK) { TLOGE(WmsLogTag::DEFAULT, "[ANI] find ns %{public}u", ret); return ANI_NOT_FOUND; } std::array functions = { - ani_native_function {"CreateWindow", "J:L@ohos/window/window/WindowInternal;", + ani_native_function {"CreateWindow", "l:C{@ohos.window.window.WindowInternal}", reinterpret_cast(WindowCreate)}, }; if ((ret = env->Namespace_BindNativeFunctions(ns, functions.data(), functions.size())) != ANI_OK) { TLOGE(WmsLogTag::DEFAULT, "[ANI] bind ns window func %{public}u", ret); } return ANI_OK; -} \ No newline at end of file +} diff --git a/interfaces/kits/ani/window_runtime/window_stage_ani/src/ani_window_listener.cpp b/interfaces/kits/ani/window_runtime/window_stage_ani/src/ani_window_listener.cpp index e55f8476eeed9a3f9c2d9896ba4211009e1053a1..ccb884c947d32418cd2a9b3fb5e452093f78d150 100644 --- a/interfaces/kits/ani/window_runtime/window_stage_ani/src/ani_window_listener.cpp +++ b/interfaces/kits/ani/window_runtime/window_stage_ani/src/ani_window_listener.cpp @@ -27,7 +27,7 @@ using namespace AbilityRuntime; AniWindowListener::~AniWindowListener() { - ani_status ret = env_->GlobalReference_Delete(aniCallBack_); + ani_status ret = env_->GlobalReference_Delete(aniCallback_); TLOGI(WmsLogTag::DEFAULT, "[ANI]~AniWindowListener ret:%{public}d", static_cast(ret)); } @@ -58,18 +58,18 @@ void AniWindowListener::OnSizeChange(Rect rect, WindowSizeChangeReason reason, auto task = [self = weakRef_, rect, eng = env_] () { auto thisListener = self.promote(); - if (thisListener == nullptr || eng == nullptr) { - TLOGE(WmsLogTag::DEFAULT, "[ANI]this listener or eng is nullptr"); + if (thisListener == nullptr || eng == nullptr || thisListener->aniCallback_ == nullptr) { + TLOGE(WmsLogTag::DEFAULT, "[ANI]this listener, eng or callback is nullptr"); return; } - AniWindowUtils::CallAniFunctionVoid(eng, "L@ohos/window/window;", "runWindowSizeCallBack", - nullptr, thisListener->aniCallBack_, AniWindowUtils::CreateAniSize(eng, rect.width_, rect.height_)); + AniWindowUtils::CallAniFunctionVoid(eng, "@ohos.window.window", "runWindowSizeCallback", + nullptr, thisListener->aniCallback_, AniWindowUtils::CreateAniSize(eng, rect.width_, rect.height_)); }; if (!eventHandler_) { TLOGE(WmsLogTag::DEFAULT, "get main event handler failed!"); return; } - eventHandler_->PostTask(task, "wms:AniWindowListener::SizeChangeCallBack", 0, + eventHandler_->PostTask(task, "wms:AniWindowListener::SizeChangeCallback", 0, AppExecFwk::EventQueue::Priority::IMMEDIATE); } @@ -79,38 +79,111 @@ void AniWindowListener::OnModeChange(WindowMode mode, bool hasDeco) void AniWindowListener::OnSystemBarPropertyChange(DisplayId displayId, const SystemBarRegionTints& tints) { + TLOGI(WmsLogTag::DEFAULT, "[ANI]"); + auto task = [self = weakRef_, eng = env_, displayId, tints] { + auto thisListener = self.promote(); + if (thisListener == nullptr || eng == nullptr || thisListener->aniCallback_ == nullptr) { + TLOGE(WmsLogTag::DEFAULT, "[ANI]this listener, eng or callback is nullptr"); + return; + } + AniWindowUtils::CallAniFunctionVoid(eng, "@ohos.window.window", "runSystemBarTintChangeCallback", + nullptr, thisListener->aniCallback_, AniWindowUtils::CreateAniSystemBarTintState(eng, displayId, tints)); + }; + if (!eventHandler_) { + TLOGE(WmsLogTag::DEFAULT, "get main event handler failed!"); + return; + } + eventHandler_->PostTask(task, __func__, 0, AppExecFwk::EventQueue::Priority::HIGH); } void AniWindowListener::OnAvoidAreaChanged(const AvoidArea avoidArea, AvoidAreaType type, const sptr& info) { + TLOGI(WmsLogTag::DEFAULT, "[ANI]"); + auto task = [self = weakRef_, eng = env_, avoidArea, type] { + HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "AniWindowListener::OnAvoidAreaChanged"); + auto thisListener = self.promote(); + if (thisListener == nullptr || eng == nullptr || thisListener->aniCallback_ == nullptr) { + TLOGE(WmsLogTag::DEFAULT, "[ANI]this listener, eng or callback is nullptr"); + return; + } + auto nativeAvoidArea = AniWindowUtils::CreateAniAvoidArea(eng, avoidArea, type); + AniWindowUtils::CallAniFunctionVoid(eng, "@ohos.window.window", "runAvoidAreaChangeCallback", + nullptr, thisListener->aniCallback_, nativeAvoidArea, static_cast(type)); + }; + if (!eventHandler_) { + TLOGE(WmsLogTag::DEFAULT, "get main event handler failed!"); + return; + } + eventHandler_->PostTask(task, __func__, 0, AppExecFwk::EventQueue::Priority::IMMEDIATE); +} + +void AniWindowListener::OnSystemDensityChanged(float density) +{ + TLOGI(WmsLogTag::DEFAULT, "[ANI]"); + auto task = [self = weakRef_, density, eng = env_] { + HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "AniWindowListener::OnSystemDensityChanged"); + auto thisListener = self.promote(); + if (thisListener == nullptr || eng == nullptr || thisListener->aniCallback_ == nullptr) { + TLOGE(WmsLogTag::DEFAULT, "[ANI]this listener, eng or callback is nullptr"); + return; + } + AniWindowUtils::CallAniFunctionVoid(eng, "@ohos.window.window", "runSystemDensityChangeCallback", + nullptr, thisListener->aniCallback_, static_cast(density)); + }; + if (!eventHandler_) { + TLOGE(WmsLogTag::DEFAULT, "get main event handler failed!"); + return; + } + eventHandler_->PostTask(task, __func__, 0, AppExecFwk::EventQueue::Priority::HIGH); +} + +void AniWindowListener::OnDisplayIdChanged(DisplayId displayId) +{ + TLOGI(WmsLogTag::DEFAULT, "[ANI]"); + auto task = [self = weakRef_, displayId, eng = env_] { + HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "AniWindowListener::OnDisplayIdChanged"); + auto thisListener = self.promote(); + if (thisListener == nullptr || eng == nullptr || thisListener->aniCallback_ == nullptr) { + TLOGE(WmsLogTag::DEFAULT, "[ANI]this listener, eng or callback is nullptr"); + return; + } + AniWindowUtils::CallAniFunctionVoid(eng, "@ohos.window.window", "runDisplayIdChangeCallback", + nullptr, thisListener->aniCallback_, static_cast(displayId)); + }; + if (!eventHandler_) { + TLOGE(WmsLogTag::DEFAULT, "get main event handler failed!"); + return; + } + eventHandler_->PostTask(task, __func__, 0, AppExecFwk::EventQueue::Priority::HIGH); } -void AniWindowListener::LifeCycleCallBack(LifeCycleEventType eventType) +void AniWindowListener::LifeCycleCallback(LifeCycleEventType eventType) { - TLOGI(WmsLogTag::DEFAULT, "[ANI]LifeCycleCallBack, envent type: %{public}u", eventType); - auto task = [self = weakRef_, eventType, eng = env_] () { - HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "AniWindowListener::LifeCycleCallBack"); + TLOGI(WmsLogTag::DEFAULT, "[ANI]LifeCycleCallback, envent type: %{public}u", eventType); + auto task = [self = weakRef_, eventType, caseType = caseType_, eng = env_] () { + HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "AniWindowListener::LifeCycleCallback"); auto thisListener = self.promote(); - if (thisListener == nullptr || eng == nullptr) { - TLOGE(WmsLogTag::DEFAULT, "[ANI]this listener or eng is nullptr"); + if (thisListener == nullptr || eng == nullptr || thisListener->aniCallback_ == nullptr) { + TLOGE(WmsLogTag::DEFAULT, "[ANI]this listener, eng or callback is nullptr"); return; } - AniWindowUtils::CallAniFunctionVoid(eng, "L@ohos/window/window;", "runWindowEventCallBack", - nullptr, thisListener->aniCallBack_, static_cast(eventType)); + AniWindowUtils::CallAniFunctionVoid(eng, "@ohos.window.window", + caseType == CaseType::CASE_STAGE ? "runWindowStageEventCallback" : "runWindowEventCallback", + nullptr, thisListener->aniCallback_, static_cast(eventType)); }; if (!eventHandler_) { TLOGE(WmsLogTag::DEFAULT, "get main event handler failed!"); return; } - eventHandler_->PostTask(task, "wms:AniWindowListener::LifeCycleCallBack", 0, + eventHandler_->PostTask(task, "wms:AniWindowListener::LifeCycleCallback", 0, AppExecFwk::EventQueue::Priority::IMMEDIATE); } void AniWindowListener::AfterForeground() { if (state_ == WindowState::STATE_INITIAL || state_ == WindowState::STATE_HIDDEN) { - LifeCycleCallBack(LifeCycleEventType::FOREGROUND); + LifeCycleCallback(LifeCycleEventType::FOREGROUND); state_ = WindowState::STATE_SHOWN; } else { TLOGD(WmsLogTag::DEFAULT, "[ANI]window is already shown"); @@ -120,7 +193,7 @@ void AniWindowListener::AfterForeground() void AniWindowListener::AfterBackground() { if (state_ == WindowState::STATE_INITIAL || state_ == WindowState::STATE_SHOWN) { - LifeCycleCallBack(LifeCycleEventType::BACKGROUND); + LifeCycleCallback(LifeCycleEventType::BACKGROUND); state_ = WindowState::STATE_HIDDEN; } else { TLOGD(WmsLogTag::DEFAULT, "[ANI]window is already hide"); @@ -129,50 +202,137 @@ void AniWindowListener::AfterBackground() void AniWindowListener::AfterFocused() { - LifeCycleCallBack(LifeCycleEventType::ACTIVE); + LifeCycleCallback(LifeCycleEventType::ACTIVE); } void AniWindowListener::AfterUnfocused() { - LifeCycleCallBack(LifeCycleEventType::INACTIVE); + LifeCycleCallback(LifeCycleEventType::INACTIVE); } void AniWindowListener::AfterResumed() { if (caseType_ == CaseType::CASE_STAGE) { - LifeCycleCallBack(LifeCycleEventType::RESUMED); + LifeCycleCallback(LifeCycleEventType::RESUMED); } } void AniWindowListener::AfterPaused() { if (caseType_ == CaseType::CASE_STAGE) { - LifeCycleCallBack(LifeCycleEventType::PAUSED); + LifeCycleCallback(LifeCycleEventType::PAUSED); } } void AniWindowListener::AfterDestroyed() { if (caseType_ == CaseType::CASE_WINDOW) { - LifeCycleCallBack(LifeCycleEventType::DESTROYED); + LifeCycleCallback(LifeCycleEventType::DESTROYED); } } void AniWindowListener::OnSizeChange(const sptr& info, const std::shared_ptr& rsTransaction) { + TLOGI(WmsLogTag::WMS_KEYBOARD, + "OccupiedAreaChangeInfo, type: %{public}u, input rect: [%{public}d, %{public}d, %{public}u, %{public}u]", + static_cast(info->type_), + info->rect_.posX_, info->rect_.posY_, info->rect_.width_, info->rect_.height_); + // callback should run in js thread + auto thisListener = weakRef_.promote(); + if (thisListener == nullptr || env_ == nullptr || thisListener->aniCallback_ == nullptr) { + TLOGE(WmsLogTag::WMS_KEYBOARD, "[ANI]this listener, env_ or callback is nullptr"); + return; + } + AniWindowUtils::CallAniFunctionVoid(env_, "@ohos.window.window", "runKeyboardHeightChangeCallback", + nullptr, thisListener->aniCallback_, static_cast(info->rect_.height_)); +} + +void AniWindowListener::OnKeyboardDidShow(const KeyboardPanelInfo& keyboardPanelInfo) +{ + TLOGD(WmsLogTag::WMS_KEYBOARD, + "keyboardPanelInfo, beginRect: %{public}s, endRect: %{public}s", + keyboardPanelInfo.beginRect_.ToString().c_str(), keyboardPanelInfo.endRect_.ToString().c_str()); + auto thisListener = weakRef_.promote(); + if (thisListener == nullptr || env_ == nullptr || thisListener->aniCallback_ == nullptr) { + TLOGE(WmsLogTag::DEFAULT, "[ANI]this listener, env_ or callback is nullptr"); + return; + } + AniWindowUtils::CallAniFunctionVoid(env_, "@ohos.window.window", "runKeyboardDidShowCallback", + nullptr, thisListener->aniCallback_, AniWindowUtils::CreateAniKeyboardInfo(env_, keyboardPanelInfo)); +} + +void AniWindowListener::OnKeyboardDidHide(const KeyboardPanelInfo& keyboardPanelInfo) +{ + TLOGD(WmsLogTag::WMS_KEYBOARD, + "keyboardPanelInfo, beginRect: %{public}s, endRect: %{public}s", + keyboardPanelInfo.beginRect_.ToString().c_str(), keyboardPanelInfo.endRect_.ToString().c_str()); + auto thisListener = weakRef_.promote(); + if (thisListener == nullptr || env_ == nullptr || thisListener->aniCallback_ == nullptr) { + TLOGE(WmsLogTag::WMS_KEYBOARD, "[ANI]this listener, env_ or callback is nullptr"); + return; + } + AniWindowUtils::CallAniFunctionVoid(env_, "@ohos.window.window", "runKeyboardDidHideCallback", + nullptr, thisListener->aniCallback_, AniWindowUtils::CreateAniKeyboardInfo(env_, keyboardPanelInfo)); } void AniWindowListener::OnTouchOutside() const { + TLOGI(WmsLogTag::DEFAULT, "[ANI] touchoutside"); + auto task = [self = weakRef_, eng = env_] () { + auto thisListener = self.promote(); + if (thisListener == nullptr || eng == nullptr || thisListener->aniCallback_ == nullptr) { + TLOGE(WmsLogTag::DEFAULT, "[ANI]this listener, eng or callback is nullptr"); + return; + } + AniWindowUtils::CallAniFunctionVoid(eng, "@ohos.window.window", "runWindowTouchOutCallback", + nullptr, thisListener->aniCallback_); + }; + if (!eventHandler_) { + TLOGE(WmsLogTag::DEFAULT, "get main event handler failed!"); + return; + } + eventHandler_->PostTask(task, "wms:AniWindowListener::TouchOutsideCallback", 0, + AppExecFwk::EventQueue::Priority::HIGH); } void AniWindowListener::OnScreenshot() { + TLOGI(WmsLogTag::DEFAULT, "[ANI]"); + auto task = [self = weakRef_, eng = env_] { + auto thisListener = self.promote(); + if (thisListener == nullptr || eng == nullptr || thisListener->aniCallback_ == nullptr) { + TLOGE(WmsLogTag::DEFAULT, "[ANI]this listener, eng or callback is nullptr"); + return; + } + AniWindowUtils::CallAniFunctionVoid(eng, "@ohos.window.window", "runWindowListenerVoidArgCallback", + nullptr, thisListener->aniCallback_); + }; + if (!eventHandler_) { + TLOGE(WmsLogTag::DEFAULT, "get main event handler failed!"); + return; + } + eventHandler_->PostTask(task, __func__, 0, AppExecFwk::EventQueue::Priority::HIGH); } void AniWindowListener::OnDialogTargetTouch() const { + TLOGI(WmsLogTag::DEFAULT, "[ANI] diaglogtargettouch"); + auto task = [self = weakRef_, eng = env_] () { + auto thisListener = self.promote(); + if (thisListener == nullptr || eng == nullptr || thisListener->aniCallback_ == nullptr) { + TLOGE(WmsLogTag::DEFAULT, "[ANI]this listener, eng or callback is nullptr"); + return; + } + AniWindowUtils::CallAniFunctionVoid(eng, "@ohos.window.window", "runWindowDialogTargetCallback", + nullptr, thisListener->aniCallback_); + }; + if (!eventHandler_) { + TLOGE(WmsLogTag::DEFAULT, "get main event handler failed!"); + return; + } + eventHandler_->PostTask(task, "wms:AniWindowListener::DialogTargetTouchCallback", 0, + AppExecFwk::EventQueue::Priority::HIGH); } void AniWindowListener::OnDialogDeathRecipient() const @@ -181,14 +341,70 @@ void AniWindowListener::OnDialogDeathRecipient() const void AniWindowListener::OnGestureNavigationEnabledUpdate(bool enable) { + TLOGI(WmsLogTag::DEFAULT, "[ANI]"); + auto task = [self = weakRef_, eng = env_, enable] { + auto thisListener = self.promote(); + if (thisListener == nullptr || eng == nullptr || thisListener->aniCallback_ == nullptr) { + TLOGE(WmsLogTag::DEFAULT, "[ANI]this listener, eng or callback is nullptr"); + return; + } + AniWindowUtils::CallAniFunctionVoid(eng, "@ohos.window.window", "runWindowListenerBooleanArgCallback", + nullptr, thisListener->aniCallback_, ani_boolean(enable)); + }; + if (!eventHandler_) { + TLOGE(WmsLogTag::DEFAULT, "get main event handler failed!"); + return; + } + eventHandler_->PostTask(task, __func__, 0, AppExecFwk::EventQueue::Priority::HIGH); } void AniWindowListener::OnWaterMarkFlagUpdate(bool showWaterMark) { + TLOGI(WmsLogTag::DEFAULT, "[ANI]"); + auto task = [self = weakRef_, eng = env_, showWaterMark] { + auto thisListener = self.promote(); + if (thisListener == nullptr || eng == nullptr || thisListener->aniCallback_ == nullptr) { + TLOGE(WmsLogTag::DEFAULT, "[ANI]this listener, eng or callback is nullptr"); + return; + } + AniWindowUtils::CallAniFunctionVoid(eng, "@ohos.window.window", "runWindowListenerBooleanArgCallback", + nullptr, thisListener->aniCallback_, ani_boolean(showWaterMark)); + }; + if (!eventHandler_) { + TLOGE(WmsLogTag::DEFAULT, "get main event handler failed!"); + return; + } + eventHandler_->PostTask(task, __func__, 0, AppExecFwk::EventQueue::Priority::HIGH); +} + +void AniWindowListener::SetTimeout(int64_t timeout) +{ + noInteractionTimeout_ = timeout; +} + +int64_t AniWindowListener::GetTimeout() const +{ + return noInteractionTimeout_; } void AniWindowListener::OnWindowNoInteractionCallback() { + TLOGI(WmsLogTag::DEFAULT, "[ANI] diaglogtargettouch"); + auto task = [self = weakRef_, eng = env_] () { + auto thisListener = self.promote(); + if (thisListener == nullptr || eng == nullptr || thisListener->aniCallback_ == nullptr) { + TLOGE(WmsLogTag::DEFAULT, "[ANI]this listener, eng or callback is nullptr"); + return; + } + AniWindowUtils::CallAniFunctionVoid(eng, "@ohos.window.window", "runWindowNoInteractionCallback", + nullptr, thisListener->aniCallback_); + }; + if (!eventHandler_) { + TLOGE(WmsLogTag::DEFAULT, "get main event handler failed!"); + return; + } + eventHandler_->PostTask(task, "wms:AniWindowListener::WindowNoInteractionCallback", 0, + AppExecFwk::EventQueue::Priority::HIGH); } void AniWindowListener::OnWindowStatusChange(WindowStatus windowstatus) @@ -196,23 +412,57 @@ void AniWindowListener::OnWindowStatusChange(WindowStatus windowstatus) TLOGI(WmsLogTag::DEFAULT, "[ANI] windowstatus: %{public}u", windowstatus); auto task = [self = weakRef_, windowstatus, eng = env_] () { auto thisListener = self.promote(); - if (thisListener == nullptr || eng == nullptr) { - TLOGE(WmsLogTag::DEFAULT, "[ANI]this listener or eng is nullptr"); + if (thisListener == nullptr || eng == nullptr || thisListener->aniCallback_ == nullptr) { + TLOGE(WmsLogTag::DEFAULT, "[ANI]this listener, eng or callback is nullptr"); return; } - AniWindowUtils::CallAniFunctionVoid(eng, "L@ohos/window/window;", "runWindowStatusCallBack", - nullptr, thisListener->aniCallBack_, static_cast(windowstatus)); + AniWindowUtils::CallAniFunctionVoid(eng, "@ohos.window.window", "runWindowStatusCallback", + nullptr, thisListener->aniCallback_, static_cast(windowstatus)); }; if (!eventHandler_) { TLOGE(WmsLogTag::DEFAULT, "get main event handler failed!"); return; } - eventHandler_->PostTask(task, "wms:AniWindowListener::StatusChangeCallBack", 0, + eventHandler_->PostTask(task, "wms:AniWindowListener::StatusChangeCallback", 0, AppExecFwk::EventQueue::Priority::IMMEDIATE); } void AniWindowListener::OnWindowVisibilityChangedCallback(const bool isVisible) { + TLOGI(WmsLogTag::DEFAULT, "[ANI]"); + auto task = [self = weakRef_, eng = env_, isVisible] { + auto thisListener = self.promote(); + if (thisListener == nullptr || eng == nullptr || thisListener->aniCallback_ == nullptr) { + TLOGE(WmsLogTag::DEFAULT, "[ANI]this listener, eng or callback is nullptr"); + return; + } + AniWindowUtils::CallAniFunctionVoid(eng, "@ohos.window.window", "runWindowListenerBooleanArgCallback", + nullptr, thisListener->aniCallback_, ani_boolean(isVisible)); + }; + if (!eventHandler_) { + TLOGE(WmsLogTag::DEFAULT, "get main event handler failed!"); + return; + } + eventHandler_->PostTask(task, __func__, 0, AppExecFwk::EventQueue::Priority::HIGH); +} + +void AniWindowListener::OnWindowHighlightChange(bool isHighlight) +{ + TLOGI(WmsLogTag::DEFAULT, "[ANI]"); + auto task = [self = weakRef_, eng = env_, isHighlight] { + auto thisListener = self.promote(); + if (thisListener == nullptr || eng == nullptr || thisListener->aniCallback_ == nullptr) { + TLOGE(WmsLogTag::DEFAULT, "[ANI]this listener, eng or callback is nullptr"); + return; + } + AniWindowUtils::CallAniFunctionVoid(eng, "@ohos.window.window", "runWindowListenerBooleanArgCallback", + nullptr, thisListener->aniCallback_, ani_boolean(isHighlight)); + }; + if (!eventHandler_) { + TLOGE(WmsLogTag::DEFAULT, "get main event handler failed!"); + return; + } + eventHandler_->PostTask(task, __func__, 0, AppExecFwk::EventQueue::Priority::IMMEDIATE); } void AniWindowListener::OnWindowTitleButtonRectChanged(const TitleButtonRect& titleButtonRect) @@ -221,14 +471,98 @@ void AniWindowListener::OnWindowTitleButtonRectChanged(const TitleButtonRect& ti void AniWindowListener::OnRectChange(Rect rect, WindowSizeChangeReason reason) { + TLOGI(WmsLogTag::WMS_LAYOUT, "[ANI] rect:%{public}s, reason:%{public}d", rect.ToString().c_str(), reason); + if (currRect_ == rect && reason == WindowSizeChangeReason::UNDEFINED) { + TLOGD(WmsLogTag::WMS_LAYOUT, "skip redundant rect update"); + return; + } + RectChangeReason rectChangeReason = RectChangeReason::UNDEFINED; + if (JS_SIZE_CHANGE_REASON.count(reason) != 0 && + !(reason == WindowSizeChangeReason::MAXIMIZE && rect.posX_ != 0)) { + rectChangeReason = JS_SIZE_CHANGE_REASON.at(reason); + } + if (rectChangeReason == RectChangeReason::DRAG_END && + currentReason_ != RectChangeReason::DRAG_START && currentReason_ != RectChangeReason::DRAG) { + TLOGD(WmsLogTag::WMS_LAYOUT, "drag end change to move event"); + rectChangeReason = RectChangeReason::MOVE; + } + auto task = [self = weakRef_, rect, rectChangeReason, eng = env_] () { + auto thisListener = self.promote(); + if (thisListener == nullptr || eng == nullptr || thisListener->aniCallback_ == nullptr) { + TLOGE(WmsLogTag::WMS_LAYOUT, "[ANI]this listener, eng or callback is nullptr"); + return; + } + AniWindowUtils::CallAniFunctionVoid(eng, "@ohos.window.window", "runWindowRectChangeCallback", + nullptr, thisListener->aniCallback_, AniWindowUtils::CreateAniRect(eng, rect), + static_cast(rectChangeReason)); + }; + if (!eventHandler_) { + TLOGE(WmsLogTag::WMS_LAYOUT, "get main event handler failed!"); + return; + } + eventHandler_->PostTask(task, "wms:AniWindowListener::RectChangeCallback", 0, + AppExecFwk::EventQueue::Priority::IMMEDIATE); + currRect_ = rect; + if (rectChangeReason == RectChangeReason::UNDEFINED) { + TLOGD(WmsLogTag::WMS_LAYOUT, "ignore undefined reason to change last reason"); + } else { + currentReason_ = rectChangeReason; + } } void AniWindowListener::OnSubWindowClose(bool& terminateCloseProcess) { + TLOGI(WmsLogTag::WMS_SUB, "[ANI]"); + auto task = [self = weakRef_, eng = env_, terminateCloseProcess] { + auto thisListener = self.promote(); + if (thisListener == nullptr || eng == nullptr || thisListener->aniCallback_ == nullptr) { + TLOGE(WmsLogTag::WMS_SUB, "[ANI]this listener, eng or callback is nullptr"); + return; + } + AniWindowUtils::CallAniFunctionVoid(eng, "@ohos.window.window", "runWindowListenerBooleanArgCallback", + nullptr, thisListener->aniCallback_, ani_boolean(terminateCloseProcess)); + }; + if (!eventHandler_) { + TLOGE(WmsLogTag::DEFAULT, "get main event handler failed!"); + return; + } + eventHandler_->PostTask(task, __func__, 0, AppExecFwk::EventQueue::Priority::IMMEDIATE); } void AniWindowListener::OnMainWindowClose(bool& terminateCloseProcess) { } + +void AniWindowListener::OnRotationChange(const RotationChangeInfo& rotationChangeInfo, + RotationChangeResult& rotationChangeResult) +{ + TLOGI(WmsLogTag::WMS_ROTATION, "[ANI]"); + auto task = [self = weakRef_, eng = env_, rotationChangeInfo, &rotationChangeResult] { + HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "AniWindowListener::OnRotationChange"); + auto thisListener = self.promote(); + if (thisListener == nullptr || eng == nullptr || thisListener->aniCallback_ == nullptr) { + TLOGE(WmsLogTag::WMS_ROTATION, "[ANI]this listener, eng or callback is nullptr"); + return; + } + ani_object rotationInfoObj = AniWindowUtils::CreateAniRotationChangeInfo(eng, rotationChangeInfo); + if (rotationInfoObj == nullptr) { + TLOGE(WmsLogTag::WMS_ROTATION, "failed to create ani object"); + return; + } + ani_ref rotationChangeResultObj; + AniWindowUtils::CallAniFunctionRef(eng, rotationChangeResultObj, thisListener->aniCallback_, 1, + rotationInfoObj); + if (rotationChangeResultObj != nullptr) { + AniWindowUtils::ParseRotationChangeResult(eng, static_cast(rotationChangeResultObj), + rotationChangeResult); + } + }; + if (!eventHandler_ || + (eventHandler_->GetEventRunner() && eventHandler_->GetEventRunner()->IsCurrentRunnerThread())) { + TLOGW(WmsLogTag::WMS_ROTATION, "get main event handler failed or current is already main thread!"); + return task(); + } + eventHandler_->PostSyncTask(task, __func__, AppExecFwk::EventQueue::Priority::IMMEDIATE); +} } // namespace Rosen -} // namespace OHOS \ No newline at end of file +} // namespace OHOS 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 eb1ca962abb58b3a332d0fa87e10608784ae1476..ddfa527d2940ed7166d18b4f44a3ad6a5a4e8e30 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 @@ -18,18 +18,72 @@ #include #include "ani.h" -#include "window_scene.h" +#include "ani_window.h" +#include "ani_window_stage.h" +#include "ani_window.h" +#include "ani_window_stage.h" +#include "ani_window_utils.h" +#include "singleton_container.h" +#include "window_manager.h" #include "window_manager_hilog.h" +#include "window_scene.h" #include "ani_window_utils.h" -#include "ani_window.h" +#include "ability_context.h" +#include "window_option.h" +#include "window_helper.h" +#include "permission.h" namespace OHOS { namespace Rosen { -ani_status AniWindowManager::AniWindowManagerInit(ani_env* env, ani_namespace windowNameSpace) +using DisplayId = uint64_t; +namespace { +const std::string PIP_WINDOW = "pip_window"; +constexpr int32_t INVALID_COORDINATE = -1; +} +AniWindowManager::AniWindowManager() : registerManager_(std::make_unique()) +{ +} + +ani_status AniWindowManager::AniWindowManagerInit(ani_env* env) { TLOGI(WmsLogTag::DEFAULT, "[ANI]"); + ani_namespace ns; + ani_status ret; + if ((ret = env->FindNamespace("@ohos.window.window", &ns)) != ANI_OK) { + TLOGE(WmsLogTag::DEFAULT, "[ANI] find ns %{public}u", ret); + return ANI_NOT_FOUND; + } + std::array functions = { + ani_native_function {"CreateWindowStage", "l:C{@ohos.window.window.WindowStageInternal}", + reinterpret_cast(AniWindowManager::WindowStageCreate)}, + ani_native_function {"getWindowsByCoordinate", + "lC{@ohos.window.window.GetWindowsByCoordinateParam}:C{escompat.Array}", + reinterpret_cast(AniWindowManager::GetWindowsByCoordinate)}, + ani_native_function {"getLastWindowSync", + "lC{application.BaseContext.BaseContext}:C{@ohos.window.window.Window}", + reinterpret_cast(AniWindowManager::GetLastWindow)}, + ani_native_function {"findWindowSync", + "lC{std.core.String}:C{@ohos.window.window.Window}", + reinterpret_cast(AniWindowManager::FindWindow)}, + ani_native_function {"minimizeAllSync", "ll:", reinterpret_cast(AniWindowManager::MinimizeAll)}, + ani_native_function {"shiftAppWindowFocusSync", "lii:", + reinterpret_cast(AniWindowManager::ShiftAppWindowFocus)}, + ani_native_function {"onSync", nullptr, + reinterpret_cast(AniWindowManager::RegisterWindowManagerCallback)}, + ani_native_function {"offSync", nullptr, + reinterpret_cast(AniWindowManager::UnregisterWindowManagerCallback)}, + ani_native_function {"windowDestroyCallback", nullptr, reinterpret_cast(AniWindow::Finalizer)}, + ani_native_function {"createWindowSync", + "lC{@ohos.window.window.Configuration}:C{@ohos.window.window.Window}", + reinterpret_cast(AniWindowManager::CreateWindow)}, + }; + if ((ret = env->Namespace_BindNativeFunctions(ns, functions.data(), functions.size())) != ANI_OK) { + TLOGE(WmsLogTag::DEFAULT, "[ANI] bind ns func %{public}u", ret); + return ANI_NOT_FOUND; + } + ani_function setObjFunc = nullptr; - ani_status ret = env->Namespace_FindFunction(windowNameSpace, "setNativeObj", "J:V", &setObjFunc); + ret = env->Namespace_FindFunction(ns, "setNativeObj", "l:", &setObjFunc); if (ret != ANI_OK) { TLOGE(WmsLogTag::DEFAULT, "[ANI] find setNativeObj func fail %{public}u", ret); return ret; @@ -37,20 +91,77 @@ ani_status AniWindowManager::AniWindowManagerInit(ani_env* env, ani_namespace wi std::unique_ptr aniWinManager = std::make_unique(); ret = env->Function_Call_Void(setObjFunc, aniWinManager.release()); if (ret != ANI_OK) { - TLOGE(WmsLogTag::DEFAULT, "[ANI] find setNativeObj func fail %{public}u", ret); + TLOGE(WmsLogTag::DEFAULT, "[ANI] call setNativeObj func fail %{public}u", ret); return ret; } return ret; } -ani_object AniWindowManager::GetLastWindow(ani_env* env, ani_object obj, ani_long nativeObj, ani_object context) +ani_object AniWindowManager::WindowStageCreate(ani_env* env, ani_long scene) +{ + std::shared_ptr scenePtr; + return CreateAniWindowStage(env, scenePtr); +} + +ani_object AniWindowManager::GetWindowsByCoordinate(ani_env* env, ani_long nativeObj, ani_object getWindowsParam) +{ + TLOGI(WmsLogTag::WMS_PC, "[ANI]"); + AniWindowManager* aniWindowManager = reinterpret_cast(nativeObj); + return aniWindowManager != nullptr ? aniWindowManager->OnGetWindowsByCoordinate(env, getWindowsParam) : nullptr; +} + +ani_object AniWindowManager::OnGetWindowsByCoordinate(ani_env* env, ani_object getWindowsParam) +{ + uint64_t displayId = static_cast(DISPLAY_ID_INVALID); + ani_double aniDisplayId; + if (ANI_OK != env->Object_GetPropertyByName_Double(getWindowsParam, "displayId", &aniDisplayId)) { + TLOGE(WmsLogTag::WMS_PC, "[ANI] Failed to convert parameter to displayId"); + return AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_INVALID_PARAM); + } + displayId = static_cast(aniDisplayId); + if (displayId < 0 || + SingletonContainer::Get().GetDisplayById(displayId) == nullptr) { + TLOGE(WmsLogTag::WMS_PC, "[ANI] invalid displayId"); + return AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_INVALID_PARAM); + } + int32_t windowNumber = 0; + ani_double aniWindowNumber; + if (ANI_OK == env->Object_GetPropertyByName_Double(getWindowsParam, "windowNumber", &aniWindowNumber)) { + windowNumber = static_cast(aniWindowNumber); + } + int32_t x = INVALID_COORDINATE; + ani_double aniX; + if (ANI_OK == env->Object_GetPropertyByName_Double(getWindowsParam, "x", &aniX)) { + x = static_cast(aniX); + } + int32_t y = INVALID_COORDINATE; + ani_double aniY; + if (ANI_OK == env->Object_GetPropertyByName_Double(getWindowsParam, "y", &aniY)) { + y = static_cast(aniY); + } + std::vector windowIds; + WmErrorCode ret = WM_JS_TO_ERROR_CODE_MAP.at(SingletonContainer::Get(). + GetWindowIdsByCoordinate(displayId, windowNumber, x, y, windowIds)); + if (ret != WmErrorCode::WM_OK) { + TLOGE(WmsLogTag::WMS_PC, "[ANI] getWindowsByCoordinate failed"); + return AniWindowUtils::AniThrowError(env, ret); + } + std::vector windows(windowIds.size()); + for (size_t i = 0; i < windowIds.size(); i++) { + sptr window = Window::GetWindowWithId(windowIds[i]); + windows[i] = CreateAniWindowObject(env, window); + } + return AniWindowUtils::CreateAniWindowArray(env, windows); +} + +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); @@ -66,5 +177,280 @@ ani_object AniWindowManager::OnGetLastWindow(ani_env* env, ani_object aniContext } return CreateAniWindowObject(env, window); } + +ani_ref AniWindowManager::FindWindow(ani_env* env, ani_long nativeObj, ani_string windowName) +{ + TLOGI(WmsLogTag::DEFAULT, "[ANI]"); + AniWindowManager* aniWindowManager = reinterpret_cast(nativeObj); + return aniWindowManager != nullptr ? aniWindowManager->OnFindWindow(env, windowName) : nullptr; +} + +ani_ref AniWindowManager::OnFindWindow(ani_env* env, ani_string windowName) +{ + std::string name; + AniWindowUtils::GetStdString(env, windowName, name); + TLOGI(WmsLogTag::DEFAULT, "[ANI]Window name=%{public}s", name.c_str()); + if (name.compare(PIP_WINDOW) == 0) { + return AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_INVALID_PARAM); + } + ani_ref aniWindowObj = FindAniWindowObject(name); + if (aniWindowObj != nullptr) { + TLOGD(WmsLogTag::DEFAULT, "[ANI]Find window: %{public}s, use exist js window", name.c_str()); + return aniWindowObj; + } else { + sptr window = Window::Find(name); + if (window == nullptr) { + return AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); + } else { + return CreateAniWindowObject(env, window); + } + } +} + +ani_ref CreateAniSystemWindow(ani_env* env, void* contextPtr, sptr windowOption) +{ + TLOGI(WmsLogTag::DEFAULT, "[ANI]"); + if (windowOption == nullptr) { + return AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_SYSTEM_ABNORMALLY); + } + auto context = static_cast*>(contextPtr); + if (contextPtr == nullptr || context == nullptr) { + return AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_CONTEXT_ABNORMALLY, + "[ANI] Context is nullptr"); + } + if (windowOption->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT || + windowOption->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT_CAMERA) { + auto abilityContext = AbilityRuntime::Context::ConvertTo(context->lock()); + if (abilityContext != nullptr) { + if (!Permission::CheckCallingPermission("ohos.permission.SYSTEM_FLOAT_WINDOW")) { + return AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_NO_PERMISSION, + "[ANI] TYPE_FLOAT CheckCallingPermission failed"); + } + } + } + WMError wmError = WMError::WM_OK; + sptr window = Window::Create(windowOption->GetWindowName(), windowOption, context->lock(), wmError); + WmErrorCode wmErrorCode = WM_JS_TO_ERROR_CODE_MAP.at(wmError); + if (window != nullptr && wmErrorCode == WmErrorCode::WM_OK) { + return CreateAniWindowObject(env, window); + } else { + return AniWindowUtils::AniThrowError(env, wmErrorCode, "Create window failed"); + } +} + +ani_ref CreateAniSubWindow(ani_env* env, sptr windowOption) +{ + if (windowOption == nullptr) { + return AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_SYSTEM_ABNORMALLY); + } + windowOption->SetWindowMode(Rosen::WindowMode::WINDOW_MODE_FLOATING); + if (windowOption->GetParentId() == INVALID_WINDOW_ID) { + return AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY, + "[ANI] Parent window missed"); + } + + sptr window = Window::Create(windowOption->GetWindowName(), windowOption); + if (window == nullptr) { + return AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); + } else { + return CreateAniWindowObject(env, window); + } +} + +ani_ref AniWindowManager::CreateWindow(ani_env* env, ani_long nativeObj, ani_object configuration) +{ + TLOGI(WmsLogTag::DEFAULT, "[ANI]"); + AniWindowManager* aniWindowManager = reinterpret_cast(nativeObj); + return aniWindowManager != nullptr ? aniWindowManager->OnCreateWindow(env, configuration) : nullptr; +} + +bool ParseRequiredConfigOption(ani_env* env, ani_object configuration, WindowOption &option) +{ + ani_ref result; + env->Object_GetPropertyByName_Ref(configuration, "name", &result); + ani_string aniWindowName = reinterpret_cast(result); + std::string windowName; + AniWindowUtils::GetStdString(env, aniWindowName, windowName); + TLOGI(WmsLogTag::DEFAULT, "[ANI] WindowName: %{public}s", windowName.c_str()); + option.SetWindowName(windowName); + + ani_int ret; + env->Object_GetPropertyByName_Ref(configuration, "windowType", &result); + auto status = env->EnumItem_GetValue_Int(static_cast(result), &ret); + if (status != ANI_OK) { + TLOGI(WmsLogTag::DEFAULT, "[ANI] Fail to throw err, status: %{public}d", static_cast(status)); + return false; + } + uint32_t winType = static_cast(ret); + TLOGI(WmsLogTag::DEFAULT, "[ANI] winType: %{public}u", winType); + if (winType >= static_cast(ApiWindowType::TYPE_BASE) && + winType < static_cast(ApiWindowType::TYPE_END)) { + option.SetWindowType(JS_TO_NATIVE_WINDOW_TYPE_MAP.at(static_cast(winType))); + } else { + TLOGE(WmsLogTag::DEFAULT, "[ANI] Invalid winType"); + return false; + } + return true; +} + +bool ParseConfigOption(ani_env* env, ani_object configuration, WindowOption &option, void*& contextPtr) +{ + if (!ParseRequiredConfigOption(env, configuration, option)) { + return false; + } + + ani_ref result; + env->Object_GetPropertyByName_Ref(configuration, "title", &result); + ani_boolean isTitleUndefined = false; + env->Reference_IsUndefined(result, &isTitleUndefined); + if (!isTitleUndefined) { + ani_string aniDialogTitle = reinterpret_cast(result); + std::string dialogTitle; + AniWindowUtils::GetStdString(env, aniDialogTitle, dialogTitle); + TLOGI(WmsLogTag::DEFAULT, "[ANI] dialogTitle: %{public}s", dialogTitle.c_str()); + option.SetDialogTitle(dialogTitle); + } + + env->Object_GetPropertyByName_Ref(configuration, "ctx", &result); + ani_object aniContextPtr = reinterpret_cast(result); + contextPtr = AniWindowUtils::GetAbilityContext(env, aniContextPtr); + + ani_boolean dialogDecorEnable; + env->Object_GetPropertyByName_Boolean(configuration, "decorEnabled", &dialogDecorEnable); + option.SetDialogDecorEnable(dialogDecorEnable); + + ani_double ret; + env->Object_GetPropertyByName_Double(configuration, "displayId", &ret); + int64_t displayId = static_cast(ret); + if (displayId < 0 || + SingletonContainer::Get().GetDisplayById(static_cast(displayId)) == nullptr) { + TLOGI(WmsLogTag::DEFAULT, "[ANI] DisplayId is invalid"); + return AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_INVALID_PARAM); + } + option.SetDisplayId(displayId); + + env->Object_GetPropertyByName_Double(configuration, "parentId", &ret); + int64_t parentId = static_cast(ret); + option.SetParentId(parentId); + + return true; +} + +ani_ref AniWindowManager::OnCreateWindow(ani_env* env, ani_object configuration) +{ + WindowOption option; + void* contextPtr = nullptr; + if (!ParseConfigOption(env, configuration, option, contextPtr)) { + return AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_INVALID_PARAM, "[ANI] Failed to parse config"); + } + sptr windowOption = new WindowOption(option); + if (WindowHelper::IsSystemWindow(option.GetWindowType())) { + return CreateAniSystemWindow(env, contextPtr, windowOption); + } else if (WindowHelper::IsSubWindow(option.GetWindowType())) { + return CreateAniSubWindow(env, windowOption); + } else { + return AniWindowUtils::AniThrowError(env, WMError::WM_ERROR_NULLPTR, "[ANI] Create window failed"); + } +} + +void AniWindowManager::MinimizeAll(ani_env* env, ani_long nativeObj, ani_long displayId) +{ + TLOGI(WmsLogTag::WMS_LIFE, "[ANI]"); + AniWindowManager* aniWindowManager = reinterpret_cast(nativeObj); + if (aniWindowManager != nullptr) { + aniWindowManager->OnMinimizeAll(env, displayId); + } else { + TLOGE(WmsLogTag::WMS_LIFE, "[ANI] aniWindowManager is nullptr"); + } +} + +void AniWindowManager::OnMinimizeAll(ani_env* env, ani_long displayId) +{ + TLOGI(WmsLogTag::WMS_LIFE, "[ANI]"); + if (static_cast(displayId) < 0 || + SingletonContainer::Get().GetDisplayById(static_cast(displayId)) == nullptr) { + TLOGE(WmsLogTag::WMS_LIFE, "[ANI] Minimize all failed, Invalidate params."); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_INVALID_PARAM); + return; + } + WmErrorCode ret = WM_JS_TO_ERROR_CODE_MAP.at( + SingletonContainer::Get().MinimizeAllAppWindows(static_cast(displayId))); + if (ret != WmErrorCode::WM_OK) { + TLOGE(WmsLogTag::WMS_LIFE, "[ANI] Minimize all failed, ret:%{public}d", static_cast(ret)); + AniWindowUtils::AniThrowError(env, ret, "OnMinimizeAll failed"); + return; + } +} + +void AniWindowManager::RegisterWindowManagerCallback(ani_env* env, ani_long nativeObj, + ani_string type, ani_ref callback) +{ + TLOGI(WmsLogTag::DEFAULT, "[ANI]"); + AniWindowManager* aniWindowManager = reinterpret_cast(nativeObj); + if (aniWindowManager != nullptr) { + aniWindowManager->OnRegisterWindowManagerCallback(env, type, callback); + } else { + TLOGE(WmsLogTag::DEFAULT, "[ANI] aniWindowManager is nullptr"); + } +} + +void AniWindowManager::OnRegisterWindowManagerCallback(ani_env* env, ani_string type, ani_ref callback) +{ + std::string cbType; + AniWindowUtils::GetStdString(env, type, cbType); + TLOGI(WmsLogTag::DEFAULT, "[ANI] type:%{public}s", cbType.c_str()); + WmErrorCode ret = registerManager_->RegisterListener(nullptr, cbType, CaseType::CASE_WINDOW_MANAGER, + env, callback, ani_double(0)); + if (ret != WmErrorCode::WM_OK) { + AniWindowUtils::AniThrowError(env, ret); + } +} + +void AniWindowManager::UnregisterWindowManagerCallback(ani_env* env, ani_long nativeObj, + ani_string type, ani_ref callback) +{ + TLOGI(WmsLogTag::DEFAULT, "[ANI]"); + AniWindowManager* aniWindowManager = reinterpret_cast(nativeObj); + if (aniWindowManager != nullptr) { + aniWindowManager->OnUnregisterWindowManagerCallback(env, type, callback); + } else { + TLOGE(WmsLogTag::DEFAULT, "[ANI] aniWindowManager is nullptr"); + } +} + +void AniWindowManager::OnUnregisterWindowManagerCallback(ani_env* env, ani_string type, ani_ref callback) +{ + std::string cbType; + AniWindowUtils::GetStdString(env, type, cbType); + TLOGI(WmsLogTag::DEFAULT, "[ANI] type:%{public}s", cbType.c_str()); + WmErrorCode ret = registerManager_->UnregisterListener(nullptr, cbType, CaseType::CASE_WINDOW_MANAGER, + env, callback); + if (ret != WmErrorCode::WM_OK) { + AniWindowUtils::AniThrowError(env, ret); + } +} + +void AniWindowManager::ShiftAppWindowFocus(ani_env* env, ani_long nativeObj, + ani_int sourceWindowId, ani_int targetWindowId) +{ + AniWindowManager* aniWindowManager = reinterpret_cast(nativeObj); + if (aniWindowManager != nullptr) { + aniWindowManager->OnShiftAppWindowFocus(env, sourceWindowId, targetWindowId); + } else { + TLOGE(WmsLogTag::WMS_FOCUS, "[ANI] aniWindowManager is nullptr"); + } +} + +void AniWindowManager::OnShiftAppWindowFocus(ani_env* env, ani_int sourceWindowId, ani_int targetWindowId) +{ + TLOGI(WmsLogTag::WMS_FOCUS, "[ANI] sourceWindowId: %{public}d targetWindowId: %{public}d", + static_cast(sourceWindowId), static_cast(targetWindowId)); + WmErrorCode ret = WM_JS_TO_ERROR_CODE_MAP.at( + SingletonContainer::Get().ShiftAppWindowFocus(sourceWindowId, targetWindowId)); + if (ret != WmErrorCode::WM_OK) { + AniWindowUtils::AniThrowError(env, ret, "ShiftAppWindowFocus failed."); + } + return ; +} } // namespace Rosen -} // namespace OHOS \ No newline at end of file +} // namespace OHOS 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 310aab13aabea639d530c670c7b7888d729caa8a..4bc13af26023ca2603382d8926ef1387f74b7389 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 @@ -13,6 +13,7 @@ * limitations under the License. */ +#include "ani.h" #include "ani_window_register_manager.h" #include "singleton_container.h" #include "window_manager.h" @@ -36,6 +37,8 @@ const std::map WINDOW_LISTENER_MAP { {LIFECYCLE_EVENT_CB, RegisterListenerType::LIFECYCLE_EVENT_CB}, {WINDOW_EVENT_CB, RegisterListenerType::WINDOW_EVENT_CB}, {KEYBOARD_HEIGHT_CHANGE_CB, RegisterListenerType::KEYBOARD_HEIGHT_CHANGE_CB}, + {KEYBOARD_DID_SHOW_CB, RegisterListenerType::KEYBOARD_DID_SHOW_CB}, + {KEYBOARD_DID_HIDE_CB, RegisterListenerType::KEYBOARD_DID_HIDE_CB}, {TOUCH_OUTSIDE_CB, RegisterListenerType::TOUCH_OUTSIDE_CB}, {SCREENSHOT_EVENT_CB, RegisterListenerType::SCREENSHOT_EVENT_CB}, {DIALOG_TARGET_TOUCH_CB, RegisterListenerType::DIALOG_TARGET_TOUCH_CB}, @@ -46,6 +49,10 @@ const std::map WINDOW_LISTENER_MAP { {WINDOW_NO_INTERACTION_DETECT_CB, RegisterListenerType::WINDOW_NO_INTERACTION_DETECT_CB}, {WINDOW_RECT_CHANGE_CB, RegisterListenerType::WINDOW_RECT_CHANGE_CB}, {SUB_WINDOW_CLOSE_CB, RegisterListenerType::SUB_WINDOW_CLOSE_CB}, + {WINDOW_HIGHLIGHT_CHANGE_CB, RegisterListenerType::WINDOW_HIGHLIGHT_CHANGE_CB}, + {WINDOW_DISPLAYID_CHANGE_CB, RegisterListenerType::WINDOW_DISPLAYID_CHANGE_CB}, + {SYSTEM_DENSITY_CHANGE_CB, RegisterListenerType::SYSTEM_DENSITY_CHANGE_CB}, + {WINDOW_ROTATION_CHANGE_CB, RegisterListenerType::WINDOW_ROTATION_CHANGE_CB}, }; const std::map WINDOW_STAGE_LISTENER_MAP { // white register list for window stage @@ -124,6 +131,40 @@ WmErrorCode AniWindowRegisterManager::ProcessAvoidAreaChangeRegister(sptr listener, + sptr window, bool isRegister, ani_env* env) +{ + if (window == nullptr) { + TLOGE(WmsLogTag::DEFAULT, "[ANI]Window is nullptr"); + return WmErrorCode::WM_ERROR_STATE_ABNORMALLY; + } + sptr thisListener(listener); + WmErrorCode ret = WmErrorCode::WM_OK; + if (isRegister) { + ret = WM_JS_TO_ERROR_CODE_MAP.at(window->RegisterSystemDensityChangeListener(thisListener)); + } else { + ret = WM_JS_TO_ERROR_CODE_MAP.at(window->UnregisterSystemDensityChangeListener(thisListener)); + } + return ret; +} + +WmErrorCode AniWindowRegisterManager::ProcessDisplayIdChangeRegister(sptr listener, + sptr window, bool isRegister, ani_env* env) +{ + if (window == nullptr) { + TLOGE(WmsLogTag::DEFAULT, "[ANI]Window is nullptr"); + return WmErrorCode::WM_ERROR_STATE_ABNORMALLY; + } + sptr thisListener(listener); + WmErrorCode ret = WmErrorCode::WM_OK; + if (isRegister) { + ret = WM_JS_TO_ERROR_CODE_MAP.at(window->RegisterDisplayIdChangeListener(thisListener)); + } else { + ret = WM_JS_TO_ERROR_CODE_MAP.at(window->UnregisterDisplayIdChangeListener(thisListener)); + } + return ret; +} + WmErrorCode AniWindowRegisterManager::ProcessLifeCycleEventRegister(sptr listener, sptr window, bool isRegister, ani_env* env) { @@ -145,7 +186,7 @@ WmErrorCode AniWindowRegisterManager::ProcessOccupiedAreaChangeRegister(sptr window, bool isRegister, ani_env* env) { if (window == nullptr) { - TLOGE(WmsLogTag::DEFAULT, "[ANI]Window is nullptr"); + TLOGE(WmsLogTag::WMS_KEYBOARD, "[ANI]Window is nullptr"); return WmErrorCode::WM_ERROR_STATE_ABNORMALLY; } sptr thisListener(listener); @@ -158,6 +199,40 @@ WmErrorCode AniWindowRegisterManager::ProcessOccupiedAreaChangeRegister(sptr listener, + sptr window, bool isRegister, ani_env* env) +{ + if (window == nullptr) { + TLOGE(WmsLogTag::WMS_KEYBOARD, "[ANI]Window is nullptr"); + return WmErrorCode::WM_ERROR_STATE_ABNORMALLY; + } + sptr thisListener(listener); + WmErrorCode ret = WmErrorCode::WM_OK; + if (isRegister) { + ret = WM_JS_TO_ERROR_CODE_MAP.at(window->RegisterKeyboardDidShowListener(thisListener)); + } else { + ret = WM_JS_TO_ERROR_CODE_MAP.at(window->UnregisterKeyboardDidShowListener(thisListener)); + } + return ret; +} + +WmErrorCode AniWindowRegisterManager::ProcessKeyboardDidHideRegister(sptr listener, + sptr window, bool isRegister, ani_env* env) +{ + if (window == nullptr) { + TLOGE(WmsLogTag::WMS_KEYBOARD, "[ANI]Window is nullptr"); + return WmErrorCode::WM_ERROR_STATE_ABNORMALLY; + } + sptr thisListener(listener); + WmErrorCode ret = WmErrorCode::WM_OK; + if (isRegister) { + ret = WM_JS_TO_ERROR_CODE_MAP.at(window->RegisterKeyboardDidHideListener(thisListener)); + } else { + ret = WM_JS_TO_ERROR_CODE_MAP.at(window->UnregisterKeyboardDidHideListener(thisListener)); + } + return ret; +} + WmErrorCode AniWindowRegisterManager::ProcessSystemBarChangeRegister(sptr listener, sptr window, bool isRegister, ani_env* env) { @@ -237,9 +312,24 @@ WmErrorCode AniWindowRegisterManager::ProcessWindowVisibilityChangeRegister(sptr } WmErrorCode AniWindowRegisterManager::ProcessWindowNoInteractionRegister(sptr listener, - sptr window, bool isRegister, ani_env* env) + sptr window, bool isRegister, ani_env* env, ani_long timeout) { - return WmErrorCode::WM_OK; + if (window == nullptr) { + return WmErrorCode::WM_ERROR_STATE_ABNORMALLY; + } + sptr thisListener(listener); + if (!isRegister) { + return WM_JS_TO_ERROR_CODE_MAP.at(window->UnregisterWindowNoInteractionListener(thisListener)); + } + constexpr ani_long secToMicrosecRatio = 1000; + constexpr ani_long noInteractionMax = LLONG_MAX / secToMicrosecRatio; + if (timeout <= 0 || (timeout > noInteractionMax)) { + TLOGE(WmsLogTag::DEFAULT, "invalid parameter: no-interaction-timeout %{public}" PRId64 " is not in " + "(0s~%{public}" PRId64, timeout, noInteractionMax); + return WmErrorCode::WM_ERROR_INVALID_PARAM; + } + thisListener->SetTimeout(timeout * secToMicrosecRatio); + return WM_JS_TO_ERROR_CODE_MAP.at(window->RegisterWindowNoInteractionListener(thisListener)); } WmErrorCode AniWindowRegisterManager::ProcessScreenshotRegister(sptr listener, @@ -328,8 +418,8 @@ bool AniWindowRegisterManager::IsCallbackRegistered(ani_env* env, std::string ty return false; } -WmErrorCode AniWindowRegisterManager::RegisterListener(sptr window, std::string type, - CaseType caseType, ani_env* env, ani_ref callback) +WmErrorCode AniWindowRegisterManager::RegisterListener(sptr window, const std::string& type, + CaseType caseType, ani_env* env, ani_ref callback, ani_long timeout) { std::lock_guard lock(mtx_); if (IsCallbackRegistered(env, type, callback)) { @@ -357,107 +447,102 @@ WmErrorCode AniWindowRegisterManager::RegisterListener(sptr window, std: return WmErrorCode::WM_ERROR_STATE_ABNORMALLY; } windowManagerListener->SetMainEventHandler(); - WmErrorCode ret = ProcessListener(listenerType, caseType, windowManagerListener, window, true, env); + WmErrorCode ret = ProcessListener(listenerType, caseType, windowManagerListener, window, true, env, timeout); if (ret != WmErrorCode::WM_OK) { TLOGE(WmsLogTag::DEFAULT, "[ANI]Register type %{public}s failed", type.c_str()); return ret; } - jsCbMap_[type][callback] = windowManagerListener; + jsCbMap_[type][cbRef] = windowManagerListener; TLOGI(WmsLogTag::DEFAULT, "[ANI]Register type %{public}s success! callback map size: %{public}zu", type.c_str(), jsCbMap_[type].size()); return WmErrorCode::WM_OK; } -WmErrorCode AniWindowRegisterManager::ProcessWindowStageListener(RegisterListenerType registerListenerType, - const sptr& windowManagerListener, const sptr& window, bool isRegister, ani_env* env) -{ - switch (registerListenerType) { - case RegisterListenerType::WINDOW_STAGE_EVENT_CB: - return ProcessLifeCycleEventRegister(windowManagerListener, window, isRegister, env); - case RegisterListenerType::WINDOW_STAGE_CLOSE_CB: - return ProcessMainWindowCloseRegister(windowManagerListener, window, isRegister, env); - default: - TLOGE(WmsLogTag::DEFAULT, "[ANI]RegisterListenerType %{public}u is not supported", - static_cast(registerListenerType)); - return WmErrorCode::WM_ERROR_INVALID_PARAM; - } -} - -WmErrorCode AniWindowRegisterManager::ProcessWindowListener(RegisterListenerType registerListenerType, - const sptr& windowManagerListener, const sptr& window, bool isRegister, ani_env* env) -{ - switch (static_cast(registerListenerType)) { - case static_cast(RegisterListenerType::WINDOW_SIZE_CHANGE_CB): - return ProcessWindowChangeRegister(windowManagerListener, window, isRegister, env); - case static_cast(RegisterListenerType::SYSTEM_AVOID_AREA_CHANGE_CB): - return ProcessSystemAvoidAreaChangeRegister(windowManagerListener, window, isRegister, env); - case static_cast(RegisterListenerType::AVOID_AREA_CHANGE_CB): - return ProcessAvoidAreaChangeRegister(windowManagerListener, window, isRegister, env); - case static_cast(RegisterListenerType::LIFECYCLE_EVENT_CB): - return ProcessLifeCycleEventRegister(windowManagerListener, window, isRegister, env); - case static_cast(RegisterListenerType::WINDOW_EVENT_CB): - return ProcessLifeCycleEventRegister(windowManagerListener, window, isRegister, env); - case static_cast(RegisterListenerType::KEYBOARD_HEIGHT_CHANGE_CB): - return ProcessOccupiedAreaChangeRegister(windowManagerListener, window, isRegister, env); - case static_cast(RegisterListenerType::TOUCH_OUTSIDE_CB): - return ProcessTouchOutsideRegister(windowManagerListener, window, isRegister, env); - case static_cast(RegisterListenerType::SCREENSHOT_EVENT_CB): - return ProcessScreenshotRegister(windowManagerListener, window, isRegister, env); - case static_cast(RegisterListenerType::DIALOG_TARGET_TOUCH_CB): - return ProcessDialogTargetTouchRegister(windowManagerListener, window, isRegister, env); - case static_cast(RegisterListenerType::DIALOG_DEATH_RECIPIENT_CB): - return ProcessDialogDeathRecipientRegister(windowManagerListener, window, isRegister, env); - case static_cast(RegisterListenerType::WINDOW_STATUS_CHANGE_CB): - return ProcessWindowStatusChangeRegister(windowManagerListener, window, isRegister, env); - case static_cast(RegisterListenerType::WINDOW_TITLE_BUTTON_RECT_CHANGE_CB): - return ProcessWindowTitleButtonRectChangeRegister(windowManagerListener, window, isRegister, env); - case static_cast(RegisterListenerType::WINDOW_VISIBILITY_CHANGE_CB): - return ProcessWindowVisibilityChangeRegister(windowManagerListener, window, isRegister, env); - case static_cast(RegisterListenerType::WINDOW_NO_INTERACTION_DETECT_CB): - return ProcessWindowNoInteractionRegister(windowManagerListener, window, isRegister, env); - case static_cast(RegisterListenerType::WINDOW_RECT_CHANGE_CB): - return ProcessWindowRectChangeRegister(windowManagerListener, window, isRegister, env); - case static_cast(RegisterListenerType::SUB_WINDOW_CLOSE_CB): - return ProcessSubWindowCloseRegister(windowManagerListener, window, isRegister, env); - default: - TLOGE(WmsLogTag::DEFAULT, "[ANI]RegisterListenerType %{public}u is not supported", - static_cast(registerListenerType)); - return WmErrorCode::WM_ERROR_INVALID_PARAM; - } -} - -WmErrorCode AniWindowRegisterManager::ProcessWindowManagerListener(RegisterListenerType registerListenerType, - const sptr& windowManagerListener, const sptr& window, bool isRegister, ani_env* env) -{ - switch (static_cast(registerListenerType)) { - case static_cast(RegisterListenerType::SYSTEM_BAR_TINT_CHANGE_CB): - return ProcessSystemBarChangeRegister(windowManagerListener, window, isRegister, env); - case static_cast(RegisterListenerType::GESTURE_NAVIGATION_ENABLED_CHANGE_CB): - return ProcessGestureNavigationEnabledChangeRegister(windowManagerListener, window, isRegister, - env); - case static_cast(RegisterListenerType::WATER_MARK_FLAG_CHANGE_CB): - return ProcessWaterMarkFlagChangeRegister(windowManagerListener, window, isRegister, env); - default: - TLOGE(WmsLogTag::DEFAULT, "[ANI]RegisterListenerType %{public}u is not supported", - static_cast(registerListenerType)); - return WmErrorCode::WM_ERROR_INVALID_PARAM; - } -} - WmErrorCode AniWindowRegisterManager::ProcessListener(RegisterListenerType registerListenerType, CaseType caseType, - const sptr& windowManagerListener, const sptr& window, bool isRegister, ani_env* env) + const sptr& windowManagerListener, const sptr& window, bool isRegister, + ani_env* env, ani_long timeout) { if (caseType == CaseType::CASE_WINDOW_MANAGER) { - ProcessWindowManagerListener(registerListenerType, windowManagerListener, window, isRegister, env); + switch (static_cast(registerListenerType)) { + case static_cast(RegisterListenerType::SYSTEM_BAR_TINT_CHANGE_CB): + return ProcessSystemBarChangeRegister(windowManagerListener, window, isRegister, env); + case static_cast(RegisterListenerType::GESTURE_NAVIGATION_ENABLED_CHANGE_CB): + return ProcessGestureNavigationEnabledChangeRegister(windowManagerListener, window, isRegister, + env); + case static_cast(RegisterListenerType::WATER_MARK_FLAG_CHANGE_CB): + return ProcessWaterMarkFlagChangeRegister(windowManagerListener, window, isRegister, env); + default: + TLOGE(WmsLogTag::DEFAULT, "[ANI]RegisterListenerType %{public}u is not supported", + static_cast(registerListenerType)); + return WmErrorCode::WM_ERROR_INVALID_PARAM; + } } else if (caseType == CaseType::CASE_WINDOW) { - ProcessWindowListener(registerListenerType, windowManagerListener, window, isRegister, env); + switch (static_cast(registerListenerType)) { + case static_cast(RegisterListenerType::WINDOW_SIZE_CHANGE_CB): + return ProcessWindowChangeRegister(windowManagerListener, window, isRegister, env); + case static_cast(RegisterListenerType::SYSTEM_AVOID_AREA_CHANGE_CB): + return ProcessSystemAvoidAreaChangeRegister(windowManagerListener, window, isRegister, env); + case static_cast(RegisterListenerType::AVOID_AREA_CHANGE_CB): + return ProcessAvoidAreaChangeRegister(windowManagerListener, window, isRegister, env); + case static_cast(RegisterListenerType::LIFECYCLE_EVENT_CB): + return ProcessLifeCycleEventRegister(windowManagerListener, window, isRegister, env); + case static_cast(RegisterListenerType::WINDOW_EVENT_CB): + return ProcessLifeCycleEventRegister(windowManagerListener, window, isRegister, env); + case static_cast(RegisterListenerType::KEYBOARD_HEIGHT_CHANGE_CB): + return ProcessOccupiedAreaChangeRegister(windowManagerListener, window, isRegister, env); + case static_cast(RegisterListenerType::KEYBOARD_DID_SHOW_CB): + return ProcessKeyboardDidShowRegister(windowManagerListener, window, isRegister, env); + case static_cast(RegisterListenerType::KEYBOARD_DID_HIDE_CB): + return ProcessKeyboardDidHideRegister(windowManagerListener, window, isRegister, env); + case static_cast(RegisterListenerType::TOUCH_OUTSIDE_CB): + return ProcessTouchOutsideRegister(windowManagerListener, window, isRegister, env); + case static_cast(RegisterListenerType::SCREENSHOT_EVENT_CB): + return ProcessScreenshotRegister(windowManagerListener, window, isRegister, env); + case static_cast(RegisterListenerType::DIALOG_TARGET_TOUCH_CB): + return ProcessDialogTargetTouchRegister(windowManagerListener, window, isRegister, env); + case static_cast(RegisterListenerType::DIALOG_DEATH_RECIPIENT_CB): + return ProcessDialogDeathRecipientRegister(windowManagerListener, window, isRegister, env); + case static_cast(RegisterListenerType::WINDOW_STATUS_CHANGE_CB): + return ProcessWindowStatusChangeRegister(windowManagerListener, window, isRegister, env); + case static_cast(RegisterListenerType::WINDOW_TITLE_BUTTON_RECT_CHANGE_CB): + return ProcessWindowTitleButtonRectChangeRegister(windowManagerListener, window, isRegister, env); + case static_cast(RegisterListenerType::WINDOW_VISIBILITY_CHANGE_CB): + return ProcessWindowVisibilityChangeRegister(windowManagerListener, window, isRegister, env); + case static_cast(RegisterListenerType::WINDOW_NO_INTERACTION_DETECT_CB): + return ProcessWindowNoInteractionRegister(windowManagerListener, window, isRegister, env, timeout); + case static_cast(RegisterListenerType::WINDOW_RECT_CHANGE_CB): + return ProcessWindowRectChangeRegister(windowManagerListener, window, isRegister, env); + case static_cast(RegisterListenerType::SUB_WINDOW_CLOSE_CB): + return ProcessSubWindowCloseRegister(windowManagerListener, window, isRegister, env); + case static_cast(RegisterListenerType::WINDOW_HIGHLIGHT_CHANGE_CB): + return ProcessWindowHighlightChangeRegister(windowManagerListener, window, isRegister, env); + case static_cast(RegisterListenerType::SYSTEM_DENSITY_CHANGE_CB): + return ProcessSystemDensityChangeRegister(windowManagerListener, window, isRegister, env); + case static_cast(RegisterListenerType::WINDOW_DISPLAYID_CHANGE_CB): + return ProcessDisplayIdChangeRegister(windowManagerListener, window, isRegister, env); + case static_cast(RegisterListenerType::WINDOW_ROTATION_CHANGE_CB): + return ProcessWindowRotationChangeRegister(windowManagerListener, window, isRegister, env); + default: + TLOGE(WmsLogTag::DEFAULT, "[ANI]RegisterListenerType %{public}u is not supported", + static_cast(registerListenerType)); + return WmErrorCode::WM_ERROR_INVALID_PARAM; + } } else if (caseType == CaseType::CASE_STAGE) { - ProcessWindowStageListener(registerListenerType, windowManagerListener, window, isRegister, env); + switch (registerListenerType) { + case RegisterListenerType::WINDOW_STAGE_EVENT_CB: + return ProcessLifeCycleEventRegister(windowManagerListener, window, isRegister, env); + case RegisterListenerType::WINDOW_STAGE_CLOSE_CB: + return ProcessMainWindowCloseRegister(windowManagerListener, window, isRegister, env); + default: + TLOGE(WmsLogTag::DEFAULT, "[ANI]RegisterListenerType %{public}u is not supported", + static_cast(registerListenerType)); + return WmErrorCode::WM_ERROR_INVALID_PARAM; + } } 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_); @@ -476,13 +561,18 @@ 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 callback, 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); + WmErrorCode ret = ProcessListener(listenerType, caseType, it->second, window, false, env, 0); 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()); + it->second->SetAniCallback(nullptr); jsCbMap_[type].erase(it++); } } else { @@ -490,15 +580,18 @@ 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; } findFlag = true; - WmErrorCode ret = ProcessListener(listenerType, caseType, it->second, window, false, env); + WmErrorCode ret = ProcessListener(listenerType, caseType, it->second, window, false, env, 0); if (ret != WmErrorCode::WM_OK) { TLOGE(WmsLogTag::DEFAULT, "[ANI]Unregister type %{public}s failed", type.c_str()); return ret; } + env->GlobalReference_Delete(it->second->GetAniCallback()); + it->second->SetAniCallback(nullptr); jsCbMap_[type].erase(it); break; } @@ -566,6 +659,22 @@ WmErrorCode AniWindowRegisterManager::ProcessSubWindowCloseRegister(sptr listener, + sptr window, bool isRegister, ani_env* env) +{ + if (window == nullptr) { + return WmErrorCode::WM_ERROR_STATE_ABNORMALLY; + } + sptr thisListener(listener); + WmErrorCode ret = WmErrorCode::WM_OK; + if (isRegister) { + ret = WM_JS_TO_ERROR_CODE_MAP.at(window->RegisterWindowHighlightChangeListeners(thisListener)); + } else { + ret = WM_JS_TO_ERROR_CODE_MAP.at(window->UnregisterWindowHighlightChangeListeners(thisListener)); + } + return ret; +} + WmErrorCode AniWindowRegisterManager::ProcessMainWindowCloseRegister(const sptr& listener, const sptr& window, bool isRegister, ani_env* env) { @@ -580,5 +689,24 @@ WmErrorCode AniWindowRegisterManager::ProcessMainWindowCloseRegister(const sptr< } return ret; } + +WmErrorCode AniWindowRegisterManager::ProcessWindowRotationChangeRegister(const sptr& listener, + const sptr& window, bool isRegister, ani_env* env) +{ + if (window == nullptr || listener == nullptr) { + return WmErrorCode::WM_ERROR_STATE_ABNORMALLY; + } + sptr thisListener(listener); + WmErrorCode ret = WmErrorCode::WM_OK; + if (window->IsPcWindow()) { + return WmErrorCode::WM_ERROR_DEVICE_NOT_SUPPORT; + } + if (isRegister) { + ret = WM_JS_TO_ERROR_CODE_MAP.at(window->RegisterWindowRotationChangeListener(thisListener)); + } else { + ret = WM_JS_TO_ERROR_CODE_MAP.at(window->UnregisterWindowRotationChangeListener(thisListener)); + } + return ret; +} } // namespace Rosen } // namespace OHOS \ No newline at end of file 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 21cb29abf849a483b083e8d4d422ddf08b6e57eb..093e311e82f111c1dbba2ce99fed0f4552a9fb88 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 @@ -22,6 +22,11 @@ #include "ani_window.h" #include "ani_window_manager.h" #include "ani_window_utils.h" +#include "interop_js/arkts_esvalue.h" +#include "interop_js/arkts_interop_js_api.h" +#include "interop_js/hybridgref_ani.h" +#include "interop_js/hybridgref_napi.h" +#include "js_window_stage.h" #include "window_manager_hilog.h" #include "permission.h" #include "window_scene.h" @@ -37,7 +42,7 @@ static std::map localObjs; } // namespace AniWindowStage::AniWindowStage(const std::shared_ptr& windowScene) - : windowScene_(windowScene) + : windowScene_(windowScene), registerManager_(std::make_unique()) { } AniWindowStage::~AniWindowStage() @@ -45,18 +50,99 @@ AniWindowStage::~AniWindowStage() TLOGE(WmsLogTag::DEFAULT, "[ANI] Ani WindowStage died"); } -void AniWindowStage::LoadContent(ani_env* env, const std::string& content) +ani_object AniWindowStage::NativeTransferStatic(ani_env* aniEnv, ani_class cls, ani_object input) { - 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]"); + void *unwrapResult = nullptr; + if (!arkts_esvalue_unwrap(aniEnv, input, &unwrapResult)) { + TLOGE(WmsLogTag::WMS_LIFE, "[ANI] fail to unwrap input"); + return AniWindowUtils::CreateAniUndefined(aniEnv); + } + if (unwrapResult == nullptr) { + TLOGE(WmsLogTag::WMS_LIFE, "[ANI] unwrapResult is nullptr"); + return AniWindowUtils::CreateAniUndefined(aniEnv); + } + JsWindowStage* jsWindowStage = static_cast(unwrapResult); + if (jsWindowStage == nullptr) { + TLOGE(WmsLogTag::WMS_LIFE, "[ANI] jsWindowStage is nullptr"); + return AniWindowUtils::CreateAniUndefined(aniEnv); + } + std::shared_ptr windowScene = jsWindowStage->GetWindowScene().lock(); + return CreateAniWindowStage(aniEnv, windowScene); +} + +ani_object AniWindowStage::NativeTransferDynamic(ani_env* aniEnv, ani_class cls, ani_long nativeObj) +{ + TLOGI(WmsLogTag::WMS_LIFE, "[ANI]"); + AniWindowStage* aniWindowStage = reinterpret_cast(nativeObj); + if (aniWindowStage == nullptr) { + TLOGE(WmsLogTag::WMS_LIFE, "[ANI] aniWindowStage is nullptr"); + return AniWindowUtils::CreateAniUndefined(aniEnv); + } + napi_env napiEnv {}; + if (!arkts_napi_scope_open(aniEnv, &napiEnv)) { + TLOGE(WmsLogTag::WMS_LIFE, "[ANI] napi scope open fail"); + return AniWindowUtils::CreateAniUndefined(aniEnv); + } + napi_value jsWindowStage = CreateJsWindowStage(napiEnv, aniWindowStage->GetWindowScene().lock()); + hybridgref ref {}; + if (!hybridgref_create_from_napi(napiEnv, jsWindowStage, &ref)) { + TLOGE(WmsLogTag::WMS_LIFE, "[ANI] create hybridgref fail"); + return AniWindowUtils::CreateAniUndefined(aniEnv); + } + ani_object result {}; + if (!hybridgref_get_esvalue(aniEnv, ref, &result)) { + TLOGE(WmsLogTag::WMS_LIFE, "[ANI] get esvalue fail"); + return AniWindowUtils::CreateAniUndefined(aniEnv); + } + if (!hybridgref_delete_from_napi(napiEnv, ref)) { + TLOGE(WmsLogTag::WMS_LIFE, "[ANI] delete hybridgref fail"); + } + if (!arkts_napi_scope_close_n(napiEnv, 0, nullptr, nullptr)) { + TLOGE(WmsLogTag::WMS_LIFE, "[ANI] napi close scope fail"); + return AniWindowUtils::CreateAniUndefined(aniEnv); + } + return result; +} + +void AniWindowStage::LoadContent(ani_env* env, ani_object obj, ani_long nativeObj, ani_string path, + ani_object storage) +{ + 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(); @@ -94,15 +180,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"))) { @@ -114,20 +191,16 @@ __attribute__((no_sanitize("cfi"))) ani_status ret; ani_class cls = nullptr; - if ((ret = env->FindClass("L@ohos/window/window/WindowStageInternal;", &cls)) != ANI_OK) { + if ((ret = env->FindClass("@ohos.window.window.WindowStageInternal", &cls)) != ANI_OK) { TLOGE(WmsLogTag::DEFAULT, "[ANI] null env %{public}u", ret); return cls; } 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; - } + TLOGD(WmsLogTag::DEFAULT, "[ANI] native obj %{public}p", windowStage.get()); ani_method initFunc = nullptr; - if ((ret = env->Class_FindMethod(cls, "", ":V", &initFunc)) != ANI_OK) { + if ((ret = env->Class_FindMethod(cls, "", ":", &initFunc)) != ANI_OK) { TLOGE(WmsLogTag::DEFAULT, "[ANI] get ctor fail %{public}u", ret); return nullptr; } @@ -137,12 +210,14 @@ __attribute__((no_sanitize("cfi"))) return nullptr; } 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); + if ((ret = env->Class_FindMethod(cls, "setNativeObj", "l:", &setObjFunc)) != ANI_OK) { + 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())); + + TLOGD(WmsLogTag::DEFAULT, "[ANI] window stage created %{public}p", reinterpret_cast(obj)); return obj; } @@ -216,7 +291,7 @@ void AniWindowStage::OnSetShowOnLockScreen(ani_env* env, ani_boolean showOnLockS } auto mainWindow = windowScene->GetMainWindow(); if (mainWindow == nullptr) { - TLOGE(WmsLogTag::DEFAULT, "[ANI] mainWindowis nullptr!"); + TLOGE(WmsLogTag::DEFAULT, "[ANI] mainWindow is nullptr!"); AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); return; } @@ -227,88 +302,177 @@ void AniWindowStage::OnSetShowOnLockScreen(ani_env* env, ani_boolean showOnLockS } TLOGE(WmsLogTag::DEFAULT, "[ANI] OnSetShowOnLockScreen end!"); } -} // namespace Rosen -} // namespace OHOS -static ani_int WindowStageLoadContent(ani_env* env, ani_object obj, - ani_long nativeObj, ani_string content) +void AniWindowStage::RegisterWindowCallback(ani_env* env, ani_object obj, ani_long nativeObj, ani_string type, + ani_ref callback) { - using namespace OHOS::Rosen; - AniWindowStage* windowStage = reinterpret_cast(nativeObj); - std::string contentStr; - GetStdString(env, content, contentStr); - windowStage->LoadContent(env, contentStr); - return (ani_int)0u; + TLOGI(WmsLogTag::DEFAULT, "[ANI]"); + AniWindowStage* aniWindowStage = reinterpret_cast(nativeObj); + if (aniWindowStage != nullptr) { + aniWindowStage->OnRegisterWindowCallback(env, type, callback); + } else { + TLOGE(WmsLogTag::DEFAULT, "[ANI] aniWindowStage is nullptr"); + } } -static ani_object WindowStageCreate(ani_env* env, ani_long scene) +void AniWindowStage::OnRegisterWindowCallback(ani_env* env, ani_string type, ani_ref callback) { - using namespace OHOS::Rosen; - std::shared_ptr scenePtr; - return CreateAniWindowStage(env, scenePtr); // just for test + TLOGI(WmsLogTag::DEFAULT, "[ANI]"); + auto windowScene = GetWindowScene().lock(); + if (windowScene == nullptr) { + TLOGE(WmsLogTag::DEFAULT, "[ANI]windowScene is nullptr!"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); + return; + } + auto mainWindow = windowScene->GetMainWindow(); + if (mainWindow == nullptr) { + TLOGE(WmsLogTag::DEFAULT, "[ANI] mainWindow is nullptr!"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); + return; + } + std::string cbType; + AniWindowUtils::GetStdString(env, type, cbType); + TLOGI(WmsLogTag::DEFAULT, "[ANI] type:%{public}s", cbType.c_str()); + WmErrorCode ret = registerManager_->RegisterListener(mainWindow, cbType, CaseType::CASE_STAGE, env, callback, 0); + if (ret != WmErrorCode::WM_OK) { + AniWindowUtils::AniThrowError(env, ret); + return; + } } -static ani_object WindowGetMainWindow(ani_env* env, ani_object obj, ani_long nativeObj) +void AniWindowStage::UnregisterWindowCallback(ani_env* env, ani_object obj, ani_long nativeObj, ani_string type, + ani_ref callback) { - using namespace OHOS::Rosen; - TLOGD(WmsLogTag::DEFAULT, "[ANI]"); - AniWindowStage* windowStage = reinterpret_cast(nativeObj); - if (windowStage == nullptr || windowStage->GetWindowScene().lock() == nullptr) { - TLOGD(WmsLogTag::DEFAULT, "[ANI] windowStage is nullptr"); - return AniWindowUtils::CreateAniUndefined(env); + TLOGI(WmsLogTag::DEFAULT, "[ANI]"); + AniWindowStage* aniWindowStage = reinterpret_cast(nativeObj); + if (aniWindowStage != nullptr) { + aniWindowStage->OnUnregisterWindowCallback(env, type, callback); + } else { + TLOGE(WmsLogTag::DEFAULT, "[ANI] aniWindowStage is nullptr"); } - return windowStage->GetMainWindow(env); } -extern "C" { -ANI_EXPORT ani_status ANI_Constructor(ani_vm *vm, uint32_t *result) +void AniWindowStage::OnUnregisterWindowCallback(ani_env* env, ani_string type, ani_ref callback) { - using namespace OHOS::Rosen; - ani_status ret; - ani_env* env; - if ((ret = vm->GetEnv(ANI_VERSION_1, &env)) != ANI_OK) { - TLOGE(WmsLogTag::DEFAULT, "[ANI] null env"); - return ANI_NOT_FOUND; + TLOGI(WmsLogTag::DEFAULT, "[ANI]"); + auto windowScene = GetWindowScene().lock(); + if (windowScene == nullptr) { + TLOGE(WmsLogTag::DEFAULT, "[ANI]windowScene is nullptr!"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); + return; + } + auto mainWindow = windowScene->GetMainWindow(); + if (mainWindow == nullptr) { + TLOGE(WmsLogTag::DEFAULT, "[ANI] mainWindow is nullptr!"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); + return; } + std::string cbType; + AniWindowUtils::GetStdString(env, type, cbType); + TLOGI(WmsLogTag::DEFAULT, "[ANI] type:%{public}s", cbType.c_str()); + WmErrorCode ret = registerManager_->UnregisterListener(mainWindow, cbType, CaseType::CASE_STAGE, env, callback); + if (ret != WmErrorCode::WM_OK) { + AniWindowUtils::AniThrowError(env, ret); + return; + } +} - ani_class cls = nullptr; - if ((ret = env->FindClass("L@ohos/window/window/WindowStageInternal;", &cls)) != ANI_OK) { - TLOGE(WmsLogTag::DEFAULT, "[ANI] can't find class %{public}u", ret); - return ANI_NOT_FOUND; - } - std::array methods = { - ani_native_function {"loadContent", "JLstd/core/String;:I", reinterpret_cast(WindowStageLoadContent)}, - ani_native_function {"disableWindowDecorSync", nullptr, - reinterpret_cast(AniWindowStage::DisableWindowDecor)}, - ani_native_function {"setShowOnLockScreenSync", - nullptr, reinterpret_cast(AniWindowStage::SetShowOnLockScreen)}, - ani_native_function {"getMainWindowSync", "J:L@ohos/window/window/Window;", - reinterpret_cast(WindowGetMainWindow)}, - }; - if ((ret = env->Class_BindNativeMethods(cls, methods.data(), methods.size())) != ANI_OK) { - TLOGE(WmsLogTag::DEFAULT, "[ANI] bind fail %{public}u", ret); - return ANI_NOT_FOUND; - } - *result = ANI_VERSION_1; - - // just for test - ani_namespace ns; - if ((ret = env->FindNamespace("L@ohos/window/window;", &ns)) != ANI_OK) { - TLOGE(WmsLogTag::DEFAULT, "[ANI] find ns %{public}u", ret); - return ANI_NOT_FOUND; - } - std::array functions = { - ani_native_function {"CreateWindowStage", "J:L@ohos/window/window/WindowStageInternal;", - reinterpret_cast(WindowStageCreate)}, - ani_native_function {"getLastWindowSync", nullptr, reinterpret_cast(AniWindowManager::GetLastWindow)}, - }; - if ((ret = env->Namespace_BindNativeFunctions(ns, functions.data(), functions.size())) != ANI_OK) { - TLOGE(WmsLogTag::DEFAULT, "[ANI] bind ns func %{public}u", ret); - return ANI_NOT_FOUND; - } - AniWindowManager::AniWindowManagerInit(env, ns); - - OHOS::Rosen::ANI_Window_Constructor(vm, result); - return ANI_OK; +void AniWindowStage::SetWindowRectAutoSave(ani_env* env, ani_boolean enabled, ani_boolean isSaveBySpecifiedFlag) +{ + TLOGI(WmsLogTag::WMS_LAYOUT_PC, "[ANI]"); + auto windowScene = GetWindowScene().lock(); + if (windowScene == nullptr) { + TLOGE(WmsLogTag::WMS_LAYOUT_PC, "[ANI] WindowScene is null"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); + return; + } + auto mainWindow = windowScene->GetMainWindow(); + if (mainWindow == nullptr) { + TLOGE(WmsLogTag::WMS_LAYOUT_PC, "[ANI] MainWindow is nullptr"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); + return; + } + WmErrorCode ret = WM_JS_TO_ERROR_CODE_MAP.at(mainWindow->SetWindowRectAutoSave(enabled, isSaveBySpecifiedFlag)); + if (ret != WmErrorCode::WM_OK) { + TLOGE(WmsLogTag::WMS_LAYOUT_PC, "[ANI] Enable recover position failed!"); + AniWindowUtils::AniThrowError(env, ret); + } else { + TLOGI(WmsLogTag::WMS_MAIN, "[ANI] id %{public}d isSaveBySpecifiedFlag: %{public}d " + "enable:%{public}d", mainWindow->GetWindowId(), isSaveBySpecifiedFlag, enabled); + } +} + +ani_boolean AniWindowStage::IsWindowRectAutoSave(ani_env* env) +{ + TLOGI(WmsLogTag::WMS_LAYOUT_PC, "[ANI]"); + auto windowScene = GetWindowScene().lock(); + if (windowScene == nullptr) { + TLOGE(WmsLogTag::WMS_LAYOUT_PC, "[ANI] WindowScene is null"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); + return ani_boolean(false); + } + auto mainWindow = windowScene->GetMainWindow(); + if (mainWindow == nullptr) { + TLOGE(WmsLogTag::WMS_LAYOUT_PC, "[ANI] MainWindow is nullptr"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); + return ani_boolean(false); + } + bool enabled = false; + WmErrorCode ret = WM_JS_TO_ERROR_CODE_MAP.at(mainWindow->IsWindowRectAutoSave(enabled)); + if (ret != WmErrorCode::WM_OK) { + TLOGE(WmsLogTag::WMS_LAYOUT_PC, "[ANI] Get the auto-save state of the window rect failed!"); + AniWindowUtils::AniThrowError(env, ret); + return ani_boolean(false); + } else { + return ani_boolean(enabled); + } } -} \ No newline at end of file + +void AniWindowStage::RemoveStartingWindow(ani_env* env) +{ + TLOGI(WmsLogTag::WMS_STARTUP_PAGE, "[ANI]"); + auto windowScene = GetWindowScene().lock(); + if (windowScene == nullptr) { + TLOGE(WmsLogTag::WMS_STARTUP_PAGE, "[ANI] windowScene is null"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); + return; + } + auto window = windowScene->GetMainWindow(); + if (window == nullptr) { + TLOGE(WmsLogTag::WMS_STARTUP_PAGE, "[ANI] window is nullptr"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); + return; + } + WmErrorCode ret = WM_JS_TO_ERROR_CODE_MAP.at(window->NotifyRemoveStartingWindow()); + if (ret != WmErrorCode::WM_OK) { + TLOGE(WmsLogTag::WMS_STARTUP_PAGE, "[ANI] Notify remove starting window failed"); + AniWindowUtils::AniThrowError(env, ret); + } +} + +ani_ref AniWindowStage::OnCreateSubWindow(ani_env* env, ani_string name) +{ + std::string windowName; + ani_status ret = AniWindowUtils::GetStdString(env, name, windowName); + if (ret != ANI_OK) { + TLOGE(WmsLogTag::DEFAULT, "[ANI] invalid param of name"); + return AniWindowUtils::CreateAniUndefined(env); + } + + auto weakScene = windowScene_.lock(); + if (weakScene == nullptr) { + TLOGI(WmsLogTag::DEFAULT, "[ANI] WindowScene is nullptr"); + return AniWindowUtils::CreateAniUndefined(env); + } + sptr windowOption = new Rosen::WindowOption(); + windowOption->SetWindowType(Rosen::WindowType::WINDOW_TYPE_APP_SUB_WINDOW); + windowOption->SetWindowMode(Rosen::WindowMode::WINDOW_MODE_FLOATING); + auto window = weakScene->CreateWindow(windowName, windowOption); + if (window == nullptr) { + return AniWindowUtils::CreateAniUndefined(env); + } + return CreateAniWindowObject(env, window); +} +} // namespace Rosen +} // namespace OHOS + diff --git a/interfaces/kits/ani/window_runtime/window_stage_ani/src/ani_window_stage_module.cpp b/interfaces/kits/ani/window_runtime/window_stage_ani/src/ani_window_stage_module.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1aaf49acc388563780ca1b76dccaaf7579768d54 --- /dev/null +++ b/interfaces/kits/ani/window_runtime/window_stage_ani/src/ani_window_stage_module.cpp @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include + +#include "ani.h" +#include "ani_window.h" +#include "ani_window_manager.h" +#include "ani_window_stage.h" +#include "ani_window_utils.h" +#include "permission.h" +#include "window_manager_hilog.h" +#include "window_scene.h" + +using namespace OHOS::Rosen; + + +static void SetWindowRectAutoSave(ani_env* env, ani_object obj, ani_long nativeObj, + ani_boolean enabled, ani_boolean isSaveBySpecifiedFlag) +{ + TLOGD(WmsLogTag::WMS_LAYOUT_PC, "[ANI] start"); + AniWindowStage* windowStage = reinterpret_cast(nativeObj); + if (windowStage == nullptr || windowStage->GetWindowScene().lock() == nullptr) { + TLOGD(WmsLogTag::WMS_LAYOUT_PC, "[ANI] windowStage is nullptr"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); + return; + } + windowStage->SetWindowRectAutoSave(env, enabled, isSaveBySpecifiedFlag); +} + +static ani_boolean IsWindowRectAutoSave(ani_env* env, ani_object obj, ani_long nativeObj) +{ + TLOGD(WmsLogTag::WMS_LAYOUT_PC, "[ANI] start"); + AniWindowStage* windowStage = reinterpret_cast(nativeObj); + if (windowStage == nullptr || windowStage->GetWindowScene().lock() == nullptr) { + TLOGD(WmsLogTag::WMS_LAYOUT_PC, "[ANI] windowStage is nullptr"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); + return ani_boolean(false); + } + return windowStage->IsWindowRectAutoSave(env); +} + +static void RemoveStartingWindow(ani_env* env, ani_object obj, ani_long nativeObj) +{ + TLOGD(WmsLogTag::WMS_STARTUP_PAGE, "[ANI] start"); + AniWindowStage* windowStage = reinterpret_cast(nativeObj); + if (windowStage == nullptr || windowStage->GetWindowScene().lock() == nullptr) { + TLOGD(WmsLogTag::WMS_STARTUP_PAGE, "[ANI] windowStage is nullptr"); + AniWindowUtils::AniThrowError(env, WmErrorCode::WM_ERROR_STATE_ABNORMALLY); + return; + } + windowStage->RemoveStartingWindow(env); +} + +static ani_ref WindowGetMainWindow(ani_env* env, ani_object obj, ani_long nativeObj) +{ + TLOGD(WmsLogTag::DEFAULT, "[ANI]"); + AniWindowStage* windowStage = reinterpret_cast(nativeObj); + if (windowStage == nullptr || windowStage->GetWindowScene().lock() == nullptr) { + TLOGD(WmsLogTag::DEFAULT, "[ANI] windowStage is nullptr"); + return AniWindowUtils::CreateAniUndefined(env); + } + return windowStage->GetMainWindow(env); +} + +static ani_ref CreateSubWindow(ani_env* env, ani_object obj, ani_long nativeObj, ani_string name) +{ + TLOGI(WmsLogTag::DEFAULT, "[ANI]"); + AniWindowStage* windowStage = reinterpret_cast(nativeObj); + if (windowStage == nullptr || windowStage->GetWindowScene().lock() == nullptr) { + TLOGD(WmsLogTag::DEFAULT, "[ANI] windowStage is nullptr"); + return AniWindowUtils::CreateAniUndefined(env); + } + return windowStage->OnCreateSubWindow(env, name); +} + +extern "C" { +ANI_EXPORT ani_status ANI_Constructor(ani_vm *vm, uint32_t *result) +{ + ani_status ret = ANI_OK; + ani_env* env = nullptr; + if ((ret = vm->GetEnv(ANI_VERSION_1, &env)) != ANI_OK) { + TLOGE(WmsLogTag::DEFAULT, "[ANI] null env"); + return ANI_NOT_FOUND; + } + ani_class cls = nullptr; + if ((ret = env->FindClass("@ohos.window.window.WindowStageInternal", &cls)) != ANI_OK) { + TLOGE(WmsLogTag::DEFAULT, "[ANI] can't find class %{public}u", ret); + return ANI_NOT_FOUND; + } + std::array methods = { + ani_native_function {"setWindowRectAutoSave", "lzz:", + reinterpret_cast(SetWindowRectAutoSave)}, + ani_native_function {"isWindowRectAutoSave", "l:z", + reinterpret_cast(IsWindowRectAutoSave)}, + ani_native_function {"removeStartingWindow", "l:", + reinterpret_cast(RemoveStartingWindow)}, + ani_native_function {"loadContentSync", + "lC{std.core.String}C{arkui.stateManagement.storage.localStorage.LocalStorage}:", + reinterpret_cast(AniWindowStage::LoadContent)}, + ani_native_function {"disableWindowDecorSync", nullptr, + reinterpret_cast(AniWindowStage::DisableWindowDecor)}, + ani_native_function {"setShowOnLockScreenSync", + nullptr, reinterpret_cast(AniWindowStage::SetShowOnLockScreen)}, + ani_native_function {"getMainWindowSync", "l:C{@ohos.window.window.Window}", + reinterpret_cast(WindowGetMainWindow)}, + ani_native_function {"createSubWindowSync", "lC{std.core.String}:C{@ohos.window.window.Window}", + reinterpret_cast(CreateSubWindow)}, + ani_native_function {"onSync", nullptr, + reinterpret_cast(AniWindowStage::RegisterWindowCallback)}, + ani_native_function {"offSync", nullptr, + reinterpret_cast(AniWindowStage::UnregisterWindowCallback)}, + ani_native_function {"nativeTransferStatic", "C{std.interop.ESValue}:C{std.core.Object}", + reinterpret_cast(AniWindowStage::NativeTransferStatic)}, + ani_native_function {"nativeTransferDynamic", "l:C{std.interop.ESValue}", + reinterpret_cast(AniWindowStage::NativeTransferDynamic)}, + }; + for (auto method : methods) { + if ((ret = env->Class_BindNativeMethods(cls, &method, 1u)) != ANI_OK) { + TLOGE(WmsLogTag::DEFAULT, "[ANI] bind window method fail %{public}u, %{public}s, %{public}s", + ret, method.name, method.signature); + return ANI_NOT_FOUND; + } + } + *result = ANI_VERSION_1; + AniWindowManager::AniWindowManagerInit(env); + OHOS::Rosen::ANI_Window_Constructor(vm, result); + return ANI_OK; +} +} \ No newline at end of file diff --git a/interfaces/kits/ani/window_runtime/window_stage_ani/src/ani_window_utils.cpp b/interfaces/kits/ani/window_runtime/window_stage_ani/src/ani_window_utils.cpp index 3da485ebe49c18da324df5d85e0c88ff3135ae1d..6a2f701123adf4804a2be622a7947bbdcc386d49 100644 --- a/interfaces/kits/ani/window_runtime/window_stage_ani/src/ani_window_utils.cpp +++ b/interfaces/kits/ani/window_runtime/window_stage_ani/src/ani_window_utils.cpp @@ -22,12 +22,28 @@ #include "ani_err_utils.h" #include "ani_window.h" #include "bundle_constants.h" +#include "foundation/arkui/ace_engine/interfaces/inner_api/ace/ui_content.h" #include "ipc_skeleton.h" #include "window_manager_hilog.h" -#include "ui_content.h" namespace OHOS { namespace Rosen { +namespace { +std::string GetHexColor(uint32_t color) +{ + std::stringstream ioss; + std::string temp; + ioss << std::setiosflags(std::ios::uppercase) << std::hex << color; + ioss >> temp; + int count = RGBA_LENGTH - static_cast(temp.length()); + std::string tmpColor(count, '0'); + tmpColor += temp; + std::string finalColor("#"); + finalColor += tmpColor; + return finalColor; +} +} + ani_status AniWindowUtils::GetStdString(ani_env *env, ani_string ani_str, std::string &result) { ani_size strSize; @@ -49,14 +65,14 @@ ani_status AniWindowUtils::GetStdString(ani_env *env, ani_string ani_str, std::s ani_status AniWindowUtils::GetStdStringVector(ani_env* env, ani_object ary, std::vector& result) { - ani_double length; - ani_status ret = env->Object_GetPropertyByName_Double(ary, "length", &length); + ani_int length; + ani_status ret = env->Object_GetPropertyByName_Int(ary, "length", &length); if (ret != ANI_OK) { return ret; } for (int32_t i = 0; i< static_cast(length); i++) { ani_ref stringRef; - ret = env->Object_CallMethodByName_Ref(ary, "$_get", "I:Lstd/core/Object;", &stringRef, ani_int(i)); + ret = env->Object_CallMethodByName_Ref(ary, "$_get", "i:C{std.core.Object}", &stringRef, ani_int(i)); if (ret != ANI_OK) { return ret; } @@ -67,6 +83,142 @@ ani_status AniWindowUtils::GetStdStringVector(ani_env* env, ani_object ary, std: return ANI_OK; } +ani_status AniWindowUtils::GetPropertyIntObject(ani_env* env, const char* propertyName, + ani_object object, int32_t& result) +{ + ani_ref int_ref; + ani_status ret = env->Object_GetPropertyByName_Ref(object, propertyName, &int_ref); + if (ret != ANI_OK) { + TLOGE(WmsLogTag::DEFAULT, "[ANI] Object_GetPropertyByName_Ref %{public}s Failed, ret : %{public}u", + propertyName, static_cast(ret)); + return ret; + } + + ani_boolean isUndefined; + if (ANI_OK != env->Reference_IsUndefined(int_ref, &isUndefined)) { + TLOGE(WmsLogTag::DEFAULT, "[ANI] Object_GetPropertyByName_Ref %{public}s Failed", propertyName); + return ret; + } + + if (isUndefined) { + TLOGE(WmsLogTag::DEFAULT, "[ANI] %{public}s is Undefined Now", propertyName); + return ret; + } + + ani_int int_value; + if (ANI_OK != env->Object_CallMethodByName_Int(static_cast(int_ref), "intValue", nullptr, &int_value)) { + TLOGE(WmsLogTag::DEFAULT, "[ANI] Object_GetPropertyByName_Ref %{public}s Failed", propertyName); + return ret; + } + result = static_cast(int_value); + TLOGI(WmsLogTag::DEFAULT, "[ANI] %{public}s is: %{public}u", propertyName, result); + return ret; +} + +ani_status AniWindowUtils::GetPropertyDoubleObject(ani_env* env, const char* propertyName, + ani_object object, double& result) +{ + ani_ref double_ref; + ani_status ret = env->Object_GetPropertyByName_Ref(object, propertyName, &double_ref); + if (ret != ANI_OK) { + TLOGE(WmsLogTag::DEFAULT, "[ANI] Object_GetPropertyByName_Ref %{public}s Failed, ret : %{public}u", + propertyName, static_cast(ret)); + return ret; + } + + ani_boolean isUndefined; + if (ANI_OK != env->Reference_IsUndefined(double_ref, &isUndefined)) { + TLOGE(WmsLogTag::DEFAULT, "[ANI] Object_GetPropertyByName_Ref %{public}s Failed", propertyName); + return ret; + } + + if (isUndefined) { + TLOGE(WmsLogTag::DEFAULT, "[ANI] %{public}s is Undefined Now", propertyName); + return ret; + } + + ani_double double_value; + if (ANI_OK != env->Object_CallMethodByName_Double(static_cast(double_ref), + "doubleValue", nullptr, &double_value)) { + TLOGE(WmsLogTag::DEFAULT, "[ANI] Object_GetPropertyByName_Ref %{public}s Failed", propertyName); + return ret; + } + result = static_cast(double_value); + TLOGI(WmsLogTag::DEFAULT, "[ANI] %{public}s is: %{public}f", propertyName, result); + return ret; +} + +bool AniWindowUtils::GetPropertyRectObject(ani_env* env, const char* propertyName, + ani_object object, Rect& result) +{ + ani_ref windowRect; + ani_status ret = env->Object_GetPropertyByName_Ref(object, propertyName, &windowRect); + if (ret != ANI_OK) { + TLOGE(WmsLogTag::DEFAULT, "[ANI] Object_GetPropertyByName_Ref %{public}s Failed, ret : %{public}u", + propertyName, static_cast(ret)); + return false; + } + + int32_t posX = 0; + int32_t posY = 0; + int32_t width = 0; + int32_t height = 0; + bool ret_bool = GetIntObject(env, "left", static_cast(windowRect), posX); + ret_bool |= GetIntObject(env, "top", static_cast(windowRect), posY); + ret_bool |= GetIntObject(env, "width", static_cast(windowRect), width); + ret_bool |= GetIntObject(env, "height", static_cast(windowRect), height); + if (!ret_bool) { + TLOGE(WmsLogTag::DEFAULT, "[ANI] GetIntObject Failed"); + return false; + } + result.posX_ = posX; + result.posY_ = posY; + result.width_ = width; + result.height_ = height; + TLOGI(WmsLogTag::DEFAULT, "[ANI] rect is [%{public}u, %{public}u, %{public}u, %{public}u]", + result.posX_, result.posY_, result.width_, result.height_); + return ret_bool; +} + +bool AniWindowUtils::GetIntObject(ani_env* env, const char* propertyName, + ani_object object, int32_t& result) +{ + ani_int int_value; + ani_status ret = env->Object_GetPropertyByName_Int(object, propertyName, &int_value); + if (ret != ANI_OK) { + TLOGE(WmsLogTag::DEFAULT, "[ANI] Object_GetPropertyByName_Int %{public}s Failed, ret : %{public}u", + propertyName, static_cast(ret)); + return false; + } + result = static_cast(int_value); + return true; +} + +ani_status AniWindowUtils::GetDoubleObject(ani_env* env, ani_object double_object, double& result) +{ + ani_boolean isUndefined; + ani_status isUndefinedRet = env->Reference_IsUndefined(double_object, &isUndefined); + if (ANI_OK != isUndefinedRet) { + TLOGE(WmsLogTag::DEFAULT, "[ANI] Check double_object isUndefined fail"); + return isUndefinedRet; + } + + if (isUndefined) { + TLOGE(WmsLogTag::DEFAULT, "[ANI] CallMeWithOptionalDouble Not Pass Value"); + return ANI_INVALID_ARGS; + } + + ani_double double_value; + ani_status ret = env->Object_CallMethodByName_Double(double_object, "doubleValue", nullptr, &double_value); + if (ANI_OK != ret) { + TLOGE(WmsLogTag::DEFAULT, "[ANI] Object_CallMethodByName_Double Failed!"); + return ret; + } + result = static_cast(double_value); + TLOGI(WmsLogTag::DEFAULT, "[ANI] double result is: %{public}f", result); + return ret; +} + ani_status AniWindowUtils::NewAniObjectNoParams(ani_env* env, const char* cls, ani_object* object) { ani_class aniClass; @@ -132,7 +284,7 @@ ani_object AniWindowUtils::CreateAniSize(ani_env* env, int32_t width, int32_t he { TLOGI(WmsLogTag::DEFAULT, "[ANI]"); ani_class aniClass; - ani_status ret = env->FindClass("L@ohos/window/window/SizeInternal;", &aniClass); + ani_status ret = env->FindClass("@ohos.window.window.SizeInternal", &aniClass); if (ret != ANI_OK) { TLOGE(WmsLogTag::DEFAULT, "[ANI] class not found"); return AniWindowUtils::CreateAniUndefined(env); @@ -149,16 +301,98 @@ ani_object AniWindowUtils::CreateAniSize(ani_env* env, int32_t width, int32_t he TLOGE(WmsLogTag::DEFAULT, "[ANI] fail to new obj"); return AniWindowUtils::CreateAniUndefined(env); } - CallAniMethodVoid(env, aniRect, aniClass, "width", nullptr, ani_double(width)); - CallAniMethodVoid(env, aniRect, aniClass, "height", nullptr, ani_double(height)); + CallAniMethodVoid(env, aniRect, aniClass, "width", nullptr, ani_int(width)); + CallAniMethodVoid(env, aniRect, aniClass, "height", nullptr, ani_int(height)); return aniRect; } +ani_object AniWindowUtils::CreateAniDecorButtonStyle(ani_env* env, const DecorButtonStyle& decorButtonStyle) +{ + TLOGI(WmsLogTag::WMS_DECOR, "[ANI]"); + ani_class aniClass; + ani_status ret = env->FindClass("@ohos.window.window.DecorButtonStyle", &aniClass); + if (ret != ANI_OK) { + TLOGE(WmsLogTag::WMS_DECOR, "[ANI] class not found"); + return AniWindowUtils::CreateAniUndefined(env); + } + ani_method aniCtor; + ret = env->Class_FindMethod(aniClass, "", nullptr, &aniCtor); + if (ret != ANI_OK) { + TLOGE(WmsLogTag::WMS_DECOR, "[ANI] ctor not found"); + return AniWindowUtils::CreateAniUndefined(env); + } + ani_object aniDecorButtonStyle; + ret = env->Object_New(aniClass, aniCtor, &aniDecorButtonStyle); + if (ret != ANI_OK) { + TLOGE(WmsLogTag::WMS_DECOR, "[ANI] fail to new obj"); + return AniWindowUtils::CreateAniUndefined(env); + } + CallAniMethodVoid(env, aniDecorButtonStyle, aniClass, + "colorMode", nullptr, ani_long(decorButtonStyle.colorMode)); + CallAniMethodVoid(env, aniDecorButtonStyle, aniClass, + "buttonBackgroundSize", nullptr, ani_double(decorButtonStyle.buttonBackgroundSize)); + CallAniMethodVoid(env, aniDecorButtonStyle, aniClass, + "spacingBetweenButtons", nullptr, ani_double(decorButtonStyle.spacingBetweenButtons)); + CallAniMethodVoid(env, aniDecorButtonStyle, aniClass, + "closeButtonRightMargin", nullptr, ani_double(decorButtonStyle.closeButtonRightMargin)); + return aniDecorButtonStyle; +} + +ani_object AniWindowUtils::CreateAniTitleButtonRect(ani_env* env, const TitleButtonRect& titleButtonRect) +{ + TLOGI(WmsLogTag::WMS_DECOR, "[ANI]"); + ani_class aniClass; + ani_status ret = env->FindClass("@ohos.window.window.TitleButtonRect", &aniClass); + if (ret != ANI_OK) { + TLOGE(WmsLogTag::WMS_DECOR, "[ANI] class not found"); + return AniWindowUtils::CreateAniUndefined(env); + } + ani_method aniCtor; + ret = env->Class_FindMethod(aniClass, "", nullptr, &aniCtor); + if (ret != ANI_OK) { + TLOGE(WmsLogTag::WMS_DECOR, "[ANI] ctor not found"); + return AniWindowUtils::CreateAniUndefined(env); + } + ani_object aniTitleButtonRect; + ret = env->Object_New(aniClass, aniCtor, &aniTitleButtonRect); + if (ret != ANI_OK) { + TLOGE(WmsLogTag::WMS_DECOR, "[ANI] fail to new obj"); + return AniWindowUtils::CreateAniUndefined(env); + } + CallAniMethodVoid(env, aniTitleButtonRect, aniClass, "right", nullptr, ani_double(titleButtonRect.posX_)); + CallAniMethodVoid(env, aniTitleButtonRect, aniClass, "top", nullptr, ani_double(titleButtonRect.posY_)); + CallAniMethodVoid(env, aniTitleButtonRect, aniClass, "width", nullptr, ani_double(titleButtonRect.width_)); + CallAniMethodVoid(env, aniTitleButtonRect, aniClass, "height", nullptr, ani_double(titleButtonRect.height_)); + return aniTitleButtonRect; +} + +ani_object AniWindowUtils::CreateAniWindowArray(ani_env* env, std::vector& windows) +{ + TLOGI(WmsLogTag::DEFAULT, "[ANI]"); + ani_array_ref windowArray = nullptr; + ani_class windowCls; + if (env->FindClass("@ohos.window.window.WindowInternal", &windowCls) != ANI_OK) { + TLOGE(WmsLogTag::DEFAULT, "[ANI] class not found"); + return AniWindowUtils::CreateAniUndefined(env); + } + if (env->Array_New_Ref(windowCls, windows.size(), CreateAniUndefined(env), &windowArray) != ANI_OK) { + TLOGE(WmsLogTag::DEFAULT, "[ANI] create array fail"); + return AniWindowUtils::CreateAniUndefined(env); + } + for (size_t i = 0; i < windows.size(); i++) { + if (env->Array_Set_Ref(windowArray, i, windows[i]) != ANI_OK) { + TLOGE(WmsLogTag::DEFAULT, "[ANI] set window array failed"); + return AniWindowUtils::CreateAniUndefined(env); + } + } + return windowArray; +} + ani_object AniWindowUtils::CreateAniRect(ani_env* env, const Rect& rect) { TLOGI(WmsLogTag::DEFAULT, "[ANI]"); ani_class aniClass; - ani_status ret = env->FindClass("L@ohos/window/window/RectInternal;", &aniClass); + ani_status ret = env->FindClass("@ohos.window.window.RectInternal", &aniClass); if (ret != ANI_OK) { TLOGE(WmsLogTag::DEFAULT, "[ANI] class not found"); return AniWindowUtils::CreateAniUndefined(env); @@ -175,10 +409,10 @@ ani_object AniWindowUtils::CreateAniRect(ani_env* env, const Rect& rect) TLOGE(WmsLogTag::DEFAULT, "[ANI] fail to create new obj"); return AniWindowUtils::CreateAniUndefined(env); } - CallAniMethodVoid(env, aniRect, aniClass, "left", nullptr, ani_double(rect.posX_)); - CallAniMethodVoid(env, aniRect, aniClass, "top", nullptr, ani_double(rect.posY_)); - CallAniMethodVoid(env, aniRect, aniClass, "width", nullptr, ani_double(rect.width_)); - CallAniMethodVoid(env, aniRect, aniClass, "height", nullptr, ani_double(rect.height_)); + CallAniMethodVoid(env, aniRect, aniClass, "left", nullptr, ani_int(rect.posX_)); + CallAniMethodVoid(env, aniRect, aniClass, "top", nullptr, ani_int(rect.posY_)); + CallAniMethodVoid(env, aniRect, aniClass, "width", nullptr, ani_int(rect.width_)); + CallAniMethodVoid(env, aniRect, aniClass, "height", nullptr, ani_int(rect.height_)); return aniRect; } @@ -186,7 +420,7 @@ ani_object AniWindowUtils::CreateAniAvoidArea(ani_env* env, const AvoidArea& avo { TLOGI(WmsLogTag::DEFAULT, "[ANI]"); ani_class aniClass; - ani_status ret = env->FindClass("L@ohos/window/window/AvoidAreaInternal;", &aniClass); + ani_status ret = env->FindClass("@ohos.window.window.AvoidAreaInternal", &aniClass); if (ret != ANI_OK) { TLOGE(WmsLogTag::DEFAULT, "[ANI] class not found"); return AniWindowUtils::CreateAniUndefined(env); @@ -216,18 +450,207 @@ ani_object AniWindowUtils::CreateAniAvoidArea(ani_env* env, const AvoidArea& avo return aniAvoidArea; } +ani_object AniWindowUtils::CreateAniKeyboardInfo(ani_env* env, const KeyboardPanelInfo& keyboardPanelInfo) +{ + TLOGI(WmsLogTag::WMS_KEYBOARD, "[ANI]"); + ani_class aniClass; + ani_status ret = env->FindClass("@ohos.window.window.KeyboardInfoInternal", &aniClass); + if (ret != ANI_OK) { + TLOGE(WmsLogTag::WMS_KEYBOARD, "[ANI] class not found"); + return AniWindowUtils::CreateAniUndefined(env); + } + ani_method aniCtor; + ret = env->Class_FindMethod(aniClass, "", nullptr, &aniCtor); + if (ret != ANI_OK) { + TLOGE(WmsLogTag::WMS_KEYBOARD, "[ANI] ctor not found"); + return AniWindowUtils::CreateAniUndefined(env); + } + ani_object keyboardInfo; + ret = env->Object_New(aniClass, aniCtor, &keyboardInfo); + if (ret != ANI_OK) { + TLOGE(WmsLogTag::WMS_KEYBOARD, "[ANI] failed to new obj"); + return AniWindowUtils::CreateAniUndefined(env); + } + CallAniMethodVoid(env, keyboardInfo, aniClass, "beginRect", nullptr, + CreateAniRect(env, keyboardPanelInfo.beginRect_)); + CallAniMethodVoid(env, keyboardInfo, aniClass, "endRect", nullptr, + CreateAniRect(env, keyboardPanelInfo.endRect_)); + return keyboardInfo; +} + +ani_object AniWindowUtils::CreateAniSystemBarTintState(ani_env* env, DisplayId displayId, + const SystemBarRegionTints& tints) +{ + TLOGI(WmsLogTag::DEFAULT, "[ANI]"); + ani_class aniClass; + if (env->FindClass("@ohos.window.window.SystemBarTintStateInternal", &aniClass) != ANI_OK) { + TLOGE(WmsLogTag::DEFAULT, "[ANI] class not found"); + return AniWindowUtils::CreateAniUndefined(env); + } + ani_method aniCtor; + if (env->Class_FindMethod(aniClass, "", nullptr, &aniCtor) != ANI_OK) { + TLOGE(WmsLogTag::DEFAULT, "[ANI] ctor not found"); + return AniWindowUtils::CreateAniUndefined(env); + } + ani_object state; + if (env->Object_New(aniClass, aniCtor, &state) != ANI_OK) { + TLOGE(WmsLogTag::DEFAULT, "[ANI] fail to new obj"); + return AniWindowUtils::CreateAniUndefined(env); + } + CallAniMethodVoid(env, state, aniClass, "displayId", nullptr, static_cast(displayId)); + ani_array_ref regionTintArray = nullptr; + ani_class regionTintCls; + if (env->FindClass("@ohos.window.window.SystemBarRegionTintInternal", ®ionTintCls) != ANI_OK) { + TLOGE(WmsLogTag::DEFAULT, "[ANI] class not found"); + return AniWindowUtils::CreateAniUndefined(env); + } + if (env->Array_New_Ref(regionTintCls, tints.size(), CreateAniUndefined(env), ®ionTintArray) != ANI_OK) { + TLOGE(WmsLogTag::DEFAULT, "[ANI] create array failed"); + return AniWindowUtils::CreateAniUndefined(env); + } + for (size_t i = 0; i < tints.size(); i++) { + if (env->Array_Set_Ref(regionTintArray, i, CreateAniSystemBarRegionTint(env, tints[i])) != ANI_OK) { + TLOGE(WmsLogTag::DEFAULT, "[ANI] create region tint failed"); + return AniWindowUtils::CreateAniUndefined(env); + } + } + CallAniMethodVoid(env, state, aniClass, "regionTint", nullptr, regionTintArray); + return state; +} + +ani_object AniWindowUtils::CreateAniSystemBarRegionTint(ani_env* env, const SystemBarRegionTint& tint) +{ + ani_class regionTintCls; + if (env->FindClass("@ohos.window.window.SystemBarRegionTintInternal", ®ionTintCls) != ANI_OK) { + TLOGE(WmsLogTag::DEFAULT, "[ANI] class not found"); + return AniWindowUtils::CreateAniUndefined(env); + } + ani_method regionTintCtor; + if (env->Class_FindMethod(regionTintCls, "", nullptr, ®ionTintCtor) != ANI_OK) { + TLOGE(WmsLogTag::DEFAULT, "[ANI] ctor not found"); + return AniWindowUtils::CreateAniUndefined(env); + } + ani_object regionTint; + if (env->Object_New(regionTintCls, regionTintCtor, ®ionTint) != ANI_OK) { + TLOGE(WmsLogTag::DEFAULT, "[ANI] fail to new obj"); + return AniWindowUtils::CreateAniUndefined(env); + } + if (NATIVE_JS_TO_WINDOW_TYPE_MAP.count(tint.type_) != 0) { + CallAniMethodVoid(env, regionTint, regionTintCls, "type", nullptr, + ani_long(NATIVE_JS_TO_WINDOW_TYPE_MAP.at(tint.type_))); + } else { + CallAniMethodVoid(env, regionTint, regionTintCls, "type", nullptr, ani_long(tint.type_)); + } + CallAniMethodVoid(env, regionTint, regionTintCls, "isEnable", nullptr, ani_boolean(tint.prop_.enable_)); + ani_string backgroundColor; + if (GetAniString(env, GetHexColor(tint.prop_.backgroundColor_), &backgroundColor) != ANI_OK) { + TLOGE(WmsLogTag::DEFAULT, "[ANI] create string failed"); + return AniWindowUtils::CreateAniUndefined(env); + } + CallAniMethodVoid(env, regionTint, regionTintCls, "backgroundColor", nullptr, backgroundColor); + ani_string contentColor; + if (GetAniString(env, GetHexColor(tint.prop_.contentColor_), &contentColor) != ANI_OK) { + TLOGE(WmsLogTag::DEFAULT, "[ANI] create string failed"); + return AniWindowUtils::CreateAniUndefined(env); + } + CallAniMethodVoid(env, regionTint, regionTintCls, "contentColor", nullptr, contentColor); + CallAniMethodVoid(env, regionTint, regionTintCls, "region", nullptr, CreateAniRect(env, tint.region_)); + return regionTint; +} + +ani_object AniWindowUtils::CreateAniRotationChangeInfo(ani_env* env, const RotationChangeInfo& info) +{ + TLOGI(WmsLogTag::WMS_ROTATION, "[ANI]"); + ani_class aniClass; + ani_status ret = env->FindClass("L@ohos/window/window/RotationChangeInfoInternal;", &aniClass); + if (ret != ANI_OK) { + TLOGE(WmsLogTag::WMS_ROTATION, "[ANI] class not found"); + return AniWindowUtils::CreateAniUndefined(env); + } + ani_method aniCtor; + ret = env->Class_FindMethod(aniClass, "", nullptr, &aniCtor); + if (ret != ANI_OK) { + TLOGE(WmsLogTag::WMS_ROTATION, "[ANI] ctor not found"); + return AniWindowUtils::CreateAniUndefined(env); + } + ani_object RotationChangeInfo; + ret = env->Object_New(aniClass, aniCtor, &RotationChangeInfo); + if (ret != ANI_OK) { + TLOGE(WmsLogTag::WMS_ROTATION, "[ANI] failed to new obj"); + return AniWindowUtils::CreateAniUndefined(env); + } + ani_enum rotationChangeType; + ret = env->FindEnum("L@ohos/window/window/RotationChangeType;", &rotationChangeType); + if (ret != ANI_OK) { + TLOGE(WmsLogTag::WMS_ROTATION, "[ANI] failed to FindEnum"); + return AniWindowUtils::CreateAniUndefined(env); + } + ani_enum_item rotationChangeTypeItem; + std::string itemName = + info.type_ == RotationChangeType::WINDOW_WILL_ROTATE? "WINDOW_WILL_ROTATE" : "WINDOW_DID_ROTATE"; + ret = env->Enum_GetEnumItemByName(rotationChangeType, itemName.c_str(), &rotationChangeTypeItem); + if (ret != ANI_OK) { + TLOGE(WmsLogTag::WMS_ROTATION, "[ANI] Enum_GetEnumItemByName failed"); + return AniWindowUtils::CreateAniUndefined(env); + } + CallAniMethodVoid(env, RotationChangeInfo, aniClass, "type", nullptr, + rotationChangeTypeItem); + CallAniMethodVoid(env, RotationChangeInfo, aniClass, "orientation", nullptr, + ani_int(info.orientation_)); + CallAniMethodVoid(env, RotationChangeInfo, aniClass, "displayId", nullptr, + ani_long(info.displayId_)); + CallAniMethodVoid(env, RotationChangeInfo, aniClass, "displayRect", nullptr, + CreateAniRect(env, info.displayRect_)); + return RotationChangeInfo; +} + +void AniWindowUtils::ParseRotationChangeResult(ani_env* env, ani_object obj, RotationChangeResult& rotationChangeResult) +{ + ani_boolean isUndefined; + ani_status ret = env->Reference_IsUndefined(obj, &isUndefined); + if (ret != ANI_OK) { + TLOGE(WmsLogTag::WMS_ROTATION, "[ANI] Check rotationChangeResultObj isUndefined failed, ret: %{public}d", ret); + return; + } + if (isUndefined) { + TLOGI(WmsLogTag::WMS_ROTATION, "[ANI] RotationChangeResult is undefined"); + return; + } + ani_ref rectTypeRef; + ret = env->Object_GetPropertyByName_Ref(obj, "rectType", &rectTypeRef); + if (ret != ANI_OK) { + TLOGE(WmsLogTag::WMS_ROTATION, "[ANI] Object_GetPropertyByName_Ref failed, ret: %{public}d", ret); + return; + } + ani_int rectType; + ret = env->EnumItem_GetValue_Int(static_cast(rectTypeRef), &rectType); + if (ret != ANI_OK) { + TLOGE(WmsLogTag::WMS_ROTATION, "[ANI] EnumItem_GetValue_Int failed, ret: %{public}d", ret); + return; + } + + Rect windowRect; + bool ret_bool = GetPropertyRectObject(env, "windowRect", obj, windowRect); + if (!ret_bool) { + TLOGE(WmsLogTag::WMS_ROTATION, "[ANI] GetPropertyRectObject failed"); + return; + } + rotationChangeResult.rectType_ = static_cast(rectType); + rotationChangeResult.windowRect_ = windowRect; +} + ani_status AniWindowUtils::CallAniFunctionVoid(ani_env *env, const char* ns, const char* fn, const char* signature, ...) { ani_status ret = ANI_OK; ani_namespace aniNamespace{}; if ((ret = env->FindNamespace(ns, &aniNamespace)) != ANI_OK) { - TLOGE(WmsLogTag::DEFAULT, "[ANI]canot find ns %{public}d", ret); + TLOGE(WmsLogTag::DEFAULT, "[ANI]cannot find ns:%{public}s ret:%{public}d", ns, ret); return ret; } ani_function func{}; if ((ret = env->Namespace_FindFunction(aniNamespace, fn, signature, &func)) != ANI_OK) { - TLOGE(WmsLogTag::DEFAULT, "[ANI]canot find callBack %{public}d", ret); + TLOGE(WmsLogTag::DEFAULT, "[ANI]cannot find callback %{public}d", ret); return ret; } va_list args; @@ -235,7 +658,26 @@ ani_status AniWindowUtils::CallAniFunctionVoid(ani_env *env, const char* ns, ret = env->Function_Call_Void_V(func, args); va_end(args); if (ret != ANI_OK) { - TLOGE(WmsLogTag::DEFAULT, "[ANI]canot run callBack %{public}d", ret); + TLOGE(WmsLogTag::DEFAULT, "[ANI]cannot run callback %{public}d", ret); + return ret; + } + return ret; +} + +ani_status AniWindowUtils::CallAniFunctionRef(ani_env *env, ani_ref& result, + ani_ref ani_callback, const int32_t args_num, ...) +{ + va_list args; + va_start(args, args_num); + std::vector vec; + for (int i = 0; i < args_num; i++) { + vec.push_back(va_arg(args, ani_object)); + } + va_end(args); + ani_status ret = env->FunctionalObject_Call(static_cast(ani_callback), ani_size(args_num), + vec.data(), &result); + if (ret != ANI_OK) { + TLOGE(WmsLogTag::DEFAULT, "[ANI]cannot run callback %{public}d", ret); return ret; } return ret; @@ -368,7 +810,7 @@ void AniWindowUtils::SetSystemPropertiesWindowFousable(ani_env* env, const sptr< void AniWindowUtils::SetSystemPropertiesWindowIsPrivacyMode(ani_env* env, const sptr& window, ani_object& systemProperties, const char* clsName) { - TLOGI(WmsLogTag::DEFAULT, "[ANI]"); + TLOGI(WmsLogTag::WMS_ATTRIBUTE, "[ANI]"); bool windowIsPrivacyMode = window->IsPrivacyMode(); CallAniMethodVoid(env, systemProperties, clsName, "isPrivacyMode", nullptr, static_cast(windowIsPrivacyMode)); @@ -377,7 +819,7 @@ void AniWindowUtils::SetSystemPropertiesWindowIsPrivacyMode(ani_env* env, const void AniWindowUtils::SetSystemPropertiesWindowIsKeepScreenOn(ani_env* env, const sptr& window, ani_object& systemProperties, const char* clsName) { - TLOGI(WmsLogTag::DEFAULT, "[ANI]"); + TLOGI(WmsLogTag::WMS_ATTRIBUTE, "[ANI]"); bool windowIsKeepScreenOn = window->IsKeepScreenOn(); CallAniMethodVoid(env, systemProperties, clsName, "isKeepScreenOn", nullptr, static_cast(windowIsKeepScreenOn)); @@ -386,7 +828,7 @@ void AniWindowUtils::SetSystemPropertiesWindowIsKeepScreenOn(ani_env* env, const void AniWindowUtils::SetSystemPropertiesWindowBrightness(ani_env* env, const sptr& window, ani_object& systemProperties, const char* clsName) { - TLOGI(WmsLogTag::DEFAULT, "[ANI]"); + TLOGI(WmsLogTag::WMS_ATTRIBUTE, "[ANI]"); float windowBrightness = window->GetBrightness(); CallAniMethodVoid(env, systemProperties, clsName, "brightness", nullptr, static_cast(windowBrightness)); @@ -396,17 +838,17 @@ void AniWindowUtils::SetSystemPropertiesWindowBrightness(ani_env* env, const spt void AniWindowUtils::SetSystemPropertiesWindowIsTransparent(ani_env* env, const sptr& window, ani_object& systemProperties, const char* clsName) { - TLOGI(WmsLogTag::DEFAULT, "[ANI]"); + TLOGI(WmsLogTag::WMS_ATTRIBUTE, "[ANI]"); bool isTransparent = window->IsTransparent(); CallAniMethodVoid(env, systemProperties, clsName, "isTransparent", nullptr, static_cast(isTransparent)); } -void AniWindowUtils::SetSystemPropertieswindowIsRoundCorner(ani_env* env, const sptr& window, +void AniWindowUtils::SetSystemPropertiesWindowIsRoundCorner(ani_env* env, const sptr& window, ani_object& systemProperties, const char* clsName) { - TLOGI(WmsLogTag::DEFAULT, "[ANI]"); + TLOGI(WmsLogTag::WMS_ATTRIBUTE, "[ANI]"); bool windowIsRoundCorner {false}; CallAniMethodVoid(env, systemProperties, clsName, "isRoundCorner", nullptr, static_cast(windowIsRoundCorner)); @@ -416,29 +858,42 @@ void AniWindowUtils::SetSystemPropertieswindowIsRoundCorner(ani_env* env, const void AniWindowUtils::SetSystemPropertiesWindowDimBehindValue(ani_env* env, const sptr& window, ani_object& systemProperties, const char* clsName) { - TLOGI(WmsLogTag::DEFAULT, "[ANI]"); + TLOGI(WmsLogTag::WMS_ATTRIBUTE, "[ANI]"); int windowDimBehindValue {0}; CallAniMethodVoid(env, systemProperties, clsName, "dimBehindValue", nullptr, static_cast(windowDimBehindValue)); } -void AniWindowUtils::SetSystemPropertieswindowId(ani_env* env, const sptr& window, +void AniWindowUtils::SetSystemPropertiesWindowId(ani_env* env, const sptr& window, ani_object& systemProperties, const char* clsName) { - TLOGI(WmsLogTag::DEFAULT, "[ANI]"); + TLOGI(WmsLogTag::WMS_ATTRIBUTE, "[ANI]"); uint32_t windowId = window->GetWindowId(); CallAniMethodVoid(env, systemProperties, clsName, "id", nullptr, static_cast(windowId)); } -void AniWindowUtils::SetSystemPropertiesdisplayId(ani_env* env, const sptr& window, +void AniWindowUtils::SetSystemPropertiesDisplayId(ani_env* env, const sptr& window, ani_object& systemProperties, const char* clsName) { - TLOGI(WmsLogTag::DEFAULT, "[ANI]"); + TLOGI(WmsLogTag::WMS_ATTRIBUTE, "[ANI]"); uint32_t displayId = window->GetDisplayId(); - CallAniMethodVoid(env, systemProperties, clsName, "displayId", nullptr, - static_cast(displayId)); + CallAniMethodVoid(env, systemProperties, clsName, "displayIdInternal", nullptr, + static_cast(displayId)); +} + +void AniWindowUtils::SetSystemPropertiesWindowName(ani_env* env, const sptr& window, + ani_object& systemProperties, const char* clsName) +{ + TLOGI(WmsLogTag::WMS_ATTRIBUTE, "[ANI]"); + std::string windowName = window->GetWindowName(); + ani_string aniWindowName; + if (ANI_OK != GetAniString(env, windowName, &aniWindowName)) { + TLOGE(WmsLogTag::WMS_ATTRIBUTE, "get ANI string failed"); + return; + } + CallAniMethodVoid(env, systemProperties, clsName, "name", nullptr, aniWindowName); } ani_object AniWindowUtils::CreateWindowsProperties(ani_env* env, const sptr& window) @@ -449,7 +904,7 @@ ani_object AniWindowUtils::CreateWindowsProperties(ani_env* env, const sptrGetWindowId(), window->GetWindowName().c_str()); @@ -492,6 +948,13 @@ uint32_t AniWindowUtils::GetColorFromAni(ani_env* env, { ani_ref result; env->Object_GetPropertyByName_Ref(aniObject, name, &result); + ani_boolean isColorUndefined; + env->Reference_IsUndefined(result, &isColorUndefined); + if (isColorUndefined) { + TLOGI(WmsLogTag::WMS_IMMS, "the color is undefined, return default"); + return defaultColor; + } + ani_string aniColor = reinterpret_cast(result); std::string colorStr; GetStdString(env, aniColor, colorStr); @@ -566,6 +1029,35 @@ bool AniWindowUtils::SetWindowNavigationBarContentColor(ani_env* env, return true; } +bool AniWindowUtils::SetDecorButtonStyleFromAni(ani_env* env, DecorButtonStyle& decorButtonStyle, + const ani_object& decorStyle) +{ + int32_t colorMode; + bool emptyParam = true; + ani_ref colorModeRef; + if (ANI_OK == env->Object_GetPropertyByName_Ref(decorStyle, "colorMode", &colorModeRef) && + ANI_OK == env->EnumItem_GetValue_Int(static_cast(colorModeRef), &colorMode)) { + decorButtonStyle.colorMode = colorMode; + emptyParam = false; + } + ani_double buttonBackgroundSize; + if (ANI_OK == env->Object_GetPropertyByName_Double(decorStyle, "buttonBackgroundSize", &buttonBackgroundSize)) { + decorButtonStyle.buttonBackgroundSize = static_cast(buttonBackgroundSize); + emptyParam = false; + } + ani_double spacingBetweenButtons; + if (ANI_OK == env->Object_GetPropertyByName_Double(decorStyle, "spacingBetweenButtons", &spacingBetweenButtons)) { + decorButtonStyle.spacingBetweenButtons = static_cast(spacingBetweenButtons); + emptyParam = false; + } + ani_double closeButtonRightMargin; + if (ANI_OK == env->Object_GetPropertyByName_Double(decorStyle, "closeButtonRightMargin", &closeButtonRightMargin)) { + decorButtonStyle.closeButtonRightMargin = static_cast(closeButtonRightMargin); + emptyParam = false; + } + return !emptyParam; +} + bool AniWindowUtils::SetSystemBarPropertiesFromAni(ani_env* env, std::map& windowBarProperties, std::map& windowPropertyFlags, @@ -705,7 +1197,7 @@ void* AniWindowUtils::GetAbilityContext(ani_env *env, ani_object aniObj) ani_class cls = nullptr; ani_field contextField = nullptr; ani_status status = ANI_ERROR; - if ((status = env->FindClass("Lapplication/UIAbilityContext/UIAbilityContext;", &cls)) != ANI_OK) { + if ((status = env->FindClass("application.UIAbilityContext.UIAbilityContext", &cls)) != ANI_OK) { TLOGE(WmsLogTag::DEFAULT, "[ANI] find class fail, status : %{public}d", status); return nullptr; } @@ -734,5 +1226,17 @@ void AniWindowUtils::GetSpecificBarStatus(sptr& window, const std::strin systemBarProperties[type].settingFlag_ = systemBarProperties[type].settingFlag_ | SystemBarSettingFlag::ENABLE_SETTING; } + +WmErrorCode AniWindowUtils::ToErrorCode(WMError error, WmErrorCode defaultCode) +{ + auto it = WM_JS_TO_ERROR_CODE_MAP.find(error); + if (it != WM_JS_TO_ERROR_CODE_MAP.end()) { + return it->second; + } + TLOGW(WmsLogTag::DEFAULT, + "[ANI] Unknown error: %{public}d, return defaultCode: %{public}d", + static_cast(error), static_cast(defaultCode)); + return defaultCode; +} } // namespace Rosen -} // namespace OHOS \ No newline at end of file +} // namespace OHOS diff --git a/interfaces/kits/napi/display_runtime/BUILD.gn b/interfaces/kits/napi/display_runtime/BUILD.gn index a0f98c9ecbd27dcbd5b732cae30cf7fed9a40c94..f68e9d28919b1d0f7faead33f7313853abfffc23 100644 --- a/interfaces/kits/napi/display_runtime/BUILD.gn +++ b/interfaces/kits/napi/display_runtime/BUILD.gn @@ -69,3 +69,41 @@ ohos_shared_library("display_napi") { subsystem_name = "window" } ## Build display_napi.so }}} + +ohos_shared_library("display_kit") { + branch_protector_ret = "pac_ret" + sanitize = { + cfi = true + cfi_cross_dso = true + cfi_vcall_icall_only = true + debug = false + } + sources = [ + "js_display.cpp", + "js_display_listener.cpp", + ] + + configs = [ + ":display_config", + "../../../../resources/config/build:coverage_flags", + ] + + deps = [ + "../../../../dm:libdm", + "../../../../utils:libwmutil", + "../../../../utils:libwmutil_base", + "../common:wm_napi_util", + ] + + external_deps = [ + "ability_runtime:runtime", + "c_utils:utils", + "hilog:libhilog", + "hitrace:hitrace_meter", + "napi:ace_napi", + ] + + innerapi_tags = [ "platformsdk" ] + part_name = "window_manager" + subsystem_name = "window" +} diff --git a/interfaces/kits/napi/display_runtime/js_display.h b/interfaces/kits/napi/display_runtime/js_display.h index 84e99054422776a68aabd29e5f62c598a3c148c8..eaa2006b85596c7fcb7de08f2a28f147b47ab901 100644 --- a/interfaces/kits/napi/display_runtime/js_display.h +++ b/interfaces/kits/napi/display_runtime/js_display.h @@ -78,6 +78,7 @@ public: static napi_value GetDisplayCapability(napi_env env, napi_callback_info info); static napi_value RegisterDisplayManagerCallback(napi_env env, napi_callback_info info); static napi_value UnregisterDisplayManagerCallback(napi_env env, napi_callback_info info); + sptr GetDisplay() const { return display_; } private: sptr display_ = nullptr; diff --git a/interfaces/kits/napi/screen_runtime/BUILD.gn b/interfaces/kits/napi/screen_runtime/BUILD.gn index 02aaec1f98819b31ba2ae40fa050751368f28b94..3c75394218e8233084620e73ee7e1d9f3f7160c7 100644 --- a/interfaces/kits/napi/screen_runtime/BUILD.gn +++ b/interfaces/kits/napi/screen_runtime/BUILD.gn @@ -70,3 +70,41 @@ ohos_shared_library("screen_napi") { part_name = "window_manager" subsystem_name = "window" } + +ohos_shared_library("screen_kit") { + branch_protector_ret = "pac_ret" + sanitize = { + cfi = true + cfi_cross_dso = true + cfi_vcall_icall_only = true + debug = false + } + sources = [ + "napi/js_screen.cpp", + ] + + configs = [ + ":screen_runtime_config", + "../../../../resources/config/build:coverage_flags", + ] + + deps = [ + "../../../../dm:libdm", + "../../../../utils:libwmutil", + "../../../../utils:libwmutil_base", + ] + + external_deps = [ + "ability_runtime:runtime", + "c_utils:utils", + "graphic_2d:librender_service_base", + "graphic_surface:surface", # use for SurfaceUtils + "hilog:libhilog", + "hitrace:hitrace_meter", + "napi:ace_napi", + ] + + innerapi_tags = [ "platformsdk" ] + part_name = "window_manager" + subsystem_name = "window" +} diff --git a/interfaces/kits/napi/screen_runtime/napi/js_screen.h b/interfaces/kits/napi/screen_runtime/napi/js_screen.h index fb5385e9ad672843f8013db329697f2500185cb9..469dc9de30c9a7f3589495ae25eae067b35aa0b9 100644 --- a/interfaces/kits/napi/screen_runtime/napi/js_screen.h +++ b/interfaces/kits/napi/screen_runtime/napi/js_screen.h @@ -37,6 +37,7 @@ public: static napi_value SetScreenActiveMode(napi_env env, napi_callback_info info); static napi_value SetOrientation(napi_env env, napi_callback_info info); static napi_value SetDensityDpi(napi_env env, napi_callback_info info); + sptr GetScreen() const { return screen_; } private: sptr screen_ = nullptr; diff --git a/interfaces/kits/napi/window_runtime/window_napi/js_window.h b/interfaces/kits/napi/window_runtime/window_napi/js_window.h index d2b29df191b964d3c630be14d6ece23125cbe93f..ef3ba55df56ee3c52bf743cf4fdb9533eb3e97fe 100644 --- a/interfaces/kits/napi/window_runtime/window_napi/js_window.h +++ b/interfaces/kits/napi/window_runtime/window_napi/js_window.h @@ -43,6 +43,7 @@ class JsWindow final { public: explicit JsWindow(const sptr& window); ~JsWindow(); + sptr GetWindow() { return windowToken_; } static void Finalizer(napi_env env, void* data, void* hint); static napi_value Show(napi_env env, napi_callback_info info); static napi_value ShowWindow(napi_env env, napi_callback_info info); diff --git a/interfaces/kits/napi/window_runtime/window_stage_napi/js_window_stage.h b/interfaces/kits/napi/window_runtime/window_stage_napi/js_window_stage.h index 91059a79248b1f590f8c88d9fbbc4db02b6172e7..9e3df492b847ed1245040b24f8c867f8ac181522 100644 --- a/interfaces/kits/napi/window_runtime/window_stage_napi/js_window_stage.h +++ b/interfaces/kits/napi/window_runtime/window_stage_napi/js_window_stage.h @@ -73,6 +73,8 @@ public: */ static napi_value SetImageForRecent(napi_env env, napi_callback_info info); + std::weak_ptr GetWindowScene() { return windowScene_; } + private: napi_value OnSetUIContent(napi_env env, napi_callback_info info); napi_value OnGetMainWindow(napi_env env, napi_callback_info info); diff --git a/window_scene/interfaces/kits/ani/scene_session_manager/BUILD.gn b/window_scene/interfaces/kits/ani/scene_session_manager/BUILD.gn index 810fb3e2f0f558957777e5f3ba01a10693e4499f..26351a1fb8006ff11ae41d459c111951f80f5bbf 100644 --- a/window_scene/interfaces/kits/ani/scene_session_manager/BUILD.gn +++ b/window_scene/interfaces/kits/ani/scene_session_manager/BUILD.gn @@ -34,6 +34,7 @@ config("scene_session_manager_kit_public_config") { # lib generate ohos_shared_library("scenesessionmanagerani_kit") { + shlib_type = "ani" branch_protector_ret = "pac_ret" sanitize = { cfi = true diff --git a/window_scene/interfaces/kits/ani/scene_session_manager/scene_session_manager_ani/ets/@ohos.sceneSessionManager.ets b/window_scene/interfaces/kits/ani/scene_session_manager/scene_session_manager_ani/ets/@ohos.sceneSessionManager.ets index dee97766880f190ebb647330a941b0c065a84e91..1e39bfb3e481bea6a2f79cbe2eb1ed7d4e81b495 100644 --- a/window_scene/interfaces/kits/ani/scene_session_manager/scene_session_manager_ani/ets/@ohos.sceneSessionManager.ets +++ b/window_scene/interfaces/kits/ani/scene_session_manager/scene_session_manager_ani/ets/@ohos.sceneSessionManager.ets @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Copyright (c) 2025-2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at diff --git a/window_scene/interfaces/kits/ani/scene_session_manager/scene_session_manager_ani/include/ani_scene_session_manager.h b/window_scene/interfaces/kits/ani/scene_session_manager/scene_session_manager_ani/include/ani_scene_session_manager.h index 1a63bbf3c9f7b0d919231189c2643ddaf0dcbb5e..9f2a524d0114e926888056f0fd623483d96017c2 100644 --- a/window_scene/interfaces/kits/ani/scene_session_manager/scene_session_manager_ani/include/ani_scene_session_manager.h +++ b/window_scene/interfaces/kits/ani/scene_session_manager/scene_session_manager_ani/include/ani_scene_session_manager.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Copyright (c) 2025-2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at diff --git a/window_scene/interfaces/kits/ani/scene_session_manager/scene_session_manager_ani/src/ani_err_utils.cpp b/window_scene/interfaces/kits/ani/scene_session_manager/scene_session_manager_ani/src/ani_err_utils.cpp index bdb800577861c4b0d7754087b3c8779028327633..ca9900352117279fca5030c25de1394287d182c6 100644 --- a/window_scene/interfaces/kits/ani/scene_session_manager/scene_session_manager_ani/src/ani_err_utils.cpp +++ b/window_scene/interfaces/kits/ani/scene_session_manager/scene_session_manager_ani/src/ani_err_utils.cpp @@ -91,13 +91,13 @@ ani_status AniErrUtils::CreateBusinessError(ani_env* env, int32_t error, std::st { TLOGI(WmsLogTag::DMS, "[ANI] in1"); ani_class aniClass; - ani_status status = env->FindClass("Lescompat/Error;", &aniClass); + ani_status status = env->FindClass("escompat.Error", &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, "", "Lstd/core/String;Lescompat/ErrorOptions;:V", &aniCtor); + status = env->Class_FindMethod(aniClass, "", "C{std.core.String}C{escompat.ErrorOptions}:", &aniCtor); if (status != ANI_OK) { TLOGE(WmsLogTag::DEFAULT, "[ANI] ctor not found, status:%{public}d", static_cast(status)); return status; @@ -112,4 +112,4 @@ ani_status AniErrUtils::CreateBusinessError(ani_env* env, int32_t error, std::st return ANI_OK; } -} // namespace OHOS::Rosen \ No newline at end of file +} // namespace OHOS::Rosen diff --git a/window_scene/interfaces/kits/ani/scene_session_manager/scene_session_manager_ani/src/ani_scene_session_manager.cpp b/window_scene/interfaces/kits/ani/scene_session_manager/scene_session_manager_ani/src/ani_scene_session_manager.cpp index e3d4c6248e37ec19d0cb98046e57398ccec838ba..9af3f7f33ab7c14f7f806795403f284695d90153 100644 --- a/window_scene/interfaces/kits/ani/scene_session_manager/scene_session_manager_ani/src/ani_scene_session_manager.cpp +++ b/window_scene/interfaces/kits/ani/scene_session_manager/scene_session_manager_ani/src/ani_scene_session_manager.cpp @@ -28,7 +28,7 @@ ani_status AniSceneSessionManager::Init(ani_env* env, ani_namespace nsp) { TLOGI(WmsLogTag::DEFAULT, "[ANI] AniSceneSessionManager Init"); ani_function setObjFunc = nullptr; - ani_status ret = env->Namespace_FindFunction(nsp, "setSceneSessionManagerRef", "J:V", &setObjFunc); + ani_status ret = env->Namespace_FindFunction(nsp, "setSceneSessionManagerRef", "l:", &setObjFunc); if (ret != ANI_OK) { TLOGE(WmsLogTag::DEFAULT, "[ANI] find setSceneSessionManagerRef func fail %{public}u", ret); return ret; @@ -79,12 +79,12 @@ ANI_EXPORT ani_status ANI_Constructor(ani_vm* vm, uint32_t* result) return ANI_NOT_FOUND; } ani_namespace nsp; - if ((ret = env->FindNamespace("L@ohos/sceneSessionManager/sceneSessionManager;", &nsp)) != ANI_OK) { + if ((ret = env->FindNamespace("@ohos.sceneSessionManager.sceneSessionManager", &nsp)) != ANI_OK) { TLOGE(WmsLogTag::DEFAULT, "[ANI] null env %{public}u", ret); return ANI_NOT_FOUND; } std::array funcs = { - ani_native_function {"getRootSceneUIContextSync", "J:L@ohos/arkui/UIContext/UIContext;", + ani_native_function {"getRootSceneUIContextSync", "l:C{@ohos.arkui.UIContext.UIContext}", reinterpret_cast(AniSceneSessionManager::GetRootSceneUIContext)} }; if ((ret = env->Namespace_BindNativeFunctions(nsp, funcs.data(), funcs.size()))) { @@ -98,4 +98,4 @@ ANI_EXPORT ani_status ANI_Constructor(ani_vm* vm, uint32_t* result) } } // namespace Rosen -} // namespace OHOS \ No newline at end of file +} // namespace OHOS diff --git a/window_scene/session/container/src/zidl/session_stage_proxy.cpp b/window_scene/session/container/src/zidl/session_stage_proxy.cpp index f40a62771e86963f0945397dce1cbc0717525c69..36793e016bf833db43352c6667a54b47b89fdc15 100644 --- a/window_scene/session/container/src/zidl/session_stage_proxy.cpp +++ b/window_scene/session/container/src/zidl/session_stage_proxy.cpp @@ -1501,9 +1501,12 @@ void SessionStageProxy::NotifyKeyboardPanelInfoChange(const KeyboardPanelInfo& k TLOGE(WmsLogTag::WMS_KEYBOARD, "remote is null"); return; } - if (remote->SendRequest(static_cast(SessionStageInterfaceCode::TRANS_ID_NOTIFY_KEYBOARD_INFO_CHANGE), - data, reply, option) != ERR_NONE) { - TLOGE(WmsLogTag::WMS_KEYBOARD, "SendRequest notify keyboard panel info change failed"); + int sendCode = remote->SendRequest( + static_cast(SessionStageInterfaceCode::TRANS_ID_NOTIFY_KEYBOARD_INFO_CHANGE), + data, reply, option); + if (sendCode != ERR_NONE) { + TLOGE(WmsLogTag::WMS_KEYBOARD, + "SendRequest notify keyboard panel info change failed, code:%{public}d", sendCode); return; } } @@ -1967,10 +1970,11 @@ void SessionStageProxy::NotifyKeyboardAnimationCompleted(const KeyboardPanelInfo TLOGE(WmsLogTag::WMS_KEYBOARD, "remote is null"); return; } - if (remote->SendRequest( + int sendCode = remote->SendRequest( static_cast(SessionStageInterfaceCode::TRANS_ID_NOTIFY_KEYBOARD_ANIMATION_COMPLETED), - data, reply, option) != ERR_NONE) { - TLOGE(WmsLogTag::WMS_KEYBOARD, "SendRequest failed"); + data, reply, option); + if (sendCode != ERR_NONE) { + TLOGE(WmsLogTag::WMS_KEYBOARD, "SendRequest failed, code:%{public}d", sendCode); } } @@ -2112,10 +2116,11 @@ void SessionStageProxy::NotifyKeyboardAnimationWillBegin(const KeyboardAnimation TLOGE(WmsLogTag::WMS_KEYBOARD, "remote is null"); return; } - if (remote->SendRequest( + int sendCode = remote->SendRequest( static_cast(SessionStageInterfaceCode::TRANS_ID_NOTIFY_KEYBOARD_ANIMATION_WILLBEGIN), - data, reply, option) != ERR_NONE) { - TLOGE(WmsLogTag::WMS_KEYBOARD, "SendRequest failed"); + data, reply, option); + if (sendCode != ERR_NONE) { + TLOGE(WmsLogTag::WMS_KEYBOARD, "SendRequest failed, code:%{public}d", sendCode); } } diff --git a/window_scene/session/host/src/zidl/session_proxy.cpp b/window_scene/session/host/src/zidl/session_proxy.cpp index 698e8d857a102011dbbec62a334b8c5cc978bf1d..aeedd3f93234cc8cd5fa50951257b5c4781db98d 100644 --- a/window_scene/session/host/src/zidl/session_proxy.cpp +++ b/window_scene/session/host/src/zidl/session_proxy.cpp @@ -1052,9 +1052,11 @@ WMError SessionProxy::NotifySnapshotUpdate() TLOGE(WmsLogTag::WMS_PATTERN, "remote is null"); return WMError::WM_ERROR_IPC_FAILED; } - if (remote->SendRequest(static_cast(SessionInterfaceCode::TRANS_ID_NOTIFY_SNAPSHOT_UPDATE), - data, reply, option) != ERR_NONE) { - TLOGE(WmsLogTag::WMS_PATTERN, "SendRequest failed"); + int sendCode = remote->SendRequest(static_cast( + SessionInterfaceCode::TRANS_ID_NOTIFY_SNAPSHOT_UPDATE), + data, reply, option); + if (sendCode != ERR_NONE) { + TLOGE(WmsLogTag::WMS_PATTERN, "SendRequest failed, code:%{public}d", sendCode); return WMError::WM_ERROR_IPC_FAILED; } return WMError::WM_OK; @@ -2117,9 +2119,11 @@ void SessionProxy::SetCallingSessionId(const uint32_t callingSessionId) TLOGE(WmsLogTag::DEFAULT, "remote is null"); return; } - if (remote->SendRequest(static_cast(SessionInterfaceCode::TRANS_ID_SET_CALLING_SESSION_ID), - data, reply, option) != ERR_NONE) { - TLOGE(WmsLogTag::WMS_KEYBOARD, "SendRequest failed"); + int sendCode = remote->SendRequest( + static_cast(SessionInterfaceCode::TRANS_ID_SET_CALLING_SESSION_ID), + data, reply, option); + if (sendCode != ERR_NONE) { + TLOGE(WmsLogTag::WMS_KEYBOARD, "SendRequest failed, code:%{public}d", sendCode); return; } } @@ -2167,9 +2171,11 @@ WSError SessionProxy::AdjustKeyboardLayout(const KeyboardLayoutParams& params) TLOGE(WmsLogTag::DEFAULT, "remote is null"); return WSError::WS_ERROR_IPC_FAILED; } - if (remote->SendRequest(static_cast(SessionInterfaceCode::TRANS_ID_ADJUST_KEYBOARD_LAYOUT), - data, reply, option) != ERR_NONE) { - TLOGE(WmsLogTag::WMS_KEYBOARD, "SendRequest failed"); + int sendCode = remote->SendRequest( + static_cast(SessionInterfaceCode::TRANS_ID_ADJUST_KEYBOARD_LAYOUT), + data, reply, option); + if (sendCode != ERR_NONE) { + TLOGE(WmsLogTag::WMS_KEYBOARD, "SendRequest failed, code:%{public}d", sendCode); return WSError::WS_ERROR_IPC_FAILED; } return static_cast(reply.ReadInt32()); @@ -2193,9 +2199,11 @@ WSError SessionProxy::ChangeKeyboardEffectOption(const KeyboardEffectOption& eff TLOGE(WmsLogTag::DEFAULT, "remote is null"); return WSError::WS_ERROR_IPC_FAILED; } - if (remote->SendRequest(static_cast(SessionInterfaceCode::TRANS_ID_CHANGE_KEYBOARD_VIEW_MODE), - data, reply, option) != ERR_NONE) { - TLOGE(WmsLogTag::WMS_KEYBOARD, "SendRequest failed"); + int sendCode = remote->SendRequest( + static_cast(SessionInterfaceCode::TRANS_ID_CHANGE_KEYBOARD_VIEW_MODE), + data, reply, option); + if (sendCode != ERR_NONE) { + TLOGE(WmsLogTag::WMS_KEYBOARD, "SendRequest failed, code:%{public}d",sendCode); return WSError::WS_ERROR_IPC_FAILED; } return WSError::WS_OK; @@ -3031,10 +3039,11 @@ void SessionProxy::NotifyWindowAttachStateListenerRegistered(bool registered) TLOGE(WmsLogTag::WMS_MAIN, "remote is null"); return; } - if (remote->SendRequest( + int sendCode = remote->SendRequest( static_cast(SessionInterfaceCode::TRANS_ID_NOTIFY_WINDOW_ATTACH_STATE_LISTENER_REGISTERED), - data, reply, option) != ERR_NONE) { - TLOGE(WmsLogTag::WMS_MAIN, "SendRequest failed"); + data, reply, option); + if (sendCode != ERR_NONE) { + TLOGE(WmsLogTag::WMS_MAIN, "SendRequest failed, code:%{public}d", sendCode); } } @@ -3056,9 +3065,11 @@ void SessionProxy::NotifyKeyboardWillShowRegistered(bool registered) TLOGE(WmsLogTag::WMS_KEYBOARD, "Remote is null"); return; } - if (remote->SendRequest(static_cast(SessionInterfaceCode::TRANS_ID_SET_KEYBOARD_WILL_SHOW_REGISTERED), - data, reply, option) != ERR_NONE) { - TLOGE(WmsLogTag::WMS_KEYBOARD, "SendRequest failed"); + int sendCode = remote->SendRequest( + static_cast(SessionInterfaceCode::TRANS_ID_SET_KEYBOARD_WILL_SHOW_REGISTERED), + data, reply, option); + if (sendCode != ERR_NONE) { + TLOGE(WmsLogTag::WMS_KEYBOARD, "SendRequest failed, code:%{public}d", sendCode); } } @@ -3080,9 +3091,11 @@ void SessionProxy::NotifyKeyboardWillHideRegistered(bool registered) TLOGE(WmsLogTag::WMS_KEYBOARD, "Remote is null"); return; } - if (remote->SendRequest(static_cast(SessionInterfaceCode::TRANS_ID_SET_KEYBOARD_WILL_HIDE_REGISTERED), - data, reply, option) != ERR_NONE) { - TLOGE(WmsLogTag::WMS_KEYBOARD, "SendRequest failed"); + int sendCode = remote->SendRequest( + static_cast(SessionInterfaceCode::TRANS_ID_SET_KEYBOARD_WILL_HIDE_REGISTERED), + data, reply, option); + if (sendCode != ERR_NONE) { + TLOGE(WmsLogTag::WMS_KEYBOARD, "SendRequest failed, code:%{public}d", sendCode); } } @@ -3104,9 +3117,11 @@ void SessionProxy::NotifyKeyboardDidShowRegistered(bool registered) TLOGE(WmsLogTag::WMS_KEYBOARD, "Remote is null"); return; } - if (remote->SendRequest(static_cast(SessionInterfaceCode::TRANS_ID_SET_KEYBOARD_DID_SHOW_REGISTERED), - data, reply, option) != ERR_NONE) { - TLOGE(WmsLogTag::WMS_KEYBOARD, "SendRequest failed"); + int sendCode = remote->SendRequest( + static_cast(SessionInterfaceCode::TRANS_ID_SET_KEYBOARD_DID_SHOW_REGISTERED), + data, reply, option); + if (sendCode != ERR_NONE) { + TLOGE(WmsLogTag::WMS_KEYBOARD, "SendRequest failed, code:%{public}d", sendCode); } } @@ -3128,9 +3143,11 @@ void SessionProxy::NotifyKeyboardDidHideRegistered(bool registered) TLOGE(WmsLogTag::WMS_KEYBOARD, "Remote is null"); return; } - if (remote->SendRequest(static_cast(SessionInterfaceCode::TRANS_ID_SET_KEYBOARD_DID_HIDE_REGISTERED), - data, reply, option) != ERR_NONE) { - TLOGE(WmsLogTag::WMS_KEYBOARD, "SendRequest failed"); + int sendCode = remote->SendRequest( + static_cast(SessionInterfaceCode::TRANS_ID_SET_KEYBOARD_DID_HIDE_REGISTERED), + data, reply, option); + if (sendCode != ERR_NONE) { + TLOGE(WmsLogTag::WMS_KEYBOARD, "SendRequest failed, code:%{public}d", sendCode); } } diff --git a/window_scene/session_manager/src/zidl/scene_session_manager_proxy.cpp b/window_scene/session_manager/src/zidl/scene_session_manager_proxy.cpp index db6bc357c139789579d2ae44c1f1dc10ede7ed75..6d72ab68d1417e9cde788cdbe23561d36a7a35c4 100644 --- a/window_scene/session_manager/src/zidl/scene_session_manager_proxy.cpp +++ b/window_scene/session_manager/src/zidl/scene_session_manager_proxy.cpp @@ -2620,9 +2620,11 @@ WMError SceneSessionManagerProxy::GetCallingWindowWindowStatus(int32_t persisten TLOGE(WmsLogTag::WMS_KEYBOARD, "remote is null"); return WMError::WM_ERROR_IPC_FAILED; } - if (remote->SendRequest(static_cast(SceneSessionManagerMessage::TRANS_ID_GET_WINDOW_STATUS), - data, reply, option) != ERR_NONE) { - TLOGE(WmsLogTag::WMS_KEYBOARD, "SendRequest failed"); + int sendCode = remote->SendRequest( + static_cast(SceneSessionManagerMessage::TRANS_ID_GET_WINDOW_STATUS), + data, reply, option); + if (sendCode != ERR_NONE) { + TLOGE(WmsLogTag::WMS_KEYBOARD, "SendRequest failed, code:%{public}d", sendCode); return WMError::WM_ERROR_IPC_FAILED; } auto ret = static_cast(reply.ReadInt32()); @@ -2650,9 +2652,11 @@ WMError SceneSessionManagerProxy::GetCallingWindowRect(int32_t persistentId, Rec TLOGE(WmsLogTag::WMS_KEYBOARD, "remote is null"); return WMError::WM_ERROR_IPC_FAILED; } - if (remote->SendRequest(static_cast(SceneSessionManagerMessage::TRANS_ID_GET_WINDOW_RECT), - data, reply, option) != ERR_NONE) { - TLOGE(WmsLogTag::WMS_KEYBOARD, "SendRequest failed"); + int sendCode = remote->SendRequest( + static_cast(SceneSessionManagerMessage::TRANS_ID_GET_WINDOW_RECT), + data, reply, option); + if (sendCode != ERR_NONE) { + TLOGE(WmsLogTag::WMS_KEYBOARD, "SendRequest failed, code:%{public}d", sendCode); return WMError::WM_ERROR_IPC_FAILED; } auto ret = static_cast(reply.ReadInt32()); @@ -3188,9 +3192,11 @@ WMError SceneSessionManagerProxy::SetImageForRecent(uint32_t imgResourceId, Imag TLOGE(WmsLogTag::WMS_PATTERN, "remote is null"); return WMError::WM_ERROR_IPC_FAILED; } - if (remote->SendRequest(static_cast(SceneSessionManagerMessage::TRANS_ID_SET_IMAGE_FOR_RECENT), - data, reply, option) != ERR_NONE) { - TLOGE(WmsLogTag::WMS_PATTERN, "SendRequest failed"); + int sendCode = remote->SendRequest( + static_cast(SceneSessionManagerMessage::TRANS_ID_SET_IMAGE_FOR_RECENT), + data, reply, option); + if (sendCode != ERR_NONE) { + TLOGE(WmsLogTag::WMS_PATTERN, "SendRequest failed, code:%{public}d", sendCode); return WMError::WM_ERROR_IPC_FAILED; } uint32_t ret = 0; @@ -3447,9 +3453,11 @@ WMError SceneSessionManagerProxy::SetStartWindowBackgroundColor( TLOGE(WmsLogTag::WMS_PATTERN, "Remote is null"); return WMError::WM_ERROR_IPC_FAILED; } - if (remote->SendRequest(static_cast( - SceneSessionManagerMessage::TRANS_ID_SET_START_WINDOW_BACKGROUND_COLOR), data, reply, option) != ERR_NONE) { - TLOGE(WmsLogTag::WMS_PATTERN, "SendRequest failed"); + int sendCode = remote->SendRequest(static_cast( + SceneSessionManagerMessage::TRANS_ID_SET_START_WINDOW_BACKGROUND_COLOR), + data, reply, option); + if (sendCode != ERR_NONE) { + TLOGE(WmsLogTag::WMS_PATTERN, "SendRequest failed, code:%{public}d", sendCode); return WMError::WM_ERROR_IPC_FAILED; } int32_t ret = 0; diff --git a/wm/src/zidl/window_manager_agent_proxy.cpp b/wm/src/zidl/window_manager_agent_proxy.cpp index f50504ebd30cf5900779e137891040aca6720647..7c82cd426614541d6e180d7b855206de5ba858ea 100644 --- a/wm/src/zidl/window_manager_agent_proxy.cpp +++ b/wm/src/zidl/window_manager_agent_proxy.cpp @@ -445,9 +445,11 @@ void WindowManagerAgentProxy::NotifyCallingWindowDisplayChanged(const CallingWin TLOGE(WmsLogTag::WMS_KEYBOARD, "remote is null"); return; } - if (remote->SendRequest(static_cast(WindowManagerAgentMsg::TRANS_ID_NOTIFY_CALLING_DISPLAY_CHANGE), - data, reply, option) != ERR_NONE) { - TLOGE(WmsLogTag::WMS_KEYBOARD, "SendRequest calling display info change failed"); + int sendCode = remote->SendRequest( + static_cast(WindowManagerAgentMsg::TRANS_ID_NOTIFY_CALLING_DISPLAY_CHANGE), + data, reply, option); + if (sendCode != ERR_NONE) { + TLOGE(WmsLogTag::WMS_KEYBOARD, "SendRequest calling display info change failed, code:%{public}d", sendCode); } } diff --git a/wm/test/unittest/floating_ball_controller_test.cpp b/wm/test/unittest/floating_ball_controller_test.cpp index 6b9fd1f348e177d5dc98ec0bd908c357ee6f459f..e1e3388dbc7aabdb8d9f34fc871615f4fbb924a3 100644 --- a/wm/test/unittest/floating_ball_controller_test.cpp +++ b/wm/test/unittest/floating_ball_controller_test.cpp @@ -125,8 +125,9 @@ namespace { */ HWTEST_F(FloatingBallControllerTest, CreateFloatingBallWindow01, TestSize.Level1) { - AbilityRuntime::AbilityContextImpl* contextPtr = new AbilityRuntime::AbilityContextImpl(); - fbController_->contextPtr_ = contextPtr; + std::shared_ptr contextPtr = + std::make_shared(); + fbController_->contextPtr_ = &contextPtr; fbController_->fbOption_ = nullptr; EXPECT_EQ(WMError::WM_ERROR_FB_STATE_ABNORMALLY, fbController_->CreateFloatingBallWindow()); fbController_->fbOption_ = option_; @@ -140,7 +141,7 @@ HWTEST_F(FloatingBallControllerTest, CreateFloatingBallWindow01, TestSize.Level1 EXPECT_EQ(100, fbController_->mainWindowId_); fbController_->UpdateMainWindow(mw_); EXPECT_EQ(101, fbController_->mainWindowId_); - delete contextPtr; + fbController_->contextPtr_ = nullptr; } /** @@ -170,11 +171,12 @@ HWTEST_F(FloatingBallControllerTest, StartFloatingBall01, TestSize.Level1) EXPECT_EQ(WMError::WM_ERROR_FB_STATE_ABNORMALLY, fbController_->StartFloatingBall(option_)); EXPECT_EQ(FbWindowState::STATE_UNDEFINED, fbController_->curState_); - AbilityRuntime::AbilityContextImpl* contextPtr = new AbilityRuntime::AbilityContextImpl(); - fbController_->contextPtr_ = contextPtr; + std::shared_ptr contextPtr = + std::make_shared(); + fbController_->contextPtr_ = &contextPtr; EXPECT_NE(WMError::WM_OK, fbController_->StartFloatingBall(option_)); EXPECT_EQ(FbWindowState::STATE_UNDEFINED, fbController_->GetControllerState()); - delete contextPtr; + fbController_->contextPtr_ = nullptr; } /**