diff --git a/wmserver/BUILD.gn b/wmserver/BUILD.gn index 86ce6f97cad9ba09b7a7f3957d9af8230116708f..a32aacdcebc89a806ba6ebaeeffe717dc6e069f3 100644 --- a/wmserver/BUILD.gn +++ b/wmserver/BUILD.gn @@ -19,6 +19,7 @@ config("libwms_config") { include_dirs = [ "include", + "include/window_snapshot", "//utils/system/safwk/native/include", "//foundation/windowmanager/interfaces/innerkits/wm", "//foundation/windowmanager/interfaces/innerkits/dm", @@ -49,6 +50,9 @@ ohos_shared_library("libwms") { "src/window_node.cpp", "src/window_node_container.cpp", "src/window_root.cpp", + "src/window_snapshot/snapshot_controller.cpp", + "src/window_snapshot/snapshot_proxy.cpp", + "src/window_snapshot/snapshot_stub.cpp", "src/window_zorder_policy.cpp", ] @@ -58,6 +62,8 @@ ohos_shared_library("libwms") { "//base/hiviewdfx/hilog/interfaces/native/innerkits:libhilog", "//foundation/distributedschedule/safwk/interfaces/innerkits/safwk:system_ability_fwk", "//foundation/distributedschedule/samgr/interfaces/innerkits/samgr_proxy:samgr_proxy", + "//foundation/graphic/standard:libsurface", + "//foundation/graphic/standard/rosen/modules/render_service_base:librender_service_base", "//utils/native/base:utils", ] diff --git a/wmserver/include/window_manager_service.h b/wmserver/include/window_manager_service.h index 2cee42de12eaa89f08936248270da22edce82eea..d14c936b6aaf797fb8a4e324aa92c52d9ed0a5c2 100644 --- a/wmserver/include/window_manager_service.h +++ b/wmserver/include/window_manager_service.h @@ -27,6 +27,7 @@ #include "window_controller.h" #include "window_manager_stub.h" #include "window_root.h" +#include "snapshot_controller.h" namespace OHOS { namespace Rosen { @@ -66,12 +67,14 @@ protected: private: bool Init(); + void RegisterSnapshotHandler(); void OnWindowEvent(Event event, uint32_t windowId); static inline SingletonDelegator delegator; std::recursive_mutex mutex_; sptr windowRoot_; sptr windowController_; sptr inputWindowMonitor_; + sptr snapshotController_; const int WAITING_RS_TIME = 10; }; } diff --git a/wmserver/include/window_root.h b/wmserver/include/window_root.h index 486290089b6235893876f02e6bee327e80e640e3..d2f79b032a3838a602db41ef153f43ad2fb0f0eb 100644 --- a/wmserver/include/window_root.h +++ b/wmserver/include/window_root.h @@ -71,6 +71,8 @@ public: void RegisterFocusChangedListener(const sptr& windowManagerAgent); void UnregisterFocusChangedListener(const sptr& windowManagerAgent); + std::shared_ptr GetSurfaceNodeByAbilityToken(const sptr& abilityToken) const; + private: void OnRemoteDied(const sptr& remoteObject); void ClearWindowManagerAgent(const sptr& remoteObject); diff --git a/wmserver/include/window_snapshot/snapshot_controller.h b/wmserver/include/window_snapshot/snapshot_controller.h new file mode 100644 index 0000000000000000000000000000000000000000..49ef2d52a5de0ad72521ba07bb71318b8c76fd3d --- /dev/null +++ b/wmserver/include/window_snapshot/snapshot_controller.h @@ -0,0 +1,66 @@ +/* + * 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. + */ + +#ifndef OHOS_ROSEN_SNAPSHOT_CONTROLLER_H +#define OHOS_ROSEN_SNAPSHOT_CONTROLLER_H + +#include +#include +#include "window_root.h" +#include "snapshot_stub.h" +#include "window_manager_hilog.h" + +namespace OHOS { +namespace Rosen { +class SnapshotController : public SnapshotStub { +public: + SnapshotController(sptr& root) : windowRoot_(root), rsInterface_(RSInterfaces::GetInstance()) {}; + ~SnapshotController() = default; + + int32_t GetSnapshot(const sptr &token, AAFwk::Snapshot& snapshot) override; + +private: + sptr windowRoot_; + RSInterfaces& rsInterface_; + + WMError TakeSnapshot(const std::shared_ptr& surfaceNode, AAFwk::Snapshot& snapshot); + + class GetSurfaceCapture : public SurfaceCaptureCallback { + public: + GetSurfaceCapture() = default; + ~GetSurfaceCapture() {}; + 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; + }; +}; +} +} +#endif // OHOS_ROSEN_SNAPSHOT_CONTROLLER_H diff --git a/wmserver/include/window_snapshot/snapshot_proxy.h b/wmserver/include/window_snapshot/snapshot_proxy.h new file mode 100644 index 0000000000000000000000000000000000000000..cf433d53c2696fe32fa915f23e8f3fa8a890217b --- /dev/null +++ b/wmserver/include/window_snapshot/snapshot_proxy.h @@ -0,0 +1,37 @@ +/* + * 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. + */ + +#ifndef OHOS_SNAPSHOT_PROXY_H +#define OHOS_SNAPSHOT_PROXY_H + +#include +#include +#include +#include "wm_common.h" + +namespace OHOS { +namespace Rosen { +class SnapshotProxy : public IRemoteProxy { +public: + explicit SnapshotProxy(const sptr& impl) : IRemoteProxy(impl) {}; + ~SnapshotProxy() = default; + int32_t GetSnapshot(const sptr &token, AAFwk::Snapshot& snapshot) override; + +private: + static inline BrokerDelegator delegator_; +}; +} +} +#endif // OHOS_SNAPSHOT_PROXY_H diff --git a/wmserver/include/window_snapshot/snapshot_stub.h b/wmserver/include/window_snapshot/snapshot_stub.h new file mode 100644 index 0000000000000000000000000000000000000000..76dc374a21163e2972a8f528d5446694d1701d13 --- /dev/null +++ b/wmserver/include/window_snapshot/snapshot_stub.h @@ -0,0 +1,35 @@ +/* + * 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. + */ + +#ifndef OHOS_SNAPSHOT_STUB_H +#define OHOS_SNAPSHOT_STUB_H + +#include +#include +#include + +namespace OHOS { +using namespace AAFwk; +namespace Rosen { +class SnapshotStub : public IRemoteStub { +public: + SnapshotStub() = default; + ~SnapshotStub() = default; + virtual int32_t OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, + MessageOption &option) override; +}; +} +} +#endif // OHOS_SNAPSHOT_STUB_H diff --git a/wmserver/src/window_manager_service.cpp b/wmserver/src/window_manager_service.cpp index 594f9a0f6c88f8d4db67d330a8c73677435da8fb..c62b771fe51406d5ac1a888c3b456ac715f47730 100644 --- a/wmserver/src/window_manager_service.cpp +++ b/wmserver/src/window_manager_service.cpp @@ -19,6 +19,7 @@ #include #include +#include #include "dm_common.h" #include "window_manager_hilog.h" @@ -38,6 +39,7 @@ WindowManagerService::WindowManagerService() : SystemAbility(WINDOW_MANAGER_SERV std::bind(&WindowManagerService::OnWindowEvent, this, std::placeholders::_1, std::placeholders::_2)); windowController_ = new WindowController(windowRoot_); inputWindowMonitor_ = new InputWindowMonitor(windowRoot_); + snapshotController_ = new SnapshotController(windowRoot_); } void WindowManagerService::OnStart() @@ -46,6 +48,15 @@ void WindowManagerService::OnStart() if (!Init()) { return; } + RegisterSnapshotHandler(); +} + +void WindowManagerService::RegisterSnapshotHandler() +{ + if (!snapshotController_) { + snapshotController_ = new SnapshotController(windowRoot_); + } + AAFwk::AbilityManagerClient::GetInstance()->RegisterSnapshotHandler(snapshotController_); } bool WindowManagerService::Init() diff --git a/wmserver/src/window_root.cpp b/wmserver/src/window_root.cpp index ce2ccbe20cfe93015fa38982ab08684faaa6e251..c8b1128f5f92a7b28315ad0dee64c845c060abbe 100644 --- a/wmserver/src/window_root.cpp +++ b/wmserver/src/window_root.cpp @@ -251,6 +251,18 @@ void WindowRoot::UpdateFocusStatus(uint32_t windowId, const sptr& } } +std::shared_ptr WindowRoot::GetSurfaceNodeByAbilityToken(const sptr &abilityToken) const +{ + for (auto iter = windowNodeMap_.begin(); iter != windowNodeMap_.end(); iter++) { + if (iter->second->abilityToken_ != abilityToken) { + continue; + } + return iter->second->surfaceNode_; + } + WLOGFE("could not find required abilityToken!"); + return nullptr; +} + void WindowRoot::OnRemoteDied(const sptr& remoteObject) { std::lock_guard lock(mutex_); diff --git a/wmserver/src/window_snapshot/snapshot_controller.cpp b/wmserver/src/window_snapshot/snapshot_controller.cpp new file mode 100644 index 0000000000000000000000000000000000000000..378b93616bf5a0838993cc2bbd88b6c0155001df --- /dev/null +++ b/wmserver/src/window_snapshot/snapshot_controller.cpp @@ -0,0 +1,61 @@ +/* + * 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 "snapshot_controller.h" +#include "window_manager_hilog.h" +#include "wm_common.h" + +namespace OHOS { +namespace Rosen { +namespace { + constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, 0, "SnapshotController"}; +} + +WMError SnapshotController::TakeSnapshot(const std::shared_ptr& surfaceNode, Snapshot& snapshot) +{ + std::shared_ptr callback = std::make_shared(); + rsInterface_.TakeSurfaceCapture(surfaceNode, 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 WMError::WM_ERROR_NULLPTR; + } + } + std::shared_ptr pixelMap = callback->GetPixelMap(); + + if (pixelMap == nullptr) { + WLOGFE("Failed to get pixelmap, return nullptr!"); + return WMError::WM_ERROR_NULLPTR; + } + snapshot.SetPixelMap(pixelMap); + return WMError::WM_OK; +} + +int32_t SnapshotController::GetSnapshot(const sptr &token, Snapshot& snapshot) +{ + std::shared_ptr surfaceNode = windowRoot_->GetSurfaceNodeByAbilityToken(token); + if (surfaceNode == nullptr) { + WLOGFE("Get surfaceNode failed!"); + return static_cast(WMError::WM_ERROR_NULLPTR); + } + TakeSnapshot(surfaceNode, snapshot); + return static_cast(TakeSnapshot(surfaceNode, snapshot)); +} +} // namespace Rosen +} // namespace OHOS \ No newline at end of file diff --git a/wmserver/src/window_snapshot/snapshot_proxy.cpp b/wmserver/src/window_snapshot/snapshot_proxy.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e61d67f50d7654b875a8cecefb1ecf2e107eb46a --- /dev/null +++ b/wmserver/src/window_snapshot/snapshot_proxy.cpp @@ -0,0 +1,54 @@ +/* + * 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 "snapshot_proxy.h" +#include "ipc_types.h" +#include "pixel_map.h" +#include "window_manager_hilog.h" +#include "wm_common.h" + +namespace OHOS { +namespace Rosen { +namespace { + constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, 0, "SnapshotProxy"}; +} + +int32_t SnapshotProxy::GetSnapshot(const sptr &token, AAFwk::Snapshot& snapshot) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + + if (!data.WriteInterfaceToken(GetDescriptor())) { + WLOGFE("WriteInterfaceToken failed"); + return static_cast(WMError::WM_ERROR_IPC_FAILED); + } + + if (!data.WriteRemoteObject(token)) { + WLOGFE("Write ability token failed"); + return static_cast(WMError::WM_ERROR_IPC_FAILED); + } + + if (Remote()->SendRequest(TRANS_ID_GET_SNAPSHOT, data, reply, option) != ERR_NONE) { + return static_cast(WMError::WM_ERROR_IPC_FAILED); + } + + std::shared_ptr pixelMap(reply.ReadParcelable()); + snapshot.SetPixelMap(pixelMap); + int32_t ret = reply.ReadInt32(); + return ret; +} +} +} \ No newline at end of file diff --git a/wmserver/src/window_snapshot/snapshot_stub.cpp b/wmserver/src/window_snapshot/snapshot_stub.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d4435b4faba874d93f57febcc0deafc3fb0b837c --- /dev/null +++ b/wmserver/src/window_snapshot/snapshot_stub.cpp @@ -0,0 +1,56 @@ +/* + * 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 "snapshot_stub.h" +#include +#include "window_manager_hilog.h" +#include "wm_common.h" + +namespace OHOS { +namespace Rosen { +namespace { + constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, 0, "SnapshotStub"}; +} + +int32_t SnapshotStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, + MessageOption &option) +{ + WLOGFI("SnapshotStub::OnRemoteRequest code is %{public}d", code); + if (data.ReadInterfaceToken() != GetDescriptor()) { + WLOGFE("InterfaceToken check failed!"); + return -1; + } + switch (code) { + case TRANS_ID_GET_SNAPSHOT : { + AAFwk::Snapshot snapshot_; + sptr abilityObject = data.ReadRemoteObject(); + int32_t ret = GetSnapshot(abilityObject, snapshot_); + if (snapshot_.GetPixelMap() == nullptr) { + reply.WriteParcelable(nullptr); + reply.WriteInt32(static_cast(WMError::WM_ERROR_NULLPTR)); + break; + } + reply.WriteParcelable(snapshot_.GetPixelMap().get()); + reply.WriteInt32(ret); + break; + } + default: + WLOGFW("unknown transaction code"); + return IPCObjectStub::OnRemoteRequest(code, data, reply, option); + } + return 0; +} +} +}