diff --git a/dm/include/display_manager_adapter.h b/dm/include/display_manager_adapter.h index a1e7490f110095e37649e6d1117e8e32db04e89c..8f9d44ade0f2a9f7b1790ee3792a76b151a58df4 100644 --- a/dm/include/display_manager_adapter.h +++ b/dm/include/display_manager_adapter.h @@ -37,7 +37,7 @@ public: DisplayId CreateVirtualDisplay(const VirtualDisplayInfo &virtualDisplayInfo, sptr surface); bool DestroyVirtualDisplay(DisplayId displayId); - sptr GetDisplaySnapshot(DisplayId displayId); + std::shared_ptr GetDisplaySnapshot(DisplayId displayId); bool SuspendBegin(PowerStateChangeReason reason); bool SetDisplayState(DisplayState state, DisplayStateCallback callback); diff --git a/dm/src/display_manager.cpp b/dm/src/display_manager.cpp index 2df4a0af41512d8cb6456be7a9dc131f431a4282..87ba8a41d3c9cd37c14d42ddb8cce8b1c780d754 100644 --- a/dm/src/display_manager.cpp +++ b/dm/src/display_manager.cpp @@ -42,13 +42,13 @@ const sptr DisplayManager::GetDisplayById(DisplayId displayId) return display; } -sptr DisplayManager::GetScreenshot(DisplayId displayId) +std::shared_ptr DisplayManager::GetScreenshot(DisplayId displayId) { if (displayId == DISPLAY_ID_INVALD) { WLOGFE("displayId invalid!"); return nullptr; } - sptr screenShot = SingletonContainer::Get().GetDisplaySnapshot(displayId); + std::shared_ptr screenShot = SingletonContainer::Get().GetDisplaySnapshot(displayId); if (screenShot == nullptr) { WLOGFE("DisplayManager::GetScreenshot failed!"); return nullptr; @@ -73,7 +73,7 @@ bool DisplayManager::CheckRectSizeValid(int32_t param) const return true; } -sptr DisplayManager::GetScreenshot(DisplayId displayId, const Media::Rect &rect, +std::shared_ptr DisplayManager::GetScreenshot(DisplayId displayId, const Media::Rect &rect, const Media::Size &size, int rotation) { if (displayId == DISPLAY_ID_INVALD) { @@ -90,7 +90,7 @@ sptr DisplayManager::GetScreenshot(DisplayId displayId, const M WLOGFE("size invalid! w %{public}d, h %{public}d", rect.width, rect.height); return nullptr; } - sptr screenShot = SingletonContainer::Get().GetDisplaySnapshot(displayId); + std::shared_ptr screenShot = SingletonContainer::Get().GetDisplaySnapshot(displayId); if (screenShot == nullptr) { WLOGFE("DisplayManager::GetScreenshot failed!"); return nullptr; @@ -109,7 +109,7 @@ sptr DisplayManager::GetScreenshot(DisplayId displayId, const M WLOGFE("Media::PixelMap::Create failed!"); return nullptr; } - sptr dstScreenshot = pixelMap.release(); + std::shared_ptr dstScreenshot(pixelMap.release()); return dstScreenshot; } diff --git a/dm/src/display_manager_adapter.cpp b/dm/src/display_manager_adapter.cpp index 28e246abf139e352386f29f0e6b6f71934f0af95..178cf5a6273f63bf76844fbad53dabde990e0c2a 100644 --- a/dm/src/display_manager_adapter.cpp +++ b/dm/src/display_manager_adapter.cpp @@ -63,7 +63,7 @@ sptr DisplayManagerAdapter::GetDisplayById(DisplayId displayId) return display; } -sptr DisplayManagerAdapter::GetDisplaySnapshot(DisplayId displayId) +std::shared_ptr DisplayManagerAdapter::GetDisplaySnapshot(DisplayId displayId) { std::lock_guard lock(mutex_); @@ -72,7 +72,7 @@ sptr DisplayManagerAdapter::GetDisplaySnapshot(DisplayId displa return nullptr; } - sptr dispalySnapshot = displayManagerServiceProxy_->GetDispalySnapshot(displayId); + std::shared_ptr dispalySnapshot = displayManagerServiceProxy_->GetDispalySnapshot(displayId); return dispalySnapshot; } diff --git a/dmserver/include/abstract_display_controller.h b/dmserver/include/abstract_display_controller.h index 67c8e535121347370ac74969ee2d681fb8089af6..c4567139ca0567f2963f1353826f732a07f3f704 100644 --- a/dmserver/include/abstract_display_controller.h +++ b/dmserver/include/abstract_display_controller.h @@ -35,7 +35,7 @@ public: RSScreenModeInfo GetScreenActiveMode(ScreenId id); ScreenId CreateVirtualScreen(const VirtualDisplayInfo &virtualDisplayInfo, sptr surface); bool DestroyVirtualScreen(ScreenId screenId); - sptr GetScreenSnapshot(ScreenId screenId); + std::shared_ptr GetScreenSnapshot(DisplayId displayId, ScreenId screenId); private: AbstractDisplayController(); @@ -43,6 +43,30 @@ private: void parepareRSScreenManger(); OHOS::Rosen::RSInterfaces *rsInterface_; + + class ScreenshotCallback : public SurfaceCaptureCallback { + public: + ScreenshotCallback() = default; + ~ScreenshotCallback() {}; + void OnSurfaceCapture(std::shared_ptr pixelmap) override + { + if (flag_ == false) { + flag_ = true; + pixelMap_ = pixelmap; + } + } + bool IsPixelMapOk() + { + return flag_; + } + std::shared_ptr GetPixelMap() + { + return pixelMap_; + } + private: + bool flag_ = false; + std::shared_ptr pixelMap_ = nullptr; + }; }; } // namespace OHOS::Rosen #endif // FOUNDATION_DMSERVER_ABSTRACT_DISPLAY_CONTROLLER_H \ No newline at end of file diff --git a/dmserver/include/display_manager_interface.h b/dmserver/include/display_manager_interface.h index 5ce9d66e28a46f435c2f15f50602688015a3b94b..7cfa1815b471c4d39e46fce5e0740f6a0c2f488c 100644 --- a/dmserver/include/display_manager_interface.h +++ b/dmserver/include/display_manager_interface.h @@ -47,7 +47,7 @@ public: virtual DisplayId CreateVirtualDisplay(const VirtualDisplayInfo &virtualDisplayInfo, sptr surface) = 0; virtual bool DestroyVirtualDisplay(DisplayId displayId) = 0; - virtual sptr GetDispalySnapshot(DisplayId displayId) = 0; + virtual std::shared_ptr GetDispalySnapshot(DisplayId displayId) = 0; virtual bool SuspendBegin(PowerStateChangeReason reason) = 0; virtual bool SetDisplayState(DisplayState state) = 0; diff --git a/dmserver/include/display_manager_proxy.h b/dmserver/include/display_manager_proxy.h index 4b81d380dc4e40729642f902f9901d6ce7e92863..bd0f452aac9965fd28f98d8b36ec1119e90c9610 100644 --- a/dmserver/include/display_manager_proxy.h +++ b/dmserver/include/display_manager_proxy.h @@ -33,7 +33,7 @@ public: DisplayId CreateVirtualDisplay(const VirtualDisplayInfo &virtualDisplayInfo, sptr surface) override; bool DestroyVirtualDisplay(DisplayId displayId) override; - sptr GetDispalySnapshot(DisplayId displayId) override; + std::shared_ptr GetDispalySnapshot(DisplayId displayId) override; bool SuspendBegin(PowerStateChangeReason reason) override; bool SetDisplayState(DisplayState state) override; diff --git a/dmserver/include/display_manager_service.h b/dmserver/include/display_manager_service.h index f1c17fa5f418d1c2c40982816b6aeced85c17af0..39bf0635fec1ac183ff293fe4c7f03ad63bba16a 100644 --- a/dmserver/include/display_manager_service.h +++ b/dmserver/include/display_manager_service.h @@ -45,7 +45,7 @@ public: DisplayId GetDefaultDisplayId() override; DisplayInfo GetDisplayInfoById(DisplayId displayId) override; - sptr GetDispalySnapshot(DisplayId displayId) override; + std::shared_ptr GetDispalySnapshot(DisplayId displayId) override; bool SuspendBegin(PowerStateChangeReason reason) override; bool SetDisplayState(DisplayState state) override; diff --git a/dmserver/src/abstract_display_controller.cpp b/dmserver/src/abstract_display_controller.cpp index 40f24ba2a1c06fda801d6009b6079e7547265acd..2e82b2ae7dd2f7fd38d99014a466c05fb6d63103 100644 --- a/dmserver/src/abstract_display_controller.cpp +++ b/dmserver/src/abstract_display_controller.cpp @@ -15,11 +15,12 @@ #include "abstract_display_controller.h" +#include "window_manager_hilog.h" +#include "window_manager_service.h" + #include #include -#include "window_manager_hilog.h" - namespace OHOS::Rosen { namespace { constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, 0, "AbstractDisplayController"}; @@ -78,14 +79,31 @@ bool AbstractDisplayController::DestroyVirtualScreen(ScreenId screenId) return true; } -sptr AbstractDisplayController::GetScreenSnapshot(ScreenId screenId) +std::shared_ptr AbstractDisplayController::GetScreenSnapshot(DisplayId displayId, ScreenId screenId) { if (rsInterface_ == nullptr) { return nullptr; } - sptr screenshot = nullptr; + std::shared_ptr displayNode = SingletonContainer::Get().GetDisplayNode(displayId); + std::shared_ptr callback = std::make_shared(); + rsInterface_->TakeSurfaceCapture(displayNode, callback); + + int counter = 0; + while (!callback->IsPixelMapOk()) { + usleep(10000); // 10000us equals to 10ms + counter++; + if (counter >= 200) { // wait for 200 * 10ms = 2s + WLOGFE("Failed to get pixelmap, timeout"); + return nullptr; + } + } + std::shared_ptr screenshot = callback->GetPixelMap(); + + if (screenshot == nullptr) { + WLOGFE("Failed to get pixelmap from RS, return nullptr!"); + } 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 55a285e2df2f6c6417d9e84ddba8b2faa89aeaf4..9449f5403c9466e9e54de8ca383238a671db5443 100644 --- a/dmserver/src/display_manager_proxy.cpp +++ b/dmserver/src/display_manager_proxy.cpp @@ -135,7 +135,7 @@ bool DisplayManagerProxy::DestroyVirtualDisplay(DisplayId displayId) return reply.ReadBool(); } -sptr DisplayManagerProxy::GetDispalySnapshot(DisplayId displayId) +std::shared_ptr DisplayManagerProxy::GetDispalySnapshot(DisplayId displayId) { sptr remote = Remote(); if (remote == nullptr) { @@ -161,7 +161,7 @@ sptr DisplayManagerProxy::GetDispalySnapshot(DisplayId displayI return nullptr; } - sptr pixelMap = reply.ReadParcelable(); + std::shared_ptr pixelMap(reply.ReadParcelable()); if (pixelMap == nullptr) { WLOGFW("DisplayManagerProxy::GetDispalySnapshot SendRequest nullptr."); return nullptr; diff --git a/dmserver/src/display_manager_service.cpp b/dmserver/src/display_manager_service.cpp index 3825b0740166b8f3844fef5eb59274b15c0121f3..aed60579a7ce953adb1d66b458bc82860c6b3cc1 100644 --- a/dmserver/src/display_manager_service.cpp +++ b/dmserver/src/display_manager_service.cpp @@ -101,10 +101,11 @@ bool DisplayManagerService::DestroyVirtualDisplay(DisplayId displayId) return AbstractDisplayController::GetInstance().DestroyVirtualScreen(screenId); } -sptr DisplayManagerService::GetDispalySnapshot(DisplayId displayId) +std::shared_ptr DisplayManagerService::GetDispalySnapshot(DisplayId displayId) { ScreenId screenId = GetScreenIdFromDisplayId(displayId); - sptr screenSnapshot = AbstractDisplayController::GetInstance().GetScreenSnapshot(screenId); + std::shared_ptr screenSnapshot + = AbstractDisplayController::GetInstance().GetScreenSnapshot(displayId, screenId); return screenSnapshot; } diff --git a/dmserver/src/display_manager_stub.cpp b/dmserver/src/display_manager_stub.cpp index 107d4db7b92153207b7b1d13fd1052ec2b122715..2f891ea00656a7e106cf4f2b5c433582dbdf9a5d 100644 --- a/dmserver/src/display_manager_stub.cpp +++ b/dmserver/src/display_manager_stub.cpp @@ -64,12 +64,12 @@ int32_t DisplayManagerStub::OnRemoteRequest(uint32_t code, MessageParcel &data, } case TRANS_ID_GET_DISPLAY_SNAPSHOT: { DisplayId displayId = data.ReadUint64(); - sptr dispalySnapshot = GetDispalySnapshot(displayId); + std::shared_ptr dispalySnapshot = GetDispalySnapshot(displayId); if (dispalySnapshot == nullptr) { reply.WriteParcelable(nullptr); break; } - reply.WriteParcelable(dispalySnapshot.GetRefPtr()); + reply.WriteParcelable(dispalySnapshot.get()); } case TRANS_ID_SUSPEND_BEGIN: { PowerStateChangeReason reason = static_cast(data.ReadUint32()); diff --git a/interfaces/innerkits/dm/display_manager.h b/interfaces/innerkits/dm/display_manager.h index 7ad77df09c7f6303cc6425f7e76bef4c448938fd..1b6ad67d0d49cc4d03df2a96c548c905c781df08 100644 --- a/interfaces/innerkits/dm/display_manager.h +++ b/interfaces/innerkits/dm/display_manager.h @@ -46,8 +46,8 @@ public: sptr surface, DisplayId displayIdToMirror, int32_t flags); bool DestroyVirtualDisplay(DisplayId displayId); - sptr GetScreenshot(DisplayId displayId); - sptr GetScreenshot(DisplayId displayId, const Media::Rect &rect, + std::shared_ptr GetScreenshot(DisplayId displayId); + std::shared_ptr GetScreenshot(DisplayId displayId, const Media::Rect &rect, const Media::Size &size, int rotation); bool WakeUpBegin(PowerStateChangeReason reason); diff --git a/wmserver/include/window_manager_service.h b/wmserver/include/window_manager_service.h index 3f5422220d9c3d593ae1e1474a2749edd3282612..dce096d91eeb2120a1da8c9222c98a39924c6f47 100644 --- a/wmserver/include/window_manager_service.h +++ b/wmserver/include/window_manager_service.h @@ -54,6 +54,7 @@ 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, diff --git a/wmserver/include/window_node_container.h b/wmserver/include/window_node_container.h index 4051cce4044c73ed6d65185b704b60ebc5f2a5a8..1f2abb492ff2ab247481e1324640f028d26caf84 100644 --- a/wmserver/include/window_node_container.h +++ b/wmserver/include/window_node_container.h @@ -51,6 +51,7 @@ public: Rect GetDisplayRect() const; sptr GetTopImmersiveNode() const; void NotifySystemBarIfChanged(); + std::shared_ptr GetDisplayNode() const; private: void AssignZOrder(sptr& node); diff --git a/wmserver/src/window_manager_service.cpp b/wmserver/src/window_manager_service.cpp index 7b8478581a11cdde962ab9e1850820840735e273..56bcf6408690cdd4ae38ca8dc4705269a4c257c7 100644 --- a/wmserver/src/window_manager_service.cpp +++ b/wmserver/src/window_manager_service.cpp @@ -226,6 +226,11 @@ 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) { diff --git a/wmserver/src/window_node_container.cpp b/wmserver/src/window_node_container.cpp index 94b11f3f2c170158895f37ef831f32d15351a9bf..96d5291385627be427647db582b413f475f3b701 100644 --- a/wmserver/src/window_node_container.cpp +++ b/wmserver/src/window_node_container.cpp @@ -457,5 +457,10 @@ Rect WindowNodeContainer::GetDisplayRect() const { return displayRect_; } + +std::shared_ptr WindowNodeContainer::GetDisplayNode() const +{ + return displayNode_; +} } }