From 9c3a8ebaf2b8589b898ac0824666945c635c5c91 Mon Sep 17 00:00:00 2001 From: huojia Date: Thu, 4 Sep 2025 21:36:14 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E8=8E=B7=E5=8F=96=E5=85=A8?= =?UTF-8?q?=E9=87=8F=E7=AA=97=E5=8F=A3=E4=BF=A1=E6=81=AF=E3=80=81=E6=88=AA?= =?UTF-8?q?=E5=9B=BE=20Signed-off-by:=20huojia=20?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- interfaces/innerkits/wm/window_manager.h | 19 +++ interfaces/innerkits/wm/wm_common.h | 43 ++++++ .../window_manager_napi/js_window_manager.cpp | 108 ++++++++++++++++ .../window_manager_napi/js_window_manager.h | 6 + .../window_napi/js_window_utils.cpp | 72 +++++++++++ .../window_napi/js_window_utils.h | 6 + interfaces/kits/ndk/wm/oh_window.h | 61 +++++++++ interfaces/kits/ndk/wm/oh_window_comm.h | 26 ++++ window_scene/session/host/include/session.h | 2 + window_scene/session/host/src/session.cpp | 6 + .../include/scene_session_manager.h | 5 + .../zidl/scene_session_manager_interface.h | 5 + .../zidl/scene_session_manager_proxy.h | 3 + .../include/zidl/scene_session_manager_stub.h | 2 + .../src/scene_session_manager.cpp | 98 ++++++++++++++ .../src/zidl/scene_session_manager_proxy.cpp | 69 ++++++++++ .../src/zidl/scene_session_manager_stub.cpp | 44 +++++++ window_scene/test/unittest/BUILD.gn | 10 +- .../scene_session_manager_lifecycle_test2.cpp | 122 ++++++++++++++++++ ...e_session_manager_proxy_lifecycle_test.cpp | 120 +++++++++++++++++ ...ne_session_manager_stub_lifecycle_test.cpp | 44 +++++++ wm/BUILD.gn | 6 + wm/include/get_snapshot_callback.h | 40 ++++++ wm/include/window_adapter.h | 3 + wm/include/window_scene_session_impl.h | 2 +- wm/include/window_session_impl.h | 3 +- .../zidl/get_snapshot_callback_interface.h | 37 ++++++ wm/include/zidl/get_snapshot_callback_proxy.h | 38 ++++++ wm/include/zidl/get_snapshot_callback_stub.h | 36 ++++++ wm/src/get_snapshot_callback.cpp | 38 ++++++ wm/src/oh_window.cpp | 119 ++++++++++++++++- wm/src/window_adapter.cpp | 17 +++ wm/src/window_manager.cpp | 20 +++ wm/src/window_scene_session_impl.cpp | 9 +- wm/src/window_session_impl.cpp | 3 +- wm/src/zidl/get_snapshot_callback_proxy.cpp | 60 +++++++++ wm/src/zidl/get_snapshot_callback_stub.cpp | 80 ++++++++++++ wm/test/unittest/BUILD.gn | 33 +++++ .../get_snapshot_callback_proxy_test.cpp | 108 ++++++++++++++++ .../get_snapshot_callback_stub_test.cpp | 111 ++++++++++++++++ wm/test/unittest/oh_window_test.cpp | 52 ++++++++ wm/test/unittest/window_manager_test.cpp | 33 +++++ .../include/zidl/window_manager_interface.h | 10 ++ 43 files changed, 1717 insertions(+), 12 deletions(-) create mode 100644 wm/include/get_snapshot_callback.h create mode 100644 wm/include/zidl/get_snapshot_callback_interface.h create mode 100644 wm/include/zidl/get_snapshot_callback_proxy.h create mode 100644 wm/include/zidl/get_snapshot_callback_stub.h create mode 100644 wm/src/get_snapshot_callback.cpp create mode 100644 wm/src/zidl/get_snapshot_callback_proxy.cpp create mode 100644 wm/src/zidl/get_snapshot_callback_stub.cpp create mode 100644 wm/test/unittest/get_snapshot_callback_proxy_test.cpp create mode 100644 wm/test/unittest/get_snapshot_callback_stub_test.cpp diff --git a/interfaces/innerkits/wm/window_manager.h b/interfaces/innerkits/wm/window_manager.h index bbdc7aec17..e83139f241 100644 --- a/interfaces/innerkits/wm/window_manager.h +++ b/interfaces/innerkits/wm/window_manager.h @@ -944,6 +944,25 @@ public: */ WMError GetAllWindowLayoutInfo(DisplayId displayId, std::vector>& infos) const; + /** + * @brief Get main window info. + * + * @param infos Main Window infos. + * @return WM_OK means get success, others means get failed. + */ + WMError GetAllMainWindowInfo(std::vector>& infos) const; + + /** + * @brief Get main window snap shot. + * + * @param windowIds Window id which want to get. + * @param config Snapshot configuration. + * @param callback callback. + * @return WM_OK means get success, others means get failed. + */ + WMError GetMainWindowSnapshot(const std::vector& windowIds, const WindowSnapshotConfiguration& config, + const sptr& callback) const; + /** * @brief Get global window mode. * diff --git a/interfaces/innerkits/wm/wm_common.h b/interfaces/innerkits/wm/wm_common.h index 0e344de181..2fcae5d5f8 100644 --- a/interfaces/innerkits/wm/wm_common.h +++ b/interfaces/innerkits/wm/wm_common.h @@ -816,6 +816,19 @@ struct MainWindowInfo : public Parcelable { if (!parcel.WriteInt32(bundleType_)) { return false; } + + if (!parcel.WriteUint64(displayId_)) { + return false; + } + + if (!parcel.WriteBool(showing_)) { + return false; + } + + if (!parcel.WriteString(label_)) { + return false; + } + return true; } @@ -826,6 +839,9 @@ struct MainWindowInfo : public Parcelable { mainWindowInfo->bundleName_ = parcel.ReadString(); mainWindowInfo->persistentId_ = parcel.ReadInt32(); mainWindowInfo->bundleType_ = parcel.ReadInt32(); + mainWindowInfo->displayId_ = parcel.ReadUint64(); + mainWindowInfo->showing_ = parcel.ReadBool(); + mainWindowInfo->label_ = parcel.ReadString().c_str(); return mainWindowInfo; } @@ -833,6 +849,33 @@ struct MainWindowInfo : public Parcelable { std::string bundleName_ = ""; int32_t persistentId_ = 0; int32_t bundleType_ = 0; + DisplayId displayId_; + bool showing_; + std::string label_; +}; + +/** + * @struct WindowSnapshotConfiguration + * + * @brief main window info for all windows on the screen. + */ +struct WindowSnapshotConfiguration : public Parcelable { + bool useCache; + + bool Marshalling(Parcel& parcel) const override + { + return parcel.WriteBool(useCache); + } + + static WindowSnapshotConfiguration* Unmarshalling(Parcel& parcel) + { + WindowSnapshotConfiguration* windowSnapshotConfiguration = new WindowSnapshotConfiguration(); + if (!parcel.ReadBool(windowSnapshotConfiguration->useCache)) { + delete windowSnapshotConfiguration; + return nullptr; + } + return windowSnapshotConfiguration; + } }; /** diff --git a/interfaces/kits/napi/window_runtime/window_manager_napi/js_window_manager.cpp b/interfaces/kits/napi/window_runtime/window_manager_napi/js_window_manager.cpp index 46241fdaa9..271615412a 100644 --- a/interfaces/kits/napi/window_runtime/window_manager_napi/js_window_manager.cpp +++ b/interfaces/kits/napi/window_runtime/window_manager_napi/js_window_manager.cpp @@ -36,6 +36,7 @@ #include "scene_board_judgement.h" #include "singleton_container.h" #include "sys_cap_util.h" +#include "get_snapshot_callback.h" namespace OHOS { namespace Rosen { @@ -191,6 +192,18 @@ napi_value JsWindowManager::GetAllWindowLayoutInfo(napi_env env, napi_callback_i return (me != nullptr) ? me->OnGetAllWindowLayoutInfo(env, info) : nullptr; } +napi_value JsWindowManager::GetAllMainWindowInfo(napi_env env, napi_callback_info info) +{ + JsWindowManager* me = CheckParamsAndGetThis(env, info); + return (me != nullptr) ? me->OnGetAllMainWindowInfo(env, info) : nullptr; +} + +napi_value JsWindowManager::GetMainWindowSnapshot(napi_env env, napi_callback_info info) +{ + JsWindowManager* me = CheckParamsAndGetThis(env, info); + return (me != nullptr) ? me->OnGetMainWindowSnapshot(env, info) : nullptr; +} + napi_value JsWindowManager::GetGlobalWindowMode(napi_env env, napi_callback_info info) { TLOGI(WmsLogTag::WMS_ATTRIBUTE, "[NAPI]"); @@ -609,6 +622,18 @@ bool JsWindowManager::ParseConfigOption(napi_env env, napi_value jsObject, return true; } +bool JsWindowManager::ParseWindowSnapshotConfiguration(napi_env env, napi_value jsObject, + WindowSnapshotConfiguration& config) +{ + bool useCache = true; + if (!ParseJsValue(jsObject, env, "useCache", useCache)) { + TLOGE(WmsLogTag::WMS_LIFE, "parse useCache failed"); + return false; + } + config.useCache = useCache; + return true; +} + napi_value JsWindowManager::OnCreateWindow(napi_env env, napi_callback_info info) { TLOGD(WmsLogTag::WMS_LIFE, "[NAPI]"); @@ -1422,6 +1447,87 @@ napi_value JsWindowManager::OnGetAllWindowLayoutInfo(napi_env env, napi_callback return result; } +napi_value JsWindowManager::OnGetAllMainWindowInfo(napi_env env, napi_callback_info info) +{ + size_t argc = ARGC_FOUR; + napi_value argv[ARGC_FOUR] = { nullptr }; + napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); + if (argc >= ARGC_ONE) { + TLOGE(WmsLogTag::WMS_ATTRIBUTE, "Argc is invalid: %{public}zu", argc); + return NapiThrowError(env, WmErrorCode::WM_ERROR_INVALID_PARAM); + } + napi_value result = nullptr; + std::shared_ptr napiAsyncTask = CreateEmptyAsyncTask(env, nullptr, &result); + auto asyncTask = [env, task = napiAsyncTask, where = __func__] { + std::vector> infos; + WmErrorCode ret = WM_JS_TO_ERROR_CODE_MAP.at( + SingletonContainer::Get().GetAllMainWindowInfo(infos)); + if (ret == WmErrorCode::WM_OK) { + task->Resolve(env, CreateJsMainWindowInfoArrayObject(env, infos)); + TLOGNI(WmsLogTag::WMS_ATTRIBUTE, "%{public}s success", where); + } else { + task->Reject(env, JsErrUtils::CreateJsError(env, ret, "failed")); + TLOGNE(WmsLogTag::WMS_ATTRIBUTE, "%{public}s failed", where); + } + }; + if (napi_send_event(env, asyncTask, napi_eprio_high, "OnGetAllMainWindowInfo") != napi_status::napi_ok) { + napiAsyncTask->Reject(env, + CreateJsError(env, static_cast(WmErrorCode::WM_ERROR_SYSTEM_ABNORMALLY), "send event failed")); + } + return result; +} + +napi_value JsWindowManager::OnGetMainWindowSnapshot(napi_env env, napi_callback_info info) +{ + size_t argc = ARGC_FOUR; + napi_value argv[ARGC_FOUR] = { nullptr }; + napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); + + if (argc != ARGC_TWO) { + TLOGE(WmsLogTag::WMS_ATTRIBUTE, "Argc is invalid: %{public}zu", argc); + return NapiThrowError(env, WmErrorCode::WM_ERROR_INVALID_PARAM); + } + + std::vector windowIds; + if (!GetWindowIdFromJsValue(env, argv[INDEX_ZERO], windowIds)) { + TLOGE(WmsLogTag::WMS_PC, "GetWindowIdFromJsValue failed"); + return NapiThrowError(env, WmErrorCode::WM_ERROR_INVALID_PARAM); + } + + WindowSnapshotConfiguration config; + if (!ParseWindowSnapshotConfiguration(env, argv[INDEX_ONE], config)) { + TLOGE(WmsLogTag::WMS_ATTRIBUTE, "Failed to convert parameter to config"); + return NapiThrowError(env, WmErrorCode::WM_ERROR_INVALID_PARAM); + } + napi_value result = nullptr; + std::shared_ptr napiAsyncTask = CreateEmptyAsyncTask(env, nullptr, &result); + auto asyncTask = [env, task = napiAsyncTask, windowIds, config, where = __func__] { + sptr getSnapshotCallback = sptr::MakeSptr(); + getSnapshotCallback->RegisterFunc([env, task, where = __func__] + (WMError errCode, std::vector> pixelMaps) { + if (errCode != WMError::WM_OK) { + task->Reject(env, CreateJsError( + env, static_cast(WmErrorCode::WM_ERROR_SYSTEM_ABNORMALLY), "failed")); + TLOGNE(WmsLogTag::WMS_ATTRIBUTE, "%{public}s failed", where); + } else { + task->Resolve(env, CreateJsPixelMapArrayObject(env, pixelMaps)); + TLOGNI(WmsLogTag::WMS_ATTRIBUTE, "%{public}s success", where); + } + }); + WmErrorCode ret = WM_JS_TO_ERROR_CODE_MAP.at(SingletonContainer::Get(). + GetMainWindowSnapshot(windowIds, config, getSnapshotCallback->AsObject())); + if (ret != WmErrorCode::WM_OK) { + task->Reject(env, JsErrUtils::CreateJsError(env, ret, "failed")); + TLOGNE(WmsLogTag::WMS_ATTRIBUTE, "%{public}s failed", where); + } + }; + if (napi_send_event(env, asyncTask, napi_eprio_high, "OnGetMainWindowSnapshot") != napi_status::napi_ok) { + napiAsyncTask->Reject(env, + CreateJsError(env, static_cast(WmErrorCode::WM_ERROR_SYSTEM_ABNORMALLY), "send event failed")); + } + return result; +} + napi_value JsWindowManager::OnGetGlobalWindowMode(napi_env env, napi_callback_info info) { size_t argc = ARGC_FOUR; @@ -1856,6 +1962,8 @@ napi_value JsWindowManagerInit(napi_env env, napi_value exportObj) JsWindowManager::SetWatermarkImageForApp); BindNativeFunction(env, exportObj, "shiftAppWindowFocus", moduleName, JsWindowManager::ShiftAppWindowFocus); BindNativeFunction(env, exportObj, "getAllWindowLayoutInfo", moduleName, JsWindowManager::GetAllWindowLayoutInfo); + BindNativeFunction(env, exportObj, "getAllMainWindowInfo", moduleName, JsWindowManager::GetAllMainWindowInfo); + BindNativeFunction(env, exportObj, "getMainWindowSnapshot", moduleName, JsWindowManager::GetMainWindowSnapshot); BindNativeFunction(env, exportObj, "getGlobalWindowMode", moduleName, JsWindowManager::GetGlobalWindowMode); BindNativeFunction(env, exportObj, "getTopNavDestinationName", moduleName, JsWindowManager::GetTopNavDestinationName); diff --git a/interfaces/kits/napi/window_runtime/window_manager_napi/js_window_manager.h b/interfaces/kits/napi/window_runtime/window_manager_napi/js_window_manager.h index 37ea58d0fe..6463d779db 100644 --- a/interfaces/kits/napi/window_runtime/window_manager_napi/js_window_manager.h +++ b/interfaces/kits/napi/window_runtime/window_manager_napi/js_window_manager.h @@ -57,6 +57,8 @@ public: static napi_value ShiftAppWindowTouchEvent(napi_env env, napi_callback_info info); static napi_value NotifyScreenshotEvent(napi_env env, napi_callback_info info); static napi_value CreateUIEffectController(napi_env env, napi_callback_info info); + static napi_value GetAllMainWindowInfo(napi_env env, napi_callback_info info); + static napi_value GetMainWindowSnapshot(napi_env env, napi_callback_info info); private: static napi_value OnCreate(napi_env env, napi_callback_info info); @@ -76,6 +78,8 @@ private: static napi_value OnSetWatermarkImageForApp(napi_env env, napi_callback_info info); static napi_value OnShiftAppWindowFocus(napi_env env, napi_callback_info info); static napi_value OnGetAllWindowLayoutInfo(napi_env env, napi_callback_info info); + static napi_value OnGetAllMainWindowInfo(napi_env env, napi_callback_info info); + static napi_value OnGetMainWindowSnapshot(napi_env env, napi_callback_info info); static napi_value OnGetGlobalWindowMode(napi_env env, napi_callback_info info); static napi_value OnGetTopNavDestinationName(napi_env env, napi_callback_info info); static napi_value OnGetVisibleWindowInfo(napi_env env, napi_callback_info info); @@ -89,6 +93,8 @@ private: napi_env env, napi_value jsObject, WindowOption& option); static bool ParseConfigOption( napi_env env, napi_value jsObject, WindowOption& option, void*& contextPtr); + static bool ParseWindowSnapshotConfiguration( + napi_env env, napi_value jsObject, WindowSnapshotConfiguration& option); std::unique_ptr registerManager_ = nullptr; }; } // namespace Rosen diff --git a/interfaces/kits/napi/window_runtime/window_napi/js_window_utils.cpp b/interfaces/kits/napi/window_runtime/window_napi/js_window_utils.cpp index 8d271cf2e9..352ef751db 100644 --- a/interfaces/kits/napi/window_runtime/window_napi/js_window_utils.cpp +++ b/interfaces/kits/napi/window_runtime/window_napi/js_window_utils.cpp @@ -23,6 +23,8 @@ #include "window_manager_hilog.h" #include "js_window.h" #include "wm_common.h" +#include "pixel_map.h" +#include "pixel_map_napi.h" namespace OHOS { namespace Rosen { @@ -714,6 +716,34 @@ napi_value CreateJsWindowLayoutInfoArrayObject(napi_env env, const std::vector>& pixelMaps) +{ + napi_value arrayValue = nullptr; + napi_create_array_with_length(env, pixelMaps.size(), &arrayValue); + if (arrayValue == nullptr) { + TLOGE(WmsLogTag::WMS_ATTRIBUTE, "arrayValue is null"); + return nullptr; + } + for (size_t i = 0; i < pixelMaps.size(); i++) { + napi_set_element(env, arrayValue, i, CreateJsPixelMapObject(env, pixelMaps[i])); + } + return arrayValue; +} + +napi_value CreateJsMainWindowInfoArrayObject(napi_env env, const std::vector>& infos) +{ + napi_value arrayValue = nullptr; + napi_create_array_with_length(env, infos.size(), &arrayValue); + if (arrayValue == nullptr) { + TLOGE(WmsLogTag::WMS_ATTRIBUTE, "arrayValue is null"); + return nullptr; + } + for (size_t i = 0; i < infos.size(); i++) { + napi_set_element(env, arrayValue, i, CreateJsMainWindowInfoObject(env, infos[i])); + } + return arrayValue; +} + napi_value CreateJsWindowInfoArrayObject(napi_env env, const std::vector>& infos) { napi_value arrayValue = nullptr; @@ -795,6 +825,27 @@ napi_value CreateJsWindowLayoutInfoObject(napi_env env, const sptr& info) +{ + napi_value objValue = nullptr; + CHECK_NAPI_CREATE_OBJECT_RETURN_IF_NULL(env, objValue); + + napi_set_named_property(env, objValue, "displayId", CreateJsValue(env, static_cast(info->displayId_))); + napi_set_named_property(env, objValue, "windowId", CreateJsValue(env, info->persistentId_)); + napi_set_named_property(env, objValue, "showing", CreateJsValue(env, info->showing_)); + napi_set_named_property(env, objValue, "label", CreateJsValue(env, info->label_)); + return objValue; +} + +napi_value CreateJsPixelMapObject(napi_env env, const std::shared_ptr& pixelMap) +{ + napi_value objValue = nullptr; + CHECK_NAPI_CREATE_OBJECT_RETURN_IF_NULL(env, objValue); + + objValue = Media::PixelMapNapi::CreatePixelMap(env, pixelMap); + return objValue; +} + napi_value CreateJsWindowInfoObject(napi_env env, const sptr& info) { napi_value objValue = nullptr; @@ -1294,6 +1345,27 @@ bool GetWindowMaskFromJsValue(napi_env env, napi_value jsObject, std::vector& windowIds) +{ + if (jsObject == nullptr) { + WLOGFE("Failed to convert parameter to window mask"); + return false; + } + uint32_t size = 0; + napi_get_array_length(env, jsObject, &size); + for (uint32_t i = 0; i < size; i++) { + int32_t elementArray; + napi_value getElementValue = nullptr; + napi_get_element(env, jsObject, i, &getElementValue); + if (!ConvertFromJsValue(env, getElementValue, elementArray)) { + WLOGFE("Failed to convert parameter to window id"); + return false; + } + windowIds.emplace_back(elementArray); + } + return true; +} + bool GetMoveConfigurationFromJsValue(napi_env env, napi_value jsObject, MoveConfiguration& moveConfiguration) { if (jsObject == nullptr) { diff --git a/interfaces/kits/napi/window_runtime/window_napi/js_window_utils.h b/interfaces/kits/napi/window_runtime/window_napi/js_window_utils.h index 48c7bba201..13336921ee 100644 --- a/interfaces/kits/napi/window_runtime/window_napi/js_window_utils.h +++ b/interfaces/kits/napi/window_runtime/window_napi/js_window_utils.h @@ -340,6 +340,11 @@ public: napi_value CreateJsWindowLayoutInfoArrayObject(napi_env env, const std::vector>& infos); napi_value CreateJsWindowLayoutInfoObject(napi_env env, const sptr& info); + napi_value CreateJsPixelMapArrayObject(napi_env env, const std::vector>& pixelMap); + napi_value CreateJsPixelMapObject(napi_env env, const std::shared_ptr& pixelMap); + napi_value CreateJsMainWindowInfoArrayObject(napi_env env, const std::vector>& infos); + napi_value CreateJsMainWindowInfoObject(napi_env env, const sptr& info); + napi_value CreateJsWindowInfoArrayObject(napi_env env, const std::vector>& infos); napi_value CreateJsWindowInfoObject(napi_env env, const sptr& window); napi_value GetRectAndConvertToJsValue(napi_env env, const Rect& rect); @@ -404,6 +409,7 @@ public: bool ConvertDecorButtonStyleFromJs(napi_env env, napi_value jsObject, DecorButtonStyle& decorButtonStyle); bool GetAPI7Ability(napi_env env, AppExecFwk::Ability* &ability); bool GetWindowMaskFromJsValue(napi_env env, napi_value jsObject, std::vector>& windowMask); + bool GetWindowIdFromJsValue(napi_env env, napi_value jsObject, std::vector& windowIds); bool GetMoveConfigurationFromJsValue(napi_env env, napi_value jsObject, MoveConfiguration& moveConfiguration); bool ParseRectAnimationConfig(napi_env env, napi_value jsObject, RectAnimationConfig& rectAnimationConfig); void ConvertJSSystemBarStyleToSystemBarProperties(napi_env env, napi_value jsObject, diff --git a/interfaces/kits/ndk/wm/oh_window.h b/interfaces/kits/ndk/wm/oh_window.h index 36c16685e6..4e77e6858a 100644 --- a/interfaces/kits/ndk/wm/oh_window.h +++ b/interfaces/kits/ndk/wm/oh_window.h @@ -283,6 +283,67 @@ void OH_WindowManager_ReleaseAllWindowLayoutInfoList(WindowManager_Rect* windowL */ int32_t OH_WindowManager_InjectTouchEvent( int32_t windowId, Input_TouchEvent* touchEvent, int32_t windowX, int32_t windowY); + +/** + * @brief Get all main window info on device. + * + * @permission {@code ohos.permission.CUSTOM_SCREEN_CAPTURE} + * @param infoList Indicates the pointer to a main window info list. + * @param mainWindowInfoSize The size of main window info list. + * @return Returns the status code of the execution. + * {@link WS_OK} the function call is successful. + * {@link WINDOW_MANAGER_ERRORCODE_NO_PERMISSION} permission verification failed. + * {@link WINDOW_MANAGER_ERRORCODE_DEVICE_NOT_SUPPORTED} capability not supported. + * {@link WINDOW_MANAGER_ERRORCODE_SYSTEM_ABNORMAL} the window manager service works abnormally. + * @since 21 + */ +int32_t OH_WindowManager_GetAllMainWindowInfo( + WindowManager_MainWindowInfo** infoList, size_t* mainWindowInfoSize); + +/** + * @brief Release all main window info list. + * + * @param infoList Pointer to the main window info list. + * @since 21 + */ +void OH_WindowManager_ReleaseAllMainWindowInfo(WindowManager_MainWindowInfo* infoList); + +/** + * @brief Callback interface for getting main windows' snapshot. + * + * @param snapshotPixelMapList List of windows' snapshot + * @param snapshotListSize Size of snapshotPixelMapList + * @since 21 + */ +typedef void (*OH_WindowManager_WindowSnapshotCallback)(const OH_PixelmapNative* snapshotPixelMapList, + size_t snapshotListSize); + +/** + * @brief Get snapshot of the specified windows. + * + * @permission {@code ohos.permission.CUSTOM_SCREEN_CAPTURE} + * @param windowIdList Main window id list for getting snapshot. + * @param windowIdListSize Size of main window id list. + * @param config Configuration for getting snapshot. + * @param callback Snapshot callback object. + * @return Returns the status code of the execution. + * {@link WS_OK} the function call is successful. + * {@link WINDOW_MANAGER_ERRORCODE_NO_PERMISSION} permission verification failed. + * {@link WINDOW_MANAGER_ERRORCODE_DEVICE_NOT_SUPPORTED} capability not supported. + * {@link WINDOW_MANAGER_ERRORCODE_SYSTEM_ABNORMAL} the window manager service works abnormally. + * @since 21 + */ +int32_t OH_WindowManager_GetMainWindowSnapshot(int32_t* windowIdList, size_t windowIdListSize, + WindowManager_WindowSnapshotConfig config, OH_WindowManager_WindowSnapshotCallback callback); + +/** + * @brief Release main window snapshot list. + * + * @param snapshotPixelMapList Indicates the pointer of a windows' snapshot list. + * @since 21 + */ +void OH_WindowManager_ReleaseMainWindowSnapshot(const OH_PixelmapNative* snapshotPixelMapList); + #ifdef __cplusplus } #endif diff --git a/interfaces/kits/ndk/wm/oh_window_comm.h b/interfaces/kits/ndk/wm/oh_window_comm.h index e980cb5e77..11cdab0f2f 100644 --- a/interfaces/kits/ndk/wm/oh_window_comm.h +++ b/interfaces/kits/ndk/wm/oh_window_comm.h @@ -208,6 +208,32 @@ typedef struct { WindowManager_Rect bottomRect; } WindowManager_AvoidArea; +/** + * @brief Main window info + * + * @since 21 + */ +typedef struct { + /** Display id of the window. */ + uint64_t displayId; + /** Window id. */ + int32_t windowId; + /** Showing state of the window. */ + bool showing; + /** Label of the window. */ + const char* label; +} WindowManager_MainWindowInfo; + +/** + * @brief Window snapshot config info + * + * @since 21 + */ +typedef struct { + /** Use cached windows' snapshot. */ + bool useCache; +} WindowManager_WindowSnapshotConfig; + #ifdef __cplusplus } #endif diff --git a/window_scene/session/host/include/session.h b/window_scene/session/host/include/session.h index 8f34f7a32a..632725248d 100644 --- a/window_scene/session/host/include/session.h +++ b/window_scene/session/host/include/session.h @@ -206,6 +206,7 @@ public: void SetSessionSnapshotListener(const NotifySessionSnapshotFunc& func); WSError TerminateSessionNew(const sptr info, bool needStartCaller, bool isFromBroker); WSError TerminateSessionTotal(const sptr info, TerminateType terminateType); + std::string GetSessionLabel() const; /* * App Use Control @@ -836,6 +837,7 @@ protected: std::atomic_bool isExitSplitOnBackground_ = false; bool isVisible_ = false; int32_t currentRotation_ = 0; + std::string label_; NotifyChangeSessionVisibilityWithStatusBarFunc changeSessionVisibilityWithStatusBarFunc_; NotifySessionStateChangeFunc sessionStateChangeFunc_; diff --git a/window_scene/session/host/src/session.cpp b/window_scene/session/host/src/session.cpp index 981f94db9f..96436c2b15 100644 --- a/window_scene/session/host/src/session.cpp +++ b/window_scene/session/host/src/session.cpp @@ -2021,9 +2021,15 @@ WSError Session::SetSessionLabel(const std::string& label) if (updateSessionLabelFunc_) { updateSessionLabelFunc_(label); } + label_ = label; return WSError::WS_OK; } +std::string Session::GetSessionLabel() const +{ + return label_; +} + void Session::SetUpdateSessionLabelListener(const NofitySessionLabelUpdatedFunc& func) { updateSessionLabelFunc_ = func; diff --git a/window_scene/session_manager/include/scene_session_manager.h b/window_scene/session_manager/include/scene_session_manager.h index b5bc7c4f9d..12bcc4cb74 100644 --- a/window_scene/session_manager/include/scene_session_manager.h +++ b/window_scene/session_manager/include/scene_session_manager.h @@ -736,6 +736,9 @@ public: int32_t StartUIAbilityBySCB(sptr& abilitySessionInfo, sptr& sceneSession); int32_t StartUIAbilityBySCB(sptr& sceneSessions); WMError GetMainWindowInfos(int32_t topNum, std::vector& topNInfo); + WMError GetAllMainWindowInfo(std::vector>& infos) override; + WMError GetMainWindowSnapshot(const std::vector& windowIds, const WindowSnapshotConfiguration& config, + const sptr& callback) override; WMError GetCallingWindowInfo(CallingWindowInfo& callingWindowInfo); void NotifyDisplayIdChanged(int32_t persistentId, uint64_t displayId); WMError GetAllMainWindowInfos(std::vector& infos) const; @@ -917,6 +920,8 @@ private: void ResetSceneMissionInfo(const sptr& abilitySessionInfo); void UpdateAbilityHookState(sptr& sceneSession, bool isAbilityHook); void CloseAllFd(std::shared_ptr& want); + WMError CheckWindowIds( + const std::vector& windowIds, const sptr& callback); /* * Window Focus diff --git a/window_scene/session_manager/include/zidl/scene_session_manager_interface.h b/window_scene/session_manager/include/zidl/scene_session_manager_interface.h index 8af9a8d0b3..12f742b96b 100644 --- a/window_scene/session_manager/include/zidl/scene_session_manager_interface.h +++ b/window_scene/session_manager/include/zidl/scene_session_manager_interface.h @@ -98,6 +98,8 @@ public: TRANS_ID_SHIFT_APP_WINDOW_FOCUS, TRANS_ID_LIST_WINDOW_INFO, TRANS_ID_GET_WINDOW_LAYOUT_INFO, + TRANS_ID_GET_ALL_MAIN_WINDOW_INFO, + TRANS_ID_GET_MAIN_WINDOW_SNAPSHOT, TRANS_ID_GET_GLOBAL_WINDOW_MODE, TRANS_ID_GET_TOP_NAV_DEST_NAME, TRANS_ID_SET_APP_WATERMARK_IMAGE, @@ -295,6 +297,9 @@ public: std::vector>& infos) override { return WMError::WM_OK; } WMError GetAllWindowLayoutInfo(DisplayId displayId, std::vector>& infos) override { return WMError::WM_OK; } + WMError GetAllMainWindowInfo(std::vector>& infos) override { return WMError::WM_OK; } + WMError GetMainWindowSnapshot(const std::vector& windowIds, const WindowSnapshotConfiguration& config, + const sptr& callback) override { return WMError::WM_OK; } WMError GetGlobalWindowMode(DisplayId displayId, GlobalWindowMode& globalWinMode) override { return WMError::WM_OK; } WMError GetTopNavDestinationName(int32_t windowId, std::string& topNavDestName) override { return WMError::WM_OK; } diff --git a/window_scene/session_manager/include/zidl/scene_session_manager_proxy.h b/window_scene/session_manager/include/zidl/scene_session_manager_proxy.h index 285e7f6ac8..d4228f758b 100644 --- a/window_scene/session_manager/include/zidl/scene_session_manager_proxy.h +++ b/window_scene/session_manager/include/zidl/scene_session_manager_proxy.h @@ -111,6 +111,9 @@ public: WMError GetParentMainWindowId(int32_t windowId, int32_t& mainWindowId) override; WMError ListWindowInfo(const WindowInfoOption& windowInfoOption, std::vector>& infos) override; WMError GetAllWindowLayoutInfo(DisplayId displayId, std::vector>& infos) override; + WMError GetAllMainWindowInfo(std::vector>& infos) override; + WMError GetMainWindowSnapshot(const std::vector& windowIds, const WindowSnapshotConfiguration& config, + const sptr& callback) override; WMError GetGlobalWindowMode(DisplayId displayId, GlobalWindowMode& globalWinMode) override; WMError GetTopNavDestinationName(int32_t windowId, std::string& topNavDestName) override; WMError SetWatermarkImageForApp(const std::shared_ptr& pixelMap, diff --git a/window_scene/session_manager/include/zidl/scene_session_manager_stub.h b/window_scene/session_manager/include/zidl/scene_session_manager_stub.h index 57ca3b9ae6..14dcd0eaa4 100644 --- a/window_scene/session_manager/include/zidl/scene_session_manager_stub.h +++ b/window_scene/session_manager/include/zidl/scene_session_manager_stub.h @@ -99,6 +99,8 @@ private: int HandleShiftAppWindowFocus(MessageParcel& data, MessageParcel& reply); int HandleListWindowInfo(MessageParcel& data, MessageParcel& reply); int HandleGetAllWindowLayoutInfo(MessageParcel& data, MessageParcel& reply); + int HandleGetAllMainWindowInfo(MessageParcel& data, MessageParcel& reply); + int HandleGetMainWindowSnapshot(MessageParcel& data, MessageParcel& reply); int HandleGetGlobalWindowMode(MessageParcel& data, MessageParcel& reply); int HandleGetTopNavDestinationName(MessageParcel& data, MessageParcel& reply); int HandleSetWatermarkImageForApp(MessageParcel& data, MessageParcel& reply); diff --git a/window_scene/session_manager/src/scene_session_manager.cpp b/window_scene/session_manager/src/scene_session_manager.cpp index 957d463be2..f90da65099 100644 --- a/window_scene/session_manager/src/scene_session_manager.cpp +++ b/window_scene/session_manager/src/scene_session_manager.cpp @@ -82,6 +82,7 @@ #include "xcollie/xcollie.h" #include "xcollie/xcollie_define.h" #include "session_permission.h" +#include "get_snapshot_callback.h" #include "ui_effect_manager.h" #ifdef MEMMGR_WINDOW_ENABLE @@ -117,6 +118,7 @@ const std::string EMPTY_DEVICE_ID = ""; const std::string STARTWINDOW_TYPE = "startWindowType"; const std::string STARTWINDOW_COLOR_MODE_TYPE = "startWindowColorModeType"; const int32_t MAX_NUMBER_OF_DISTRIBUTED_SESSIONS = 20; +const int32_t MAX_SESSION_LIMIT_ALL_APP = 512; constexpr int WINDOW_NAME_MAX_WIDTH = 21; constexpr int DISPLAY_NAME_MAX_WIDTH = 10; @@ -15276,6 +15278,102 @@ WMError SceneSessionManager::GetAllMainWindowInfos(std::vector& return WMError::WM_OK; } +WMError SceneSessionManager::GetAllMainWindowInfo(std::vector>& infos) +{ + if (!SessionPermission::VerifyCallingPermission("ohos.permission.CUSTOM_SCREEN_CAPTURE")) { + TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted"); + return WMError::WM_ERROR_INVALID_PERMISSION; + } + std::shared_lock lock(sceneSessionMapMutex_); + for (const auto& [_, session] : sceneSessionMap_) { + if (session == nullptr) { + continue; + } + if (WindowHelper::IsMainWindow(session->GetWindowType())) { + auto mainWindowInfo = sptr::MakeSptr(); + mainWindowInfo->displayId_ = session->GetSessionProperty()->GetDisplayId(); + mainWindowInfo->persistentId_ = session->GetPersistentId(); + mainWindowInfo->showing_ = (session->GetSessionState() == SessionState::STATE_ACTIVE || + session->GetSessionState() == SessionState::STATE_FOREGROUND) ? true : false; + mainWindowInfo->label_ = session->GetSessionLabel(); + infos.emplace_back(mainWindowInfo); + } + } + return WMError::WM_OK; +} + +WMError SceneSessionManager::GetMainWindowSnapshot(const std::vector& windowIds, + const WindowSnapshotConfiguration& config, const sptr& callback) +{ + WMError ret = CheckWindowIds(windowIds, callback); + if (WMError::WM_OK != ret) { + return ret; + } + const char* const where = __func__; + taskScheduler_->PostAsyncTask([this, callback, config, windowIds, where] { + std::vector> pixelMaps; + WMError errCode = WMError::WM_OK; + for (const auto windowId : windowIds) { + auto pixelMap = SceneSessionManager::GetSessionSnapshotPixelMap( + windowId, 1.0f, SnapshotNodeType::LEASH_NODE, !config.useCache); + if (config.useCache && !pixelMap) { + pixelMap = SceneSessionManager::GetSessionSnapshotPixelMap( + windowId, 1.0f, SnapshotNodeType::LEASH_NODE, true); + } + if (!pixelMap) { + TLOGNW(WmsLogTag::WMS_LIFE, "get snapshot failed id:%{public}d.", windowId); + continue; + } + pixelMaps.emplace_back(pixelMap); + } + sptr getSnapshotCallback = iface_cast(callback); + if (getSnapshotCallback) { + getSnapshotCallback->OnReceived(errCode, pixelMaps); + } else { + TLOGNE(WmsLogTag::WMS_LIFE, "getSnapshotCallback is null"); + } + }, __func__); + return ret; +} + +WMError SceneSessionManager::CheckWindowIds( + const std::vector& windowIds, const sptr& callback) +{ + if (!SessionPermission::VerifyCallingPermission("ohos.permission.CUSTOM_SCREEN_CAPTURE")) { + TLOGE(WmsLogTag::WMS_LIFE, "The caller has not permission granted."); + return WMError::WM_ERROR_INVALID_PERMISSION; + } + if (windowIds.empty()) { + TLOGE(WmsLogTag::WMS_LIFE, "Input param invalid, windowIds empty."); + return WMError::WM_ERROR_INVALID_PARAM; + } + if (callback == nullptr) { + TLOGE(WmsLogTag::WMS_LIFE, "Input param invalid, callback is null."); + return WMError::WM_ERROR_INVALID_PARAM; + } + if (windowIds.size() > MAX_SESSION_LIMIT_ALL_APP) { + TLOGE(WmsLogTag::WMS_LIFE, "Input param invalid, windowIds is too long."); + return WMError::WM_ERROR_INVALID_PARAM; + } + std::unordered_set uniqueIds(windowIds.begin(), windowIds.end()); + if (uniqueIds.size() != windowIds.size()) { + TLOGE(WmsLogTag::WMS_LIFE, "Input param invalid, duplicate windowId exist."); + return WMError::WM_ERROR_INVALID_PARAM; + } + for (const auto windowId : windowIds) { + auto sceneSession = GetSceneSession(windowId); + if (sceneSession == nullptr) { + TLOGE(WmsLogTag::WMS_LIFE, "Session id:%{public}d is not found.", windowId); + return WMError::WM_ERROR_INVALID_PARAM; + } + if (!WindowHelper::IsMainWindow(sceneSession->GetWindowType())) { + TLOGE(WmsLogTag::WMS_LIFE, "Session id:%{public}d is not mainWindow.", windowId); + return WMError::WM_ERROR_INVALID_PARAM; + } + } + return WMError::WM_OK; +} + WMError SceneSessionManager::ClearMainSessions(const std::vector& persistentIds, std::vector& clearFailedIds) { 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 9aa2f8e956..f25ac8d430 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 @@ -2197,6 +2197,75 @@ WMError SceneSessionManagerProxy::GetAllWindowLayoutInfo(DisplayId displayId, return static_cast(errCode); } +WMError SceneSessionManagerProxy::GetAllMainWindowInfo(std::vector>& infos) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + if (!data.WriteInterfaceToken(GetDescriptor())) { + TLOGE(WmsLogTag::WMS_LIFE, "Write interfaceToken failed"); + return WMError::WM_ERROR_IPC_FAILED; + } + sptr remote = Remote(); + if (remote == nullptr) { + TLOGE(WmsLogTag::WMS_LIFE, "remote is null"); + return WMError::WM_ERROR_IPC_FAILED; + } + if (remote->SendRequest(static_cast( + SceneSessionManagerMessage::TRANS_ID_GET_ALL_MAIN_WINDOW_INFO), data, reply, option) != ERR_NONE) { + return WMError::WM_ERROR_IPC_FAILED; + } + if (!MarshallingHelper::UnmarshallingVectorParcelableObj(reply, infos)) { + TLOGE(WmsLogTag::WMS_LIFE, "read main window info failed"); + return WMError::WM_ERROR_IPC_FAILED; + } + int32_t errCode = 0; + if (!reply.ReadInt32(errCode)) { + TLOGE(WmsLogTag::WMS_LIFE, "read errcode failed"); + return WMError::WM_ERROR_IPC_FAILED; + } + return static_cast(errCode); +} + +WMError SceneSessionManagerProxy::GetMainWindowSnapshot(const std::vector& windowIds, + const WindowSnapshotConfiguration& config, const sptr& callback) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + if (!data.WriteInterfaceToken(GetDescriptor())) { + TLOGE(WmsLogTag::WMS_LIFE, "Write interfaceToken failed"); + return WMError::WM_ERROR_IPC_FAILED; + } + if (!data.WriteInt32Vector(windowIds)) { + TLOGE(WmsLogTag::WMS_LIFE, "Write windowIds failed"); + return WMError::WM_ERROR_IPC_FAILED; + } + if (!data.WriteBool(config.useCache)) { + TLOGE(WmsLogTag::WMS_LIFE, "Write useCache failed!"); + return WMError::WM_ERROR_IPC_FAILED; + } + if (!data.WriteRemoteObject(callback)) { + TLOGE(WmsLogTag::WMS_LIFE, "Write callback failed!"); + return WMError::WM_ERROR_IPC_FAILED; + } + sptr remote = Remote(); + if (remote == nullptr) { + TLOGE(WmsLogTag::WMS_LIFE, "remote is null"); + return WMError::WM_ERROR_IPC_FAILED; + } + if (remote->SendRequest(static_cast( + SceneSessionManagerMessage::TRANS_ID_GET_MAIN_WINDOW_SNAPSHOT), data, reply, option) != ERR_NONE) { + return WMError::WM_ERROR_IPC_FAILED; + } + int32_t errCode = 0; + if (!reply.ReadInt32(errCode)) { + TLOGE(WmsLogTag::WMS_LIFE, "read errcode failed"); + return WMError::WM_ERROR_IPC_FAILED; + } + return static_cast(errCode); +} + WMError SceneSessionManagerProxy::GetGlobalWindowMode(DisplayId displayId, GlobalWindowMode& globalWinMode) { MessageParcel data; diff --git a/window_scene/session_manager/src/zidl/scene_session_manager_stub.cpp b/window_scene/session_manager/src/zidl/scene_session_manager_stub.cpp index 61331467e2..03a0e1674d 100644 --- a/window_scene/session_manager/src/zidl/scene_session_manager_stub.cpp +++ b/window_scene/session_manager/src/zidl/scene_session_manager_stub.cpp @@ -155,6 +155,10 @@ int SceneSessionManagerStub::ProcessRemoteRequest(uint32_t code, MessageParcel& return HandleListWindowInfo(data, reply); case static_cast(SceneSessionManagerMessage::TRANS_ID_GET_WINDOW_LAYOUT_INFO): return HandleGetAllWindowLayoutInfo(data, reply); + case static_cast(SceneSessionManagerMessage::TRANS_ID_GET_ALL_MAIN_WINDOW_INFO): + return HandleGetAllMainWindowInfo(data, reply); + case static_cast(SceneSessionManagerMessage::TRANS_ID_GET_MAIN_WINDOW_SNAPSHOT): + return HandleGetMainWindowSnapshot(data, reply); case static_cast(SceneSessionManagerMessage::TRANS_ID_GET_GLOBAL_WINDOW_MODE): return HandleGetGlobalWindowMode(data, reply); case static_cast(SceneSessionManagerMessage::TRANS_ID_GET_TOP_NAV_DEST_NAME): @@ -1398,6 +1402,46 @@ int SceneSessionManagerStub::HandleGetAllWindowLayoutInfo(MessageParcel& data, M return ERR_NONE; } +int SceneSessionManagerStub::HandleGetAllMainWindowInfo(MessageParcel& data, MessageParcel& reply) +{ + std::vector> infos; + WMError errCode = GetAllMainWindowInfo(infos); + if (!MarshallingHelper::MarshallingVectorParcelableObj(reply, infos)) { + TLOGE(WmsLogTag::WMS_LIFE, "Failed to write main window info"); + return ERR_INVALID_DATA; + } + if (!reply.WriteInt32(static_cast(errCode))) { + TLOGE(WmsLogTag::WMS_LIFE, "Write errCode fail"); + return ERR_INVALID_DATA; + } + return ERR_NONE; +} + +int SceneSessionManagerStub::HandleGetMainWindowSnapshot(MessageParcel& data, MessageParcel& reply) +{ + std::vector windowIds; + if (!data.ReadInt32Vector(&windowIds)) { + TLOGE(WmsLogTag::WMS_LIFE, "Read windowIds Failed"); + return ERR_INVALID_DATA; + } + WindowSnapshotConfiguration config; + if (!data.ReadBool(config.useCache)) { + TLOGE(WmsLogTag::WMS_LIFE, "read useCache failed!"); + return ERR_INVALID_DATA; + } + sptr callback = data.ReadRemoteObject(); + if (callback == nullptr) { + TLOGE(WmsLogTag::WMS_LIFE, "callback is null"); + return ERR_INVALID_DATA; + } + WMError errCode = GetMainWindowSnapshot(windowIds, config, callback); + if (!reply.WriteInt32(static_cast(errCode))) { + TLOGE(WmsLogTag::WMS_LIFE, "Write errCode fail"); + return ERR_INVALID_DATA; + } + return ERR_NONE; +} + int SceneSessionManagerStub::HandleGetGlobalWindowMode(MessageParcel& data, MessageParcel& reply) { uint64_t displayId = 0; diff --git a/window_scene/test/unittest/BUILD.gn b/window_scene/test/unittest/BUILD.gn index 61db84a37b..4d26a11f9e 100644 --- a/window_scene/test/unittest/BUILD.gn +++ b/window_scene/test/unittest/BUILD.gn @@ -478,7 +478,10 @@ ohos_unittest("ws_scene_session_manager_lifecycle_test") { ohos_unittest("ws_scene_session_manager_lifecycle_test2") { module_out_path = module_out_path - sources = [ "scene_session_manager_lifecycle_test2.cpp" ] + sources = [ + "${window_base_path}/window_scene/test/mock/mock_accesstoken_kit.cpp", + "scene_session_manager_lifecycle_test2.cpp", + ] cflags_cc = [ "-Wno-thread-safety" ] @@ -499,7 +502,10 @@ ohos_unittest("ws_scene_session_manager_lifecycle_test2") { ohos_unittest("ws_scene_session_manager_proxy_lifecycle_test") { module_out_path = module_out_path - sources = [ "scene_session_manager_proxy_lifecycle_test.cpp" ] + sources = [ + "../mock/mock_message_parcel.cpp", + "scene_session_manager_proxy_lifecycle_test.cpp", + ] deps = [ ":ws_unittest_common" ] diff --git a/window_scene/test/unittest/scene_session_manager_lifecycle_test2.cpp b/window_scene/test/unittest/scene_session_manager_lifecycle_test2.cpp index c412c9e05f..6b00c94bad 100644 --- a/window_scene/test/unittest/scene_session_manager_lifecycle_test2.cpp +++ b/window_scene/test/unittest/scene_session_manager_lifecycle_test2.cpp @@ -29,8 +29,10 @@ #include "zidl/window_manager_agent_interface.h" #include "mock/mock_session_stage.h" #include "mock/mock_window_event_channel.h" +#include "mock/mock_accesstoken_kit.h" #include "application_info.h" #include "context.h" +#include "get_snapshot_callback.h" using namespace testing; using namespace testing::ext; @@ -250,6 +252,126 @@ HWTEST_F(SceneSessionManagerLifecycleTest2, NotifyWindowStateErrorFromMMI, TestS ssm_->NotifyWindowStateErrorFromMMI(100, 10086); ASSERT_EQ(ret, 0); } + +/** + * @tc.name: GetAllMainWindowInfo + * @tc.desc: GetAllMainWindowInfo + * @tc.type: FUNC + */ +HWTEST_F(SceneSessionManagerLifecycleTest2, GetAllMainWindowInfo, TestSize.Level1) +{ + int ret = 0; + ssm_->sceneSessionMap_.clear(); + SessionInfo info; + info.abilityName_ = "SceneSessionManagerLifecycleTest2"; + info.bundleName_ = "GetAllMainWindowInfo"; + info.screenId_ = 0; + sptr sceneSession = sptr::MakeSptr(info, nullptr); + ASSERT_NE(nullptr, sceneSession); + sptr property = sptr::MakeSptr(); + ASSERT_NE(nullptr, property); + property->SetWindowType(WindowType::WINDOW_TYPE_APP_MAIN_WINDOW); + sceneSession->property_ = property; + sceneSession->SetSessionInfoPersistentId(99); + sceneSession->SetSessionState(SessionState::STATE_ACTIVE); + sceneSession->SetSessionLabel("GetAllMainWindowInfo"); + + std::vector> infos; + MockAccesstokenKit::MockAccessTokenKitRet(-1); + EXPECT_EQ(ssm_->GetAllMainWindowInfo(infos), WMError::WM_ERROR_INVALID_PERMISSION); + + ssm_->sceneSessionMap_.insert({1, nullptr}); + ssm_->sceneSessionMap_.insert({9, sceneSession}); + MockAccesstokenKit::MockAccessTokenKitRet(0); + EXPECT_EQ(ssm_->GetAllMainWindowInfo(infos), WMError::WM_OK); + + property->SetWindowType(WindowType::APP_MAIN_WINDOW_END); + EXPECT_EQ(ssm_->GetAllMainWindowInfo(infos), WMError::WM_OK); +} + +/** + * @tc.name: GetMainWindowSnapshot + * @tc.desc: GetMainWindowSnapshot + * @tc.type: FUNC + */ +HWTEST_F(SceneSessionManagerLifecycleTest2, GetMainWindowSnapshot, TestSize.Level1) +{ + SessionInfo info; + info.abilityName_ = "SceneSessionManagerLifecycleTest2"; + info.bundleName_ = "GetMainWindowSnapshot"; + info.screenId_ = 0; + sptr sceneSession = sptr::MakeSptr(info, nullptr); + ASSERT_NE(nullptr, sceneSession); + sptr property = sptr::MakeSptr(); + ASSERT_NE(nullptr, property); + property->SetWindowType(WindowType::WINDOW_TYPE_APP_MAIN_WINDOW); + sceneSession->property_ = property; + sceneSession->SetCallingPid(100); + + std::vector windowIds; + WindowSnapshotConfiguration configs; + configs.useCache = true; + sptr callback = sptr::MakeSptr(); + MockAccesstokenKit::MockAccessTokenKitRet(-1); + EXPECT_EQ(ssm_->GetMainWindowSnapshot(windowIds, configs, callback), WMError::WM_ERROR_INVALID_PERMISSION); + MockAccesstokenKit::MockAccessTokenKitRet(0); + EXPECT_EQ(ssm_->GetMainWindowSnapshot(windowIds, configs, callback), WMError::WM_ERROR_INVALID_PARAM); + + windowIds.emplace_back(1); + windowIds.emplace_back(9); + EXPECT_EQ(ssm_->GetMainWindowSnapshot(windowIds, configs, nullptr), WMError::WM_ERROR_INVALID_PARAM); + MockAccesstokenKit::MockAccessTokenKitRet(-1); + EXPECT_EQ(ssm_->GetMainWindowSnapshot(windowIds, configs, callback), WMError::WM_ERROR_INVALID_PERMISSION); + MockAccesstokenKit::MockAccessTokenKitRet(0); + EXPECT_EQ(ssm_->GetMainWindowSnapshot(windowIds, configs, callback), WMError::WM_ERROR_INVALID_PARAM); + + sptr getSnapshotCallback = sptr::MakeSptr(); + EXPECT_EQ(ssm_->GetMainWindowSnapshot(windowIds, configs, getSnapshotCallback), WMError::WM_ERROR_INVALID_PARAM); +} + +/** + * @tc.name: GetMainWindowSnapshot01 + * @tc.desc: GetMainWindowSnapshot01 + * @tc.type: FUNC + */ +HWTEST_F(SceneSessionManagerLifecycleTest2, GetMainWindowSnapshot01, TestSize.Level1) +{ + SessionInfo info; + info.abilityName_ = "SceneSessionManagerLifecycleTest2"; + info.bundleName_ = "GetMainWindowSnapshot01"; + info.screenId_ = 0; + sptr sceneSession = sptr::MakeSptr(info, nullptr); + ASSERT_NE(nullptr, sceneSession); + sptr property = sptr::MakeSptr(); + ASSERT_NE(nullptr, property); + property->SetWindowType(WindowType::WINDOW_TYPE_APP_MAIN_WINDOW); + sceneSession->property_ = property; + sceneSession->SetCallingPid(99); + + std::vector windowIdsRepeat; + windowIdsRepeat.emplace_back(1); + windowIdsRepeat.emplace_back(1); + WindowSnapshotConfiguration configs; + configs.useCache = true; + MockAccesstokenKit::MockAccessTokenKitRet(0); + sptr callback = sptr::MakeSptr(); + EXPECT_EQ(ssm_->GetMainWindowSnapshot(windowIdsRepeat, configs, callback), WMError::WM_ERROR_INVALID_PARAM); + + std::vector windowIdsAbnormal; + windowIdsAbnormal.emplace_back(1); // windowId + windowIdsAbnormal.emplace_back(1000); // abnormal windowId + ssm_->sceneSessionMap_.insert(std::make_pair(1, sceneSession)); + MockAccesstokenKit::MockAccessTokenKitRet(0); + EXPECT_EQ(ssm_->GetMainWindowSnapshot(windowIdsAbnormal, configs, callback), WMError::WM_ERROR_INVALID_PARAM); + + std::vector windowIdsMaxSize; + ssm_->sceneSessionMap_.clear(); + for (int i = 0; i < 600; i++) { // windowIdsMax size + windowIdsMaxSize.emplace_back(i); + } + callback = sceneSession->AsObject(); + EXPECT_EQ(ssm_->GetMainWindowSnapshot(windowIdsMaxSize, configs, callback), WMError::WM_ERROR_INVALID_PARAM); +} } // namespace } // namespace Rosen } // namespace OHOS diff --git a/window_scene/test/unittest/scene_session_manager_proxy_lifecycle_test.cpp b/window_scene/test/unittest/scene_session_manager_proxy_lifecycle_test.cpp index ed7da8606a..6df2b1dec0 100644 --- a/window_scene/test/unittest/scene_session_manager_proxy_lifecycle_test.cpp +++ b/window_scene/test/unittest/scene_session_manager_proxy_lifecycle_test.cpp @@ -15,6 +15,7 @@ #include #include "iremote_object_mocker.h" +#include "mock/mock_message_parcel.h" #include "mock/mock_session.h" #include "mock/mock_session_stage.h" #include "mock/mock_window_event_channel.h" @@ -112,6 +113,125 @@ HWTEST_F(sceneSessionManagerProxyLifecycleTest, GetVisibilityWindowInfo, TestSiz std::vector> infos; ASSERT_EQ(WMError::WM_OK, sceneSessionManagerProxy->GetVisibilityWindowInfo(infos)); } + +/** + * @tc.name: GetAllMainWindowInfo + * @tc.desc: normal function + * @tc.type: FUNC + */ +HWTEST_F(sceneSessionManagerProxyLifecycleTest, GetAllMainWindowInfo, TestSize.Level1) +{ + sptr iRemoteObjectMocker = nullptr; + sptr sceneSessionManagerProxy = + sptr::MakeSptr(iRemoteObjectMocker); + EXPECT_NE(sceneSessionManagerProxy, nullptr); + std::vector> infos; + MockMessageParcel::SetWriteInterfaceTokenErrorFlag(false); + EXPECT_EQ(WMError::WM_ERROR_IPC_FAILED, sceneSessionManagerProxy->GetAllMainWindowInfo(infos)); + + iRemoteObjectMocker = sptr::MakeSptr(); + sceneSessionManagerProxy = sptr::MakeSptr(iRemoteObjectMocker); + ASSERT_NE(sceneSessionManagerProxy, nullptr); + + MockMessageParcel::SetWriteInterfaceTokenErrorFlag(true); + EXPECT_EQ(WMError::WM_ERROR_IPC_FAILED, sceneSessionManagerProxy->GetAllMainWindowInfo(infos)); + MockMessageParcel::SetWriteInterfaceTokenErrorFlag(false); + EXPECT_EQ(WMError::WM_ERROR_IPC_FAILED, sceneSessionManagerProxy->GetAllMainWindowInfo(infos)); + MockMessageParcel::ClearAllErrorFlag(); + + MockMessageParcel::SetReadInt32ErrorFlag(true); + EXPECT_EQ(WMError::WM_ERROR_IPC_FAILED, sceneSessionManagerProxy->GetAllMainWindowInfo(infos)); + MockMessageParcel::ClearAllErrorFlag(); + MockMessageParcel::SetReadInt32ErrorFlag(false); + EXPECT_EQ(WMError::WM_ERROR_IPC_FAILED, sceneSessionManagerProxy->GetAllMainWindowInfo(infos)); + MockMessageParcel::ClearAllErrorFlag(); +} + +/** + * @tc.name: GetAllMainWindowInfo01 + * @tc.desc: normal function + * @tc.type: FUNC + */ +HWTEST_F(sceneSessionManagerProxyLifecycleTest, GetAllMainWindowInfo01, TestSize.Level1) +{ + sptr iRemoteObjMocker = sptr::MakeSptr(); + sptr ssManagerProxy = + sptr::MakeSptr(iRemoteObjMocker); + ASSERT_NE(ssManagerProxy, nullptr); + std::vector> infos; + MockMessageParcel::SetWriteInterfaceTokenErrorFlag(false); + iRemoteObjMocker->SetRequestResult(ERR_INVALID_DATA); + EXPECT_EQ(WMError::WM_ERROR_IPC_FAILED, ssManagerProxy->GetAllMainWindowInfo(infos)); + iRemoteObjMocker->SetRequestResult(ERR_NONE); + MockMessageParcel::ClearAllErrorFlag(); +} + +/** + * @tc.name: GetMainWindowSnapshot + * @tc.desc: normal function + * @tc.type: FUNC + */ +HWTEST_F(sceneSessionManagerProxyLifecycleTest, GetMainWindowSnapshot, TestSize.Level1) +{ + sptr iRemoteObjectMocker = nullptr; + sptr ssManagerProxy = + sptr::MakeSptr(iRemoteObjectMocker); + ASSERT_NE(ssManagerProxy, nullptr); + std::vector windowIds; + WindowSnapshotConfiguration configs; + configs.useCache = true; + sptr callback = sptr::MakeSptr(); + MockMessageParcel::SetWriteInterfaceTokenErrorFlag(false); + EXPECT_EQ(WMError::WM_ERROR_IPC_FAILED, ssManagerProxy->GetMainWindowSnapshot(windowIds, configs, callback)); + + iRemoteObjectMocker = sptr::MakeSptr(); + ssManagerProxy = sptr::MakeSptr(iRemoteObjectMocker); + ASSERT_NE(ssManagerProxy, nullptr); + MockMessageParcel::SetWriteInterfaceTokenErrorFlag(true); + EXPECT_EQ(WMError::WM_ERROR_IPC_FAILED, ssManagerProxy->GetMainWindowSnapshot(windowIds, configs, callback)); + MockMessageParcel::SetWriteInterfaceTokenErrorFlag(false); + EXPECT_EQ(WMError::WM_ERROR_IPC_FAILED, ssManagerProxy->GetMainWindowSnapshot(windowIds, configs, callback)); + MockMessageParcel::SetWriteBoolErrorFlag(true); + EXPECT_EQ(WMError::WM_ERROR_IPC_FAILED, ssManagerProxy->GetMainWindowSnapshot(windowIds, configs, callback)); + MockMessageParcel::SetWriteBoolErrorFlag(false); + EXPECT_EQ(WMError::WM_ERROR_IPC_FAILED, ssManagerProxy->GetMainWindowSnapshot(windowIds, configs, nullptr)); + MockMessageParcel::SetReadInt32ErrorFlag(false); + EXPECT_EQ(WMError::WM_ERROR_IPC_FAILED, ssManagerProxy->GetMainWindowSnapshot(windowIds, configs, callback)); + MockMessageParcel::SetReadInt32ErrorFlag(true); + EXPECT_EQ(WMError::WM_ERROR_IPC_FAILED, ssManagerProxy->GetMainWindowSnapshot(windowIds, configs, callback)); + MockMessageParcel::ClearAllErrorFlag(); +} + +/** + * @tc.name: GetMainWindowSnapshot01 + * @tc.desc: normal function + * @tc.type: FUNC + */ +HWTEST_F(sceneSessionManagerProxyLifecycleTest, GetMainWindowSnapshot01, TestSize.Level1) +{ + sptr iRemoteObjectMocker = sptr::MakeSptr(); + sptr ssManagerProxy = + sptr::MakeSptr(iRemoteObjectMocker); + ASSERT_NE(ssManagerProxy, nullptr); + std::vector windowIds; + WindowSnapshotConfiguration configs; + configs.useCache = true; + sptr callback = sptr::MakeSptr(); + MockMessageParcel::SetWriteInterfaceTokenErrorFlag(false); + MockMessageParcel::SetWriteBoolErrorFlag(false); + + iRemoteObjectMocker->SetRequestResult(ERR_INVALID_DATA); + EXPECT_EQ(WMError::WM_ERROR_IPC_FAILED, ssManagerProxy->GetMainWindowSnapshot(windowIds, configs, callback)); + iRemoteObjectMocker->SetRequestResult(ERR_NONE); + + MockMessageParcel::SetWriteRemoteObjectErrorFlag(true); + EXPECT_EQ(WMError::WM_ERROR_IPC_FAILED, ssManagerProxy->GetMainWindowSnapshot(windowIds, configs, callback)); + EXPECT_EQ(WMError::WM_ERROR_IPC_FAILED, ssManagerProxy->GetMainWindowSnapshot(windowIds, configs, nullptr)); + MockMessageParcel::SetWriteRemoteObjectErrorFlag(false); + EXPECT_EQ(WMError::WM_ERROR_IPC_FAILED, ssManagerProxy->GetMainWindowSnapshot(windowIds, configs, callback)); + EXPECT_EQ(WMError::WM_ERROR_IPC_FAILED, ssManagerProxy->GetMainWindowSnapshot(windowIds, configs, nullptr)); + MockMessageParcel::ClearAllErrorFlag(); +} } // namespace } // namespace Rosen } // namespace OHOS diff --git a/window_scene/test/unittest/scene_session_manager_stub_lifecycle_test.cpp b/window_scene/test/unittest/scene_session_manager_stub_lifecycle_test.cpp index cb9fa51e76..2cb92ca6a1 100644 --- a/window_scene/test/unittest/scene_session_manager_stub_lifecycle_test.cpp +++ b/window_scene/test/unittest/scene_session_manager_stub_lifecycle_test.cpp @@ -317,6 +317,50 @@ HWTEST_F(SceneSessionManagerStubLifecycleTest, HandleGetVisibilityWindowInfo, Te int res = stub_->HandleGetVisibilityWindowInfo(data, reply); EXPECT_EQ(res, ERR_NONE); } + +/** + * @tc.name: HandleGetAllMainWindowInfo + * @tc.desc: test HandleGetAllMainWindowInfo + * @tc.type: FUNC + */ +HWTEST_F(SceneSessionManagerStubLifecycleTest, GetAllMainWindowInfo, TestSize.Level1) +{ + ASSERT_NE(nullptr, stub_); + MessageParcel data; + MessageParcel reply; + + int res = stub_->HandleGetAllMainWindowInfo(data, reply); + EXPECT_EQ(res, ERR_NONE); +} + +/** + * @tc.name: HandleGetMainWindowSnapshot + * @tc.desc: test HandleGetMainWindowSnapshot + * @tc.type: FUNC + */ +HWTEST_F(SceneSessionManagerStubLifecycleTest, HandleGetMainWindowSnapshot, TestSize.Level1) +{ + ASSERT_NE(nullptr, stub_); + MessageParcel data; + MessageParcel reply; + data.WriteBool(true); + EXPECT_EQ(stub_->HandleGetMainWindowSnapshot(data, reply), ERR_INVALID_DATA); + + std::vector windowIds; + windowIds.emplace_back(1); + windowIds.emplace_back(2); + data.WriteInt32Vector(windowIds); + EXPECT_EQ(stub_->HandleGetMainWindowSnapshot(data, reply), ERR_INVALID_DATA); + + data.WriteInt32Vector(windowIds); + data.WriteBool(true); + EXPECT_EQ(stub_->HandleGetMainWindowSnapshot(data, reply), ERR_INVALID_DATA); + + data.WriteInt32Vector(windowIds); + data.WriteBool(true); + data.WriteRemoteObject(stub_->AsObject()); + EXPECT_EQ(stub_->HandleGetMainWindowSnapshot(data, reply), ERR_NONE); +} } // namespace } // namespace Rosen } // namespace OHOS \ No newline at end of file diff --git a/wm/BUILD.gn b/wm/BUILD.gn index e32469eec9..bee633145e 100644 --- a/wm/BUILD.gn +++ b/wm/BUILD.gn @@ -69,6 +69,7 @@ ohos_static_library("libwm_static") { "src/input_transfer_station.cpp", "src/native_pip_window_listener.cpp", "src/pattern_detach_callback.cpp", + "src/get_snapshot_callback.cpp", "src/picture_in_picture_controller.cpp", "src/picture_in_picture_controller_base.cpp", "src/picture_in_picture_manager.cpp", @@ -98,6 +99,8 @@ ohos_static_library("libwm_static") { "src/window_session_impl.cpp", "src/zidl/pattern_detach_callback_proxy.cpp", "src/zidl/pattern_detach_callback_stub.cpp", + "src/zidl/get_snapshot_callback_proxy.cpp", + "src/zidl/get_snapshot_callback_stub.cpp", "src/zidl/window_manager_agent_stub.cpp", "src/zidl/window_stub.cpp", ] @@ -217,6 +220,7 @@ ohos_shared_library("libwm") { "src/input_transfer_station.cpp", "src/native_pip_window_listener.cpp", "src/pattern_detach_callback.cpp", + "src/get_snapshot_callback.cpp", "src/picture_in_picture_controller.cpp", "src/picture_in_picture_controller_base.cpp", "src/picture_in_picture_manager.cpp", @@ -246,6 +250,8 @@ ohos_shared_library("libwm") { "src/window_session_impl.cpp", "src/zidl/pattern_detach_callback_proxy.cpp", "src/zidl/pattern_detach_callback_stub.cpp", + "src/zidl/get_snapshot_callback_proxy.cpp", + "src/zidl/get_snapshot_callback_stub.cpp", "src/zidl/window_manager_agent_stub.cpp", "src/zidl/window_stub.cpp", ] diff --git a/wm/include/get_snapshot_callback.h b/wm/include/get_snapshot_callback.h new file mode 100644 index 0000000000..0df4a83213 --- /dev/null +++ b/wm/include/get_snapshot_callback.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2022 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 WM_GET_SNAPSHOT_CALLBACK_H +#define WM_GET_SNAPSHOT_CALLBACK_H + +#include +#include "wm_common.h" +#include "pixel_map.h" +#include "zidl/get_snapshot_callback_stub.h" + +namespace OHOS { +namespace Rosen { +using NotifyGetMainWindowSnapshotFunc = + std::function> pixelMaps)>; + +class GetSnapshotCallback : public GetSnapshotCallbackStub { +public: + void RegisterFunc(const NotifyGetMainWindowSnapshotFunc& func); + + void OnReceived(WMError errCode, std::vector> pixelMaps) override; + +private: + NotifyGetMainWindowSnapshotFunc getMainWindowSnapshotFunc_; +}; +} // Rosen +} // OHOS +#endif // WM_GET_SNAPSHOT_CALLBACK_H \ No newline at end of file diff --git a/wm/include/window_adapter.h b/wm/include/window_adapter.h index 6367df9994..0dcbf8edef 100644 --- a/wm/include/window_adapter.h +++ b/wm/include/window_adapter.h @@ -87,6 +87,9 @@ public: virtual WMError GetUnreliableWindowInfo(int32_t windowId, std::vector>& infos); virtual WMError ListWindowInfo(const WindowInfoOption& windowInfoOption, std::vector>& infos); virtual WMError GetAllWindowLayoutInfo(DisplayId displayId, std::vector>& infos); + virtual WMError GetAllMainWindowInfo(std::vector>& infos); + virtual WMError GetMainWindowSnapshot(const std::vector& windowIds, + const WindowSnapshotConfiguration& config, const sptr& callback); virtual WMError GetGlobalWindowMode(DisplayId displayId, GlobalWindowMode& globalWinMode); virtual WMError GetTopNavDestinationName(int32_t windowId, std::string& topNavDestName); virtual WMError GetVisibilityWindowInfo(std::vector>& infos); diff --git a/wm/include/window_scene_session_impl.h b/wm/include/window_scene_session_impl.h index ab6fe0d41e..357418ac35 100644 --- a/wm/include/window_scene_session_impl.h +++ b/wm/include/window_scene_session_impl.h @@ -145,7 +145,7 @@ public: void NotifySessionForeground(uint32_t reason, bool withAnimation) override; void NotifySessionBackground(uint32_t reason, bool withAnimation, bool isFromInnerkits) override; WMError NotifyPrepareClosePiPWindow() override; - void UpdateSubWindowState(const WindowType& type, bool waitDetach = false); + void UpdateSubWindowState(const WindowType& type); WMError SetSystemBarProperties(const std::map& properties, const std::map& propertyFlags) override; WMError GetSystemBarProperties(std::map& properties) override; diff --git a/wm/include/window_session_impl.h b/wm/include/window_session_impl.h index ec8fad751c..c6b650a190 100644 --- a/wm/include/window_session_impl.h +++ b/wm/include/window_session_impl.h @@ -326,8 +326,7 @@ public: void NotifyAfterForeground(bool needNotifyListeners = true, bool needNotifyUiContent = true, bool waitAttach = false); void GetAttachStateSyncResult(bool waitAttachState, bool afterForeground) const; - void NotifyAfterBackground(bool needNotifyListeners = true, - bool needNotifyUiContent = true, bool waitDetach = false); + void NotifyAfterBackground(bool needNotifyListeners = true, bool needNotifyUiContent = true); void NotifyAfterDidForeground(uint32_t reason = static_cast(WindowStateChangeReason::NORMAL)); void NotifyAfterDidBackground(uint32_t reason = static_cast(WindowStateChangeReason::NORMAL)); void NotifyForegroundFailed(WMError ret); diff --git a/wm/include/zidl/get_snapshot_callback_interface.h b/wm/include/zidl/get_snapshot_callback_interface.h new file mode 100644 index 0000000000..670fd8f044 --- /dev/null +++ b/wm/include/zidl/get_snapshot_callback_interface.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2024 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_ROSEN_GET_SNAPSHOT_CALLBACK_INTERFACE_H +#define OHOS_ROSEN_GET_SNAPSHOT_CALLBACK_INTERFACE_H + +#include +#include "pixel_map.h" +#include "wm_common.h" + +namespace OHOS { +namespace Rosen { +class IGetSnapshotCallback : public IRemoteBroker { +public: + DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.IGetSnapshotCallback"); + + enum class IGetSnapshotCallbackMessage : uint32_t { + TRANS_ON_GET_SNAPSHOT = 0, + }; + + virtual void OnReceived(WMError errCode, std::vector> pixelMaps) = 0; +}; +} // namespace Rosen +} // namespace OHOS +#endif // OHOS_ROSEN_GET_SNAPSHOT_CALLBACK_INTERFACE_H \ No newline at end of file diff --git a/wm/include/zidl/get_snapshot_callback_proxy.h b/wm/include/zidl/get_snapshot_callback_proxy.h new file mode 100644 index 0000000000..fc9037a3d4 --- /dev/null +++ b/wm/include/zidl/get_snapshot_callback_proxy.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2024 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_ROSEN_GET_SNAPSHOT_CALLBACK_PROXY_H +#define OHOS_ROSEN_GET_SNAPSHOT_CALLBACK_PROXY_H + +#include "get_snapshot_callback_interface.h" +#include "iremote_proxy.h" +#include "wm_common.h" + +namespace OHOS { +namespace Rosen { +class GetSnapshotCallbackProxy : public IRemoteProxy { +public: + explicit GetSnapshotCallbackProxy(const sptr& impl) : IRemoteProxy(impl) {} + + ~GetSnapshotCallbackProxy() {} + + void OnReceived(WMError errCode, std::vector> pixelMaps) override; + +private: + static inline BrokerDelegator delegator_; +}; +} // namespace Rosen +} // namespace OHOS +#endif // OHOS_ROSEN_GET_SNAPSHOT_CALLBACK_PROXY_H \ No newline at end of file diff --git a/wm/include/zidl/get_snapshot_callback_stub.h b/wm/include/zidl/get_snapshot_callback_stub.h new file mode 100644 index 0000000000..94af1f07f0 --- /dev/null +++ b/wm/include/zidl/get_snapshot_callback_stub.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2024 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_ROSEN_GET_SNAPSHOT_CALLBACK_STUB_H +#define OHOS_ROSEN_GET_SNAPSHOT_CALLBACK_STUB_H + +#include "get_snapshot_callback_interface.h" +#include "iremote_stub.h" + +namespace OHOS { +namespace Rosen { +class GetSnapshotCallbackStub : public IRemoteStub { +public: + GetSnapshotCallbackStub() = default; + ~GetSnapshotCallbackStub() = default; + + int OnRemoteRequest(uint32_t code, MessageParcel& data, MessageParcel& reply, MessageOption& option) override; + +private: + int HandleOnReceived(MessageParcel& data, MessageParcel& reply); +}; +} // namespace Rosen +} // namespace OHOS +#endif // OHOS_ROSEN_GET_SNAPSHOT_CALLBACK_STUB_H \ No newline at end of file diff --git a/wm/src/get_snapshot_callback.cpp b/wm/src/get_snapshot_callback.cpp new file mode 100644 index 0000000000..7d837ee0e3 --- /dev/null +++ b/wm/src/get_snapshot_callback.cpp @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2022 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 "get_snapshot_callback.h" +#include "hilog_tag_wrapper.h" +#include "window_manager_hilog.h" +#include "wm_common.h" + +namespace OHOS { +namespace Rosen { + +void GetSnapshotCallback::RegisterFunc(const NotifyGetMainWindowSnapshotFunc& func) +{ + getMainWindowSnapshotFunc_ = func; +} + +void GetSnapshotCallback::OnReceived(WMError errCode, std::vector> pixelMaps) +{ + if (getMainWindowSnapshotFunc_) { + getMainWindowSnapshotFunc_(errCode, pixelMaps); + } else { + TLOGE(WmsLogTag::WMS_LIFE, "OnReceived failed, getMainWindowSnapshotFunc_ is null"); + } +} +} // namespace Rosen +} // namespace OHOS \ No newline at end of file diff --git a/wm/src/oh_window.cpp b/wm/src/oh_window.cpp index 11fd38fb41..1997b4a4d9 100644 --- a/wm/src/oh_window.cpp +++ b/wm/src/oh_window.cpp @@ -21,6 +21,7 @@ #include "image/pixelmap_native.h" #include "pixelmap_native_impl.h" +#include "get_snapshot_callback.h" #include "ui_content.h" #include @@ -130,7 +131,7 @@ namespace { #define WINDOW_MANAGER_FREE_MEMORY(ptr) \ do { \ if ((ptr)) { \ - free((ptr)); \ + free((void*)(ptr)); \ (ptr) = NULL; \ } \ } while (0) @@ -167,6 +168,21 @@ void TransformedToWindowManagerRect(const Rect& rect, WindowManager_Rect& wmRect wmRect.height = rect.height_; } +void TransformedToMainWindowInfo(const OHOS::sptr mainWindowInfo, + WindowManager_MainWindowInfo& wmMainWindowInfo) +{ + wmMainWindowInfo.displayId = mainWindowInfo->displayId_; + wmMainWindowInfo.windowId = mainWindowInfo->persistentId_; + wmMainWindowInfo.showing = mainWindowInfo->showing_; + wmMainWindowInfo.label = mainWindowInfo->label_.c_str(); +} + +void TransformedToWindowSnapshotConfig(WindowSnapshotConfiguration& windowSnapshotConfiguration, + const WindowManager_WindowSnapshotConfig& wmWindowSnapshotConfiguration) +{ + windowSnapshotConfiguration.useCache = wmWindowSnapshotConfiguration.useCache; +} + void TransformedToWindowManagerAvoidArea(const AvoidArea& allAvoidArea, WindowManager_AvoidArea* avoidArea) { if (avoidArea == nullptr) { @@ -593,4 +609,105 @@ int32_t OH_WindowManager_InjectTouchEvent( errCode = OH_WINDOW_TO_ERROR_CODE_MAP.at(window->InjectTouchEvent(pointerEvent)); }, __func__); return errCode; +} + +int32_t OH_WindowManager_GetAllMainWindowInfo( + WindowManager_MainWindowInfo** infoList, size_t* mainWindowInfoSize) +{ + if (infoList == nullptr || mainWindowInfoSize == nullptr) { + TLOGE(WmsLogTag::WMS_LIFE, "param is nullptr"); + return WindowManager_ErrorCode::WINDOW_MANAGER_ERRORCODE_INVALID_PARAM; + } + WindowManager_ErrorCode errCode = WindowManager_ErrorCode::OK; + auto eventHandler = GetMainEventHandler(); + if (eventHandler == nullptr) { + TLOGE(WmsLogTag::WMS_LIFE, "eventHandler is null"); + return WindowManager_ErrorCode::WINDOW_MANAGER_ERRORCODE_SYSTEM_ABNORMAL; + } + eventHandler->PostSyncTask([infoList, mainWindowInfoSize, &errCode, where = __func__] { + std::vector> infos; + auto ret = SingletonContainer::Get().GetAllMainWindowInfo(infos); + if (OH_WINDOW_TO_ERROR_CODE_MAP.find(ret) == OH_WINDOW_TO_ERROR_CODE_MAP.end()) { + errCode = WindowManager_ErrorCode::WINDOW_MANAGER_ERRORCODE_SYSTEM_ABNORMAL; + TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s get failed, errCode: %{public}d", where, errCode); + return; + } else if (OH_WINDOW_TO_ERROR_CODE_MAP.at(ret) != WindowManager_ErrorCode::OK) { + errCode = OH_WINDOW_TO_ERROR_CODE_MAP.at(ret); + TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s get failed, errCode: %{public}d", where, errCode); + return; + } + WindowManager_MainWindowInfo* infosInner = (WindowManager_MainWindowInfo*)malloc( + sizeof(WindowManager_MainWindowInfo) * infos.size()); + if (infosInner == nullptr) { + errCode = WindowManager_ErrorCode::WINDOW_MANAGER_ERRORCODE_SYSTEM_ABNORMAL; + TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s infosInner is nullptr", where); + return; + } + for (size_t i = 0; i < infos.size(); i++) { + TransformedToMainWindowInfo(infos[i], infosInner[i]); + } + *infoList = infosInner; + *mainWindowInfoSize = infos.size(); + }, __func__); + return errCode; +} + +void OH_WindowManager_ReleaseAllMainWindowInfo(WindowManager_MainWindowInfo* infoList) +{ + WINDOW_MANAGER_FREE_MEMORY(infoList); +} + +int32_t OH_WindowManager_GetMainWindowSnapshot(int32_t* windowIdList, size_t windowIdListSize, + WindowManager_WindowSnapshotConfig config, OH_WindowManager_WindowSnapshotCallback callback) +{ + if (windowIdList == nullptr) { + TLOGNE(WmsLogTag::WMS_LIFE, "param is nullptr"); + return WindowManager_ErrorCode::WINDOW_MANAGER_ERRORCODE_INVALID_PARAM; + } + WindowManager_ErrorCode errCode = WindowManager_ErrorCode::OK; + auto eventHandler = GetMainEventHandler(); + if (eventHandler == nullptr) { + TLOGE(WmsLogTag::WMS_LIFE, "eventHandler is null"); + return WindowManager_ErrorCode::WINDOW_MANAGER_ERRORCODE_SYSTEM_ABNORMAL; + } + eventHandler->PostSyncTask([windowIdList, windowIdListSize, config, &errCode, callback, where = __func__] { + WindowSnapshotConfiguration windowSnapshotConfiguration; + TransformedToWindowSnapshotConfig(windowSnapshotConfiguration, config); + std::vector windowIdVector(windowIdList, windowIdList + windowIdListSize); + OHOS::sptr getSnapshotCallback = OHOS::sptr::MakeSptr(); + getSnapshotCallback->RegisterFunc([callback, where = __func__] + (WMError errCode, std::vector> pixelMaps) { + if (!callback) { + TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s callback is nullptr", where); + return; + } + if (errCode != WMError::WM_OK) { + TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s pixelMaps is nullptr", where); + callback(nullptr, 0); + return; + } + OH_PixelmapNative* pixelmapInner = + (OH_PixelmapNative*)malloc(sizeof(OH_PixelmapNative) * pixelMaps.size()); + if (pixelmapInner == nullptr) { + TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s pixelmapInner is nullptr", where); + callback(nullptr, 0); + return; + } + for (size_t i = 0; i < pixelMaps.size(); i++) { + pixelmapInner[i] = OH_PixelmapNative(pixelMaps[i]); + + } + callback(pixelmapInner, pixelMaps.size()); + }); + auto ret = SingletonContainer::Get().GetMainWindowSnapshot( + windowIdVector, windowSnapshotConfiguration, getSnapshotCallback->AsObject()); + errCode = OH_WINDOW_TO_ERROR_CODE_MAP.find(ret) == OH_WINDOW_TO_ERROR_CODE_MAP.end() ? + WindowManager_ErrorCode::WINDOW_MANAGER_ERRORCODE_SYSTEM_ABNORMAL : OH_WINDOW_TO_ERROR_CODE_MAP.at(ret); + }, __func__); + return errCode; +} + +void OH_WindowManager_ReleaseMainWindowSnapshot(const OH_PixelmapNative* snapshotPixelMapList) +{ + WINDOW_MANAGER_FREE_MEMORY(snapshotPixelMapList); } \ No newline at end of file diff --git a/wm/src/window_adapter.cpp b/wm/src/window_adapter.cpp index 5ca46b6e7b..cd5a71fdfc 100644 --- a/wm/src/window_adapter.cpp +++ b/wm/src/window_adapter.cpp @@ -318,6 +318,23 @@ WMError WindowAdapter::GetAllWindowLayoutInfo(DisplayId displayId, std::vectorGetAllWindowLayoutInfo(displayId, infos); } +WMError WindowAdapter::GetAllMainWindowInfo(std::vector>& infos) +{ + INIT_PROXY_CHECK_RETURN(WMError::WM_ERROR_SAMGR); + auto wmsProxy = GetWindowManagerServiceProxy(); + CHECK_PROXY_RETURN_ERROR_IF_NULL(wmsProxy, WMError::WM_ERROR_SAMGR); + return wmsProxy->GetAllMainWindowInfo(infos); +} + +WMError WindowAdapter::GetMainWindowSnapshot(const std::vector& windowIds, + const WindowSnapshotConfiguration& config, const sptr& callback) +{ + INIT_PROXY_CHECK_RETURN(WMError::WM_ERROR_SAMGR); + auto wmsProxy = GetWindowManagerServiceProxy(); + CHECK_PROXY_RETURN_ERROR_IF_NULL(wmsProxy, WMError::WM_ERROR_SAMGR); + return wmsProxy->GetMainWindowSnapshot(windowIds, config, callback); +} + WMError WindowAdapter::GetGlobalWindowMode(DisplayId displayId, GlobalWindowMode& globalWinMode) { INIT_PROXY_CHECK_RETURN(WMError::WM_ERROR_SAMGR); diff --git a/wm/src/window_manager.cpp b/wm/src/window_manager.cpp index aeff5a314c..aac395b2cd 100644 --- a/wm/src/window_manager.cpp +++ b/wm/src/window_manager.cpp @@ -28,6 +28,7 @@ #include "window_display_change_adapter.h" #include "wm_common.h" #include "ws_common.h" +#include "ws_common.h" namespace OHOS { namespace Rosen { @@ -1724,6 +1725,25 @@ WMError WindowManager::GetAllWindowLayoutInfo(DisplayId displayId, std::vector>& infos) const +{ + WMError ret = SingletonContainer::Get().GetAllMainWindowInfo(infos); + if (ret != WMError::WM_OK) { + TLOGE(WmsLogTag::WMS_LIFE, "failed"); + } + return ret; +} + +WMError WindowManager::GetMainWindowSnapshot(const std::vector& windowIds, + const WindowSnapshotConfiguration& config, const sptr& callback) const +{ + WMError ret = SingletonContainer::Get().GetMainWindowSnapshot(windowIds, config, callback); + if (ret != WMError::WM_OK) { + TLOGE(WmsLogTag::WMS_LIFE, "failed"); + } + return ret; +} + WMError WindowManager::GetGlobalWindowMode(DisplayId displayId, GlobalWindowMode& globalWinMode) const { return WindowAdapter::GetInstance(userId_)->GetGlobalWindowMode(displayId, globalWinMode); diff --git a/wm/src/window_scene_session_impl.cpp b/wm/src/window_scene_session_impl.cpp index 0b9208529e..6db0942401 100644 --- a/wm/src/window_scene_session_impl.cpp +++ b/wm/src/window_scene_session_impl.cpp @@ -1772,7 +1772,8 @@ WMError WindowSceneSessionImpl::Hide(uint32_t reason, bool withAnimation, bool i RecordLifeCycleExceptionEvent(LifeCycleEvent::HIDE_EVENT, res); if (res == WMError::WM_OK) { // update sub window state if this is main window - UpdateSubWindowState(type, waitDetach); + GetAttachStateSyncResult(waitDetach, false); + UpdateSubWindowState(type); NotifyAfterDidBackground(reason); state_ = WindowState::STATE_HIDDEN; requestState_ = WindowState::STATE_HIDDEN; @@ -1828,15 +1829,15 @@ WMError WindowSceneSessionImpl::NotifyRemoveStartingWindow() return res; } -void WindowSceneSessionImpl::UpdateSubWindowState(const WindowType& type, bool waitDetach) +void WindowSceneSessionImpl::UpdateSubWindowState(const WindowType& type) { UpdateSubWindowStateAndNotify(GetPersistentId(), WindowState::STATE_HIDDEN); if (WindowHelper::IsSubWindow(type)) { if (state_ == WindowState::STATE_SHOWN) { - NotifyAfterBackground(true, true, waitDetach); + NotifyAfterBackground(true, true); } } else { - NotifyAfterBackground(true, true, waitDetach); + NotifyAfterBackground(true, true); } } diff --git a/wm/src/window_session_impl.cpp b/wm/src/window_session_impl.cpp index 10068cf229..ea980d9c33 100644 --- a/wm/src/window_session_impl.cpp +++ b/wm/src/window_session_impl.cpp @@ -4865,7 +4865,7 @@ void WindowSessionImpl::NotifyAfterDidForeground(uint32_t reason) }, where, 0, AppExecFwk::EventQueue::Priority::IMMEDIATE); } -void WindowSessionImpl::NotifyAfterBackground(bool needNotifyListeners, bool needNotifyUiContent, bool waitDetach) +void WindowSessionImpl::NotifyAfterBackground(bool needNotifyListeners, bool needNotifyUiContent) { if (needNotifyListeners) { { @@ -4875,7 +4875,6 @@ void WindowSessionImpl::NotifyAfterBackground(bool needNotifyListeners, bool nee } NotifyAfterLifecycleBackground(); } - GetAttachStateSyncResult(waitDetach, false); if (needNotifyUiContent) { CALL_UI_CONTENT(Background); } diff --git a/wm/src/zidl/get_snapshot_callback_proxy.cpp b/wm/src/zidl/get_snapshot_callback_proxy.cpp new file mode 100644 index 0000000000..492f8ac3f5 --- /dev/null +++ b/wm/src/zidl/get_snapshot_callback_proxy.cpp @@ -0,0 +1,60 @@ +/* + * 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 "hilog_tag_wrapper.h" +#include "zidl/get_snapshot_callback_proxy.h" +#include "window_manager_hilog.h" +#include "pixel_map.h" + +namespace OHOS::Rosen { +void GetSnapshotCallbackProxy::OnReceived(WMError errCode, + std::vector> pixelMaps) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + + if (!data.WriteInterfaceToken(IGetSnapshotCallback::GetDescriptor())) { + TLOGE(WmsLogTag::WMS_LIFE, "Write interface token failed."); + return; + } + if (!data.WriteInt32(static_cast(errCode))) { + TLOGE(WmsLogTag::WMS_LIFE, "write error code failed"); + return; + } + int32_t len = static_cast(pixelMaps.size()); + if (!data.WriteInt32(len)) { + TLOGE(WmsLogTag::WMS_LIFE, "write size failed"); + return; + } + size_t size = static_cast(len); + for (size_t i = 0; i < size; i++) { + if (pixelMaps[i] == nullptr || !pixelMaps[i]->Marshalling(data)) { + TLOGE(WmsLogTag::WMS_LIFE, "write pixelMap failed"); + continue; + } + } + sptr remote = Remote(); + if (remote == nullptr) { + TLOGE(WmsLogTag::WMS_LIFE, "remote is null"); + return; + } + if (remote->SendRequest(static_cast( + IGetSnapshotCallbackMessage::TRANS_ON_GET_SNAPSHOT), data, reply, option) != NO_ERROR) { + TLOGE(WmsLogTag::WMS_LIFE, "SendRequest failed."); + return; + } +} +} \ No newline at end of file diff --git a/wm/src/zidl/get_snapshot_callback_stub.cpp b/wm/src/zidl/get_snapshot_callback_stub.cpp new file mode 100644 index 0000000000..1f23c36cc7 --- /dev/null +++ b/wm/src/zidl/get_snapshot_callback_stub.cpp @@ -0,0 +1,80 @@ +/* + * 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 "hilog_tag_wrapper.h" +#include "zidl/get_snapshot_callback_stub.h" +#include "window_manager_hilog.h" +#include "pixel_map.h" +#include "../../utils/include/marshalling_helper.h" + +namespace OHOS::Rosen { + +int GetSnapshotCallbackStub::OnRemoteRequest( + uint32_t code, MessageParcel& data, MessageParcel& reply, MessageOption& option) +{ + TLOGI(WmsLogTag::WMS_LIFE, "HJJ 31"); + if (data.ReadInterfaceToken() != GetDescriptor()) { + TLOGE(WmsLogTag::WMS_LIFE, "local descriptor not equal to remote."); + return ERR_INVALID_STATE; + } + return HandleOnReceived(data, reply); +} + +int GetSnapshotCallbackStub::HandleOnReceived(MessageParcel& data, MessageParcel& reply) +{ + TLOGD(WmsLogTag::WMS_LIFE, "in"); + TLOGI(WmsLogTag::WMS_LIFE, "HJJ 32"); + std::vector> pixelMaps; + int32_t errCode = 0; + int32_t len = 0; + if (!data.ReadInt32(errCode)) { + TLOGE(WmsLogTag::WMS_ATTRIBUTE, "read errcode failed"); + return ERR_INVALID_DATA; + } + if (!data.ReadInt32(len)) { + TLOGE(WmsLogTag::WMS_ATTRIBUTE, "read len failed"); + return ERR_INVALID_DATA; + } + if (len <= 0) { + OnReceived(static_cast(errCode), pixelMaps); + return 0; + } + + size_t readAbleSize = data.GetReadableBytes(); + size_t size = static_cast(len); + if ((size > readAbleSize) || (size > pixelMaps.max_size())) { + TLOGE(WmsLogTag::WMS_LIFE, "HJJ 34"); + return ERR_INVALID_DATA; + } + pixelMaps.resize(size); + size_t minDesireCapacity = sizeof(int32_t); + for (size_t i = 0; i < size; i++) { + readAbleSize = data.GetReadableBytes(); + if (minDesireCapacity > readAbleSize) { + TLOGE(WmsLogTag::WMS_LIFE, "HJJ 36 .."); + return ERR_INVALID_DATA; + } + pixelMaps[i] = std::shared_ptr(OHOS::Media::PixelMap::Unmarshalling(data)); + if (pixelMaps[i] == nullptr) { + TLOGE(WmsLogTag::WMS_LIFE, "HJJ 37 .."); + continue; + } + } + OnReceived(static_cast(errCode), pixelMaps); + return 0; +} +} \ No newline at end of file diff --git a/wm/test/unittest/BUILD.gn b/wm/test/unittest/BUILD.gn index 6a9fca35b8..ca2d51a22b 100644 --- a/wm/test/unittest/BUILD.gn +++ b/wm/test/unittest/BUILD.gn @@ -23,6 +23,8 @@ group("unittest") { ":wm_floating_ball_manager_test", ":wm_floating_ball_new_test", ":wm_floating_ball_test", + ":wm_get_snapshot_callback_proxy_test", + ":wm_get_snapshot_callback_stub_test", ":wm_gtx_input_event_sender_test", ":wm_input_transfer_station_new_test", ":wm_input_transfer_station_test", @@ -757,6 +759,37 @@ ohos_unittest("wm_pattern_detach_callback_proxy_test") { external_deps = test_external_deps } +ohos_unittest("wm_get_snapshot_callback_proxy_test") { + module_out_path = module_out_path + + sources = [ + "${window_base_path}/window_scene/test/mock/mock_message_parcel.cpp", + "get_snapshot_callback_proxy_test.cpp", + ] + + deps = [ + ":wm_unittest_common", + "${window_base_path}/window_scene/interfaces/innerkits:libwsutils", + ] + + external_deps = [ + "c_utils:utils", + "hilog:libhilog", + ] +} + +ohos_unittest("wm_get_snapshot_callback_stub_test") { + module_out_path = module_out_path + + sources = [ + "get_snapshot_callback_stub_test.cpp", + ] + + deps = [ ":wm_unittest_common" ] + + external_deps = [ "c_utils:utils" ] +} + ohos_unittest("wm_window_adapter_lite_test") { module_out_path = module_out_path diff --git a/wm/test/unittest/get_snapshot_callback_proxy_test.cpp b/wm/test/unittest/get_snapshot_callback_proxy_test.cpp new file mode 100644 index 0000000000..0dfcb83e9a --- /dev/null +++ b/wm/test/unittest/get_snapshot_callback_proxy_test.cpp @@ -0,0 +1,108 @@ +/* + * 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 "get_snapshot_callback_proxy.h" +#include "hilog/log.h" +#include "iremote_object_mocker.h" +#include "../../../window_scene/test/mock/mock_message_parcel.h" + +using namespace testing; +using namespace testing::ext; +namespace { + std::string logMsg; + void MyLogCallback(const LogType type, const LogLevel level, const unsigned int domain, const char* tag, + const char* msg) + { + logMsg += msg; + } +} +namespace OHOS { +namespace Rosen { +class GetSnapshotCallbackProxyTest : public testing::Test { +public: + static void SetUpTestCase(); + static void TearDownTestCase(); + void SetUp() override; + void TearDown() override; +}; + +void GetSnapshotCallbackProxyTest::SetUpTestCase() +{ +} + +void GetSnapshotCallbackProxyTest::TearDownTestCase() +{ +} + +void GetSnapshotCallbackProxyTest::SetUp() +{ +} + +void GetSnapshotCallbackProxyTest::TearDown() +{ +} + +namespace { +/** + * @tc.name: OnReceived + * @tc.desc: OnReceived Test + * @tc.type: FUNC + */ +HWTEST_F(GetSnapshotCallbackProxyTest, OnReceived, TestSize.Level1) +{ + logMsg.clear(); + LOG_SetCallback(MyLogCallback); + sptr iRemoteObjectMocker = nullptr; + sptr sProxy = sptr::MakeSptr(iRemoteObjectMocker); + ASSERT_NE(sProxy, nullptr); + + // create pixelMap + const uint32_t colors[1] = { 0x6f0000ff }; + uint32_t colorsLength = sizeof(colors) / sizeof(colors[0]); + const int32_t offset = 0; + Media::InitializationOptions opts; + opts.size.width = 200; // 200 test width + opts.size.height = 300; // 300 test height + opts.pixelFormat = Media::PixelFormat::RGBA_8888; + opts.alphaType = Media::AlphaType::IMAGE_ALPHA_TYPE_OPAQUE; + int32_t stride = opts.size.width; + std::shared_ptr pixelMap = Media::PixelMap::Create(colors, colorsLength, offset, stride, opts); + WMError errCode = WMError::WM_OK; + std::vector> pixelMaps; + pixelMaps.emplace_back(nullptr); + pixelMaps.emplace_back(pixelMap); + MockMessageParcel::SetWriteInterfaceTokenErrorFlag(false); + sProxy->OnReceived(errCode, pixelMaps); + + iRemoteObjectMocker = sptr::MakeSptr(); + sProxy = sptr::MakeSptr(iRemoteObjectMocker); + MockMessageParcel::SetWriteInterfaceTokenErrorFlag(true); + sProxy->OnReceived(errCode, pixelMaps); + MockMessageParcel::SetWriteInterfaceTokenErrorFlag(false); + sProxy->OnReceived(errCode, pixelMaps); + + iRemoteObjectMocker->SetRequestResult(ERR_INVALID_DATA); + sProxy->OnReceived(errCode, pixelMaps); + EXPECT_TRUE(logMsg.find("SendRequest failed") != std::string::npos); + iRemoteObjectMocker->SetRequestResult(ERR_NONE); + MockMessageParcel::SetWriteInt32ErrorFlag(true); + sProxy->OnReceived(errCode, pixelMaps); + EXPECT_TRUE(logMsg.find("write error code failed") != std::string::npos); +} +} +} // namespace Rosen +} // namespace OHOS \ No newline at end of file diff --git a/wm/test/unittest/get_snapshot_callback_stub_test.cpp b/wm/test/unittest/get_snapshot_callback_stub_test.cpp new file mode 100644 index 0000000000..21d73d94cb --- /dev/null +++ b/wm/test/unittest/get_snapshot_callback_stub_test.cpp @@ -0,0 +1,111 @@ +/* + * 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 "get_snapshot_callback.h" +#include "wm_common.h" + +using namespace testing; +using namespace testing::ext; + +namespace OHOS { +namespace Rosen { +class GetSnapshotCallbackTest : public testing::Test { +public: + static void SetUpTestCase(); + static void TearDownTestCase(); + void SetUp() override; + void TearDown() override; +}; + +void GetSnapshotCallbackTest::SetUpTestCase() +{ +} + +void GetSnapshotCallbackTest::TearDownTestCase() +{ +} + +void GetSnapshotCallbackTest::SetUp() +{ +} + +void GetSnapshotCallbackTest::TearDown() +{ +} + +namespace { +/** + * @tc.name: OnReceived + * @tc.desc: OnReceived Test + * @tc.type: FUNC + */ +HWTEST_F(GetSnapshotCallbackTest, OnReceived, TestSize.Level1) +{ + sptr getStub = sptr::MakeSptr(); + int32_t testId= -1; + std::vector> pixelMaps; + WMError errCode = WMError::WM_OK; + getStub->OnReceived(errCode, pixelMaps); + NotifyGetMainWindowSnapshotFunc func = [&testId]( + WMError errCode, std::vector> pixelMaps) + { + testId = 9; + }; + + getStub->RegisterFunc(func); + getStub->OnReceived(errCode, pixelMaps); + EXPECT_EQ(testId, 9); +} + +/** + * @tc.name: OnRemoteRequest + * @tc.desc: OnRemoteRequest Test + * @tc.type: FUNC + */ +HWTEST_F(GetSnapshotCallbackTest, OnRemoteRequest, TestSize.Level1) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + sptr getStub = sptr::MakeSptr(); + data.WriteInterfaceToken(u"error.GetDescriptor"); + uint32_t code = 1; + EXPECT_EQ(getStub->OnRemoteRequest(code, data, reply, option), ERR_INVALID_STATE); + data.WriteInterfaceToken(GetSnapshotCallback::GetDescriptor()); + EXPECT_EQ(getStub->OnRemoteRequest(code, data, reply, option), 1); +} +/** + * @tc.name: HandleOnReceived + * @tc.desc: HandleOnReceived Test + * @tc.type: FUNC + */ +HWTEST_F(GetSnapshotCallbackTest, HandleOnReceived, TestSize.Level1) +{ + MessageParcel data; + MessageParcel reply; + sptr getStub = sptr::MakeSptr(); + data.WriteInt32(-1); + EXPECT_EQ(getStub->HandleOnReceived(data, reply), 1); + data.WriteInt32(9); + EXPECT_EQ(getStub->HandleOnReceived(data, reply), 1); + data.WriteInt32(0); + EXPECT_EQ(getStub->HandleOnReceived(data, reply), 1); + data.WriteInt32(1); + EXPECT_EQ(getStub->HandleOnReceived(data, reply), 1); +} +} +} // namespace Rosen +} // namespace OHOS \ No newline at end of file diff --git a/wm/test/unittest/oh_window_test.cpp b/wm/test/unittest/oh_window_test.cpp index cdb6696a5e..71194c3521 100644 --- a/wm/test/unittest/oh_window_test.cpp +++ b/wm/test/unittest/oh_window_test.cpp @@ -171,6 +171,58 @@ HWTEST_F(OHWindowTest, OH_WindowManager_InjectTouchEvent, TestSize.Level0) EXPECT_EQ(static_cast(WindowManager_ErrorCode::OK), ret); OH_Input_DestroyTouchEvent(&touchEvent); } + +/** + * @tc.name: OH_WindowManager_GetAllMainWindowInfo + * @tc.desc: OH_WindowManager_GetAllMainWindowInfo test + * @tc.type: FUNC + */ +HWTEST_F(OHWindowTest, OH_WindowManager_GetAllMainWindowInfo, TestSize.Level0) +{ + WindowManager_MainWindowInfo** infoListNull = nullptr; + size_t* mainWindowInfoSizeNull = nullptr; + auto infoList = (WindowManager_MainWindowInfo**)malloc(sizeof(WindowManager_MainWindowInfo**)); + auto mainWindowInfoSize = (size_t*)malloc(sizeof(size_t*)); + auto ret = OH_WindowManager_GetAllMainWindowInfo(infoListNull, mainWindowInfoSizeNull); + EXPECT_EQ(static_cast(WindowManager_ErrorCode::WINDOW_MANAGER_ERRORCODE_INVALID_PARAM), ret); + + ret = OH_WindowManager_GetAllMainWindowInfo(infoListNull, mainWindowInfoSize); + EXPECT_EQ(static_cast(WindowManager_ErrorCode::WINDOW_MANAGER_ERRORCODE_INVALID_PARAM), ret); + + ret = OH_WindowManager_GetAllMainWindowInfo(infoList, mainWindowInfoSizeNull); + EXPECT_EQ(static_cast(WindowManager_ErrorCode::WINDOW_MANAGER_ERRORCODE_INVALID_PARAM), ret); + + ret = OH_WindowManager_GetAllMainWindowInfo(infoList, mainWindowInfoSize); + EXPECT_EQ(static_cast(WindowManager_ErrorCode::OK), ret); + OH_WindowManager_ReleaseAllMainWindowInfo(*infoList); + *infoList = nullptr; + free(infoList); + infoList = nullptr; + free(mainWindowInfoSize); + mainWindowInfoSize = nullptr; +} + +/** + * @tc.name: OH_WindowManager_GetMainWindowSnapshot + * @tc.desc: OH_WindowManager_GetMainWindowSnapshot test + * @tc.type: FUNC + */ +HWTEST_F(OHWindowTest, OH_WindowManager_GetMainWindowSnapshot, TestSize.Level0) +{ + int32_t* windowIdListNull = nullptr; + size_t windowIdListSize = 1; + WindowManager_WindowSnapshotConfig config; + config.useCache = false; + OH_WindowManager_WindowSnapshotCallback callback = nullptr; + auto ret = OH_WindowManager_GetMainWindowSnapshot(windowIdListNull, windowIdListSize, config, callback); + EXPECT_EQ(static_cast(WindowManager_ErrorCode::WINDOW_MANAGER_ERRORCODE_INVALID_PARAM), ret); + + auto windowIdList = (int32_t*)malloc(sizeof(int32_t*)); + ret = OH_WindowManager_GetMainWindowSnapshot(windowIdList, windowIdListSize, config, callback); + EXPECT_EQ(static_cast(WindowManager_ErrorCode::OK), ret); + free(windowIdList); + windowIdList = nullptr; +} } } // namespace Rosen } // namespace OHOS \ No newline at end of file diff --git a/wm/test/unittest/window_manager_test.cpp b/wm/test/unittest/window_manager_test.cpp index 4a44b92e9b..58c1fa8c38 100644 --- a/wm/test/unittest/window_manager_test.cpp +++ b/wm/test/unittest/window_manager_test.cpp @@ -2565,6 +2565,39 @@ HWTEST_F(WindowManagerTest, RemoveInstanceByUserId, TestSize.Level1) int32_t userId = 101; ASSERT_EQ(WMError::WM_OK, WindowManager::RemoveInstanceByUserId(userId)); } + +/** + * @tc.name: GetAllMainWindowInfo + * @tc.desc: check GetAllMainWindowInfo + * @tc.type: FUNC + */ +HWTEST_F(WindowManagerTest, GetAllMainWindowInfo, TestSize.Level1) +{ + std::vector> infos; + WMError ret = WindowManager::GetInstance().GetAllMainWindowInfo(infos); + EXPECT_EQ(WMError::WM_ERROR_INVALID_PERMISSION, ret); +} + +/** + * @tc.name: GetMainWindowSnapshot + * @tc.desc: check GetMainWindowSnapshot + * @tc.type: FUNC + */ +HWTEST_F(WindowManagerTest, GetMainWindowSnapshot, TestSize.Level1) +{ + std::vector windowIds; + windowIds.emplace_back(1); + windowIds.emplace_back(9); + WindowSnapshotConfiguration configs; + configs.useCache = true; + sptr iRemoteObjMocker = sptr::MakeSptr(); + WMError ret = WindowManager::GetInstance().GetMainWindowSnapshot(windowIds, configs, iRemoteObjMocker); + EXPECT_EQ(WMError::WM_ERROR_IPC_FAILED, ret); + + iRemoteObjMocker->SetRequestResult(ERR_NONE); + ret = WindowManager::GetInstance().GetMainWindowSnapshot(windowIds, configs, iRemoteObjMocker); + EXPECT_EQ(WMError::WM_ERROR_IPC_FAILED, ret); +} } } // namespace } // namespace Rosen diff --git a/wmserver/include/zidl/window_manager_interface.h b/wmserver/include/zidl/window_manager_interface.h index 8fabfad55d..ca05785c24 100644 --- a/wmserver/include/zidl/window_manager_interface.h +++ b/wmserver/include/zidl/window_manager_interface.h @@ -30,6 +30,7 @@ #include "zidl/window_interface.h" #include "zidl/window_manager_agent_interface.h" #include "interfaces/include/ws_common.h" +#include "interfaces/include/ws_common.h" namespace OHOS { namespace Rosen { @@ -140,6 +141,15 @@ public: virtual WMError UpdateWindowModeByIdForUITest(int32_t windowId, int32_t updateMode) { return WMError::WM_OK; } virtual WMError GetAllWindowLayoutInfo(DisplayId displayId, std::vector>& infos) { return WMError::WM_ERROR_DEVICE_NOT_SUPPORT; } + virtual WMError GetAllMainWindowInfo(std::vector>& infos) + { + return WMError::WM_ERROR_DEVICE_NOT_SUPPORT; + } + virtual WMError GetMainWindowSnapshot(const std::vector& windowIds, + const WindowSnapshotConfiguration& config, const sptr& callback) + { + return WMError::WM_ERROR_DEVICE_NOT_SUPPORT; + } virtual WMError GetGlobalWindowMode(DisplayId displayId, GlobalWindowMode& globalWinMode) { return WMError::WM_ERROR_DEVICE_NOT_SUPPORT; -- Gitee