From fb06738129ff102c48334a293571373900964680 Mon Sep 17 00:00:00 2001 From: Grady Date: Fri, 14 Jan 2022 20:41:55 +0800 Subject: [PATCH] Move VirtualScreen to ScreenManager, add AddMirror to Save DisplayNode in DMS Signed-off-by: Grady Change-Id: I4170cc9d5d5695adc895502f0988c7bc92b66677 --- 0001-tmp-20220114.patch | 881 ++++++++++++++++++ dm/include/display_manager_adapter.h | 10 +- dm/src/display_manager.cpp | 14 - dm/src/display_manager_adapter.cpp | 26 +- dm/src/screen_manager.cpp | 26 +- .../include/abstract_display_controller.h | 7 +- dmserver/include/abstract_screen.h | 9 +- dmserver/include/display_manager_interface.h | 12 +- dmserver/include/display_manager_proxy.h | 10 +- dmserver/include/display_manager_service.h | 10 +- dmserver/src/abstract_display_controller.cpp | 15 +- .../src/abstract_display_manager_fake.cpp | 136 +++ dmserver/src/display_manager_proxy.cpp | 76 +- dmserver/src/display_manager_service.cpp | 52 +- dmserver/src/display_manager_stub.cpp | 37 +- interfaces/innerkits/dm/display_manager.h | 4 - interfaces/innerkits/dm/dm_common.h | 13 + interfaces/innerkits/dm/screen.h | 2 +- interfaces/innerkits/dm/screen_manager.h | 11 +- push_code.sh | 3 + push_code_force.sh | 3 + snapshot/BUILD.gn | 101 +- snapshot/image_reader.cpp | 145 +++ snapshot/image_reader.h | 63 ++ snapshot/image_reader_handler.h | 33 + snapshot/image_reader_handler_impl.cpp | 39 + snapshot/image_reader_handler_impl.h | 35 + snapshot/snapshot_display.cpp | 21 +- snapshot/snapshot_utils.cpp | 144 ++- snapshot/snapshot_utils.h | 22 +- snapshot/snapshot_virtual_display.cpp | 120 +++ wmserver/include/window_layout_policy.h | 2 + wmserver/include/window_manager_service.h | 2 +- wmserver/include/window_node_container.h | 1 + wmserver/src/window_layout_policy.cpp | 1 + wmserver/src/window_manager_service.cpp | 10 +- 36 files changed, 1935 insertions(+), 161 deletions(-) create mode 100644 0001-tmp-20220114.patch create mode 100644 dmserver/src/abstract_display_manager_fake.cpp create mode 100755 push_code.sh create mode 100755 push_code_force.sh create mode 100644 snapshot/image_reader.cpp create mode 100644 snapshot/image_reader.h create mode 100644 snapshot/image_reader_handler.h create mode 100644 snapshot/image_reader_handler_impl.cpp create mode 100644 snapshot/image_reader_handler_impl.h create mode 100644 snapshot/snapshot_virtual_display.cpp diff --git a/0001-tmp-20220114.patch b/0001-tmp-20220114.patch new file mode 100644 index 0000000000..ead53fe4f2 --- /dev/null +++ b/0001-tmp-20220114.patch @@ -0,0 +1,881 @@ +From d241672c00196a5020f5ec6f0b18940801d6cbc0 Mon Sep 17 00:00:00 2001 +From: fanby01 +Date: Fri, 14 Jan 2022 20:11:44 +0800 +Subject: [PATCH] tmp 20220114 + +Change-Id: Ic29364126b80645462c2e18f17e56a4fa7bb94a4 +--- + dm/include/display_manager_adapter.h | 10 ++- + dm/src/display_manager.cpp | 14 ---- + dm/src/display_manager_adapter.cpp | 26 ++++-- + dm/src/screen_manager.cpp | 26 +++++- + .../include/abstract_display_controller.h | 7 +- + dmserver/include/abstract_screen.h | 9 +- + dmserver/include/display_manager_interface.h | 12 +-- + dmserver/include/display_manager_proxy.h | 10 ++- + dmserver/include/display_manager_service.h | 11 ++- + dmserver/src/abstract_display_controller.cpp | 15 ++-- + dmserver/src/display_manager_proxy.cpp | 83 +++++++++++++------ + dmserver/src/display_manager_service.cpp | 53 +++++++++--- + dmserver/src/display_manager_stub.cpp | 40 +++++++-- + interfaces/innerkits/dm/display_manager.h | 4 - + interfaces/innerkits/dm/dm_common.h | 13 +++ + interfaces/innerkits/dm/screen.h | 2 +- + interfaces/innerkits/dm/screen_manager.h | 11 ++- + wmserver/include/window_layout_policy.h | 2 + + wmserver/include/window_manager_service.h | 2 +- + wmserver/include/window_node_container.h | 1 + + wmserver/src/window_layout_policy.cpp | 1 + + wmserver/src/window_manager_service.cpp | 10 +-- + 22 files changed, 245 insertions(+), 117 deletions(-) + +diff --git a/dm/include/display_manager_adapter.h b/dm/include/display_manager_adapter.h +index 666f0ac..597472d 100644 +--- a/dm/include/display_manager_adapter.h ++++ b/dm/include/display_manager_adapter.h +@@ -20,6 +20,8 @@ + #include + + #include "display.h" ++#include "screen.h" ++#include "dm_common.h" + #include "display_manager_interface.h" + #include "singleton_delegator.h" + +@@ -34,9 +36,9 @@ WM_DECLARE_SINGLE_INSTANCE_BASE(DisplayManagerAdapter); + public: + DisplayId GetDefaultDisplayId(); + sptr GetDisplayById(DisplayId displayId); +- DisplayId CreateVirtualDisplay(const VirtualDisplayInfo &virtualDisplayInfo, +- sptr surface); +- bool DestroyVirtualDisplay(DisplayId displayId); ++ ++ ScreenId CreateVirtualScreen(VirtualScreenOption option); ++ DMError DestroyVirtualScreen(ScreenId screenId); + std::shared_ptr GetDisplaySnapshot(DisplayId displayId); + + void RegisterDisplayManagerAgent(const sptr& displayManagerAgent, +@@ -51,7 +53,7 @@ public: + bool SetDisplayState(DisplayState state, DisplayStateCallback callback); + DisplayState GetDisplayState(uint64_t displayId); + void NotifyDisplayEvent(DisplayEvent event); +- ++ void AddMirror(ScreenId mainScreenId, ScreenId mirrorScreenId); + void Clear(); + + private: +diff --git a/dm/src/display_manager.cpp b/dm/src/display_manager.cpp +index 43a6331..faca0d8 100644 +--- a/dm/src/display_manager.cpp ++++ b/dm/src/display_manager.cpp +@@ -154,20 +154,6 @@ std::vector> DisplayManager::GetAllDisplays() + return res; + } + +-DisplayId DisplayManager::CreateVirtualDisplay(const std::string &name, uint32_t width, uint32_t height, +- sptr surface, DisplayId displayIdToMirror, int32_t flags) +-{ +- WLOGFI("DisplayManager::CreateVirtualDisplay multi params"); +- VirtualDisplayInfo info(name, width, height, displayIdToMirror, flags); +- return SingletonContainer::Get().CreateVirtualDisplay(info, surface); +-} +- +-bool DisplayManager::DestroyVirtualDisplay(DisplayId displayId) +-{ +- WLOGFI("DisplayManager::DestroyVirtualDisplay override params"); +- return SingletonContainer::Get().DestroyVirtualDisplay(displayId); +-} +- + void DisplayManager::RegisterDisplayPowerEventListener(sptr listener) + { + if (listener == nullptr) { +diff --git a/dm/src/display_manager_adapter.cpp b/dm/src/display_manager_adapter.cpp +index bd804d7..138527c 100644 +--- a/dm/src/display_manager_adapter.cpp ++++ b/dm/src/display_manager_adapter.cpp +@@ -78,23 +78,22 @@ std::shared_ptr DisplayManagerAdapter::GetDisplaySnapshot(Displ + return dispalySnapshot; + } + +-DisplayId DisplayManagerAdapter::CreateVirtualDisplay(const VirtualDisplayInfo &virtualDisplayInfo, +- sptr surface) ++ScreenId DisplayManagerAdapter::CreateVirtualScreen(VirtualScreenOption option) + { + if (!InitDMSProxyLocked()) { +- return DISPLAY_ID_INVALD; ++ return SCREEN_ID_INVALD; + } +- WLOGFI("DisplayManagerAdapter::CreateVirtualDisplay"); +- return displayManagerServiceProxy_->CreateVirtualDisplay(virtualDisplayInfo, surface); ++ WLOGFI("DisplayManagerAdapter::CreateVirtualScreen"); ++ return displayManagerServiceProxy_->CreateVirtualScreen(option); + } + +-bool DisplayManagerAdapter::DestroyVirtualDisplay(DisplayId displayId) ++DMError DisplayManagerAdapter::DestroyVirtualScreen(ScreenId screenId) + { + if (!InitDMSProxyLocked()) { +- return false; ++ return DMError::DM_ERROR_INIT_DMS_PROXY_LOCKED; + } +- WLOGFI("DisplayManagerAdapter::DestroyVirtualDisplay"); +- return displayManagerServiceProxy_->DestroyVirtualDisplay(displayId); ++ WLOGFI("DisplayManagerAdapter::DestroyVirtualScreen"); ++ return displayManagerServiceProxy_->DestroyVirtualScreen(screenId); + } + + void DisplayManagerAdapter::RegisterDisplayManagerAgent(const sptr& displayManagerAgent, +@@ -265,4 +264,13 @@ void DisplayManagerAdapter::Clear() + } + displayManagerServiceProxy_ = nullptr; + } ++ ++void DisplayManagerAdapter::AddMirror(ScreenId mainScreenId, ScreenId mirrorScreenId) ++{ ++ if (!InitDMSProxyLocked()) { ++ WLOGFE("DisplayManagerAdapter::AddMirror: InitDMSProxyLocked failed"); ++ } ++ WLOGFI("DisplayManagerAdapter::AddMirror"); ++ displayManagerServiceProxy_->AddMirror(mainScreenId, mirrorScreenId); ++} + } // namespace OHOS::Rosen +\ No newline at end of file +diff --git a/dm/src/screen_manager.cpp b/dm/src/screen_manager.cpp +index d13344a..f31c39e 100644 +--- a/dm/src/screen_manager.cpp ++++ b/dm/src/screen_manager.cpp +@@ -14,11 +14,17 @@ + */ + + #include "screen_manager.h" ++#include "window_manager_hilog.h" ++#include "display_manager_adapter.h" ++ + + #include + #include + + namespace OHOS::Rosen { ++namespace { ++ constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, 0, "ScreenManager"}; ++} + class ScreenManager::Impl : public RefBase { + friend class ScreenManager; + private: +@@ -53,18 +59,32 @@ void ScreenManager::RegisterScreenChangeListener(sptr lis + { + } + +-sptr ScreenManager::makeExpand(std::vector screenId, std::vector startPoint) ++sptr ScreenManager::MakeExpand(std::vector screenId, std::vector startPoint) + { + return nullptr; + } + +-sptr ScreenManager::makeMirror(ScreenId mainScreenId, std::vector mirrorScreenId) ++sptr ScreenManager::MakeMirror(ScreenId mainScreenId, std::vector mirrorScreenId) + { + return nullptr; + } + +-sptr ScreenManager::createVirtualScreen(VirtualScreenOption option) ++sptr ScreenManager::AddMirror(ScreenId mainScreenId, ScreenId mirrorScreenId) + { ++ WLOGFI("ScreenManager::AddMirror"); ++ SingletonContainer::Get().AddMirror(mainScreenId, mirrorScreenId); + return nullptr; + } ++ ++ScreenId ScreenManager::CreateVirtualScreen(VirtualScreenOption option) ++{ ++ WLOGFI("ScreenManager::CreateVirtualScreen"); ++ return SingletonContainer::Get().CreateVirtualScreen(option); ++} ++ ++DMError ScreenManager::DestroyVirtualScreen(ScreenId screenId) ++{ ++ WLOGFI("ScreenManager::DestroyVirtualScreen"); ++ return SingletonContainer::Get().DestroyVirtualScreen(screenId); ++} + } // namespace OHOS::Rosen +\ No newline at end of file +diff --git a/dmserver/include/abstract_display_controller.h b/dmserver/include/abstract_display_controller.h +index 3d588e7..d94be07 100644 +--- a/dmserver/include/abstract_display_controller.h ++++ b/dmserver/include/abstract_display_controller.h +@@ -21,6 +21,8 @@ + #include + #include + ++#include "screen.h" ++#include "dm_common.h" + #include "abstract_display.h" + #include "abstract_screen_controller.h" + #include "transaction/rs_interfaces.h" +@@ -35,8 +37,9 @@ public: + void Init(sptr abstractScreenController); + ScreenId GetDefaultScreenId(); + RSScreenModeInfo GetScreenActiveMode(ScreenId id); +- ScreenId CreateVirtualScreen(const VirtualDisplayInfo &virtualDisplayInfo, sptr surface); +- bool DestroyVirtualScreen(ScreenId screenId); ++ ++ ScreenId CreateVirtualScreen(VirtualScreenOption option); ++ DMError DestroyVirtualScreen(ScreenId screenId); + std::shared_ptr GetScreenSnapshot(DisplayId displayId, ScreenId screenId); + + private: +diff --git a/dmserver/include/abstract_screen.h b/dmserver/include/abstract_screen.h +index 9b9a0c3..517ccbb 100644 +--- a/dmserver/include/abstract_screen.h ++++ b/dmserver/include/abstract_screen.h +@@ -16,19 +16,16 @@ + #ifndef FOUNDATION_DMSERVER_ABSTRACT_SCREEN_H + #define FOUNDATION_DMSERVER_ABSTRACT_SCREEN_H + +-#include + ++#include + #include + #include + ++#include "screen.h" ++ + namespace OHOS::Rosen { + constexpr static ScreenId SCREEN_ID_INVALID = INVALID_SCREEN_ID; + +-struct Point { +- int32_t posX_; +- int32_t posY_; +-}; +- + enum class ScreenCombination : uint32_t { + SCREEN_ALONE, + SCREEN_EXPAND, +diff --git a/dmserver/include/display_manager_interface.h b/dmserver/include/display_manager_interface.h +index 6834d9c..dae7bfc 100644 +--- a/dmserver/include/display_manager_interface.h ++++ b/dmserver/include/display_manager_interface.h +@@ -21,6 +21,7 @@ + #include + + #include "dm_common.h" ++#include "screen.h" + #include "display_info.h" + #include "virtual_display_info.h" + #include "zidl/display_manager_agent_interface.h" +@@ -33,8 +34,8 @@ public: + enum { + TRANS_ID_GET_DEFAULT_DISPLAY_ID = 0, + TRANS_ID_GET_DISPLAY_BY_ID, +- TRANS_ID_CREATE_VIRTUAL_DISPLAY, +- TRANS_ID_DESTROY_VIRTUAL_DISPLAY, ++ TRANS_ID_CREATE_VIRTUAL_SCREEN, ++ TRANS_ID_DESTROY_VIRTUAL_SCREEN, + TRANS_ID_GET_DISPLAY_SNAPSHOT, + TRANS_ID_REGISTER_DISPLAY_MANAGER_AGENT, + TRANS_ID_UNREGISTER_DISPLAY_MANAGER_AGENT, +@@ -46,14 +47,14 @@ public: + TRANS_ID_SET_DISPLAY_STATE, + TRANS_ID_GET_DISPLAY_STATE, + TRANS_ID_NOTIFY_DISPLAY_EVENT, ++ TRANS_ID_ADD_MIRROR + }; + + virtual DisplayId GetDefaultDisplayId() = 0; + virtual DisplayInfo GetDisplayInfoById(DisplayId displayId) = 0; + +- virtual DisplayId CreateVirtualDisplay(const VirtualDisplayInfo &virtualDisplayInfo, +- sptr surface) = 0; +- virtual bool DestroyVirtualDisplay(DisplayId displayId) = 0; ++ virtual ScreenId CreateVirtualScreen(VirtualScreenOption option) = 0; ++ virtual DMError DestroyVirtualScreen(ScreenId screenId) = 0; + virtual std::shared_ptr GetDispalySnapshot(DisplayId displayId) = 0; + + virtual void RegisterDisplayManagerAgent(const sptr& displayManagerAgent, +@@ -68,6 +69,7 @@ public: + virtual bool SetDisplayState(DisplayState state) = 0; + virtual DisplayState GetDisplayState(uint64_t displayId) = 0; + virtual void NotifyDisplayEvent(DisplayEvent event) = 0; ++ virtual void AddMirror(ScreenId mainScreenId, ScreenId mirrorScreenId) = 0; + }; + } // namespace OHOS::Rosen + +diff --git a/dmserver/include/display_manager_proxy.h b/dmserver/include/display_manager_proxy.h +index cc4fa0c..631dec2 100644 +--- a/dmserver/include/display_manager_proxy.h ++++ b/dmserver/include/display_manager_proxy.h +@@ -18,6 +18,10 @@ + + #include "display_manager_interface.h" + ++#include "dm_common.h" ++ ++#include "screen.h" ++ + #include + + namespace OHOS::Rosen { +@@ -30,9 +34,8 @@ public: + DisplayId GetDefaultDisplayId() override; + DisplayInfo GetDisplayInfoById(DisplayId displayId) override; + +- DisplayId CreateVirtualDisplay(const VirtualDisplayInfo &virtualDisplayInfo, +- sptr surface) override; +- bool DestroyVirtualDisplay(DisplayId displayId) override; ++ ScreenId CreateVirtualScreen(VirtualScreenOption option) override; ++ DMError DestroyVirtualScreen(ScreenId screenId) override; + std::shared_ptr GetDispalySnapshot(DisplayId displayId) override; + + void RegisterDisplayManagerAgent(const sptr& displayManagerAgent, +@@ -47,6 +50,7 @@ public: + bool SetDisplayState(DisplayState state) override; + DisplayState GetDisplayState(uint64_t displayId) override; + void NotifyDisplayEvent(DisplayEvent event) override; ++ void AddMirror(ScreenId mainScreenId, ScreenId mirrorScreenId) override; + + private: + static inline BrokerDelegator delegator_; +diff --git a/dmserver/include/display_manager_service.h b/dmserver/include/display_manager_service.h +index 1ea7380..7b67606 100644 +--- a/dmserver/include/display_manager_service.h ++++ b/dmserver/include/display_manager_service.h +@@ -22,6 +22,8 @@ + #include + #include + ++#include "dm_common.h" ++#include "screen.h" + #include "abstract_display.h" + #include "abstract_display_controller.h" + #include "abstract_screen_controller.h" +@@ -50,9 +52,8 @@ WM_DECLARE_SINGLE_INSTANCE_BASE(DisplayManagerService); + public: + void OnStart() override; + void OnStop() override; +- DisplayId CreateVirtualDisplay(const VirtualDisplayInfo &virtualDisplayInfo, +- sptr surface) override; +- bool DestroyVirtualDisplay(DisplayId displayId) override; ++ ScreenId CreateVirtualScreen(VirtualScreenOption option) override; ++ DMError DestroyVirtualScreen(ScreenId screenId) override; + + DisplayId GetDefaultDisplayId() override; + DisplayInfo GetDisplayInfoById(DisplayId displayId) override; +@@ -71,8 +72,9 @@ public: + DisplayState GetDisplayState(uint64_t displayId) override; + void NotifyDisplayEvent(DisplayEvent event) override; + bool NotifyDisplayPowerEvent(DisplayPowerEvent event, EventStatus status); +- + sptr GetAbstractScreenController(); ++ void AddMirror(ScreenId mainScreenId, ScreenId mirrorScreenId) override; ++ + + private: + DisplayManagerService(); +@@ -101,6 +103,7 @@ private: + std::map> > displayManagerAgentMap_; + sptr dmAgentDeath_ = new DMAgentDeathRecipient( + std::bind(&DisplayManagerService::RemoveDisplayManagerAgent, this, std::placeholders::_1)); ++ std::map> displayNodeMap_; + }; + } // namespace OHOS::Rosen + +diff --git a/dmserver/src/abstract_display_controller.cpp b/dmserver/src/abstract_display_controller.cpp +index 0304b9e..96fd031 100644 +--- a/dmserver/src/abstract_display_controller.cpp ++++ b/dmserver/src/abstract_display_controller.cpp +@@ -70,26 +70,25 @@ RSScreenModeInfo AbstractDisplayController::GetScreenActiveMode(ScreenId id) + return rsInterface_->GetScreenActiveMode(id); + } + +-ScreenId AbstractDisplayController::CreateVirtualScreen(const VirtualDisplayInfo &virtualDisplayInfo, +- sptr surface) ++ScreenId AbstractDisplayController::CreateVirtualScreen(VirtualScreenOption option) + { + if (rsInterface_ == nullptr) { + return SCREEN_ID_INVALID; + } +- ScreenId result = rsInterface_->CreateVirtualScreen(virtualDisplayInfo.name_, virtualDisplayInfo.width_, +- virtualDisplayInfo.height_, surface, virtualDisplayInfo.displayIdToMirror_, virtualDisplayInfo.flags_); +- WLOGFI("AbstractDisplayController::CreateVirtualDisplay id: %{public}" PRIu64"", result); ++ ScreenId result = rsInterface_->CreateVirtualScreen(option.name_, option.width_, ++ option.height_, option.surface_, INVALID_SCREEN_ID, option.flags_); ++ WLOGFI("AbstractDisplayController::CreateVirtualScreen id: %{public}" PRIu64"", result); + return result; + } + +-bool AbstractDisplayController::DestroyVirtualScreen(ScreenId screenId) ++DMError AbstractDisplayController::DestroyVirtualScreen(ScreenId screenId) + { + if (rsInterface_ == nullptr) { +- return false; ++ return DMError::DM_ERROR_NULLPTR; + } + WLOGFI("AbstractDisplayController::DestroyVirtualScreen"); + rsInterface_->RemoveVirtualScreen(screenId); +- return true; ++ return DMError::DM_OK; + } + + std::shared_ptr AbstractDisplayController::GetScreenSnapshot(DisplayId displayId, ScreenId screenId) +diff --git a/dmserver/src/display_manager_proxy.cpp b/dmserver/src/display_manager_proxy.cpp +index c69c99c..0059f71 100644 +--- a/dmserver/src/display_manager_proxy.cpp ++++ b/dmserver/src/display_manager_proxy.cpp +@@ -81,58 +81,63 @@ DisplayInfo DisplayManagerProxy::GetDisplayInfoById(DisplayId displayId) + return *info; + } + +-DisplayId DisplayManagerProxy::CreateVirtualDisplay(const VirtualDisplayInfo &virtualDisplayInfo, +- sptr surface) ++ScreenId DisplayManagerProxy::CreateVirtualScreen(VirtualScreenOption virtualOption) + { + sptr remote = Remote(); + if (remote == nullptr) { +- WLOGFW("create virtual display: remote is nullptr"); +- return DISPLAY_ID_INVALD; ++ WLOGFW("DisplayManagerProxy::CreateVirtualScreen: remote is nullptr"); ++ return SCREEN_ID_INVALD; + } + + MessageParcel data; + MessageParcel reply; + MessageOption option; + if (!data.WriteInterfaceToken(GetDescriptor())) { +- WLOGFE("create virtual display: WriteInterfaceToken failed"); +- return DISPLAY_ID_INVALD; +- } +- bool res = data.WriteParcelable(&virtualDisplayInfo) && +- data.WriteRemoteObject(surface->GetProducer()->AsObject()); ++ WLOGFE("DisplayManagerProxy::CreateVirtualScreen: WriteInterfaceToken failed"); ++ return SCREEN_ID_INVALD; ++ } ++ WLOGFI("DisplayManagerProxy::CreateVirtualScreen: name %{public}s, width %{public}u, height %{public}u, mirrotId %{public}f, flags %{public}d", ++ virtualOption.name_.c_str(), virtualOption.width_, virtualOption.height_, ++ virtualOption.density_, virtualOption.flags_); ++ bool res = data.WriteString(virtualOption.name_) && data.WriteUint32(virtualOption.width_) && ++ data.WriteUint32(virtualOption.height_) && data.WriteFloat(virtualOption.density_) && ++ data.WriteRemoteObject(virtualOption.surface_->GetProducer()->AsObject()) && ++ data.WriteInt32(virtualOption.flags_); + if (!res) { +- return DISPLAY_ID_INVALD; ++ WLOGFE("DisplayManagerProxy::Write data failed"); ++ return SCREEN_ID_INVALD; + } +- if (remote->SendRequest(TRANS_ID_CREATE_VIRTUAL_DISPLAY, data, reply, option) != ERR_NONE) { +- WLOGFW("create virtual display: SendRequest failed"); +- return DISPLAY_ID_INVALD; ++ if (remote->SendRequest(TRANS_ID_CREATE_VIRTUAL_SCREEN, data, reply, option) != ERR_NONE) { ++ WLOGFW("DisplayManagerProxy::CreateVirtualScreen: SendRequest failed"); ++ return SCREEN_ID_INVALD; + } + +- DisplayId displayId = reply.ReadUint64(); +- WLOGFI("DisplayManagerProxy::CreateVirtualDisplay %" PRIu64"", displayId); +- return displayId; ++ ScreenId screenId = static_cast(reply.ReadUint64()); ++ WLOGFI("DisplayManagerProxy::CreateVirtualScreen %" PRIu64"", screenId); ++ return screenId; + } + +-bool DisplayManagerProxy::DestroyVirtualDisplay(DisplayId displayId) ++DMError DisplayManagerProxy::DestroyVirtualScreen(ScreenId screenId) + { + sptr remote = Remote(); + if (remote == nullptr) { +- WLOGFW("destroy virtual display: remote is nullptr"); +- return false; ++ WLOGFW("DisplayManagerProxy::DestroyVirtualScreen: remote is nullptr"); ++ return DMError::DM_ERROR_REMOTE_CREATE_FAILED; + } + + MessageParcel data; + MessageParcel reply; + MessageOption option; + if (!data.WriteInterfaceToken(GetDescriptor())) { +- WLOGFE("destroy virtual display: WriteInterfaceToken failed"); +- return false; ++ WLOGFE("DisplayManagerProxy::DestroyVirtualScreen: WriteInterfaceToken failed"); ++ return DMError::DM_ERROR_WRITE_INTERFACE_TOKEN_FAILED; + } +- data.WriteUint64(static_cast(displayId)); +- if (remote->SendRequest(TRANS_ID_DESTROY_VIRTUAL_DISPLAY, data, reply, option) != ERR_NONE) { +- WLOGFW("destroy virtual display: SendRequest failed"); +- return false; ++ data.WriteUint64(static_cast(screenId)); ++ if (remote->SendRequest(TRANS_ID_DESTROY_VIRTUAL_SCREEN, data, reply, option) != ERR_NONE) { ++ WLOGFW("DisplayManagerProxy::DestroyVirtualScreen: SendRequest failed"); ++ return DMError::DM_ERROR_IPC_FAILED; + } +- return reply.ReadBool(); ++ return static_cast(reply.ReadInt32()); + } + + std::shared_ptr DisplayManagerProxy::GetDispalySnapshot(DisplayId displayId) +@@ -375,4 +380,30 @@ void DisplayManagerProxy::NotifyDisplayEvent(DisplayEvent event) + return; + } + } ++ ++void DisplayManagerProxy::AddMirror(ScreenId mainScreenId, ScreenId mirrorScreenId) ++{ ++ sptr remote = Remote(); ++ if (remote == nullptr) { ++ WLOGFW("DisplayManagerProxy::AddMirror: remote is nullptr"); ++ } ++ ++ MessageParcel data; ++ MessageParcel reply; ++ MessageOption option; ++ if (!data.WriteInterfaceToken(GetDescriptor())) { ++ WLOGFE("DisplayManagerProxy::AddMirror: WriteInterfaceToken failed"); ++ } ++ bool res = data.WriteUint64(static_cast(mainScreenId)) && ++ data.WriteUint64(static_cast(mirrorScreenId)); ++ if (!res) { ++ WLOGFE("DisplayManagerProxy::AddMirror: data write failed"); ++ } ++ if (remote->SendRequest(TRANS_ID_ADD_MIRROR, data, reply, option) != ERR_NONE) { ++ WLOGFW("DisplayManagerProxy::AddMirror: SendRequest failed"); ++ } ++ ++ // ScreenId screenId = reply.ReadUint64(); ++ WLOGFI("DisplayManagerProxy::AddMirror"); ++} + } // namespace OHOS::Rosen +\ No newline at end of file +diff --git a/dmserver/src/display_manager_service.cpp b/dmserver/src/display_manager_service.cpp +index f9a609c..2be676d 100644 +--- a/dmserver/src/display_manager_service.cpp ++++ b/dmserver/src/display_manager_service.cpp +@@ -14,6 +14,7 @@ + */ + + #include "display_manager_service.h" ++#include "window_manager_service.h" + + #include + #include +@@ -24,6 +25,8 @@ + + #include "window_manager_hilog.h" + ++#include "transaction/rs_interfaces.h" ++ + namespace OHOS::Rosen { + namespace { + constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, 0, "DisplayManagerService"}; +@@ -88,21 +91,31 @@ DisplayInfo DisplayManagerService::GetDisplayInfoById(DisplayId displayId) + return displayInfo; + } + +-DisplayId DisplayManagerService::CreateVirtualDisplay(const VirtualDisplayInfo &virtualDisplayInfo, +- sptr surface) ++ScreenId DisplayManagerService::CreateVirtualScreen(VirtualScreenOption option) + { +- WLOGFI("name %{public}s, width %{public}u, height %{public}u, mirrotId %{public}" PRIu64", flags %{public}d", +- virtualDisplayInfo.name_.c_str(), virtualDisplayInfo.width_, virtualDisplayInfo.height_, +- virtualDisplayInfo.displayIdToMirror_, virtualDisplayInfo.flags_); +- ScreenId screenId = abstractDisplayController_->CreateVirtualScreen(virtualDisplayInfo, surface); +- return GetDisplayIdFromScreenId(screenId); ++ ScreenId screenId = abstractDisplayController_->CreateVirtualScreen(option); ++ if (screenId == SCREEN_ID_INVALD) { ++ WLOGFE("DisplayManagerService::CreateVirtualScreen: Get virtualScreenId failed"); ++ return SCREEN_ID_INVALD; ++ } ++ return screenId; + } + +-bool DisplayManagerService::DestroyVirtualDisplay(DisplayId displayId) ++DMError DisplayManagerService::DestroyVirtualScreen(ScreenId screenId) + { +- WLOGFI("DisplayManagerService::DestroyVirtualDisplay"); +- ScreenId screenId = GetScreenIdFromDisplayId(displayId); ++ WLOGFI("DisplayManagerService::DestroyVirtualScreen"); ++ if (screenId == DISPLAY_ID_INVALD) { ++ WLOGFE("DisplayManagerService: virtualScreenId is invalid"); ++ return DMError::DM_ERROR_INVALID_PARAM; ++ } ++ if (displayNodeMap_[screenId] == nullptr) { ++ WLOGFE("DisplayManagerService: Mirror mode failed, displayNodeId is nullptr"); ++ return abstractDisplayController_->DestroyVirtualScreen(screenId); ++ } ++ displayNodeMap_[screenId]->RemoveFromTree(); ++ displayNodeMap_.erase(screenId); + return abstractDisplayController_->DestroyVirtualScreen(screenId); ++ + } + + std::shared_ptr DisplayManagerService::GetDispalySnapshot(DisplayId displayId) +@@ -259,4 +272,24 @@ void DMAgentDeathRecipient::OnRemoteDied(const wptr& wptrDeath) + WLOGFI("call OnRemoteDied callback"); + callback_(object); + } ++ ++void DisplayManagerService::AddMirror(ScreenId mainScreenId, ScreenId mirrorScreenId) ++{ ++ if (mainScreenId != DISPLAY_ID_INVALD) { ++ std::shared_ptr displayNode = ++ SingletonContainer::Get().GetDisplayNode(mainScreenId); ++ if (displayNode == nullptr) { ++ WLOGFE("DisplayManagerService::AddMirror: GetDisplayNode failed, displayNode is nullptr"); ++ } ++ NodeId nodeId = displayNode->GetId(); ++ ++ struct RSDisplayNodeConfig config = {mirrorScreenId, true, nodeId}; ++ WLOGFI("DisplayManagerService::AddMirror: mainScreenId: %{public}" PRIu64 ", mirrorScreenId: %{public}" PRIu64 "", mainScreenId, mirrorScreenId); ++ displayNodeMap_[mainScreenId] = RSDisplayNode::Create(config); ++ auto transactionProxy = RSTransactionProxy::GetInstance(); ++ transactionProxy->FlushImplicitTransaction(); ++ WLOGFI("DisplayManagerService::AddMirror: NodeId: %{public}" PRIu64 "", nodeId >> 32); ++ ++ } ++} + } // namespace OHOS::Rosen +\ No newline at end of file +diff --git a/dmserver/src/display_manager_stub.cpp b/dmserver/src/display_manager_stub.cpp +index b0232b6..dfee7c1 100644 +--- a/dmserver/src/display_manager_stub.cpp ++++ b/dmserver/src/display_manager_stub.cpp +@@ -15,6 +15,8 @@ + + #include "display_manager_stub.h" + ++#include "dm_common.h" ++ + #include + + #include "window_manager_hilog.h" +@@ -46,20 +48,34 @@ int32_t DisplayManagerStub::OnRemoteRequest(uint32_t code, MessageParcel &data, + reply.WriteParcelable(&info); + break; + } +- case TRANS_ID_CREATE_VIRTUAL_DISPLAY: { +- VirtualDisplayInfo* virtualDisplayInfo = data.ReadParcelable(); ++ case TRANS_ID_CREATE_VIRTUAL_SCREEN: { ++ std::string name = data.ReadString(); ++ uint32_t width = data.ReadUint32(); ++ uint32_t height = data.ReadUint32(); ++ float density = data.ReadFloat(); + sptr surfaceObject = data.ReadRemoteObject(); + sptr bp = iface_cast(surfaceObject); + sptr surface = Surface::CreateSurfaceAsProducer(bp); +- DisplayId virtualId = CreateVirtualDisplay(*virtualDisplayInfo, surface); +- reply.WriteUint64(virtualId); +- virtualDisplayInfo = nullptr; ++ int32_t flags = data.ReadInt32(); ++ VirtualScreenOption option = { ++ .name_ = name, ++ .width_ = width, ++ .height_ = height, ++ .density_ = density, ++ .surface_ = surface, ++ .flags_ = flags ++ }; ++ WLOGFI("DisplayManagerStub::OnRemoteRequest: name %{public}s, width %{public}u, height %{public}u, density %{public}f, flags %{public}d", ++ option.name_.c_str(), option.width_, option.height_, ++ option.density_, option.flags_); ++ ScreenId screenId = CreateVirtualScreen(option); ++ reply.WriteUint64(static_cast(screenId)); + break; + } +- case TRANS_ID_DESTROY_VIRTUAL_DISPLAY: { +- DisplayId virtualId = static_cast(data.ReadUint64()); +- bool result = DestroyVirtualDisplay(virtualId); +- reply.WriteBool(result); ++ case TRANS_ID_DESTROY_VIRTUAL_SCREEN: { ++ ScreenId screenId = static_cast(data.ReadUint64()); ++ DMError result = DestroyVirtualScreen(screenId); ++ reply.WriteInt32(static_cast(result)); + break; + } + case TRANS_ID_GET_DISPLAY_SNAPSHOT: { +@@ -122,6 +138,12 @@ int32_t DisplayManagerStub::OnRemoteRequest(uint32_t code, MessageParcel &data, + NotifyDisplayEvent(event); + break; + } ++ case TRANS_ID_ADD_MIRROR: { ++ ScreenId mainScreenId = static_cast(data.ReadUint64()); ++ ScreenId mirrorScreenId = static_cast(data.ReadUint64()); ++ AddMirror(mainScreenId, mirrorScreenId); ++ 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 80f1c1f..6fae0ec 100644 +--- a/interfaces/innerkits/dm/display_manager.h ++++ b/interfaces/innerkits/dm/display_manager.h +@@ -44,10 +44,6 @@ public: + + std::vector GetAllDisplayIds(); + +- DisplayId CreateVirtualDisplay(const std::string &name, uint32_t width, uint32_t height, +- sptr surface, DisplayId displayIdToMirror, int32_t flags); +- +- bool DestroyVirtualDisplay(DisplayId displayId); + std::shared_ptr GetScreenshot(DisplayId displayId); + std::shared_ptr GetScreenshot(DisplayId displayId, const Media::Rect &rect, + const Media::Size &size, int rotation); +diff --git a/interfaces/innerkits/dm/dm_common.h b/interfaces/innerkits/dm/dm_common.h +index 4bd1624..2e049de 100644 +--- a/interfaces/innerkits/dm/dm_common.h ++++ b/interfaces/innerkits/dm/dm_common.h +@@ -43,6 +43,19 @@ enum class DisplayState : uint32_t { + enum class DisplayEvent : uint32_t { + UNLOCK + }; ++ ++enum class DMError : int32_t { ++ DM_OK = 0, ++ DM_ERROR_INIT_DMS_PROXY_LOCKED = 100, ++ DM_ERROR_IPC_FAILED = 101, ++ DM_ERROR_REMOTE_CREATE_FAILED = 110, ++ DM_ERROR_NULLPTR = 120, ++ DM_ERROR_INVALID_PARAM = 130, ++ DM_ERROR_WRITE_INTERFACE_TOKEN_FAILED = 140, ++ DM_ERROR_DEATH_RECIPIENT = 150, ++ DM_ERROR_INVALID_MODE_ID = 160, ++ DM_ERROR_UNKNOWN, ++}; + using DisplayStateCallback = std::function; + + enum class DisplayPowerEvent : uint32_t { +diff --git a/interfaces/innerkits/dm/screen.h b/interfaces/innerkits/dm/screen.h +index ae22213..cc902bd 100644 +--- a/interfaces/innerkits/dm/screen.h ++++ b/interfaces/innerkits/dm/screen.h +@@ -31,7 +31,7 @@ struct Point { + }; + + struct VirtualScreenOption { +- const std::string& name_; ++ const std::string name_; + uint32_t width_; + uint32_t height_; + float density_; +diff --git a/interfaces/innerkits/dm/screen_manager.h b/interfaces/innerkits/dm/screen_manager.h +index 7900ef8..3310d2f 100644 +--- a/interfaces/innerkits/dm/screen_manager.h ++++ b/interfaces/innerkits/dm/screen_manager.h +@@ -18,8 +18,10 @@ + + #include + #include "screen.h" ++#include "dm_common.h" + #include "screen_group.h" + #include "wm_single_instance.h" ++#include "wm_single_instance.h" + + namespace OHOS::Rosen { + class IScreenChangeListener : public RefBase { +@@ -34,10 +36,13 @@ WM_DECLARE_SINGLE_INSTANCE_BASE(ScreenManager); + public: + sptr GetScreenById(ScreenId id); + std::vector> GetAllScreens(); ++ + void RegisterScreenChangeListener(sptr listener); +- sptr makeExpand(std::vector screenId, std::vector startPoint); +- sptr makeMirror(ScreenId mainScreenId, std::vector mirrorScreenId); +- sptr createVirtualScreen(VirtualScreenOption option); ++ sptr MakeExpand(std::vector screenId, std::vector startPoint); ++ sptr MakeMirror(ScreenId mainScreenId, std::vector mirrorScreenId); ++ sptr AddMirror(ScreenId mainScreenId, ScreenId mirrorScreenId); ++ ScreenId CreateVirtualScreen(VirtualScreenOption option); ++ DMError DestroyVirtualScreen(ScreenId screenId); + + private: + ScreenManager(); +diff --git a/wmserver/include/window_layout_policy.h b/wmserver/include/window_layout_policy.h +index a9dc89d..3c31635 100644 +--- a/wmserver/include/window_layout_policy.h ++++ b/wmserver/include/window_layout_policy.h +@@ -59,11 +59,13 @@ private: + sptr belowAppWindowNode_ = new WindowNode(); + sptr appWindowNode_ = new WindowNode(); + sptr aboveAppWindowNode_ = new WindowNode(); ++ + const std::set avoidTypes_ { + WindowType::WINDOW_TYPE_STATUS_BAR, + WindowType::WINDOW_TYPE_NAVIGATION_BAR, + }; + void UpdateLimitRect(const sptr& node, Rect& limitRect); ++ + void LayoutWindowTree(); + void LayoutWindowNode(sptr& node); + AvoidPosType GetAvoidPosType(const Rect& rect); +diff --git a/wmserver/include/window_manager_service.h b/wmserver/include/window_manager_service.h +index dce096d..07f39ff 100644 +--- a/wmserver/include/window_manager_service.h ++++ b/wmserver/include/window_manager_service.h +@@ -54,7 +54,6 @@ public: + WMError SetWindowFlags(uint32_t windowId, uint32_t flags) override; + WMError SetSystemBarProperty(uint32_t windowId, WindowType type, const SystemBarProperty& prop) override; + +- std::shared_ptr GetDisplayNode(int32_t displayId) const; + void RegisterWindowManagerAgent(WindowManagerAgentType type, + const sptr& windowManagerAgent) override; + void UnregisterWindowManagerAgent(WindowManagerAgentType type, +@@ -63,6 +62,7 @@ public: + // Inner interfaces + WMError NotifyDisplaySuspend(); + void RestoreSuspendedWindows(); ++ std::shared_ptr GetDisplayNode(int32_t displayId) const; + + protected: + WindowManagerService(); +diff --git a/wmserver/include/window_node_container.h b/wmserver/include/window_node_container.h +index 47a2061..bb2ecdf 100644 +--- a/wmserver/include/window_node_container.h ++++ b/wmserver/include/window_node_container.h +@@ -52,6 +52,7 @@ public: + sptr GetTopImmersiveNode() const; + void NotifySystemBarIfChanged(); + std::shared_ptr GetDisplayNode() const; ++ + void LayoutDividerWindow(sptr& node); + void UpdateDisplayInfo(); + +diff --git a/wmserver/src/window_layout_policy.cpp b/wmserver/src/window_layout_policy.cpp +index 92fe42c..8a79a31 100644 +--- a/wmserver/src/window_layout_policy.cpp ++++ b/wmserver/src/window_layout_policy.cpp +@@ -245,6 +245,7 @@ void WindowLayoutPolicy::UpdateLimitRect(const sptr& node, Rect& lim + } + WLOGFI("Type: %{public}d, limitRect: %{public}d %{public}d %{public}d %{public}d", + node->GetWindowType(), limitRect.posX_, limitRect.posY_, limitRect.width_, limitRect.height_); ++ + } + } + } +diff --git a/wmserver/src/window_manager_service.cpp b/wmserver/src/window_manager_service.cpp +index ef1cdb5..7381737 100644 +--- a/wmserver/src/window_manager_service.cpp ++++ b/wmserver/src/window_manager_service.cpp +@@ -231,11 +231,6 @@ void WindowManagerService::UnregisterWindowManagerAgent(WindowManagerAgentType t + windowController_->UnregisterWindowManagerAgent(type, windowManagerAgent); + } + +-std::shared_ptr WindowManagerService::GetDisplayNode(int32_t displayId) const +-{ +- return windowRoot_->GetOrCreateWindowNodeContainer(displayId)->GetDisplayNode(); +-} +- + void WindowManagerService::OnWindowEvent(Event event, uint32_t windowId) + { + switch (event) { +@@ -261,5 +256,10 @@ void WindowManagerService::RestoreSuspendedWindows() + std::lock_guard lock(mutex_); + // TODO: restore windows covered by keyguard + } ++ ++std::shared_ptr WindowManagerService::GetDisplayNode(int32_t displayId) const ++{ ++ return windowRoot_->GetOrCreateWindowNodeContainer(displayId)->GetDisplayNode(); ++} + } + } +\ No newline at end of file +-- +2.25.1 + diff --git a/dm/include/display_manager_adapter.h b/dm/include/display_manager_adapter.h index 666f0ac0d2..597472d050 100644 --- a/dm/include/display_manager_adapter.h +++ b/dm/include/display_manager_adapter.h @@ -20,6 +20,8 @@ #include #include "display.h" +#include "screen.h" +#include "dm_common.h" #include "display_manager_interface.h" #include "singleton_delegator.h" @@ -34,9 +36,9 @@ WM_DECLARE_SINGLE_INSTANCE_BASE(DisplayManagerAdapter); public: DisplayId GetDefaultDisplayId(); sptr GetDisplayById(DisplayId displayId); - DisplayId CreateVirtualDisplay(const VirtualDisplayInfo &virtualDisplayInfo, - sptr surface); - bool DestroyVirtualDisplay(DisplayId displayId); + + ScreenId CreateVirtualScreen(VirtualScreenOption option); + DMError DestroyVirtualScreen(ScreenId screenId); std::shared_ptr GetDisplaySnapshot(DisplayId displayId); void RegisterDisplayManagerAgent(const sptr& displayManagerAgent, @@ -51,7 +53,7 @@ public: bool SetDisplayState(DisplayState state, DisplayStateCallback callback); DisplayState GetDisplayState(uint64_t displayId); void NotifyDisplayEvent(DisplayEvent event); - + void AddMirror(ScreenId mainScreenId, ScreenId mirrorScreenId); void Clear(); private: diff --git a/dm/src/display_manager.cpp b/dm/src/display_manager.cpp index 43a63319db..faca0d8dcd 100644 --- a/dm/src/display_manager.cpp +++ b/dm/src/display_manager.cpp @@ -154,20 +154,6 @@ std::vector> DisplayManager::GetAllDisplays() return res; } -DisplayId DisplayManager::CreateVirtualDisplay(const std::string &name, uint32_t width, uint32_t height, - sptr surface, DisplayId displayIdToMirror, int32_t flags) -{ - WLOGFI("DisplayManager::CreateVirtualDisplay multi params"); - VirtualDisplayInfo info(name, width, height, displayIdToMirror, flags); - return SingletonContainer::Get().CreateVirtualDisplay(info, surface); -} - -bool DisplayManager::DestroyVirtualDisplay(DisplayId displayId) -{ - WLOGFI("DisplayManager::DestroyVirtualDisplay override params"); - return SingletonContainer::Get().DestroyVirtualDisplay(displayId); -} - void DisplayManager::RegisterDisplayPowerEventListener(sptr listener) { if (listener == nullptr) { diff --git a/dm/src/display_manager_adapter.cpp b/dm/src/display_manager_adapter.cpp index bd804d7b02..138527c8b9 100644 --- a/dm/src/display_manager_adapter.cpp +++ b/dm/src/display_manager_adapter.cpp @@ -78,23 +78,22 @@ std::shared_ptr DisplayManagerAdapter::GetDisplaySnapshot(Displ return dispalySnapshot; } -DisplayId DisplayManagerAdapter::CreateVirtualDisplay(const VirtualDisplayInfo &virtualDisplayInfo, - sptr surface) +ScreenId DisplayManagerAdapter::CreateVirtualScreen(VirtualScreenOption option) { if (!InitDMSProxyLocked()) { - return DISPLAY_ID_INVALD; + return SCREEN_ID_INVALD; } - WLOGFI("DisplayManagerAdapter::CreateVirtualDisplay"); - return displayManagerServiceProxy_->CreateVirtualDisplay(virtualDisplayInfo, surface); + WLOGFI("DisplayManagerAdapter::CreateVirtualScreen"); + return displayManagerServiceProxy_->CreateVirtualScreen(option); } -bool DisplayManagerAdapter::DestroyVirtualDisplay(DisplayId displayId) +DMError DisplayManagerAdapter::DestroyVirtualScreen(ScreenId screenId) { if (!InitDMSProxyLocked()) { - return false; + return DMError::DM_ERROR_INIT_DMS_PROXY_LOCKED; } - WLOGFI("DisplayManagerAdapter::DestroyVirtualDisplay"); - return displayManagerServiceProxy_->DestroyVirtualDisplay(displayId); + WLOGFI("DisplayManagerAdapter::DestroyVirtualScreen"); + return displayManagerServiceProxy_->DestroyVirtualScreen(screenId); } void DisplayManagerAdapter::RegisterDisplayManagerAgent(const sptr& displayManagerAgent, @@ -265,4 +264,13 @@ void DisplayManagerAdapter::Clear() } displayManagerServiceProxy_ = nullptr; } + +void DisplayManagerAdapter::AddMirror(ScreenId mainScreenId, ScreenId mirrorScreenId) +{ + if (!InitDMSProxyLocked()) { + WLOGFE("DisplayManagerAdapter::AddMirror: InitDMSProxyLocked failed"); + } + WLOGFI("DisplayManagerAdapter::AddMirror"); + displayManagerServiceProxy_->AddMirror(mainScreenId, mirrorScreenId); +} } // namespace OHOS::Rosen \ No newline at end of file diff --git a/dm/src/screen_manager.cpp b/dm/src/screen_manager.cpp index d13344a945..f31c39ec57 100644 --- a/dm/src/screen_manager.cpp +++ b/dm/src/screen_manager.cpp @@ -14,11 +14,17 @@ */ #include "screen_manager.h" +#include "window_manager_hilog.h" +#include "display_manager_adapter.h" + #include #include namespace OHOS::Rosen { +namespace { + constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, 0, "ScreenManager"}; +} class ScreenManager::Impl : public RefBase { friend class ScreenManager; private: @@ -53,18 +59,32 @@ void ScreenManager::RegisterScreenChangeListener(sptr lis { } -sptr ScreenManager::makeExpand(std::vector screenId, std::vector startPoint) +sptr ScreenManager::MakeExpand(std::vector screenId, std::vector startPoint) { return nullptr; } -sptr ScreenManager::makeMirror(ScreenId mainScreenId, std::vector mirrorScreenId) +sptr ScreenManager::MakeMirror(ScreenId mainScreenId, std::vector mirrorScreenId) { return nullptr; } -sptr ScreenManager::createVirtualScreen(VirtualScreenOption option) +sptr ScreenManager::AddMirror(ScreenId mainScreenId, ScreenId mirrorScreenId) { + WLOGFI("ScreenManager::AddMirror"); + SingletonContainer::Get().AddMirror(mainScreenId, mirrorScreenId); return nullptr; } + +ScreenId ScreenManager::CreateVirtualScreen(VirtualScreenOption option) +{ + WLOGFI("ScreenManager::CreateVirtualScreen"); + return SingletonContainer::Get().CreateVirtualScreen(option); +} + +DMError ScreenManager::DestroyVirtualScreen(ScreenId screenId) +{ + WLOGFI("ScreenManager::DestroyVirtualScreen"); + return SingletonContainer::Get().DestroyVirtualScreen(screenId); +} } // namespace OHOS::Rosen \ No newline at end of file diff --git a/dmserver/include/abstract_display_controller.h b/dmserver/include/abstract_display_controller.h index 3d588e7210..d94be0752f 100644 --- a/dmserver/include/abstract_display_controller.h +++ b/dmserver/include/abstract_display_controller.h @@ -21,6 +21,8 @@ #include #include +#include "screen.h" +#include "dm_common.h" #include "abstract_display.h" #include "abstract_screen_controller.h" #include "transaction/rs_interfaces.h" @@ -35,8 +37,9 @@ public: void Init(sptr abstractScreenController); ScreenId GetDefaultScreenId(); RSScreenModeInfo GetScreenActiveMode(ScreenId id); - ScreenId CreateVirtualScreen(const VirtualDisplayInfo &virtualDisplayInfo, sptr surface); - bool DestroyVirtualScreen(ScreenId screenId); + + ScreenId CreateVirtualScreen(VirtualScreenOption option); + DMError DestroyVirtualScreen(ScreenId screenId); std::shared_ptr GetScreenSnapshot(DisplayId displayId, ScreenId screenId); private: diff --git a/dmserver/include/abstract_screen.h b/dmserver/include/abstract_screen.h index 9b9a0c3e60..517ccbb947 100644 --- a/dmserver/include/abstract_screen.h +++ b/dmserver/include/abstract_screen.h @@ -16,19 +16,16 @@ #ifndef FOUNDATION_DMSERVER_ABSTRACT_SCREEN_H #define FOUNDATION_DMSERVER_ABSTRACT_SCREEN_H -#include +#include #include #include +#include "screen.h" + namespace OHOS::Rosen { constexpr static ScreenId SCREEN_ID_INVALID = INVALID_SCREEN_ID; -struct Point { - int32_t posX_; - int32_t posY_; -}; - enum class ScreenCombination : uint32_t { SCREEN_ALONE, SCREEN_EXPAND, diff --git a/dmserver/include/display_manager_interface.h b/dmserver/include/display_manager_interface.h index 6834d9c2e9..dae7bfcdb1 100644 --- a/dmserver/include/display_manager_interface.h +++ b/dmserver/include/display_manager_interface.h @@ -21,6 +21,7 @@ #include #include "dm_common.h" +#include "screen.h" #include "display_info.h" #include "virtual_display_info.h" #include "zidl/display_manager_agent_interface.h" @@ -33,8 +34,8 @@ public: enum { TRANS_ID_GET_DEFAULT_DISPLAY_ID = 0, TRANS_ID_GET_DISPLAY_BY_ID, - TRANS_ID_CREATE_VIRTUAL_DISPLAY, - TRANS_ID_DESTROY_VIRTUAL_DISPLAY, + TRANS_ID_CREATE_VIRTUAL_SCREEN, + TRANS_ID_DESTROY_VIRTUAL_SCREEN, TRANS_ID_GET_DISPLAY_SNAPSHOT, TRANS_ID_REGISTER_DISPLAY_MANAGER_AGENT, TRANS_ID_UNREGISTER_DISPLAY_MANAGER_AGENT, @@ -46,14 +47,14 @@ public: TRANS_ID_SET_DISPLAY_STATE, TRANS_ID_GET_DISPLAY_STATE, TRANS_ID_NOTIFY_DISPLAY_EVENT, + TRANS_ID_ADD_MIRROR }; virtual DisplayId GetDefaultDisplayId() = 0; virtual DisplayInfo GetDisplayInfoById(DisplayId displayId) = 0; - virtual DisplayId CreateVirtualDisplay(const VirtualDisplayInfo &virtualDisplayInfo, - sptr surface) = 0; - virtual bool DestroyVirtualDisplay(DisplayId displayId) = 0; + virtual ScreenId CreateVirtualScreen(VirtualScreenOption option) = 0; + virtual DMError DestroyVirtualScreen(ScreenId screenId) = 0; virtual std::shared_ptr GetDispalySnapshot(DisplayId displayId) = 0; virtual void RegisterDisplayManagerAgent(const sptr& displayManagerAgent, @@ -68,6 +69,7 @@ public: virtual bool SetDisplayState(DisplayState state) = 0; virtual DisplayState GetDisplayState(uint64_t displayId) = 0; virtual void NotifyDisplayEvent(DisplayEvent event) = 0; + virtual void AddMirror(ScreenId mainScreenId, ScreenId mirrorScreenId) = 0; }; } // namespace OHOS::Rosen diff --git a/dmserver/include/display_manager_proxy.h b/dmserver/include/display_manager_proxy.h index cc4fa0c8ce..631dec2592 100644 --- a/dmserver/include/display_manager_proxy.h +++ b/dmserver/include/display_manager_proxy.h @@ -18,6 +18,10 @@ #include "display_manager_interface.h" +#include "dm_common.h" + +#include "screen.h" + #include namespace OHOS::Rosen { @@ -30,9 +34,8 @@ public: DisplayId GetDefaultDisplayId() override; DisplayInfo GetDisplayInfoById(DisplayId displayId) override; - DisplayId CreateVirtualDisplay(const VirtualDisplayInfo &virtualDisplayInfo, - sptr surface) override; - bool DestroyVirtualDisplay(DisplayId displayId) override; + ScreenId CreateVirtualScreen(VirtualScreenOption option) override; + DMError DestroyVirtualScreen(ScreenId screenId) override; std::shared_ptr GetDispalySnapshot(DisplayId displayId) override; void RegisterDisplayManagerAgent(const sptr& displayManagerAgent, @@ -47,6 +50,7 @@ public: bool SetDisplayState(DisplayState state) override; DisplayState GetDisplayState(uint64_t displayId) override; void NotifyDisplayEvent(DisplayEvent event) override; + void AddMirror(ScreenId mainScreenId, ScreenId mirrorScreenId) override; private: static inline BrokerDelegator delegator_; diff --git a/dmserver/include/display_manager_service.h b/dmserver/include/display_manager_service.h index 1ea7380dcb..a80e55090b 100644 --- a/dmserver/include/display_manager_service.h +++ b/dmserver/include/display_manager_service.h @@ -22,6 +22,8 @@ #include #include +#include "dm_common.h" +#include "screen.h" #include "abstract_display.h" #include "abstract_display_controller.h" #include "abstract_screen_controller.h" @@ -50,9 +52,8 @@ WM_DECLARE_SINGLE_INSTANCE_BASE(DisplayManagerService); public: void OnStart() override; void OnStop() override; - DisplayId CreateVirtualDisplay(const VirtualDisplayInfo &virtualDisplayInfo, - sptr surface) override; - bool DestroyVirtualDisplay(DisplayId displayId) override; + ScreenId CreateVirtualScreen(VirtualScreenOption option) override; + DMError DestroyVirtualScreen(ScreenId screenId) override; DisplayId GetDefaultDisplayId() override; DisplayInfo GetDisplayInfoById(DisplayId displayId) override; @@ -71,8 +72,8 @@ public: DisplayState GetDisplayState(uint64_t displayId) override; void NotifyDisplayEvent(DisplayEvent event) override; bool NotifyDisplayPowerEvent(DisplayPowerEvent event, EventStatus status); - sptr GetAbstractScreenController(); + void AddMirror(ScreenId mainScreenId, ScreenId mirrorScreenId) override; private: DisplayManagerService(); @@ -101,6 +102,7 @@ private: std::map> > displayManagerAgentMap_; sptr dmAgentDeath_ = new DMAgentDeathRecipient( std::bind(&DisplayManagerService::RemoveDisplayManagerAgent, this, std::placeholders::_1)); + std::map> displayNodeMap_; }; } // namespace OHOS::Rosen diff --git a/dmserver/src/abstract_display_controller.cpp b/dmserver/src/abstract_display_controller.cpp index 0304b9e348..96fd03166c 100644 --- a/dmserver/src/abstract_display_controller.cpp +++ b/dmserver/src/abstract_display_controller.cpp @@ -70,26 +70,25 @@ RSScreenModeInfo AbstractDisplayController::GetScreenActiveMode(ScreenId id) return rsInterface_->GetScreenActiveMode(id); } -ScreenId AbstractDisplayController::CreateVirtualScreen(const VirtualDisplayInfo &virtualDisplayInfo, - sptr surface) +ScreenId AbstractDisplayController::CreateVirtualScreen(VirtualScreenOption option) { if (rsInterface_ == nullptr) { return SCREEN_ID_INVALID; } - ScreenId result = rsInterface_->CreateVirtualScreen(virtualDisplayInfo.name_, virtualDisplayInfo.width_, - virtualDisplayInfo.height_, surface, virtualDisplayInfo.displayIdToMirror_, virtualDisplayInfo.flags_); - WLOGFI("AbstractDisplayController::CreateVirtualDisplay id: %{public}" PRIu64"", result); + ScreenId result = rsInterface_->CreateVirtualScreen(option.name_, option.width_, + option.height_, option.surface_, INVALID_SCREEN_ID, option.flags_); + WLOGFI("AbstractDisplayController::CreateVirtualScreen id: %{public}" PRIu64"", result); return result; } -bool AbstractDisplayController::DestroyVirtualScreen(ScreenId screenId) +DMError AbstractDisplayController::DestroyVirtualScreen(ScreenId screenId) { if (rsInterface_ == nullptr) { - return false; + return DMError::DM_ERROR_NULLPTR; } WLOGFI("AbstractDisplayController::DestroyVirtualScreen"); rsInterface_->RemoveVirtualScreen(screenId); - return true; + return DMError::DM_OK; } std::shared_ptr AbstractDisplayController::GetScreenSnapshot(DisplayId displayId, ScreenId screenId) diff --git a/dmserver/src/abstract_display_manager_fake.cpp b/dmserver/src/abstract_display_manager_fake.cpp new file mode 100644 index 0000000000..06cadffaea --- /dev/null +++ b/dmserver/src/abstract_display_manager_fake.cpp @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2021 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 "abstract_display_manager.h" + +#include "window_manager_hilog.h" + +#include + +namespace OHOS::Rosen { +namespace { + constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, 0, "AbstractDisplayManager"}; +} + +#define SCREENSHOT_GENERATOR + +AbstractDisplayManager::AbstractDisplayManager() : rsInterface_(&(RSInterfaces::GetInstance())) +{ + parepareRSScreenManger(); +} + +AbstractDisplayManager::~AbstractDisplayManager() +{ + rsInterface_ = nullptr; +} + +void AbstractDisplayManager::parepareRSScreenManger() +{ +} + +ScreenId AbstractDisplayManager::GetDefaultScreenId() +{ + if (rsInterface_ == nullptr) { + return INVALID_SCREEN_ID; + } + return rsInterface_->GetDefaultScreenId(); +} + +RSScreenModeInfo AbstractDisplayManager::GetScreenActiveMode(ScreenId id) +{ + RSScreenModeInfo screenModeInfo; + if (rsInterface_ == nullptr) { + return screenModeInfo; + } + return rsInterface_->GetScreenActiveMode(id); +} + +ScreenId AbstractDisplayManager::CreateVirtualScreen(const VirtualDisplayInfo &virtualDisplayInfo, + sptr surface) +{ + if (rsInterface_ == nullptr) { + return INVALID_SCREEN_ID; + } + ScreenId result = rsInterface_->CreateVirtualScreen(virtualDisplayInfo.name_, virtualDisplayInfo.width_, + virtualDisplayInfo.height_, surface, virtualDisplayInfo.displayIdToMirror_, virtualDisplayInfo.flags_); + WLOGFI("AbstractDisplayManager::CreateVirtualDisplay id: %{public}llu", result >> 32); + return result; +} + +bool AbstractDisplayManager::DestroyVirtualScreen(ScreenId screenId) +{ + if (rsInterface_ == nullptr) { + return false; + } + WLOGFI("AbstractDisplayManager::DestroyVirtualScreen"); + rsInterface_->RemoveVirtualScreen(screenId); + return true; +} + +// TODO: fix me +// #ifdef SCREENSHOT_GENERATOR +// sptr TempCreatePixelMap() +// { +// // pixel_map testing code +// Media::InitializationOptions opt; +// opt.size.width = 1920; +// opt.size.height = 1080; +// opt.pixelFormat = Media::PixelFormat::RGBA_8888; +// opt.alphaType = Media::AlphaType::IMAGE_ALPHA_TYPE_OPAQUE; +// opt.scaleMode = Media::ScaleMode::FIT_TARGET_SIZE; +// opt.editable = false; +// opt.useSourceIfMatch = false; + +// const int bitmapDepth = 8; // color depth +// const int bpp = 4; // bytes per pixel +// const int maxByteNum = 256; + +// auto data = (uint32_t *)malloc(opt.size.width * opt.size.height * bpp); +// uint8_t *pic = (uint8_t *)data; +// for (uint32_t i = 0; i < opt.size.width; i++) { +// for (uint32_t j = 0; j < opt.size.height; j++) { +// for (uint32_t k = 0; k < bpp; k++) { +// pic[0] = rand() % maxByteNum; +// pic++; +// } +// } +// } +// uint32_t colorLen = opt.size.width * opt.size.height * bpp * bitmapDepth; +// auto newPixelMap = Media::PixelMap::Create(data, colorLen, opt); +// sptr pixelMap_ = newPixelMap.release(); +// if (pixelMap_ == nullptr) { +// WLOGFE("Failed to get pixelMap"); +// return nullptr; +// } + +// return pixelMap_; +// } +// #endif + +// sptr AbstractDisplayManager::GetScreenSnapshot(ScreenId screenId) +// { +// if (rsInterface_ == nullptr) { +// return nullptr; +// } + +// #ifdef SCREENSHOT_GENERATOR +// sptr screenshot = TempCreatePixelMap(); +// #else +// sptr screenshot = rsInterface_->GetScreenSnapshot(screenId); +// #endif + +// return screenshot; +// } +} // namespace OHOS::Rosen \ No newline at end of file diff --git a/dmserver/src/display_manager_proxy.cpp b/dmserver/src/display_manager_proxy.cpp index c69c99c218..c9aaf43a0c 100644 --- a/dmserver/src/display_manager_proxy.cpp +++ b/dmserver/src/display_manager_proxy.cpp @@ -81,58 +81,60 @@ DisplayInfo DisplayManagerProxy::GetDisplayInfoById(DisplayId displayId) return *info; } -DisplayId DisplayManagerProxy::CreateVirtualDisplay(const VirtualDisplayInfo &virtualDisplayInfo, - sptr surface) +ScreenId DisplayManagerProxy::CreateVirtualScreen(VirtualScreenOption virtualOption) { sptr remote = Remote(); if (remote == nullptr) { - WLOGFW("create virtual display: remote is nullptr"); - return DISPLAY_ID_INVALD; + WLOGFW("DisplayManagerProxy::CreateVirtualScreen: remote is nullptr"); + return SCREEN_ID_INVALD; } MessageParcel data; MessageParcel reply; MessageOption option; if (!data.WriteInterfaceToken(GetDescriptor())) { - WLOGFE("create virtual display: WriteInterfaceToken failed"); - return DISPLAY_ID_INVALD; + WLOGFE("DisplayManagerProxy::CreateVirtualScreen: WriteInterfaceToken failed"); + return SCREEN_ID_INVALD; } - bool res = data.WriteParcelable(&virtualDisplayInfo) && - data.WriteRemoteObject(surface->GetProducer()->AsObject()); + bool res = data.WriteString(virtualOption.name_) && data.WriteUint32(virtualOption.width_) && + data.WriteUint32(virtualOption.height_) && data.WriteFloat(virtualOption.density_) && + data.WriteRemoteObject(virtualOption.surface_->GetProducer()->AsObject()) && + data.WriteInt32(virtualOption.flags_); if (!res) { - return DISPLAY_ID_INVALD; + WLOGFE("DisplayManagerProxy::Write data failed"); + return SCREEN_ID_INVALD; } - if (remote->SendRequest(TRANS_ID_CREATE_VIRTUAL_DISPLAY, data, reply, option) != ERR_NONE) { - WLOGFW("create virtual display: SendRequest failed"); - return DISPLAY_ID_INVALD; + if (remote->SendRequest(TRANS_ID_CREATE_VIRTUAL_SCREEN, data, reply, option) != ERR_NONE) { + WLOGFW("DisplayManagerProxy::CreateVirtualScreen: SendRequest failed"); + return SCREEN_ID_INVALD; } - DisplayId displayId = reply.ReadUint64(); - WLOGFI("DisplayManagerProxy::CreateVirtualDisplay %" PRIu64"", displayId); - return displayId; + ScreenId screenId = static_cast(reply.ReadUint64()); + WLOGFI("DisplayManagerProxy::CreateVirtualScreen %" PRIu64"", screenId); + return screenId; } -bool DisplayManagerProxy::DestroyVirtualDisplay(DisplayId displayId) +DMError DisplayManagerProxy::DestroyVirtualScreen(ScreenId screenId) { sptr remote = Remote(); if (remote == nullptr) { - WLOGFW("destroy virtual display: remote is nullptr"); - return false; + WLOGFW("DisplayManagerProxy::DestroyVirtualScreen: remote is nullptr"); + return DMError::DM_ERROR_REMOTE_CREATE_FAILED; } MessageParcel data; MessageParcel reply; MessageOption option; if (!data.WriteInterfaceToken(GetDescriptor())) { - WLOGFE("destroy virtual display: WriteInterfaceToken failed"); - return false; + WLOGFE("DisplayManagerProxy::DestroyVirtualScreen: WriteInterfaceToken failed"); + return DMError::DM_ERROR_WRITE_INTERFACE_TOKEN_FAILED; } - data.WriteUint64(static_cast(displayId)); - if (remote->SendRequest(TRANS_ID_DESTROY_VIRTUAL_DISPLAY, data, reply, option) != ERR_NONE) { - WLOGFW("destroy virtual display: SendRequest failed"); - return false; + data.WriteUint64(static_cast(screenId)); + if (remote->SendRequest(TRANS_ID_DESTROY_VIRTUAL_SCREEN, data, reply, option) != ERR_NONE) { + WLOGFW("DisplayManagerProxy::DestroyVirtualScreen: SendRequest failed"); + return DMError::DM_ERROR_IPC_FAILED; } - return reply.ReadBool(); + return static_cast(reply.ReadInt32()); } std::shared_ptr DisplayManagerProxy::GetDispalySnapshot(DisplayId displayId) @@ -375,4 +377,28 @@ void DisplayManagerProxy::NotifyDisplayEvent(DisplayEvent event) return; } } + +void DisplayManagerProxy::AddMirror(ScreenId mainScreenId, ScreenId mirrorScreenId) +{ + sptr remote = Remote(); + if (remote == nullptr) { + WLOGFW("DisplayManagerProxy::AddMirror: remote is nullptr"); + } + + MessageParcel data; + MessageParcel reply; + MessageOption option; + if (!data.WriteInterfaceToken(GetDescriptor())) { + WLOGFE("DisplayManagerProxy::AddMirror: WriteInterfaceToken failed"); + } + bool res = data.WriteUint64(static_cast(mainScreenId)) && + data.WriteUint64(static_cast(mirrorScreenId)); + if (!res) { + WLOGFE("DisplayManagerProxy::AddMirror: data write failed"); + } + if (remote->SendRequest(TRANS_ID_ADD_MIRROR, data, reply, option) != ERR_NONE) { + WLOGFW("DisplayManagerProxy::AddMirror: SendRequest failed"); + } + WLOGFI("DisplayManagerProxy::AddMirror"); +} } // namespace OHOS::Rosen \ No newline at end of file diff --git a/dmserver/src/display_manager_service.cpp b/dmserver/src/display_manager_service.cpp index f9a609c3de..95961013cd 100644 --- a/dmserver/src/display_manager_service.cpp +++ b/dmserver/src/display_manager_service.cpp @@ -14,6 +14,7 @@ */ #include "display_manager_service.h" +#include "window_manager_service.h" #include #include @@ -24,6 +25,8 @@ #include "window_manager_hilog.h" +#include "transaction/rs_interfaces.h" + namespace OHOS::Rosen { namespace { constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, 0, "DisplayManagerService"}; @@ -88,20 +91,29 @@ DisplayInfo DisplayManagerService::GetDisplayInfoById(DisplayId displayId) return displayInfo; } -DisplayId DisplayManagerService::CreateVirtualDisplay(const VirtualDisplayInfo &virtualDisplayInfo, - sptr surface) +ScreenId DisplayManagerService::CreateVirtualScreen(VirtualScreenOption option) { - WLOGFI("name %{public}s, width %{public}u, height %{public}u, mirrotId %{public}" PRIu64", flags %{public}d", - virtualDisplayInfo.name_.c_str(), virtualDisplayInfo.width_, virtualDisplayInfo.height_, - virtualDisplayInfo.displayIdToMirror_, virtualDisplayInfo.flags_); - ScreenId screenId = abstractDisplayController_->CreateVirtualScreen(virtualDisplayInfo, surface); - return GetDisplayIdFromScreenId(screenId); + ScreenId screenId = abstractDisplayController_->CreateVirtualScreen(option); + if (screenId == SCREEN_ID_INVALD) { + WLOGFE("DisplayManagerService::CreateVirtualScreen: Get virtualScreenId failed"); + return SCREEN_ID_INVALD; + } + return screenId; } -bool DisplayManagerService::DestroyVirtualDisplay(DisplayId displayId) +DMError DisplayManagerService::DestroyVirtualScreen(ScreenId screenId) { - WLOGFI("DisplayManagerService::DestroyVirtualDisplay"); - ScreenId screenId = GetScreenIdFromDisplayId(displayId); + WLOGFI("DisplayManagerService::DestroyVirtualScreen"); + if (screenId == DISPLAY_ID_INVALD) { + WLOGFE("DisplayManagerService: virtualScreenId is invalid"); + return DMError::DM_ERROR_INVALID_PARAM; + } + if (displayNodeMap_[screenId] == nullptr) { + WLOGFE("DisplayManagerService: Mirror mode failed, displayNodeId is nullptr"); + return abstractDisplayController_->DestroyVirtualScreen(screenId); + } + displayNodeMap_[screenId]->RemoveFromTree(); + displayNodeMap_.erase(screenId); return abstractDisplayController_->DestroyVirtualScreen(screenId); } @@ -259,4 +271,24 @@ void DMAgentDeathRecipient::OnRemoteDied(const wptr& wptrDeath) WLOGFI("call OnRemoteDied callback"); callback_(object); } + +void DisplayManagerService::AddMirror(ScreenId mainScreenId, ScreenId mirrorScreenId) +{ + if (mainScreenId != DISPLAY_ID_INVALD) { + std::shared_ptr displayNode = + SingletonContainer::Get().GetDisplayNode(mainScreenId); + if (displayNode == nullptr) { + WLOGFE("DisplayManagerService::AddMirror: GetDisplayNode failed, displayNode is nullptr"); + } + NodeId nodeId = displayNode->GetId(); + + struct RSDisplayNodeConfig config = {mirrorScreenId, true, nodeId}; + WLOGFI("AddMirror: mainScreenId: %{public}" PRIu64 ", mirrorScreenId: %{public}" PRIu64 "", + mainScreenId, mirrorScreenId); + displayNodeMap_[mainScreenId] = RSDisplayNode::Create(config); + auto transactionProxy = RSTransactionProxy::GetInstance(); + transactionProxy->FlushImplicitTransaction(); + WLOGFI("DisplayManagerService::AddMirror: NodeId: %{public}" PRIu64 "", nodeId >> 32); + } +} } // namespace OHOS::Rosen \ No newline at end of file diff --git a/dmserver/src/display_manager_stub.cpp b/dmserver/src/display_manager_stub.cpp index b0232b6cd4..a601caf2fc 100644 --- a/dmserver/src/display_manager_stub.cpp +++ b/dmserver/src/display_manager_stub.cpp @@ -15,6 +15,8 @@ #include "display_manager_stub.h" +#include "dm_common.h" + #include #include "window_manager_hilog.h" @@ -46,20 +48,31 @@ int32_t DisplayManagerStub::OnRemoteRequest(uint32_t code, MessageParcel &data, reply.WriteParcelable(&info); break; } - case TRANS_ID_CREATE_VIRTUAL_DISPLAY: { - VirtualDisplayInfo* virtualDisplayInfo = data.ReadParcelable(); + case TRANS_ID_CREATE_VIRTUAL_SCREEN: { + std::string name = data.ReadString(); + uint32_t width = data.ReadUint32(); + uint32_t height = data.ReadUint32(); + float density = data.ReadFloat(); sptr surfaceObject = data.ReadRemoteObject(); sptr bp = iface_cast(surfaceObject); sptr surface = Surface::CreateSurfaceAsProducer(bp); - DisplayId virtualId = CreateVirtualDisplay(*virtualDisplayInfo, surface); - reply.WriteUint64(virtualId); - virtualDisplayInfo = nullptr; + int32_t flags = data.ReadInt32(); + VirtualScreenOption option = { + .name_ = name, + .width_ = width, + .height_ = height, + .density_ = density, + .surface_ = surface, + .flags_ = flags + }; + ScreenId screenId = CreateVirtualScreen(option); + reply.WriteUint64(static_cast(screenId)); break; } - case TRANS_ID_DESTROY_VIRTUAL_DISPLAY: { - DisplayId virtualId = static_cast(data.ReadUint64()); - bool result = DestroyVirtualDisplay(virtualId); - reply.WriteBool(result); + case TRANS_ID_DESTROY_VIRTUAL_SCREEN: { + ScreenId screenId = static_cast(data.ReadUint64()); + DMError result = DestroyVirtualScreen(screenId); + reply.WriteInt32(static_cast(result)); break; } case TRANS_ID_GET_DISPLAY_SNAPSHOT: { @@ -122,6 +135,12 @@ int32_t DisplayManagerStub::OnRemoteRequest(uint32_t code, MessageParcel &data, NotifyDisplayEvent(event); break; } + case TRANS_ID_ADD_MIRROR: { + ScreenId mainScreenId = static_cast(data.ReadUint64()); + ScreenId mirrorScreenId = static_cast(data.ReadUint64()); + AddMirror(mainScreenId, mirrorScreenId); + 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 80f1c1f1d8..6fae0ec5be 100644 --- a/interfaces/innerkits/dm/display_manager.h +++ b/interfaces/innerkits/dm/display_manager.h @@ -44,10 +44,6 @@ public: std::vector GetAllDisplayIds(); - DisplayId CreateVirtualDisplay(const std::string &name, uint32_t width, uint32_t height, - sptr surface, DisplayId displayIdToMirror, int32_t flags); - - bool DestroyVirtualDisplay(DisplayId displayId); std::shared_ptr GetScreenshot(DisplayId displayId); std::shared_ptr GetScreenshot(DisplayId displayId, const Media::Rect &rect, const Media::Size &size, int rotation); diff --git a/interfaces/innerkits/dm/dm_common.h b/interfaces/innerkits/dm/dm_common.h index 4bd162489a..2e049de702 100644 --- a/interfaces/innerkits/dm/dm_common.h +++ b/interfaces/innerkits/dm/dm_common.h @@ -43,6 +43,19 @@ enum class DisplayState : uint32_t { enum class DisplayEvent : uint32_t { UNLOCK }; + +enum class DMError : int32_t { + DM_OK = 0, + DM_ERROR_INIT_DMS_PROXY_LOCKED = 100, + DM_ERROR_IPC_FAILED = 101, + DM_ERROR_REMOTE_CREATE_FAILED = 110, + DM_ERROR_NULLPTR = 120, + DM_ERROR_INVALID_PARAM = 130, + DM_ERROR_WRITE_INTERFACE_TOKEN_FAILED = 140, + DM_ERROR_DEATH_RECIPIENT = 150, + DM_ERROR_INVALID_MODE_ID = 160, + DM_ERROR_UNKNOWN, +}; using DisplayStateCallback = std::function; enum class DisplayPowerEvent : uint32_t { diff --git a/interfaces/innerkits/dm/screen.h b/interfaces/innerkits/dm/screen.h index ae2221364c..cc902bdda0 100644 --- a/interfaces/innerkits/dm/screen.h +++ b/interfaces/innerkits/dm/screen.h @@ -31,7 +31,7 @@ struct Point { }; struct VirtualScreenOption { - const std::string& name_; + const std::string name_; uint32_t width_; uint32_t height_; float density_; diff --git a/interfaces/innerkits/dm/screen_manager.h b/interfaces/innerkits/dm/screen_manager.h index 7900ef8bc0..3310d2fdac 100644 --- a/interfaces/innerkits/dm/screen_manager.h +++ b/interfaces/innerkits/dm/screen_manager.h @@ -18,8 +18,10 @@ #include #include "screen.h" +#include "dm_common.h" #include "screen_group.h" #include "wm_single_instance.h" +#include "wm_single_instance.h" namespace OHOS::Rosen { class IScreenChangeListener : public RefBase { @@ -34,10 +36,13 @@ WM_DECLARE_SINGLE_INSTANCE_BASE(ScreenManager); public: sptr GetScreenById(ScreenId id); std::vector> GetAllScreens(); + void RegisterScreenChangeListener(sptr listener); - sptr makeExpand(std::vector screenId, std::vector startPoint); - sptr makeMirror(ScreenId mainScreenId, std::vector mirrorScreenId); - sptr createVirtualScreen(VirtualScreenOption option); + sptr MakeExpand(std::vector screenId, std::vector startPoint); + sptr MakeMirror(ScreenId mainScreenId, std::vector mirrorScreenId); + sptr AddMirror(ScreenId mainScreenId, ScreenId mirrorScreenId); + ScreenId CreateVirtualScreen(VirtualScreenOption option); + DMError DestroyVirtualScreen(ScreenId screenId); private: ScreenManager(); diff --git a/push_code.sh b/push_code.sh new file mode 100755 index 0000000000..06dcf0311c --- /dev/null +++ b/push_code.sh @@ -0,0 +1,3 @@ +# git remote set-url origin --push git@gitee.com:fanby01/windowmanager.git +git remote add fanby01 git@gitee.com:fanby01/windowmanager.git +git push fanyb01 HEAD:master diff --git a/push_code_force.sh b/push_code_force.sh new file mode 100755 index 0000000000..9662fee936 --- /dev/null +++ b/push_code_force.sh @@ -0,0 +1,3 @@ +#git remote set-url origin --push git@gitee.com:fanby01/windowmanager.git +git remote add fanby01 git@gitee.com:fanby01/windowmanager.git +git push -f fanby01 HEAD:master diff --git a/snapshot/BUILD.gn b/snapshot/BUILD.gn index c3b895ae9e..d9336cfaed 100644 --- a/snapshot/BUILD.gn +++ b/snapshot/BUILD.gn @@ -16,25 +16,120 @@ import("//build/ohos.gni") ## Build snapshot {{{ config("snapshot_config") { visibility = [ ":*" ] + + include_dirs = [ + ".", + +# for abilityContext + "//foundation/aafwk/standard/frameworks/kits/ability/ability_runtime/include", + "//foundation/appexecfwk/standard/interfaces/innerkits/appexecfwk_base/include", + "//base/global/resmgr_standard/interfaces/innerkits/include", + "//third_party/node/deps/icu-small/source/common", + "//foundation/aafwk/standard/interfaces/innerkits/ability_manager/include", + "//foundation/aafwk/standard/interfaces/innerkits/want/include/ohos/aafwk/content", + "//foundation/distributedschedule/dmsfwk/services/dtbschedmgr/include", + "//foundation/aafwk/standard/interfaces/innerkits/base/include", + +# RSSurface + "//foundation/graphic/standard/rosen/modules/render_service_client", + # "//foundation/graphic/standard/rosen/modules/render_service_base", + ] + + cflags = [ + "-Wall", + "-Werror", + "-g3", + ] +} + +ohos_static_library("snapshot_utils") { + include_dirs = [ + ".", + ] + sources = [ "snapshot_utils.cpp" ] + configs = [ ":snapshot_config" ] + public_deps = [ + "//third_party/libpng:libpng", # png + "//foundation/windowmanager/wm:libwm", + "//foundation/multimedia/image_standard/interfaces/innerkits:image_native", # PixelMap + "//foundation/ace/ace_engine/build/external_config/flutter/skia:ace_skia_ohos", + "//foundation/graphic/standard/rosen/modules/2d_graphics:2d_graphics", + # "//foundation/graphic/standard/rosen/modules/render_service_client:librender_service_client", + ] } ohos_executable("snapshot_display") { install_enable = false + sources = [ "snapshot_display.cpp", - "snapshot_utils.cpp", ] configs = [ ":snapshot_config" ] deps = [ - "//foundation/multimedia/image_standard/interfaces/innerkits:image_native", # PixelMap - "//foundation/windowmanager/dm:libdm", + ":snapshot_utils", + "//foundation/distributedschedule/samgr/interfaces/innerkits/samgr_proxy:samgr_proxy", + "//foundation/graphic/standard:libvsync_client", + "//foundation/graphic/standard:libwmclient", + "//foundation/graphic/standard:libwmservice", + "//third_party/zlib:libz", + "//foundation/windowmanager/wm:libwm", + "//foundation/windowmanager/wmserver:libwms", + "//foundation/windowmanager/wm:libwmutil", + +# native value + "//foundation/ace/napi:ace_napi", +# ace + "//foundation/ace/ace_engine/interfaces/innerkits/ace:ace_uicontent", +# libpng + "//third_party/libpng:libpng", +# PixelMap + "//foundation/multimedia/image_standard/interfaces/innerkits/:image_native" + ] + + part_name = "window_manager" + subsystem_name = "window" +} + +ohos_executable("snapshot_virtual_screen") { + install_enable = false + + sources = [ + "snapshot_virtual_display.cpp", + "image_reader.cpp", + "image_reader_handler_impl.cpp", + ] + + configs = [ ":snapshot_config" ] + + deps = [ + ":snapshot_utils", + "//foundation/distributedschedule/samgr/interfaces/innerkits/samgr_proxy:samgr_proxy", + "//foundation/graphic/standard:libvsync_client", + "//foundation/graphic/standard:libwmclient", + "//foundation/graphic/standard:libwmservice", + "//third_party/zlib:libz", "//foundation/windowmanager/wm:libwm", "//foundation/windowmanager/wm:libwmutil", "//third_party/libpng:libpng", # png + "//foundation/windowmanager/dm:libdm", + "//foundation/windowmanager/wmserver:libwms", + +# native value + "//foundation/ace/napi:ace_napi", +# ace + "//foundation/ace/ace_engine/interfaces/innerkits/ace:ace_uicontent", +# libpng + "//third_party/libpng:libpng", +# PixelMap + "//foundation/multimedia/image_standard/interfaces/innerkits/:image_native", + + "//foundation/graphic/standard/rosen/modules/render_service_client:librender_service_client", ] + public_deps = [ "//foundation/ace/ace_engine/build/external_config/flutter/skia:ace_skia_ohos" ] + part_name = "window_manager" subsystem_name = "window" } diff --git a/snapshot/image_reader.cpp b/snapshot/image_reader.cpp new file mode 100644 index 0000000000..cf91ddcbcc --- /dev/null +++ b/snapshot/image_reader.cpp @@ -0,0 +1,145 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved. + * Description: image reader + * 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 "image_reader.h" +#include + +#include "unique_fd.h" + +using namespace OHOS::Media; + +namespace OHOS { +const int BPP = 4; // bytes per pixel + +ImageReader::ImageReader() +{ +} + +ImageReader::~ImageReader() +{ + DeInit(); +} + +void ImageReader::DeInit() +{ + if (csurface_ != nullptr) { + csurface_->UnregisterConsumerListener(); + } + psurface_ = nullptr; + csurface_ = nullptr; +} + +bool ImageReader::Init() +{ + csurface_ = Surface::CreateSurfaceAsConsumer(); + if (csurface_ == nullptr) { + return false; + } + + auto producer = csurface_->GetProducer(); + psurface_ = Surface::CreateSurfaceAsProducer(producer); + if (psurface_ == nullptr) { + return false; + } + + listener_ = new BufferListener(*this); + SurfaceError ret = csurface_->RegisterConsumerListener(listener_); + if (ret != SURFACE_ERROR_OK) { + return false; + } + return true; +} + +void ImageReader::OnVsync() +{ + printf("ImageReader::OnVsync\n"); + + sptr cbuffer = nullptr; + int32_t fence = -1; + int64_t timestamp = 0; + Rect damage; + auto sret = csurface_->AcquireBuffer(cbuffer, fence, timestamp, damage); + UniqueFd fenceFd(fence); + if (cbuffer == nullptr || sret != OHOS::SURFACE_ERROR_OK) { + printf("ImageReader::OnVsync: surface buffer is null!\n"); + return; + } + + ProcessBuffer(cbuffer); + + if (cbuffer != prevBuffer_) { + if (prevBuffer_ != nullptr) { + SurfaceError ret = csurface_->ReleaseBuffer(prevBuffer_, -1); + if (ret != SURFACE_ERROR_OK) { + printf("ImageReader::OnVsync: release buffer error!\n"); + return; + } + } + + prevBuffer_ = cbuffer; + } +} + +sptr ImageReader::GetSurface() const +{ + return psurface_; +} + +void ImageReader::SetHandler(sptr handler) +{ + handler_ = handler; +} + +void ImageReader::ProcessBuffer(const sptr &buf) +{ + if (handler_ == nullptr) { + printf("ImageReaderHandler not set!\n"); + return; + } + + BufferHandle *bufferHandle = buf->GetBufferHandle(); + if (bufferHandle == nullptr) { + printf("bufferHandle nullptr!\n"); + return; + } + + uint32_t width = bufferHandle->width; + uint32_t height = bufferHandle->height; + uint32_t stride = bufferHandle->stride; + uint8_t *addr = (uint8_t *)buf->GetVirAddr(); + + auto data = (uint8_t *)malloc(width * height * BPP); + if (data == nullptr) { + return; + } + for (uint32_t i = 0; i < height; i++) { + memcpy_s(data + width * i * BPP, width * BPP, addr + stride * i, width * BPP); + } + + sptr pixelMap = new PixelMap(); + ImageInfo info; + info.size.width = width; + info.size.height = height; + info.pixelFormat = PixelFormat::RGBA_8888; + info.colorSpace = ColorSpace::SRGB; + pixelMap->SetImageInfo(info); + + // data will free by pixelMap->FreePixelMap() in ~PixelMap() + pixelMap->SetPixelsAddr(data, nullptr, width * height, AllocatorType::HEAP_ALLOC, nullptr); + + handler_->OnImageAvalible(pixelMap); +} +} \ No newline at end of file diff --git a/snapshot/image_reader.h b/snapshot/image_reader.h new file mode 100644 index 0000000000..842c6bcaaa --- /dev/null +++ b/snapshot/image_reader.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved. + * Description: image reader + * 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 IMAGE_READER_H +#define IMAGE_READER_H + +#include "refbase.h" +#include "core/ui/rs_surface_node.h" +#include "image_reader_handler.h" + +namespace OHOS { +class ImageReader { +public: + ImageReader(); + virtual ~ImageReader(); + + bool Init(); + void DeInit(); + + sptr GetSurface() const; + void SetHandler(sptr handler); +private: + class BufferListener : public IBufferConsumerListener { + public: + explicit BufferListener(ImageReader &imgReader): imgReader_(imgReader) + { + } + ~BufferListener() noexcept override = default; + void OnBufferAvailable() override + { + imgReader_.OnVsync(); + } + + private: + ImageReader &imgReader_; + }; + friend class BufferListener; + + void OnVsync(); + void ProcessBuffer(const sptr &buf); + + sptr listener_ = nullptr; + sptr csurface_ = nullptr; // cosumer surface + sptr psurface_ = nullptr; // producer surface + sptr prevBuffer_ = nullptr; + sptr handler_ = nullptr; +}; +} + +#endif // IMAGE_READER_H diff --git a/snapshot/image_reader_handler.h b/snapshot/image_reader_handler.h new file mode 100644 index 0000000000..bcc14edc3d --- /dev/null +++ b/snapshot/image_reader_handler.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved. + * Description: image reader handler + * 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 IMAGE_READER_HANDLER_H +#define IMAGE_READER_HANDLER_H + +#include "pixel_map.h" + +namespace OHOS { +class ImageReaderHandler : public RefBase { +public: + ImageReaderHandler() {} + virtual ~ImageReaderHandler() noexcept + { + } + virtual bool OnImageAvalible(sptr pixleMap) = 0; +}; +} + +#endif // IMAGE_READER_HANDLER_H diff --git a/snapshot/image_reader_handler_impl.cpp b/snapshot/image_reader_handler_impl.cpp new file mode 100644 index 0000000000..110d2ee698 --- /dev/null +++ b/snapshot/image_reader_handler_impl.cpp @@ -0,0 +1,39 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved. + * Description: image reader + * 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 "image_reader_handler_impl.h" + +namespace OHOS { +bool ImageReaderHandlerImpl::OnImageAvalible(sptr pixleMap) +{ + if (flag_ == false) { + flag_ = true; + pixleMap_ = pixleMap; + printf("Get an Image!\n"); + } + return true; +} + +bool ImageReaderHandlerImpl::IsImageOk() const +{ + return flag_; +} + +sptr ImageReaderHandlerImpl::GetPixelMap() +{ + return pixleMap_; +} +} \ No newline at end of file diff --git a/snapshot/image_reader_handler_impl.h b/snapshot/image_reader_handler_impl.h new file mode 100644 index 0000000000..9dd64b592e --- /dev/null +++ b/snapshot/image_reader_handler_impl.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved. + * Description: image reader handler + * 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 IMAGE_READER_HANDLER_IMPL_H +#define IMAGE_READER_HANDLER_IMPL_H + +#include "image_reader_handler.h" + +namespace OHOS { +class ImageReaderHandlerImpl : public ImageReaderHandler { +public: + bool OnImageAvalible(sptr pixleMap) override; + bool IsImageOk() const; + sptr GetPixelMap(); + +private: + bool flag_ = false; + sptr pixleMap_ = nullptr; +}; +} + +#endif // IMAGE_READER_HANDLER_IMPL_H diff --git a/snapshot/snapshot_display.cpp b/snapshot/snapshot_display.cpp index 40a64d2d1b..8d00e07a6c 100644 --- a/snapshot/snapshot_display.cpp +++ b/snapshot/snapshot_display.cpp @@ -1,5 +1,6 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved. + * Description: snapshot screen * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -14,6 +15,7 @@ */ #include +#include #include "snapshot_utils.h" @@ -26,23 +28,14 @@ int main(int argc, char *argv[]) CmdArgments cmdArgments; cmdArgments.fileName = "/data/snapshot_display_1.png"; - if (!SnapShotUtils::ProcessArgs(argc, argv, cmdArgments)) { + if (SnapShotUtils::ProcessArgs(argc, argv, cmdArgments) <= 0) { return 0; } // get PixelMap from DisplayManager API auto pixelMap = DisplayManager::GetInstance().GetScreenshot(cmdArgments.displayId); - bool ret = false; - if (pixelMap != nullptr) { - ret = SnapShotUtils::WriteToPngWithPixelMap(cmdArgments.fileName, *pixelMap); - } - if (!ret) { - printf("error: snapshot display %" PRIu64 ", write to %s as png failed!\n", - cmdArgments.displayId, cmdArgments.fileName.c_str()); - return -1; - } - printf("success: snapshot display %" PRIu64 ", write to %s as png\n", - cmdArgments.displayId, cmdArgments.fileName.c_str()); - return 0; + printf("snapshot display %" PRIu64 ", write to %s as png\n", cmdArgments.displayId, cmdArgments.fileName.c_str()); + + return SnapShotUtils::WriteToPngWithPixelMap(cmdArgments.fileName, *pixelMap); } \ No newline at end of file diff --git a/snapshot/snapshot_utils.cpp b/snapshot/snapshot_utils.cpp index cb6110cf26..09301aa42d 100644 --- a/snapshot/snapshot_utils.cpp +++ b/snapshot/snapshot_utils.cpp @@ -1,5 +1,6 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved. + * Description: snapshot utils * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -17,14 +18,44 @@ #include #include -#include +#include +#include + +#include "render_context/render_context.h" +#include "ui/rs_surface_extractor.h" +#include "png.h" + +#define ACE_ENABLE_GL using namespace OHOS::Media; using namespace OHOS::Rosen; -namespace OHOS { -constexpr int BITMAP_DEPTH = 8; +namespace detail { +RenderContext *g_renderContext = nullptr; + +template +using SysTime = std::chrono::time_point; +using SysMicroSeconds = SysTime; + +std::time_t MicroSecondsSinceEpoch() +{ + SysMicroSeconds tmp = std::chrono::system_clock::now(); + return tmp.time_since_epoch().count(); +} + +RenderContext *GetRenderContext() +{ + if (g_renderContext != nullptr) { + return g_renderContext; + } + g_renderContext = RenderContextFactory::GetInstance().CreateEngine(); + g_renderContext->InitializeEglContext(); + return g_renderContext; +} +} // namespace detail + +namespace OHOS { void SnapShotUtils::PrintUsage(const std::string &cmdLine) { printf("usage: %s [-i displayId] [-f output_file]\n", cmdLine.c_str()); @@ -42,36 +73,34 @@ bool SnapShotUtils::CheckFileNameValid(const std::string &fileName) char resolvedPath[PATH_MAX] = { 0 }; char *realPath = realpath(fileDir.c_str(), resolvedPath); if (realPath == nullptr) { - printf("error: fileName %s invalid, nullptr!\n", fileName.c_str()); + printf("fileName %s invalid, nullptr!\n", fileName.c_str()); return false; } std::string realPathString = realPath; if (realPathString.find("/data") != 0) { - printf("error: fileName %s invalid, %s must dump at dir: /data \n", fileName.c_str(), realPathString.c_str()); + printf("fileName %s invalid, %s must dump at dir: /data \n", fileName.c_str(), realPathString.c_str()); return false; } return true; } + bool SnapShotUtils::WriteToPng(const std::string &fileName, const WriteToPngParam ¶m) { - if (!CheckFileNameValid(fileName)) { - return false; - } png_structp pngStruct = png_create_write_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr); if (pngStruct == nullptr) { - printf("error: png_create_write_struct nullptr!\n"); + printf("png_create_write_struct error, nullptr!\n"); return false; } png_infop pngInfo = png_create_info_struct(pngStruct); if (pngInfo == nullptr) { - printf("error: png_create_info_struct error nullptr!\n"); + printf("png_create_info_struct error, nullptr!\n"); png_destroy_write_struct(&pngStruct, nullptr); return false; } FILE *fp = fopen(fileName.c_str(), "wb"); if (fp == nullptr) { - printf("error: open file [%s] error, %d [%s]!\n", fileName.c_str(), errno, strerror(errno)); + printf("open file [%s] error, nullptr!\n", fileName.c_str()); png_destroy_write_struct(&pngStruct, &pngInfo); return false; } @@ -96,9 +125,7 @@ bool SnapShotUtils::WriteToPng(const std::string &fileName, const WriteToPngPara // free png_destroy_write_struct(&pngStruct, &pngInfo); - if (fclose(fp) != 0) { - return false; - } + fclose(fp); return true; } @@ -113,6 +140,73 @@ bool SnapShotUtils::WriteToPngWithPixelMap(const std::string &fileName, PixelMap return SnapShotUtils::WriteToPng(fileName, param); } +void SnapShotUtils::DrawSurface( + SkRect surfaceGeometry, uint32_t color, SkRect shapeGeometry, std::shared_ptr surfaceNode) +{ + auto x = surfaceGeometry.x(); + auto y = surfaceGeometry.y(); + auto width = surfaceGeometry.width(); + auto height = surfaceGeometry.height(); + surfaceNode->SetBounds(x, y, width, height); + std::shared_ptr rsSurface = RSSurfaceExtractor::ExtractRSSurface(surfaceNode); + if (rsSurface == nullptr) { + return; + } +#ifdef ACE_ENABLE_GL + rsSurface->SetRenderContext(detail::GetRenderContext()); +#endif + auto framePtr = rsSurface->RequestFrame(width, height); + if (framePtr == nullptr) { + printf(": framePtr is nullptr!\n"); + return; + } + auto canvas = framePtr->GetCanvas(); + SkPaint paint; + paint.setAntiAlias(true); + paint.setStyle(SkPaint::kFill_Style); + paint.setStrokeWidth(20); // stroken width 20 + paint.setStrokeJoin(SkPaint::kRound_Join); + paint.setColor(color); + + canvas->drawRect(shapeGeometry, paint); + framePtr->SetDamageRegion(0, 0, width, height); + rsSurface->FlushFrame(framePtr); +} + +void SnapShotUtils::DumpBuffer(const sptr &buf) +{ + if (access("/data", F_OK) < 0) { + printf("ImageReader::DumpBuffer(): Can't access data directory!\n"); + return; + } + + std::string dumpFileName = "/data/snapshot_virtual_display_0.png"; + BufferHandle *bufferHandle = buf->GetBufferHandle(); + if (bufferHandle == nullptr) { + printf("bufferHandle nullptr!\n"); + } else { + printf("bufferHandle width: %d\n", bufferHandle->width); + printf("bufferHandle height: %d\n", bufferHandle->height); + printf("bufferHandle stride: %d\n", bufferHandle->stride); + printf("bufferHandle format: %d\n", bufferHandle->format); + } + + WriteToPngParam param; + param.width = buf->GetWidth(); + param.height = buf->GetHeight(); + param.data = (const uint8_t *)buf->GetVirAddr(); + param.stride = buf->GetBufferHandle()->stride; + param.bitDepth = BITMAP_DEPTH; + SnapShotUtils::WriteToPng(dumpFileName, param); + printf("ImageReader::DumpBuffer(): dump %s succeed.", dumpFileName.c_str()); +} + +std::shared_ptr SnapShotUtils::CreateSurface() +{ + RSSurfaceNodeConfig config; + return RSSurfaceNode::Create(config); +} + static bool ProcessDisplayId(DisplayId &displayId) { if (displayId == DISPLAY_ID_INVALD) { @@ -127,8 +221,8 @@ static bool ProcessDisplayId(DisplayId &displayId) } } if (!validFlag) { - printf("error: displayId %" PRIu64 " invalid!\n", displayId); - printf("tips: supported displayIds:\n"); + printf("displayId %" PRIu64 " invalid!\n", displayId); + printf("supported displayIds:\n"); for (auto id: displayIds) { printf("\t%" PRIu64 "\n", id); } @@ -138,7 +232,7 @@ static bool ProcessDisplayId(DisplayId &displayId) return true; } -bool SnapShotUtils::ProcessArgs(int argc, char * const argv[], CmdArgments &cmdArgments) +int SnapShotUtils::ProcessArgs(int argc, char * const argv[], CmdArgments &cmdArgments) { int opt = 0; const struct option longOption[] = { @@ -157,22 +251,22 @@ bool SnapShotUtils::ProcessArgs(int argc, char * const argv[], CmdArgments &cmdA break; case 'h': // help SnapShotUtils::PrintUsage(argv[0]); - return false; + return 0; default: SnapShotUtils::PrintUsage(argv[0]); - return false; + return 0; } } if (!ProcessDisplayId(cmdArgments.displayId)) { - return false; + return -1; } // check fileName - if (!SnapShotUtils::CheckFileNameValid(cmdArgments.fileName)) { - printf("error: filename %s invalid!\n", cmdArgments.fileName.c_str()); - return false; + if (SnapShotUtils::CheckFileNameValid(cmdArgments.fileName) == false) { + printf("filename %s invalid!\n", cmdArgments.fileName.c_str()); + return -1; } - return true; + return 1; } } \ No newline at end of file diff --git a/snapshot/snapshot_utils.h b/snapshot/snapshot_utils.h index 3bd7cd979e..46248bb215 100644 --- a/snapshot/snapshot_utils.h +++ b/snapshot/snapshot_utils.h @@ -1,5 +1,6 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved. + * Description: snapshot utils * 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 @@ -18,11 +19,20 @@ #include #include -#include +#include "refbase.h" +#include "pixel_map.h" #include "display_manager.h" +#include "screen_manager.h" +#include "dm_common.h" +#include "screen.h" +#include "include/core/SkCanvas.h" +#include "include/core/SkImageInfo.h" +#include "core/ui/rs_display_node.h" +#include "core/ui/rs_surface_node.h" namespace OHOS { +const int BITMAP_DEPTH = 8; using WriteToPngParam = struct { uint32_t width; uint32_t height; @@ -34,6 +44,8 @@ using WriteToPngParam = struct { using CmdArgments = struct { Rosen::DisplayId displayId = Rosen::DISPLAY_ID_INVALD; std::string fileName; + Media::Rect cropRect = { -1, -1, -1, -1 }; + Media::Size dstSize = { -1, -1 }; }; class SnapShotUtils { @@ -45,7 +57,11 @@ public: static bool CheckFileNameValid(const std::string &fileName); static bool WriteToPng(const std::string &fileName, const WriteToPngParam ¶m); static bool WriteToPngWithPixelMap(const std::string &fileName, Media::PixelMap &pixelMap); - static bool ProcessArgs(int argc, char * const argv[], CmdArgments& cmdArgments); + static void DrawSurface(SkRect surfaceGeometry, uint32_t color, + SkRect shapeGeometry, std::shared_ptr surfaceNode); + static void DumpBuffer(const sptr &buf); + static std::shared_ptr CreateSurface(); + static int ProcessArgs(int argc, char * const argv[], CmdArgments& cmdArgments); private: }; } diff --git a/snapshot/snapshot_virtual_display.cpp b/snapshot/snapshot_virtual_display.cpp new file mode 100644 index 0000000000..3b41fc73d2 --- /dev/null +++ b/snapshot/snapshot_virtual_display.cpp @@ -0,0 +1,120 @@ +/* + * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved. + * Description: snapshot virtual display + * 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 "snapshot_utils.h" +#include "image_reader.h" +#include "image_reader_handler_impl.h" + +using namespace OHOS; +using namespace OHOS::Rosen; +using namespace OHOS::Media; + +#define FAKE_VIRTUAL_DISPLAY_SURFACE + +// ABGR +namespace { +const int SLEEP_US = 10 * 1000; // 10ms +const int MAX_WAIT_COUNT = 1000; +} + +int main(int argc, char *argv[]) +{ + CmdArgments cmdArgments; + cmdArgments.fileName = "/data/snapshot_virtual_display_1.png"; + + if (SnapShotUtils::ProcessArgs(argc, argv, cmdArgments) <= 0) { + return 0; + } + + ImageReader imgReader; + sptr imgReaderHandler = new ImageReaderHandlerImpl(); + if (!imgReader.Init()) { + printf("ImgReader init failed!\n"); + } + imgReader.SetHandler(imgReaderHandler); + + auto &screenManager = ScreenManager::GetInstance(); + + auto display = DisplayManager::GetInstance().GetDefaultDisplay(); + + VirtualScreenOption option = { + .name_ = "virtualDisplay", + .width_ = display->GetWidth(), + .height_ = display->GetHeight(), + .density_ = 2.0, + .surface_ = imgReader.GetSurface(), + .flags_ = 0 + }; + ScreenId mainId = static_cast(DisplayManager::GetInstance().GetDefaultDisplayId()); + + #if 1 + ScreenId virtualscreenId2 = screenManager.CreateVirtualScreen(option); + screenManager.AddMirror(mainId, virtualscreenId2); + printf("add mirror id = %llu\n", virtualscreenId2 >> 32); + + for (int i = 0; i < 10; i++) { + ScreenId virtualscreenId = screenManager.CreateVirtualScreen(option); + screenManager.AddMirror(mainId, virtualscreenId); + screenManager.DestroyVirtualScreen(virtualscreenId); + printf("test mirror %d, id = %llu\n", i, virtualscreenId >> 32); + } + for (int i = 0; i < 10; i++) { + ScreenId virtualscreenId = screenManager.CreateVirtualScreen(option); + screenManager.DestroyVirtualScreen(virtualscreenId); + printf("test mirror %d, id = %llu\n", i, virtualscreenId >> 32); + } + #endif + + ScreenId virtualscreenId = screenManager.CreateVirtualScreen(option); + screenManager.AddMirror(mainId, virtualscreenId); + printf("virtualscreenId: %" PRIu64 "\n", virtualscreenId >> 32); + + int wait_count = 0; + while (!imgReaderHandler->IsImageOk()) { + if (wait_count >= MAX_WAIT_COUNT) { + break; // timeout + } + wait_count++; + usleep(SLEEP_US); + } + + bool ret = false; + if (wait_count < MAX_WAIT_COUNT) { + printf("enter pixelmap\n"); + auto pixelMap = imgReaderHandler->GetPixelMap(); + ret = SnapShotUtils::WriteToPngWithPixelMap(cmdArgments.fileName, *pixelMap); + } + if (ret) { + printf("snapshot %" PRIu64 ", write to %s as png\n", cmdArgments.displayId, cmdArgments.fileName.c_str()); + } else { + printf("snapshot %" PRIu64 " write to %s failed!\n", cmdArgments.displayId, cmdArgments.fileName.c_str()); + } + + imgReader.DeInit(); + + + screenManager.DestroyVirtualScreen(virtualscreenId); + printf("DestroyVirtualDisplay %" PRIu64 "\n", virtualscreenId >> 32); + + #if 1 + screenManager.DestroyVirtualScreen(virtualscreenId2); + printf("destroy id = %llu\n", virtualscreenId2 >> 32); + #endif + + return 0; +} \ No newline at end of file diff --git a/wmserver/include/window_layout_policy.h b/wmserver/include/window_layout_policy.h index a9dc89d352..3c316350cf 100644 --- a/wmserver/include/window_layout_policy.h +++ b/wmserver/include/window_layout_policy.h @@ -59,11 +59,13 @@ private: sptr belowAppWindowNode_ = new WindowNode(); sptr appWindowNode_ = new WindowNode(); sptr aboveAppWindowNode_ = new WindowNode(); + const std::set avoidTypes_ { WindowType::WINDOW_TYPE_STATUS_BAR, WindowType::WINDOW_TYPE_NAVIGATION_BAR, }; void UpdateLimitRect(const sptr& node, Rect& limitRect); + void LayoutWindowTree(); void LayoutWindowNode(sptr& node); AvoidPosType GetAvoidPosType(const Rect& rect); diff --git a/wmserver/include/window_manager_service.h b/wmserver/include/window_manager_service.h index dce096d91e..07f39ffb10 100644 --- a/wmserver/include/window_manager_service.h +++ b/wmserver/include/window_manager_service.h @@ -54,7 +54,6 @@ public: WMError SetWindowFlags(uint32_t windowId, uint32_t flags) override; WMError SetSystemBarProperty(uint32_t windowId, WindowType type, const SystemBarProperty& prop) override; - std::shared_ptr GetDisplayNode(int32_t displayId) const; void RegisterWindowManagerAgent(WindowManagerAgentType type, const sptr& windowManagerAgent) override; void UnregisterWindowManagerAgent(WindowManagerAgentType type, @@ -63,6 +62,7 @@ public: // Inner interfaces WMError NotifyDisplaySuspend(); void RestoreSuspendedWindows(); + std::shared_ptr GetDisplayNode(int32_t displayId) const; protected: WindowManagerService(); diff --git a/wmserver/include/window_node_container.h b/wmserver/include/window_node_container.h index 47a2061d60..bb2ecdf151 100644 --- a/wmserver/include/window_node_container.h +++ b/wmserver/include/window_node_container.h @@ -52,6 +52,7 @@ public: sptr GetTopImmersiveNode() const; void NotifySystemBarIfChanged(); std::shared_ptr GetDisplayNode() const; + void LayoutDividerWindow(sptr& node); void UpdateDisplayInfo(); diff --git a/wmserver/src/window_layout_policy.cpp b/wmserver/src/window_layout_policy.cpp index 92fe42c7c5..8a79a319d0 100644 --- a/wmserver/src/window_layout_policy.cpp +++ b/wmserver/src/window_layout_policy.cpp @@ -245,6 +245,7 @@ void WindowLayoutPolicy::UpdateLimitRect(const sptr& node, Rect& lim } WLOGFI("Type: %{public}d, limitRect: %{public}d %{public}d %{public}d %{public}d", node->GetWindowType(), limitRect.posX_, limitRect.posY_, limitRect.width_, limitRect.height_); + } } } diff --git a/wmserver/src/window_manager_service.cpp b/wmserver/src/window_manager_service.cpp index ef1cdb5e2b..7381737d40 100644 --- a/wmserver/src/window_manager_service.cpp +++ b/wmserver/src/window_manager_service.cpp @@ -231,11 +231,6 @@ void WindowManagerService::UnregisterWindowManagerAgent(WindowManagerAgentType t windowController_->UnregisterWindowManagerAgent(type, windowManagerAgent); } -std::shared_ptr WindowManagerService::GetDisplayNode(int32_t displayId) const -{ - return windowRoot_->GetOrCreateWindowNodeContainer(displayId)->GetDisplayNode(); -} - void WindowManagerService::OnWindowEvent(Event event, uint32_t windowId) { switch (event) { @@ -261,5 +256,10 @@ void WindowManagerService::RestoreSuspendedWindows() std::lock_guard lock(mutex_); // TODO: restore windows covered by keyguard } + +std::shared_ptr WindowManagerService::GetDisplayNode(int32_t displayId) const +{ + return windowRoot_->GetOrCreateWindowNodeContainer(displayId)->GetDisplayNode(); +} } } \ No newline at end of file -- Gitee