From ee21feb859a0e8921eb8a09366baeca83d539fd4 Mon Sep 17 00:00:00 2001 From: dubj Date: Sat, 16 Jul 2022 14:27:26 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E8=AE=BE=E7=BD=AE=E6=88=AA?= =?UTF-8?q?=E5=9B=BE=E5=8A=9F=E8=83=BD=E7=9B=B8=E5=85=B3=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: dubj Change-Id: I43d5662facbce5d75ef8d38e202f199476134be2 --- dm/include/display_manager_adapter.h | 1 + dm/src/display_manager.cpp | 11 + dm/src/display_manager_adapter.cpp | 7 + dm/test/systemtest/BUILD.gn | 12 + dm/test/systemtest/display_manager_test.cpp | 232 ++++++++++++++++++ dmserver/include/display_manager_interface.h | 2 + dmserver/include/display_manager_proxy.h | 1 + dmserver/include/display_manager_service.h | 5 +- .../include/display_manager_service_inner.h | 2 + dmserver/src/display_manager_proxy.cpp | 22 ++ dmserver/src/display_manager_service.cpp | 14 ++ .../src/display_manager_service_inner.cpp | 5 + dmserver/src/display_manager_stub.cpp | 8 + interfaces/innerkits/dm/display_manager.h | 1 + interfaces/innerkits/wm/window.h | 1 + .../display_runtime/js_display_manager.cpp | 30 +++ .../window_runtime/window_napi/js_window.cpp | 53 ++++ .../window_runtime/window_napi/js_window.h | 2 + utils/include/window_info_queried_listener.h | 28 +++ utils/include/wm_common_inner.h | 1 + utils/src/window_property.cpp | 6 + wm/include/window_impl.h | 1 + wm/src/window_impl.cpp | 6 + wmserver/include/window_manager_service.h | 7 +- wmserver/include/window_node_container.h | 2 +- wmserver/include/window_root.h | 1 + wmserver/src/window_controller.cpp | 4 + wmserver/src/window_manager_service.cpp | 16 ++ wmserver/src/window_node_container.cpp | 13 + wmserver/src/window_root.cpp | 6 + 30 files changed, 497 insertions(+), 3 deletions(-) create mode 100644 dm/test/systemtest/display_manager_test.cpp create mode 100644 utils/include/window_info_queried_listener.h diff --git a/dm/include/display_manager_adapter.h b/dm/include/display_manager_adapter.h index 2dda6823..d2423704 100644 --- a/dm/include/display_manager_adapter.h +++ b/dm/include/display_manager_adapter.h @@ -58,6 +58,7 @@ public: virtual sptr GetDisplayInfoByScreenId(ScreenId screenId); virtual std::vector GetAllDisplayIds(); virtual std::shared_ptr GetDisplaySnapshot(DisplayId displayId); + virtual DMError HasPrivateWindow(DisplayId displayId, bool& hasPrivateWindow); virtual bool WakeUpBegin(PowerStateChangeReason reason); virtual bool WakeUpEnd(); virtual bool SuspendBegin(PowerStateChangeReason reason); diff --git a/dm/src/display_manager.cpp b/dm/src/display_manager.cpp index 8e5284f4..b28a9f5e 100644 --- a/dm/src/display_manager.cpp +++ b/dm/src/display_manager.cpp @@ -40,6 +40,7 @@ public: bool CheckSizeValid(const Media::Size& size, int32_t oriHeight, int32_t oriWidth) const; sptr GetDefaultDisplay(); sptr GetDisplayById(DisplayId displayId); + DMError HasPrivateWindow(DisplayId displayId, bool& hasPrivateWindow); bool RegisterDisplayListener(sptr listener); bool UnregisterDisplayListener(sptr listener); bool SetDisplayState(DisplayState state, DisplayStateCallback callback); @@ -381,6 +382,16 @@ std::vector> DisplayManager::GetAllDisplays() return res; } +DMError DisplayManager::HasPrivateWindow(DisplayId displayId, bool& hasPrivateWindow) +{ + return pImpl_->HasPrivateWindow(displayId, hasPrivateWindow); +} + +DMError DisplayManager::Impl::HasPrivateWindow(DisplayId displayId, bool& hasPrivateWindow) +{ + return SingletonContainer::Get().HasPrivateWindow(displayId, hasPrivateWindow); +} + bool DisplayManager::Impl::RegisterDisplayListener(sptr listener) { std::lock_guard lock(mutex_); diff --git a/dm/src/display_manager_adapter.cpp b/dm/src/display_manager_adapter.cpp index 51d35ce7..7b504c9d 100644 --- a/dm/src/display_manager_adapter.cpp +++ b/dm/src/display_manager_adapter.cpp @@ -322,6 +322,13 @@ std::vector DisplayManagerAdapter::GetAllDisplayIds() return displayManagerServiceProxy_->GetAllDisplayIds(); } +DMError DisplayManagerAdapter::HasPrivateWindow(DisplayId displayId, bool& hasPrivateWindow) +{ + INIT_PROXY_CHECK_RETURN(DMError::DM_ERROR_INIT_DMS_PROXY_LOCKED); + + return displayManagerServiceProxy_->HasPrivateWindow(displayId, hasPrivateWindow); +} + sptr DisplayManagerAdapter::GetDisplayInfo(DisplayId displayId) { if (displayId == DISPLAY_ID_INVALID) { diff --git a/dm/test/systemtest/BUILD.gn b/dm/test/systemtest/BUILD.gn index 7d5fe1d7..84005205 100644 --- a/dm/test/systemtest/BUILD.gn +++ b/dm/test/systemtest/BUILD.gn @@ -20,6 +20,7 @@ group("systemtest") { deps = [ ":dm_display_change_test", + ":dm_display_manager_test", ":dm_display_minimal_test", ":dm_display_power_test", ":dm_screen_manager_test", @@ -70,6 +71,17 @@ ohos_systemtest("dm_screenshot_test") { ## SystemTest dm_screenshot_test }}} +## SystemTest dm_display_manager_test {{{ +ohos_systemtest("dm_display_manager_test") { + module_out_path = module_out_path + + sources = [ "display_manager_test.cpp" ] + + deps = [ ":dm_systemtest_common" ] +} + +## SystemTest dm_display_manager_test }}} + ## SystemTest dm_screenshot_cmd_test {{{ ohos_systemtest("dm_screenshot_cmd_test") { module_out_path = module_out_path diff --git a/dm/test/systemtest/display_manager_test.cpp b/dm/test/systemtest/display_manager_test.cpp new file mode 100644 index 00000000..3c363eba --- /dev/null +++ b/dm/test/systemtest/display_manager_test.cpp @@ -0,0 +1,232 @@ +/* + * 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 +#include "display_test_utils.h" +#include "screen.h" +#include "test_utils.h" +#include "wm_common.h" +#include "window.h" +#include "window_option.h" +#include "window_manager_hilog.h" + +using namespace testing; +using namespace testing::ext; + +namespace OHOS::Rosen { +namespace { + const int WAIT_FOR_SYNC_US = 1000 * 500; // 500ms +} + +class DisplayManagerTest : public testing::Test { +public: + static void SetUpTestCase(); + static void TearDownTestCase(); + virtual void SetUp() override; + virtual void TearDown() override; + + sptr CreateWindow(std::string name, WindowMode mode, Rect rect); +}; + +void DisplayManagerTest::SetUpTestCase() +{ +} + +void DisplayManagerTest::TearDownTestCase() +{ +} + +void DisplayManagerTest::SetUp() +{ +} + +void DisplayManagerTest::TearDown() +{ +} + +sptr DisplayManagerTest::CreateWindow(std::string name, WindowMode mode, Rect rect) +{ + sptr option = new WindowOption(); + option->SetDisplayId(DisplayManager::GetInstance().GetDefaultDisplayId()); + option->SetWindowType(WindowType::WINDOW_TYPE_APP_MAIN_WINDOW); + + if (mode != WindowMode::WINDOW_MODE_FULLSCREEN) { + option->SetWindowRect(rect); + } + option->SetWindowMode(mode); + option->SetWindowName(name); + sptr window = Window::Create(option->GetWindowName(), option); + window->AddWindowFlag(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED); + return window; +} + +namespace { +/** + * @tc.name: HasPrivateWindow + * @tc.desc: Check whether there is a private window in the current display + * @tc.type: FUNC + */ +HWTEST_F(DisplayManagerTest, HasPrivateWindow, Function | SmallTest | Level2) +{ + sptr window = CreateWindow("test", WindowMode::WINDOW_MODE_FULLSCREEN, Rect {0, 0, 0, 0}); + window->SetPrivacyMode(true); + window->Show(); + usleep(WAIT_FOR_SYNC_US); + bool hasPrivateWindow = false; + DisplayId id = DisplayManager::GetInstance().GetDefaultDisplayId(); + DisplayManager::GetInstance().HasPrivateWindow(id, hasPrivateWindow); + ASSERT_TRUE(hasPrivateWindow); + + window->SetPrivacyMode(false); + usleep(WAIT_FOR_SYNC_US); + DisplayManager::GetInstance().HasPrivateWindow(id, hasPrivateWindow); + ASSERT_TRUE(!hasPrivateWindow); + window->Destroy(); +} + +/** + * @tc.name: HasPrivateWindowCovered + * @tc.desc: The private window is covered + * @tc.type: FUNC + */ +HWTEST_F(DisplayManagerTest, HasPrivateWindowCovered, Function | SmallTest | Level2) +{ + sptr window1 = CreateWindow("test", WindowMode::WINDOW_MODE_FULLSCREEN, Rect {0, 0, 0, 0}); + window1->Show(); + // 20:rect.posX_, 120:rect.posY_, 360:rect.width, 480:rect.height + sptr window2 = CreateWindow("private", WindowMode::WINDOW_MODE_FLOATING, Rect {20, 120, 360, 480}); + window2->SetPrivacyMode(true); + window2->Show(); + // 10:rect.posX_, 110:rect.posY_, 400:rect.width, 500:rect.height + sptr window3 = CreateWindow("covered", WindowMode::WINDOW_MODE_FLOATING, Rect {10, 110, 400, 500}); + window3->Show(); + usleep(WAIT_FOR_SYNC_US); + bool hasPrivateWindow = false; + DisplayId id = DisplayManager::GetInstance().GetDefaultDisplayId(); + DisplayManager::GetInstance().HasPrivateWindow(id, hasPrivateWindow); + ASSERT_TRUE(!hasPrivateWindow); + window1->Destroy(); + window2->Destroy(); + window3->Destroy(); +} + +/** + * @tc.name: HasPrivateWindowCovered01 + * @tc.desc: The private window is partially covered + * @tc.type: FUNC + */ +HWTEST_F(DisplayManagerTest, HasPrivateWindowCovered01, Function | SmallTest | Level2) +{ + sptr window1 = CreateWindow("test", WindowMode::WINDOW_MODE_FULLSCREEN, Rect {0, 0, 0, 0}); + window1->Show(); + // 20:rect.posX_, 120:rect.posY_, 360:rect.width, 480:rect.height + sptr window2 = CreateWindow("private", WindowMode::WINDOW_MODE_FLOATING, Rect {20, 120, 360, 480}); + window2->SetPrivacyMode(true); + window2->Show(); + // 10:rect.posX_, 110:rect.posY_, 360:rect.width, 480:rect.height + sptr window3 = CreateWindow("covered", WindowMode::WINDOW_MODE_FLOATING, Rect {10, 110, 360, 480}); + window3->Show(); + usleep(WAIT_FOR_SYNC_US); + bool hasPrivateWindow = false; + DisplayId id = DisplayManager::GetInstance().GetDefaultDisplayId(); + DisplayManager::GetInstance().HasPrivateWindow(id, hasPrivateWindow); + ASSERT_TRUE(hasPrivateWindow); + window1->Destroy(); + window2->Destroy(); + window3->Destroy(); +} + +/** + * @tc.name: HasPrivateWindowCovered02 + * @tc.desc: The private window is covered + * @tc.type: FUNC + */ +HWTEST_F(DisplayManagerTest, HasPrivateWindowCovered02, Function | SmallTest | Level2) +{ + sptr window1 = CreateWindow("test", WindowMode::WINDOW_MODE_FULLSCREEN, Rect {0, 0, 0, 0}); + window1->Show(); + // 20:rect.posX_, 120:rect.posY_, 360:rect.width, 480:rect.height + sptr window2 = CreateWindow("private", WindowMode::WINDOW_MODE_FLOATING, Rect {20, 120, 360, 480}); + window2->SetPrivacyMode(true); + window2->Show(); + // 10:rect.posX_, 110:rect.posY_, 380:rect.width, 480:rect.height + sptr window3 = CreateWindow("covered1", WindowMode::WINDOW_MODE_FLOATING, Rect {10, 110, 380, 480}); + window3->Show(); + // 10:rect.posX_, 300:rect.posY_, 380:rect.width, 480:rect.height + sptr window4 = CreateWindow("covered2", WindowMode::WINDOW_MODE_FLOATING, Rect {10, 300, 380, 480}); + window4->Show(); + usleep(WAIT_FOR_SYNC_US); + bool hasPrivateWindow = false; + DisplayId id = DisplayManager::GetInstance().GetDefaultDisplayId(); + DisplayManager::GetInstance().HasPrivateWindow(id, hasPrivateWindow); + ASSERT_TRUE(!hasPrivateWindow); + window1->Destroy(); + window2->Destroy(); + window3->Destroy(); + window4->Destroy(); +} + +/** + * @tc.name: HasPrivateWindowCovered03 + * @tc.desc: The private window is partially covered + * @tc.type: FUNC + */ +HWTEST_F(DisplayManagerTest, HasPrivateWindowCovered03, Function | SmallTest | Level2) +{ + sptr window1 = CreateWindow("test", WindowMode::WINDOW_MODE_FULLSCREEN, Rect {0, 0, 0, 0}); + window1->Show(); + // 20:rect.posX_, 120:rect.pos_Y, rect.width_:360, rect.height_:700 + sptr window2 = CreateWindow("private", WindowMode::WINDOW_MODE_FLOATING, Rect {20, 120, 360, 700}); + window2->SetPrivacyMode(true); + window2->Show(); + // 10:rect.posX_, 110:rect.pos_Y, rect.width_:380, rect.height_:480 + sptr window3 = CreateWindow("covered1", WindowMode::WINDOW_MODE_FLOATING, Rect {10, 110, 380, 480}); + window3->Show(); + // 10:rect.posX_, 600:rect.pos_Y, rect.width_:380, rect.height_:480 + sptr window4 = CreateWindow("covered2", WindowMode::WINDOW_MODE_FLOATING, Rect {10, 600, 380, 480}); + window4->Show(); + usleep(WAIT_FOR_SYNC_US); + bool hasPrivateWindow = false; + DisplayId id = DisplayManager::GetInstance().GetDefaultDisplayId(); + DisplayManager::GetInstance().HasPrivateWindow(id, hasPrivateWindow); + ASSERT_TRUE(hasPrivateWindow); + window1->Destroy(); + window2->Destroy(); + window3->Destroy(); + window4->Destroy(); +} + +/** + * @tc.name: HasPrivateWindowSkipSnapShot + * @tc.desc: set snap shot skip + * @tc.type: FUNC + */ +HWTEST_F(DisplayManagerTest, HasPrivateWindowSkipSnapShot, Function | SmallTest | Level2) +{ + sptr window1 = CreateWindow("test", WindowMode::WINDOW_MODE_FULLSCREEN, Rect {0, 0, 0, 0}); + window1->Show(); + // 20:rect.posX_, 120:rect.posY_, 360:rect.width, 480:rect.height + sptr window2 = CreateWindow("private", WindowMode::WINDOW_MODE_FLOATING, Rect {20, 120, 360, 480}); + window2->SetSnapshotSkip(true); + window2->Show(); + usleep(WAIT_FOR_SYNC_US); + bool hasPrivateWindow = false; + DisplayId id = DisplayManager::GetInstance().GetDefaultDisplayId(); + DisplayManager::GetInstance().HasPrivateWindow(id, hasPrivateWindow); + ASSERT_TRUE(!hasPrivateWindow); + window1->Destroy(); + window2->Destroy(); +} +} +} // namespace OHOS::Rosen \ No newline at end of file diff --git a/dmserver/include/display_manager_interface.h b/dmserver/include/display_manager_interface.h index 17d22fc2..4c345cda 100644 --- a/dmserver/include/display_manager_interface.h +++ b/dmserver/include/display_manager_interface.h @@ -73,11 +73,13 @@ public: TRANS_ID_SCREEN_SET_COLOR_TRANSFORM, TRANS_ID_IS_SCREEN_ROTATION_LOCKED, TRANS_ID_SET_SCREEN_ROTATION_LOCKED, + TRANS_ID_HAS_PRIVATE_WINDOW, }; virtual sptr GetDefaultDisplayInfo() = 0; virtual sptr GetDisplayInfoById(DisplayId displayId) = 0; virtual sptr GetDisplayInfoByScreen(ScreenId screenId) = 0; + virtual DMError HasPrivateWindow(DisplayId displayId, bool& hasPrivateWindow) = 0; virtual ScreenId CreateVirtualScreen(VirtualScreenOption option, const sptr& displayManagerAgent) = 0; diff --git a/dmserver/include/display_manager_proxy.h b/dmserver/include/display_manager_proxy.h index 3b42f18d..4d7bbc0e 100644 --- a/dmserver/include/display_manager_proxy.h +++ b/dmserver/include/display_manager_proxy.h @@ -34,6 +34,7 @@ public: sptr GetDefaultDisplayInfo() override; sptr GetDisplayInfoById(DisplayId displayId) override; sptr GetDisplayInfoByScreen(ScreenId screenId) override; + DMError HasPrivateWindow(DisplayId displayId, bool& hasPrivateWindow) override; ScreenId CreateVirtualScreen(VirtualScreenOption option, const sptr& displayManagerAgent) override; diff --git a/dmserver/include/display_manager_service.h b/dmserver/include/display_manager_service.h index ae3a88fb..3b849333 100644 --- a/dmserver/include/display_manager_service.h +++ b/dmserver/include/display_manager_service.h @@ -34,6 +34,7 @@ #include "display_manager_stub.h" #include "display_power_controller.h" #include "singleton_delegator.h" +#include "window_info_queried_listener.h" namespace OHOS::Rosen { class DisplayManagerService : public SystemAbility, public DisplayManagerStub { @@ -60,7 +61,7 @@ public: void SetGravitySensorSubscriptionEnabled(); std::shared_ptr GetDisplaySnapshot(DisplayId displayId) override; ScreenId GetRSScreenId(DisplayId displayId) const; - + DMError HasPrivateWindow(DisplayId id, bool& hasPrivateWindow) override; // colorspace, gamut DMError GetScreenSupportedColorGamuts(ScreenId screenId, std::vector& colorGamuts) override; DMError GetScreenColorGamut(ScreenId screenId, ScreenColorGamut& colorGamut) override; @@ -100,6 +101,7 @@ public: static float GetCustomVirtualPixelRatio(); void RegisterDisplayChangeListener(sptr listener); void GetWindowPreferredOrientation(DisplayId displayId, Orientation &orientation); + void RegisterWindowInfoQueriedListener(const sptr& listener); private: DisplayManagerService(); ~DisplayManagerService() = default; @@ -117,6 +119,7 @@ private: sptr abstractScreenController_; sptr displayPowerController_; sptr displayChangeListener_; + sptr windowInfoQueriedListener_; sptr displayDumper_; static float customVirtualPixelRatio_; AtomicMap accessTokenIdMaps_; diff --git a/dmserver/include/display_manager_service_inner.h b/dmserver/include/display_manager_service_inner.h index ed8e6c4f..3d4790e5 100644 --- a/dmserver/include/display_manager_service_inner.h +++ b/dmserver/include/display_manager_service_inner.h @@ -24,6 +24,7 @@ #include "abstract_display.h" #include "display_change_listener.h" #include "wm_single_instance.h" +#include "window_info_queried_listener.h" #include "singleton_delegator.h" namespace OHOS::Rosen { @@ -47,6 +48,7 @@ public: bool SetRotationFromWindow(DisplayId displayId, Rotation targetRotation); void SetGravitySensorSubscriptionEnabled(); void GetWindowPreferredOrientation(DisplayId displayId, Orientation &orientation); + void RegisterWindowInfoQueriedListener(const sptr& listener); }; } // namespace OHOS::Rosen diff --git a/dmserver/src/display_manager_proxy.cpp b/dmserver/src/display_manager_proxy.cpp index 2c1cd08b..a2297991 100644 --- a/dmserver/src/display_manager_proxy.cpp +++ b/dmserver/src/display_manager_proxy.cpp @@ -721,6 +721,28 @@ std::vector DisplayManagerProxy::GetAllDisplayIds() return allDisplayIds; } +DMError DisplayManagerProxy::HasPrivateWindow(DisplayId displayId, bool& hasPrivateWindow) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + if (!data.WriteInterfaceToken(GetDescriptor())) { + return DMError::DM_ERROR_IPC_FAILED; + } + + if (!data.WriteUint64(displayId)) { + return DMError::DM_ERROR_IPC_FAILED; + } + + if (Remote()->SendRequest(static_cast(DisplayManagerMessage::TRANS_ID_HAS_PRIVATE_WINDOW), + data, reply, option) != ERR_NONE) { + return DMError::DM_ERROR_IPC_FAILED; + } + DMError ret = static_cast(reply.ReadInt32()); + hasPrivateWindow = reply.ReadBool(); + return ret; +} + void DisplayManagerProxy::NotifyDisplayEvent(DisplayEvent event) { MessageParcel data; diff --git a/dmserver/src/display_manager_service.cpp b/dmserver/src/display_manager_service.cpp index cc521dd2..b3dabc2e 100644 --- a/dmserver/src/display_manager_service.cpp +++ b/dmserver/src/display_manager_service.cpp @@ -123,6 +123,20 @@ void DisplayManagerService::RegisterDisplayChangeListener(sptr& listener) +{ + windowInfoQueriedListener_ = listener; +} + +DMError DisplayManagerService::HasPrivateWindow(DisplayId displayId, bool& hasPrivateWindow) +{ + if (windowInfoQueriedListener_ != nullptr) { + windowInfoQueriedListener_->HasPrivateWindow(displayId, hasPrivateWindow); + return DMError::DM_OK; + } + return DMError::DM_ERROR_NULLPTR; +} + void DisplayManagerService::NotifyDisplayStateChange(DisplayId defaultDisplayId, sptr displayInfo, const std::map>& displayInfoMap, DisplayStateChangeType type) { diff --git a/dmserver/src/display_manager_service_inner.cpp b/dmserver/src/display_manager_service_inner.cpp index 1d95e999..94dcda00 100644 --- a/dmserver/src/display_manager_service_inner.cpp +++ b/dmserver/src/display_manager_service_inner.cpp @@ -56,6 +56,11 @@ std::vector DisplayManagerServiceInner::GetAllDisplayIds() const return DisplayManagerService::GetInstance().GetAllDisplayIds(); } +void DisplayManagerServiceInner::RegisterWindowInfoQueriedListener(const sptr& listener) +{ + DisplayManagerService::GetInstance().RegisterWindowInfoQueriedListener(listener); +} + std::vector> DisplayManagerServiceInner::GetAllDisplays() const { std::vector> res; diff --git a/dmserver/src/display_manager_stub.cpp b/dmserver/src/display_manager_stub.cpp index ea976d12..104f1c97 100644 --- a/dmserver/src/display_manager_stub.cpp +++ b/dmserver/src/display_manager_stub.cpp @@ -323,6 +323,14 @@ int32_t DisplayManagerStub::OnRemoteRequest(uint32_t code, MessageParcel &data, SetScreenRotationLocked(isLocked); break; } + case DisplayManagerMessage::TRANS_ID_HAS_PRIVATE_WINDOW: { + DisplayId id = static_cast(data.ReadUint64()); + bool hasPrivateWindow = false; + DMError ret = HasPrivateWindow(id, hasPrivateWindow); + reply.WriteInt32(static_cast(ret)); + reply.WriteBool(hasPrivateWindow); + break; + } default: WLOGFW("unknown transaction code"); return IPCObjectStub::OnRemoteRequest(code, data, reply, option); diff --git a/interfaces/innerkits/dm/display_manager.h b/interfaces/innerkits/dm/display_manager.h index c4cc5d7d..1b84f04b 100644 --- a/interfaces/innerkits/dm/display_manager.h +++ b/interfaces/innerkits/dm/display_manager.h @@ -41,6 +41,7 @@ public: sptr GetDisplayById(DisplayId displayId); sptr GetDisplayByScreen(ScreenId screenId); std::vector GetAllDisplayIds(); + DMError HasPrivateWindow(DisplayId displayId, bool& hasPrivateWindow); bool RegisterDisplayListener(sptr listener); bool UnregisterDisplayListener(sptr listener); diff --git a/interfaces/innerkits/wm/window.h b/interfaces/innerkits/wm/window.h index 219934d6..1b157f7d 100644 --- a/interfaces/innerkits/wm/window.h +++ b/interfaces/innerkits/wm/window.h @@ -327,6 +327,7 @@ public: virtual void SetPrivacyMode(bool isPrivacyMode) = 0; virtual bool IsPrivacyMode() const = 0; virtual WMError BindDialogTarget(sptr targetToken) = 0; + virtual void SetSnapshotSkip(bool isSkip) = 0; virtual WMError RequestFocus() const = 0; virtual WMError UpdateSurfaceNodeAfterCustomAnimation(bool isAdd) = 0; diff --git a/interfaces/kits/napi/display_runtime/js_display_manager.cpp b/interfaces/kits/napi/display_runtime/js_display_manager.cpp index 47f02c1f..79f3f02c 100644 --- a/interfaces/kits/napi/display_runtime/js_display_manager.cpp +++ b/interfaces/kits/napi/display_runtime/js_display_manager.cpp @@ -78,6 +78,12 @@ static NativeValue* UnregisterDisplayManagerCallback(NativeEngine* engine, Nativ return (me != nullptr) ? me->OnUnregisterDisplayManagerCallback(*engine, *info) : nullptr; } +static NativeValue* HasPrivateWindow(NativeEngine* engine, NativeCallbackInfo* info) +{ + JsDisplayManager* me = CheckParamsAndGetThis(engine, info); + return (me != nullptr) ? me->OnHasPrivateWindow(*engine, *info) : nullptr; +} + private: std::map, sptr>> jsCbMap_; std::mutex mtx_; @@ -308,6 +314,29 @@ NativeValue* OnUnregisterDisplayManagerCallback(NativeEngine& engine, NativeCall return engine.CreateUndefined(); } +NativeValue* OnHasPrivateWindow(NativeEngine& engine, NativeCallbackInfo& info) +{ + bool hasPrivateWindow = false; + if (info.argc != 1) { + return engine.CreateUndefined(); + } + int64_t displayId = static_cast(DISPLAY_ID_INVALID); + if (!ConvertFromJsValue(engine, info.argv[0], displayId)) { + WLOGFE("[NAPI]Failed to convert parameter to displayId"); + return engine.CreateUndefined(); + } + if (displayId < 0) { + return engine.CreateUndefined(); + } + DMError errCode = SingletonContainer::Get().HasPrivateWindow(displayId, hasPrivateWindow); + WLOGFI("[NAPI]Display id = %{public}" PRIu64", hasPrivateWindow = %{public}u err = %{public}d", + static_cast(displayId), hasPrivateWindow, errCode); + if (errCode != DMError::DM_OK) { + return engine.CreateUndefined(); + } + return engine.CreateBoolean(hasPrivateWindow); +} + NativeValue* CreateJsDisplayArrayObject(NativeEngine& engine, std::vector>& displays) { WLOGFI("JsDisplayManager::CreateJsDisplayArrayObject is called"); @@ -381,6 +410,7 @@ NativeValue* JsDisplayManagerInit(NativeEngine* engine, NativeValue* exportObj) BindNativeFunction(*engine, *object, "getDefaultDisplay", JsDisplayManager::GetDefaultDisplay); BindNativeFunction(*engine, *object, "getDefaultDisplaySync", JsDisplayManager::GetDefaultDisplaySync); BindNativeFunction(*engine, *object, "getAllDisplay", JsDisplayManager::GetAllDisplay); + BindNativeFunction(*engine, *object, "hasPrivateWindow", JsDisplayManager::HasPrivateWindow); BindNativeFunction(*engine, *object, "on", JsDisplayManager::RegisterDisplayManagerCallback); BindNativeFunction(*engine, *object, "off", JsDisplayManager::UnregisterDisplayManagerCallback); return engine->CreateUndefined(); diff --git a/interfaces/kits/napi/window_runtime/window_napi/js_window.cpp b/interfaces/kits/napi/window_runtime/window_napi/js_window.cpp index 2e429134..61e415eb 100644 --- a/interfaces/kits/napi/window_runtime/window_napi/js_window.cpp +++ b/interfaces/kits/napi/window_runtime/window_napi/js_window.cpp @@ -310,6 +310,13 @@ NativeValue* JsWindow::SetPreferredOrientation(NativeEngine* engine, NativeCallb return (me != nullptr) ? me->OnSetPreferredOrientation(*engine, *info) : nullptr; } +NativeValue* JsWindow::SetSnapshotSkip(NativeEngine* engine, NativeCallbackInfo* info) +{ + WLOGFI("NAPI"); + JsWindow* me = CheckParamsAndGetThis(engine, info); + return (me != nullptr) ? me->OnSetSnapshotSkip(*engine, *info) : nullptr; +} + NativeValue* JsWindow::DisableWindowDecor(NativeEngine* engine, NativeCallbackInfo* info) { WLOGFI("[NAPI]DisableWindowDecor"); @@ -1896,6 +1903,51 @@ NativeValue* JsWindow::OnSnapshot(NativeEngine& engine, NativeCallbackInfo& info return result; } +NativeValue* JsWindow::OnSetSnapshotSkip(NativeEngine& engine, NativeCallbackInfo& info) +{ + WMError errCode = WMError::WM_OK; + if (info.argc < 1 || info.argc > 2) { // 2 is maximum params num + WLOGFE("[NAPI] inbalid param"); + errCode = WMError::WM_ERROR_INVALID_PARAM; + } + bool isSkip = false; + if (errCode == WMError::WM_OK) { + NativeBoolean* nativeVal = ConvertNativeValueTo(info.argv[0]); + if (nativeVal == nullptr) { + errCode = WMError::WM_ERROR_INVALID_PARAM; + } else { + isSkip = static_cast(*nativeVal); + } + } + + wptr weakToken(windowToken_); + AsyncTask::CompleteCallback complete = + [weakToken, isSkip, errCode](NativeEngine& engine, AsyncTask& task, int32_t status) { + if (errCode != WMError::WM_OK) { + task.Reject(engine, CreateJsError(engine, static_cast(errCode), "Invalidate params")); + return; + } + auto weakWindow = weakToken.promote(); + if (weakWindow == nullptr) { + task.Reject(engine, CreateJsError(engine, + static_cast(WMError::WM_ERROR_NULLPTR), "Invalidate params")); + return; + } + + weakWindow->SetSnapshotSkip(isSkip); + task.Resolve(engine, engine.CreateUndefined()); + WLOGFI("NAPI [%{public}u, %{public}s] set snapshotSkip end", + weakWindow->GetWindowId(), weakWindow->GetWindowName().c_str()); + }; + + NativeValue* lastParam = (info.argc <= 1) ? nullptr : + (info.argv[1]->TypeOf() == NATIVE_FUNCTION ? info.argv[1] : nullptr); + NativeValue* result = nullptr; + AsyncTask::Schedule("JsWindow::OnSetSnapshotSkip", + engine, CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result)); + return result; +} + NativeValue* JsWindow::OnSetOpacitySync(NativeEngine& engine, NativeCallbackInfo& info) { if (info.argc != 1 || windowToken_ == nullptr) { @@ -2212,6 +2264,7 @@ void BindFunctions(NativeEngine& engine, NativeObject* object) BindNativeFunction(engine, *object, "setTouchable", JsWindow::SetTouchable); BindNativeFunction(engine, *object, "setTransparent", JsWindow::SetTransparent); BindNativeFunction(engine, *object, "setCallingWindow", JsWindow::SetCallingWindow); + BindNativeFunction(engine, *object, "setSnapshotSkip", JsWindow::SetSnapshotSkip); BindNativeFunction(engine, *object, "disableWindowDecor", JsWindow::DisableWindowDecor); BindNativeFunction(engine, *object, "dump", JsWindow::Dump); BindNativeFunction(engine, *object, "setForbidSplitMove", JsWindow::SetForbidSplitMove); diff --git a/interfaces/kits/napi/window_runtime/window_napi/js_window.h b/interfaces/kits/napi/window_runtime/window_napi/js_window.h index 545bdd51..70cd73ff 100644 --- a/interfaces/kits/napi/window_runtime/window_napi/js_window.h +++ b/interfaces/kits/napi/window_runtime/window_napi/js_window.h @@ -65,6 +65,7 @@ public: static NativeValue* SetCallingWindow(NativeEngine* engine, NativeCallbackInfo* info); static NativeValue* SetPreferredOrientation(NativeEngine* engine, NativeCallbackInfo* info); static NativeValue* DisableWindowDecor(NativeEngine* engine, NativeCallbackInfo* info); + static NativeValue* SetSnapshotSkip(NativeEngine* engine, NativeCallbackInfo* info); // colorspace, gamut static NativeValue* IsSupportWideGamut(NativeEngine* engine, NativeCallbackInfo* info); static NativeValue* SetColorSpace(NativeEngine* engine, NativeCallbackInfo* info); @@ -124,6 +125,7 @@ private: NativeValue* OnDump(NativeEngine& engine, NativeCallbackInfo& info); NativeValue* OnSetForbidSplitMove(NativeEngine& engine, NativeCallbackInfo& info); NativeValue* OnSnapshot(NativeEngine& engine, NativeCallbackInfo& info); + NativeValue* OnSetSnapshotSkip(NativeEngine& engine, NativeCallbackInfo& info); // animation Config NativeValue* OnSetOpacitySync(NativeEngine& engine, NativeCallbackInfo& info); diff --git a/utils/include/window_info_queried_listener.h b/utils/include/window_info_queried_listener.h new file mode 100644 index 00000000..e0f6c244 --- /dev/null +++ b/utils/include/window_info_queried_listener.h @@ -0,0 +1,28 @@ +/* + * 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 OHOS_ROSEN_WINDOW_INFO_QUERIED_LISTENER_H +#define OHOS_ROSEN_WINDOW_INFO_QUERIED_LISTENER_H +#include + +#include "dm_common.h" + +namespace OHOS::Rosen { +class IWindowInfoQueriedListener : public RefBase { +public: + virtual void HasPrivateWindow(DisplayId displayId, bool& hasPrivateWindow); +}; +} // OHOS::Rosen +#endif // OHOS_ROSEN_WINDOW_INFO_QUERIED_LISTENER_H \ No newline at end of file diff --git a/utils/include/wm_common_inner.h b/utils/include/wm_common_inner.h index 31dd1396..5425adb7 100644 --- a/utils/include/wm_common_inner.h +++ b/utils/include/wm_common_inner.h @@ -77,6 +77,7 @@ enum class PropertyChangeAction : uint32_t { ACTION_UPDATE_TOUCH_HOT_AREA = 1 << 12, ACTION_UPDATE_TRANSFORM_PROPERTY = 1 << 13, ACTION_UPDATE_ANIMATION_FLAG = 1 << 14, + ACTION_UPDATE_PRIVACY_MODE = 1 << 15, }; struct ModeChangeHotZonesConfig { diff --git a/utils/src/window_property.cpp b/utils/src/window_property.cpp index ed45aaa4..fcc4e1ed 100644 --- a/utils/src/window_property.cpp +++ b/utils/src/window_property.cpp @@ -681,6 +681,9 @@ bool WindowProperty::Write(Parcel& parcel, PropertyChangeAction action) case PropertyChangeAction::ACTION_UPDATE_ANIMATION_FLAG: ret = ret && parcel.WriteUint32(animationFlag_); break; + case PropertyChangeAction::ACTION_UPDATE_PRIVACY_MODE: + ret = ret && parcel.WriteBool(isPrivacyMode_); + break; default: break; } @@ -741,6 +744,9 @@ void WindowProperty::Read(Parcel& parcel, PropertyChangeAction action) SetAnimationFlag(parcel.ReadUint32()); break; } + case PropertyChangeAction::ACTION_UPDATE_PRIVACY_MODE: + SetPrivacyMode(parcel.ReadBool()); + break; default: break; } diff --git a/wm/include/window_impl.h b/wm/include/window_impl.h index 2a672c2d..11588e27 100644 --- a/wm/include/window_impl.h +++ b/wm/include/window_impl.h @@ -164,6 +164,7 @@ public: virtual bool IsPrivacyMode() const override; virtual void DisableAppWindowDecor() override; virtual WMError BindDialogTarget(sptr targetToken) override; + virtual void SetSnapshotSkip(bool isSkip) override; virtual bool IsDecorEnable() const override; virtual WMError Maximize() override; diff --git a/wm/src/window_impl.cpp b/wm/src/window_impl.cpp index 3b4faa66..5ed095ae 100755 --- a/wm/src/window_impl.cpp +++ b/wm/src/window_impl.cpp @@ -1392,6 +1392,7 @@ void WindowImpl::SetPrivacyMode(bool isPrivacyMode) { property_->SetPrivacyMode(isPrivacyMode); surfaceNode_->SetSecurityLayer(isPrivacyMode); + UpdateProperty(PropertyChangeAction::ACTION_UPDATE_PRIVACY_MODE); } bool WindowImpl::IsPrivacyMode() const @@ -1399,6 +1400,11 @@ bool WindowImpl::IsPrivacyMode() const return property_->GetPrivacyMode(); } +void WindowImpl::SetSnapshotSkip(bool isSkip) +{ + surfaceNode_->SetSecurityLayer(isSkip); +} + void WindowImpl::DisableAppWindowDecor() { if (!WindowHelper::IsMainWindow(property_->GetWindowType())) { diff --git a/wmserver/include/window_manager_service.h b/wmserver/include/window_manager_service.h index d13bf9b5..d1c4e5f5 100644 --- a/wmserver/include/window_manager_service.h +++ b/wmserver/include/window_manager_service.h @@ -49,6 +49,11 @@ public: virtual void OnScreenshot(DisplayId displayId) override; }; +class WindowInfoQueriedListener : public IWindowInfoQueriedListener { +public: + virtual void HasPrivateWindow(DisplayId id, bool& hasPrivateWindow) override; +}; + class WindowManagerServiceHandler : public AAFwk::WindowManagerServiceHandlerStub { public: virtual void NotifyWindowTransition( @@ -113,8 +118,8 @@ public: WMError UpdateRsTree(uint32_t windowId, bool isAdd) override; void OnScreenshot(DisplayId displayId); void OnAccountSwitched(int accountId); - void OnAccountSwitched(int accountId) const; WMError BindDialogTarget(uint32_t& windowId, sptr targetToken) override; + void HasPrivateWindow(DisplayId displayId, bool& hasPrivateWindow); protected: WindowManagerService(); virtual ~WindowManagerService() = default; diff --git a/wmserver/include/window_node_container.h b/wmserver/include/window_node_container.h index 973ea67d..03896d3c 100644 --- a/wmserver/include/window_node_container.h +++ b/wmserver/include/window_node_container.h @@ -110,8 +110,8 @@ public: WindowLayoutMode GetCurrentLayoutMode() const; void RemoveSingleUserWindowNodes(int accountId); WMError IsTileRectSatisfiedWithSizeLimits(sptr& node); + bool HasPrivateWindow(); static AnimationConfig& GetAnimationConfigRef(); - private: void TraverseWindowNode(sptr& root, std::vector>& windowNodes) const; sptr FindRoot(WindowType type) const; diff --git a/wmserver/include/window_root.h b/wmserver/include/window_root.h index 9614678c..41c568c3 100644 --- a/wmserver/include/window_root.h +++ b/wmserver/include/window_root.h @@ -99,6 +99,7 @@ public: void RemoveSingleUserWindowNodes(int accountId); sptr FindDialogCallerNode(WindowType type, sptr token); bool CheckMultiDialogWindows(WindowType type, sptr token); + bool HasPrivateWindow(DisplayId displayId); private: void OnRemoteDied(const sptr& remoteObject); diff --git a/wmserver/src/window_controller.cpp b/wmserver/src/window_controller.cpp index 2a8e3507..ef2d4117 100644 --- a/wmserver/src/window_controller.cpp +++ b/wmserver/src/window_controller.cpp @@ -928,6 +928,10 @@ WMError WindowController::UpdateProperty(sptr& property, Propert ret = UpdateTransform(windowId); break; } + case PropertyChangeAction::ACTION_UPDATE_PRIVACY_MODE: { + node->GetWindowProperty()->SetPrivacyMode(property->GetPrivacyMode()); + break; + } default: break; } diff --git a/wmserver/src/window_manager_service.cpp b/wmserver/src/window_manager_service.cpp index e2716c98..4eb25e0c 100644 --- a/wmserver/src/window_manager_service.cpp +++ b/wmserver/src/window_manager_service.cpp @@ -85,6 +85,8 @@ void WindowManagerService::OnStart() WindowInnerManager::GetInstance().Start(system::GetParameter("persist.window.holder.enable", "0") == "1"); sptr listener = new DisplayChangeListener(); DisplayManagerServiceInner::GetInstance().RegisterDisplayChangeListener(listener); + sptr windowInfoQueriedListener = new WindowInfoQueriedListener(); + DisplayManagerServiceInner::GetInstance().RegisterWindowInfoQueriedListener(windowInfoQueriedListener); RegisterSnapshotHandler(); RegisterWindowManagerServiceHandler(); RegisterWindowVisibilityChangeCallback(); @@ -851,5 +853,19 @@ WMError WindowManagerService::BindDialogTarget(uint32_t& windowId, sptrBindDialogTarget(windowId, targetToken); }); } + +void WindowManagerService::HasPrivateWindow(DisplayId displayId, bool& hasPrivateWindow) +{ + PostVoidSyncTask([this, displayId, &hasPrivateWindow]() mutable { + hasPrivateWindow = windowRoot_->HasPrivateWindow(displayId); + }); + WLOGFI("called %{public}u", hasPrivateWindow); +} + +void WindowInfoQueriedListener::HasPrivateWindow(DisplayId displayId, bool& hasPrivateWindow) +{ + WLOGFI("called"); + WindowManagerService::GetInstance().HasPrivateWindow(displayId, hasPrivateWindow); +} } // namespace Rosen } // namespace OHOS diff --git a/wmserver/src/window_node_container.cpp b/wmserver/src/window_node_container.cpp index 65bd907d..6211dcfc 100644 --- a/wmserver/src/window_node_container.cpp +++ b/wmserver/src/window_node_container.cpp @@ -1345,6 +1345,19 @@ void WindowNodeContainer::MinimizeAllAppWindows(DisplayId displayId) return; } +bool WindowNodeContainer::HasPrivateWindow() +{ + std::vector> windowNodes; + TraverseContainer(windowNodes); + for (const auto& node : windowNodes) { + if (node->isVisible_ && node->GetWindowProperty()->GetPrivacyMode()) { + WLOGFI("window name %{public}s", node->GetWindowName().c_str()); + return true; + } + } + return false; +} + void WindowNodeContainer::MinimizeOldestAppWindow() { for (auto& appNode : appWindowNode_->children_) { diff --git a/wmserver/src/window_root.cpp b/wmserver/src/window_root.cpp index 796860bf..3b19355e 100644 --- a/wmserver/src/window_root.cpp +++ b/wmserver/src/window_root.cpp @@ -1301,6 +1301,12 @@ Rect WindowRoot::GetDisplayGroupRect(DisplayId displayId) const return container->GetDisplayGroupRect(); } +bool WindowRoot::HasPrivateWindow(DisplayId displayId) +{ + auto container = GetWindowNodeContainer(displayId); + return container != nullptr ? container->HasPrivateWindow() : false; +} + void WindowRoot::SetMaxAppWindowNumber(int windowNum) { maxAppWindowNumber_ = windowNum;