diff --git a/interfaces/innerkits/wm/wm_common.h b/interfaces/innerkits/wm/wm_common.h index 2afad342..f2a54af6 100644 --- a/interfaces/innerkits/wm/wm_common.h +++ b/interfaces/innerkits/wm/wm_common.h @@ -151,6 +151,8 @@ namespace { constexpr float UNDEFINED_BRIGHTNESS = -1.0f; constexpr float MINIMUM_BRIGHTNESS = 0.0f; constexpr float MAXIMUM_BRIGHTNESS = 1.0f; + constexpr int32_t INVALID_PID = -1; + constexpr int32_t INVALID_UID = -1; } struct SystemBarProperty { diff --git a/utils/include/window_property.h b/utils/include/window_property.h index 0cd4d7c6..d412fd0f 100644 --- a/utils/include/window_property.h +++ b/utils/include/window_property.h @@ -66,6 +66,8 @@ public: void SetAnimationFlag(uint32_t animationFlag); void SetWindowSizeChangeReason(WindowSizeChangeReason reason); void SetTokenState(bool hasToken); + void SetWindowPid(int32_t pid); + void SetWindowUid(int32_t uid); WindowSizeChangeReason GetWindowSizeChangeReason() const; const std::string& GetWindowName() const; @@ -96,6 +98,8 @@ public: bool GetDecorEnable() const; const PointInfo& GetHitOffset() const; uint32_t GetAnimationFlag() const; + int32_t GetWindowPid() const; + int32_t GetWindowUid() const; virtual bool Marshalling(Parcel& parcel) const override; static WindowProperty* Unmarshalling(Parcel& parcel); @@ -134,6 +138,8 @@ private: { WindowType::WINDOW_TYPE_NAVIGATION_BAR, SystemBarProperty() }, }; bool isDecorEnable_ { false }; + int32_t pid_ { INVALID_PID }; + int32_t uid_ { INVALID_UID }; DEFINE_VAR_DEFAULT_FUNC_GET_SET(Orientation, RequestedOrientation, requestedOrientation, Orientation::UNSPECIFIED); }; } diff --git a/utils/src/window_property.cpp b/utils/src/window_property.cpp index 04264759..e600ac93 100644 --- a/utils/src/window_property.cpp +++ b/utils/src/window_property.cpp @@ -165,6 +165,16 @@ void WindowProperty::SetWindowSizeChangeReason(WindowSizeChangeReason reason) windowSizeChangeReason_ = reason; } +void WindowProperty::SetWindowPid(int32_t pid) +{ + pid_ = pid; +} + +void WindowProperty::SetWindowUid(int32_t uid) +{ + uid_ = uid; +} + WindowSizeChangeReason WindowProperty::GetWindowSizeChangeReason() const { return windowSizeChangeReason_; @@ -325,6 +335,16 @@ bool WindowProperty::GetTokenState() const return tokenState_; } +int32_t WindowProperty::GetWindowPid() const +{ + return pid_; +} + +int32_t WindowProperty::GetWindowUid() const +{ + return uid_; +} + bool WindowProperty::MapMarshalling(Parcel& parcel) const { auto size = sysBarPropMap_.size(); @@ -373,7 +393,8 @@ bool WindowProperty::Marshalling(Parcel& parcel) const parcel.WriteInt32(hitOffset_.x) && parcel.WriteInt32(hitOffset_.y) && parcel.WriteUint32(animationFlag_) && parcel.WriteUint32(static_cast(windowSizeChangeReason_)) && parcel.WriteBool(tokenState_) && parcel.WriteUint32(callingWindow_) && parcel.WriteUint32(static_cast(requestedOrientation_)) && - parcel.WriteBool(turnScreenOn_) && parcel.WriteBool(keepScreenOn_); + parcel.WriteBool(turnScreenOn_) && parcel.WriteBool(keepScreenOn_) && + parcel.WriteInt32(pid_) && parcel.WriteInt32(uid_); } WindowProperty* WindowProperty::Unmarshalling(Parcel& parcel) @@ -414,6 +435,8 @@ WindowProperty* WindowProperty::Unmarshalling(Parcel& parcel) property->SetRequestedOrientation(static_cast(parcel.ReadUint32())); property->SetTurnScreenOn(parcel.ReadBool()); property->SetKeepScreenOn(parcel.ReadBool()); + property->SetWindowPid(parcel.ReadInt32()); + property->SetWindowUid(parcel.ReadInt32()); return property; } @@ -448,6 +471,8 @@ void WindowProperty::CopyFrom(const sptr& property) requestedOrientation_ = property->requestedOrientation_; turnScreenOn_ = property->turnScreenOn_; keepScreenOn_ = property->keepScreenOn_; + pid_ = property->pid_; + uid_ = property->uid_; } } } diff --git a/wmserver/BUILD.gn b/wmserver/BUILD.gn index fb3ad1cf..d751ccc8 100644 --- a/wmserver/BUILD.gn +++ b/wmserver/BUILD.gn @@ -93,6 +93,7 @@ ohos_shared_library("libwms") { "src/window_snapshot/snapshot_controller.cpp", "src/window_snapshot/snapshot_proxy.cpp", "src/window_snapshot/snapshot_stub.cpp", + "src/window_task_looper.cpp", "src/window_zorder_policy.cpp", "src/zidl/window_manager_stub.cpp", ] diff --git a/wmserver/include/starting_window.h b/wmserver/include/starting_window.h index 6cb9c904..0fc85e83 100644 --- a/wmserver/include/starting_window.h +++ b/wmserver/include/starting_window.h @@ -32,7 +32,7 @@ public: static sptr CreateWindowNode(sptr info, uint32_t winId); static void HandleClientWindowCreate(sptr& node, sptr& window, - uint32_t& windowId, const std::shared_ptr& surfaceNode); + uint32_t& windowId, const std::shared_ptr& surfaceNode, sptr& property); static void DrawStartingWindow(sptr& node, sptr pixelMap, uint32_t bkgColor, bool isColdStart); static void UpdateRSTree(sptr& node); diff --git a/wmserver/include/window_dumper.h b/wmserver/include/window_dumper.h index 266e7c02..4f4458e5 100644 --- a/wmserver/include/window_dumper.h +++ b/wmserver/include/window_dumper.h @@ -27,7 +27,7 @@ enum DumpType : uint32_t { }; class WindowDumper : public RefBase { public: - WindowDumper(const sptr& root, std::recursive_mutex& mutex) : windowRoot_(root), mutex_(mutex) {} + WindowDumper(const sptr& root) : windowRoot_(root) {} WMError Dump(int fd, const std::vector& args) const; private: @@ -37,7 +37,6 @@ private: void ShowHelpInfo(std::string& dumpInfo) const; void ShowIllegalArgsInfo(std::string& dumpInfo) const; const sptr windowRoot_; - std::recursive_mutex& mutex_; }; } } diff --git a/wmserver/include/window_manager_service.h b/wmserver/include/window_manager_service.h index c0e11716..577cdc37 100644 --- a/wmserver/include/window_manager_service.h +++ b/wmserver/include/window_manager_service.h @@ -32,6 +32,7 @@ #include "zidl/window_manager_stub.h" #include "window_dumper.h" #include "window_root.h" +#include "window_task_looper.h" #include "snapshot_controller.h" namespace OHOS { @@ -103,13 +104,12 @@ private: bool Init(); void RegisterSnapshotHandler(); void RegisterWindowManagerServiceHandler(); - void OnWindowEvent(Event event, uint32_t windowId); + void OnWindowEvent(Event event, const sptr& remoteObject); void NotifyDisplayStateChange(DisplayId id, DisplayStateChangeType type); WMError GetFocusWindowInfo(sptr& abilityToken); void ConfigureWindowManagerService(); static inline SingletonDelegator delegator; - std::recursive_mutex mutex_; sptr windowRoot_; sptr windowController_; sptr inputWindowMonitor_; @@ -120,6 +120,7 @@ private: sptr windowDumper_; SystemConfig systemConfig_; ModeChangeHotZonesConfig hotZonesConfig_ { false, 0, 0, 0 }; + std::unique_ptr wmsTaskLooper_; bool startingOpen_ = true; }; } diff --git a/wmserver/include/window_node.h b/wmserver/include/window_node.h index e33a692d..ba03b2e5 100644 --- a/wmserver/include/window_node.h +++ b/wmserver/include/window_node.h @@ -31,18 +31,12 @@ public: std::shared_ptr surfaceNode) : surfaceNode_(surfaceNode), property_(property), windowToken_(window) { - callingPid_ = IPCSkeleton::GetCallingPid(); - callingUid_ = IPCSkeleton::GetCallingUid(); } WindowNode() : property_(new WindowProperty()) { - callingPid_ = IPCSkeleton::GetCallingPid(); - callingUid_ = IPCSkeleton::GetCallingUid(); } explicit WindowNode(const sptr& property) : property_(property) { - callingPid_ = IPCSkeleton::GetCallingPid(); - callingUid_ = IPCSkeleton::GetCallingUid(); } ~WindowNode() = default; @@ -62,8 +56,8 @@ public: void SetTurnScreenOn(bool turnScreenOn); void SetKeepScreenOn(bool keepScreenOn); void SetCallingWindow(uint32_t windowId); - void SetCallingPid(); - void SetCallingUid(); + void SetCallingPid(int32_t pid); + void SetCallingUid(int32_t uid); void SetWindowToken(sptr window); uint32_t GetCallingWindow() const; void SetWindowSizeChangeReason(WindowSizeChangeReason reason); @@ -117,8 +111,6 @@ private: sptr property_ = nullptr; sptr windowToken_ = nullptr; Rect hotZoneRect_ { 0, 0, 0, 0 }; - int32_t callingPid_; - int32_t callingUid_; WindowSizeChangeReason windowSizeChangeReason_ {WindowSizeChangeReason::UNDEFINED}; }; } // Rosen diff --git a/wmserver/include/window_root.h b/wmserver/include/window_root.h index 377f3952..d6716a11 100644 --- a/wmserver/include/window_root.h +++ b/wmserver/include/window_root.h @@ -30,10 +30,10 @@ enum class Event : uint32_t { }; class WindowRoot : public RefBase { -using Callback = std::function; +using Callback = std::function& remoteObject)>; public: - WindowRoot(std::recursive_mutex& mutex, Callback callback) : mutex_(mutex), callback_(callback) {} + explicit WindowRoot(Callback callback) : callback_(callback) {} ~WindowRoot() = default; sptr GetOrCreateWindowNodeContainer(DisplayId displayId); @@ -82,6 +82,7 @@ public: ModeChangeHotZones& hotZones, const ModeChangeHotZonesConfig& config); std::vector GetAllDisplayIds() const; uint32_t GetTotalWindowNum(); + uint32_t GetWindowIdByObject(const sptr& remoteObject); private: void OnRemoteDied(const sptr& remoteObject); WMError DestroyWindowInner(sptr& node); @@ -102,7 +103,6 @@ private: void DestroyLeakStartingWindow(); WMError PostProcessAddWindowNode(sptr& node, sptr& parentNode, sptr& container); - std::recursive_mutex& mutex_; std::map> windowNodeMap_; std::map, uint32_t> windowIdMap_; std::map> windowNodeContainerMap_; diff --git a/wmserver/include/window_task_looper.h b/wmserver/include/window_task_looper.h new file mode 100644 index 00000000..9a85f948 --- /dev/null +++ b/wmserver/include/window_task_looper.h @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifndef OHOS_ROSEN_WINDOW_TASK_LOOPER_H +#define OHOS_ROSEN_WINDOW_TASK_LOOPER_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace OHOS { +namespace Rosen { +template +class ScheduledTask : public RefBase { +public: + static auto Create(SyncTask&& task) + { + sptr> t(new ScheduledTask(std::forward(task))); + return std::make_pair(t, t->task_.get_future()); + } + + void Run() + { + task_(); + } + +private: + explicit ScheduledTask(SyncTask&& task) : task_(std::move(task)) {} + ~ScheduledTask() {} + + using Return = std::invoke_result_t; + std::packaged_task task_; +}; + +class WindowTaskLooper { +public: + using Task = std::function; + WindowTaskLooper() = default; + ~WindowTaskLooper(); + + template> + std::future ScheduleTask(SyncTask&& task) + { + auto [scheduledTask, taskFuture] = ScheduledTask::Create(std::forward(task)); + PostTask([t(std::move(scheduledTask))]() { t->Run(); }); + return std::move(taskFuture); + } + void PostTask(const Task& task); + void WakeUp(); + void Start() noexcept; + bool IsRunning(); + +private: + void WaitTask(); + void TaskProcessThread(); + void ExecuteAllTask(); + +private: + mutable std::mutex mtx_; + bool wakeUp_ = false; + std::condition_variable taskCond_; + mutable std::atomic running_ { false }; + std::vector taskQ_; + std::unique_ptr taskProcessThread_; +}; +} // namespace Rosen +} // namespace OHOS +#endif \ No newline at end of file diff --git a/wmserver/src/starting_window.cpp b/wmserver/src/starting_window.cpp index eab65ebb..32de0d00 100644 --- a/wmserver/src/starting_window.cpp +++ b/wmserver/src/starting_window.cpp @@ -103,12 +103,12 @@ void StartingWindow::DrawStartingWindow(sptr& node, } void StartingWindow::HandleClientWindowCreate(sptr& node, sptr& window, - uint32_t& windowId, const std::shared_ptr& surfaceNode) + uint32_t& windowId, const std::shared_ptr& surfaceNode, sptr& property) { node->surfaceNode_ = surfaceNode; node->SetWindowToken(window); - node->SetCallingPid(); - node->SetCallingUid(); + node->SetCallingPid(property->GetWindowPid()); + node->SetCallingUid(property->GetWindowUid()); windowId = node->GetWindowId(); WLOGFI("after set Id:%{public}u, requestRect:[%{public}d, %{public}d, %{public}u, %{public}u]", node->GetWindowId(), node->GetRequestRect().posX_, node->GetRequestRect().posY_, diff --git a/wmserver/src/window_controller.cpp b/wmserver/src/window_controller.cpp index 19381adc..dd3b05e2 100644 --- a/wmserver/src/window_controller.cpp +++ b/wmserver/src/window_controller.cpp @@ -152,7 +152,7 @@ WMError WindowController::CreateWindow(sptr& window, sptr node = windowRoot_->FindWindowNodeWithToken(token); if (node != nullptr && WindowHelper::IsMainWindow(property->GetWindowType()) && node->startingWindowShown_) { - StartingWindow::HandleClientWindowCreate(node, window, windowId, surfaceNode); + StartingWindow::HandleClientWindowCreate(node, window, windowId, surfaceNode, property); windowRoot_->AddDeathRecipient(node); return WMError::WM_OK; } diff --git a/wmserver/src/window_dumper.cpp b/wmserver/src/window_dumper.cpp index 711a6767..6a15c2d9 100644 --- a/wmserver/src/window_dumper.cpp +++ b/wmserver/src/window_dumper.cpp @@ -123,7 +123,6 @@ WMError WindowDumper::DumpAllWindowInfo(std::string& dumpInfo) const { std::map windowNodeContainers; std::vector displayIds = DisplayManagerServiceInner::GetInstance().GetAllDisplayIds(); - std::lock_guard lock(mutex_); for (DisplayId displayId : displayIds) { auto windowNodeContainer = windowRoot_->GetOrCreateWindowNodeContainer(displayId); if (windowNodeContainer != nullptr) { diff --git a/wmserver/src/window_manager_service.cpp b/wmserver/src/window_manager_service.cpp index e8a9d45a..0a3b0b27 100644 --- a/wmserver/src/window_manager_service.cpp +++ b/wmserver/src/window_manager_service.cpp @@ -48,13 +48,15 @@ const bool REGISTER_RESULT = SystemAbility::MakeAndRegisterAbility(&SingletonCon WindowManagerService::WindowManagerService() : SystemAbility(WINDOW_MANAGER_SERVICE_ID, true) { - windowRoot_ = new WindowRoot(mutex_, + windowRoot_ = new WindowRoot( std::bind(&WindowManagerService::OnWindowEvent, this, std::placeholders::_1, std::placeholders::_2)); inputWindowMonitor_ = new InputWindowMonitor(windowRoot_); windowController_ = new WindowController(windowRoot_, inputWindowMonitor_); snapshotController_ = new SnapshotController(windowRoot_); dragController_ = new DragController(windowRoot_); + windowDumper_ = new WindowDumper(windowRoot_); freezeDisplayController_ = new FreezeController(); + wmsTaskLooper_ = std::make_unique(); startingOpen_ = system::GetParameter("persist.window.sw.enabled", "1") == "1"; // startingWin default enabled } @@ -69,6 +71,7 @@ void WindowManagerService::OnStart() DisplayManagerServiceInner::GetInstance().RegisterDisplayChangeListener(listener); RegisterSnapshotHandler(); RegisterWindowManagerServiceHandler(); + wmsTaskLooper_->Start(); } void WindowManagerService::RegisterSnapshotHandler() @@ -181,9 +184,11 @@ bool WindowManagerService::Init() int WindowManagerService::Dump(int fd, const std::vector& args) { if (windowDumper_ == nullptr) { - windowDumper_ = new WindowDumper(windowRoot_, mutex_); + windowDumper_ = new WindowDumper(windowRoot_); } - return static_cast(windowDumper_->Dump(fd, args)); + return wmsTaskLooper_->ScheduleTask([this, fd, &args]() { + return static_cast(windowDumper_->Dump(fd, args)); + }).get(); } void WindowManagerService::ConfigureWindowManagerService() @@ -230,41 +235,44 @@ void WindowManagerService::OnStop() WMError WindowManagerService::NotifyWindowTransition( sptr& fromInfo, sptr& toInfo) { - std::lock_guard lock(mutex_); - return windowController_->NotifyWindowTransition(fromInfo, toInfo); + return wmsTaskLooper_->ScheduleTask([this, &fromInfo, &toInfo]() { + return windowController_->NotifyWindowTransition(fromInfo, toInfo); + }).get(); } WMError WindowManagerService::GetFocusWindowInfo(sptr& abilityToken) { - std::lock_guard lock(mutex_); - return windowController_->GetFocusWindowInfo(abilityToken); + return wmsTaskLooper_->ScheduleTask([this, &abilityToken]() { + return windowController_->GetFocusWindowInfo(abilityToken); + }).get(); } void WindowManagerService::StartingWindow(sptr info, sptr pixelMap, bool isColdStart, uint32_t bkgColor) { - std::lock_guard lock(mutex_); if (!startingOpen_) { WLOGFI("startingWindow not open!"); return; } - return windowController_->StartingWindow(info, pixelMap, bkgColor, isColdStart); + return wmsTaskLooper_->ScheduleTask([this, &info, &pixelMap, isColdStart, bkgColor]() { + return windowController_->StartingWindow(info, pixelMap, bkgColor, isColdStart); + }).wait(); } void WindowManagerService::CancelStartingWindow(sptr abilityToken) { - std::lock_guard lock(mutex_); if (!startingOpen_) { WLOGFI("startingWindow not open!"); return; } - return windowController_->CancelStartingWindow(abilityToken); + return wmsTaskLooper_->ScheduleTask([this, &abilityToken]() { + return windowController_->CancelStartingWindow(abilityToken); + }).wait(); } WMError WindowManagerService::CreateWindow(sptr& window, sptr& property, const std::shared_ptr& surfaceNode, uint32_t& windowId, sptr token) { - WM_SCOPED_TRACE("wms:CreateWindow(%u)", windowId); if (window == nullptr || property == nullptr || surfaceNode == nullptr) { WLOGFE("window is invalid"); return WMError::WM_ERROR_NULLPTR; @@ -273,73 +281,83 @@ WMError WindowManagerService::CreateWindow(sptr& window, sptr lock(mutex_); - return windowController_->CreateWindow(window, property, surfaceNode, windowId, token); + return wmsTaskLooper_->ScheduleTask([this, &window, &property, &surfaceNode, &windowId, &token]() { + WM_SCOPED_TRACE("wms:CreateWindow(%u)", windowId); + return windowController_->CreateWindow(window, property, surfaceNode, windowId, token); + }).get(); } WMError WindowManagerService::AddWindow(sptr& property) { - Rect rect = property->GetRequestRect(); - uint32_t windowId = property->GetWindowId(); - WLOGFI("[WMS] Add: %{public}5d %{public}4d %{public}4d %{public}4d [%{public}4d %{public}4d " \ - "%{public}4d %{public}4d]", windowId, property->GetWindowType(), property->GetWindowMode(), - property->GetWindowFlags(), rect.posX_, rect.posY_, rect.width_, rect.height_); - WM_SCOPED_TRACE("wms:AddWindow(%u)", windowId); - std::lock_guard lock(mutex_); - WMError res = windowController_->AddWindowNode(property); - if (property->GetWindowType() == WindowType::WINDOW_TYPE_DRAGGING_EFFECT) { - dragController_->StartDrag(windowId); - } - return res; + return wmsTaskLooper_->ScheduleTask([this, &property]() { + Rect rect = property->GetRequestRect(); + uint32_t windowId = property->GetWindowId(); + WLOGFI("[WMS] Add: %{public}5d %{public}4d %{public}4d %{public}4d [%{public}4d %{public}4d " \ + "%{public}4d %{public}4d]", windowId, property->GetWindowType(), property->GetWindowMode(), + property->GetWindowFlags(), rect.posX_, rect.posY_, rect.width_, rect.height_); + WM_SCOPED_TRACE("wms:AddWindow(%u)", windowId); + WMError res = windowController_->AddWindowNode(property); + if (property->GetWindowType() == WindowType::WINDOW_TYPE_DRAGGING_EFFECT) { + dragController_->StartDrag(windowId); + } + return res; + }).get(); } WMError WindowManagerService::RemoveWindow(uint32_t windowId) { - WLOGFI("[WMS] Remove: %{public}u", windowId); - WM_SCOPED_TRACE("wms:RemoveWindow(%u)", windowId); - std::lock_guard lock(mutex_); - return windowController_->RemoveWindowNode(windowId); + return wmsTaskLooper_->ScheduleTask([this, windowId]() { + WLOGFI("[WMS] Remove: %{public}u", windowId); + WM_SCOPED_TRACE("wms:RemoveWindow(%u)", windowId); + return windowController_->RemoveWindowNode(windowId); + }).get(); } WMError WindowManagerService::DestroyWindow(uint32_t windowId, bool onlySelf) { - WLOGFI("[WMS] Destroy: %{public}u", windowId); - WM_SCOPED_TRACE("wms:DestroyWindow(%u)", windowId); - std::lock_guard lock(mutex_); - auto node = windowRoot_->GetWindowNode(windowId); - if (node != nullptr && node->GetWindowType() == WindowType::WINDOW_TYPE_DRAGGING_EFFECT) { - dragController_->FinishDrag(windowId); - } - return windowController_->DestroyWindow(windowId, onlySelf); + return wmsTaskLooper_->ScheduleTask([this, windowId, onlySelf]() { + WLOGFI("[WMS] Destroy: %{public}u", windowId); + WM_SCOPED_TRACE("wms:DestroyWindow(%u)", windowId); + auto node = windowRoot_->GetWindowNode(windowId); + if (node != nullptr && node->GetWindowType() == WindowType::WINDOW_TYPE_DRAGGING_EFFECT) { + dragController_->FinishDrag(windowId); + } + return windowController_->DestroyWindow(windowId, onlySelf); + }).get(); } WMError WindowManagerService::RequestFocus(uint32_t windowId) { - WLOGFI("[WMS] RequestFocus: %{public}u", windowId); - WM_SCOPED_TRACE("wms:RequestFocus"); - std::lock_guard lock(mutex_); - return windowController_->RequestFocus(windowId); + return wmsTaskLooper_->ScheduleTask([this, windowId]() { + WLOGFI("[WMS] RequestFocus: %{public}u", windowId); + WM_SCOPED_TRACE("wms:RequestFocus"); + return windowController_->RequestFocus(windowId); + }).get(); } WMError WindowManagerService::SetWindowBackgroundBlur(uint32_t windowId, WindowBlurLevel level) { - WM_SCOPED_TRACE("wms:SetWindowBackgroundBlur"); - std::lock_guard lock(mutex_); - return windowController_->SetWindowBackgroundBlur(windowId, level); + return wmsTaskLooper_->ScheduleTask([this, windowId, level]() { + WM_SCOPED_TRACE("wms:SetWindowBackgroundBlur"); + return windowController_->SetWindowBackgroundBlur(windowId, level); + }).get(); } WMError WindowManagerService::SetAlpha(uint32_t windowId, float alpha) { - WM_SCOPED_TRACE("wms:SetAlpha"); - std::lock_guard lock(mutex_); - return windowController_->SetAlpha(windowId, alpha); + return wmsTaskLooper_->ScheduleTask([this, windowId, alpha]() { + WM_SCOPED_TRACE("wms:SetAlpha"); + return windowController_->SetAlpha(windowId, alpha); + }).get(); } std::vector WindowManagerService::GetAvoidAreaByType(uint32_t windowId, AvoidAreaType avoidAreaType) { - WLOGFI("[WMS] GetAvoidAreaByType: %{public}u, Type: %{public}u", windowId, static_cast(avoidAreaType)); - std::lock_guard lock(mutex_); - return windowController_->GetAvoidAreaByType(windowId, avoidAreaType); + return wmsTaskLooper_->ScheduleTask([this, windowId, avoidAreaType]() { + WLOGFI("[WMS] GetAvoidAreaByType: %{public}u, Type: %{public}u", windowId, + static_cast(avoidAreaType)); + return windowController_->GetAvoidAreaByType(windowId, avoidAreaType); + }).get(); } void WindowManagerService::RegisterWindowManagerAgent(WindowManagerAgentType type, @@ -349,11 +367,12 @@ void WindowManagerService::RegisterWindowManagerAgent(WindowManagerAgentType typ WLOGFE("windowManagerAgent is null"); return; } - std::lock_guard lock(mutex_); - WindowManagerAgentController::GetInstance().RegisterWindowManagerAgent(windowManagerAgent, type); - if (type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_SYSTEM_BAR) { // if system bar, notify once - windowController_->NotifySystemBarTints(); - } + return wmsTaskLooper_->ScheduleTask([this, &windowManagerAgent, type]() { + WindowManagerAgentController::GetInstance().RegisterWindowManagerAgent(windowManagerAgent, type); + if (type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_SYSTEM_BAR) { // if system bar, notify once + windowController_->NotifySystemBarTints(); + } + }).wait(); } void WindowManagerService::UnregisterWindowManagerAgent(WindowManagerAgentType type, @@ -363,8 +382,9 @@ void WindowManagerService::UnregisterWindowManagerAgent(WindowManagerAgentType t WLOGFE("windowManagerAgent is null"); return; } - std::lock_guard lock(mutex_); - WindowManagerAgentController::GetInstance().UnregisterWindowManagerAgent(windowManagerAgent, type); + return wmsTaskLooper_->ScheduleTask([this, &windowManagerAgent, type]() { + WindowManagerAgentController::GetInstance().UnregisterWindowManagerAgent(windowManagerAgent, type); + }).wait(); } WMError WindowManagerService::SetWindowAnimationController(const sptr& controller) @@ -374,23 +394,30 @@ WMError WindowManagerService::SetWindowAnimationController(const sptr deathRecipient = new AgentDeathRecipient( - [&mutex](sptr& remoteObject) { - std::lock_guard lock(mutex); - RemoteAnimation::OnRemoteDie(remoteObject); + [this](sptr& remoteObject) { + wmsTaskLooper_->ScheduleTask([&remoteObject]() { + RemoteAnimation::OnRemoteDie(remoteObject); + }).wait(); } ); controller->AsObject()->AddDeathRecipient(deathRecipient); - - std::lock_guard lock(mutex_); - return windowController_->SetWindowAnimationController(controller); + return wmsTaskLooper_->ScheduleTask([this, &controller]() { + return windowController_->SetWindowAnimationController(controller); + }).get(); } -void WindowManagerService::OnWindowEvent(Event event, uint32_t windowId) +void WindowManagerService::OnWindowEvent(Event event, const sptr& remoteObject) { if (event == Event::REMOTE_DIED) { - DestroyWindow(windowId, true); + return wmsTaskLooper_->ScheduleTask([this, &remoteObject, event]() { + uint32_t windowId = windowRoot_->GetWindowIdByObject(remoteObject); + auto node = windowRoot_->GetWindowNode(windowId); + if (node != nullptr && node->GetWindowType() == WindowType::WINDOW_TYPE_DRAGGING_EFFECT) { + dragController_->FinishDrag(windowId); + } + windowController_->DestroyWindow(windowId, true); + }).wait(); } } @@ -402,7 +429,6 @@ void WindowManagerService::NotifyDisplayStateChange(DisplayId id, DisplayStateCh } else if (type == DisplayStateChangeType::UNFREEZE) { freezeDisplayController_->UnfreezeDisplay(id); } else { - std::lock_guard lock(mutex_); return windowController_->NotifyDisplayStateChange(id, type); } } @@ -414,50 +440,57 @@ void DisplayChangeListener::OnDisplayStateChange(DisplayId id, DisplayStateChang void WindowManagerService::ProcessPointDown(uint32_t windowId, bool isStartDrag) { - std::lock_guard lock(mutex_); - windowController_->ProcessPointDown(windowId, isStartDrag); + return wmsTaskLooper_->PostTask([this, windowId, isStartDrag]() { + windowController_->ProcessPointDown(windowId, isStartDrag); + }); } void WindowManagerService::ProcessPointUp(uint32_t windowId) { - std::lock_guard lock(mutex_); - windowController_->ProcessPointUp(windowId); + return wmsTaskLooper_->PostTask([this, windowId]() { + windowController_->ProcessPointUp(windowId); + }); } void WindowManagerService::MinimizeAllAppWindows(DisplayId displayId) { - WLOGFI("displayId %{public}" PRIu64"", displayId); - std::lock_guard lock(mutex_); - windowController_->MinimizeAllAppWindows(displayId); + return wmsTaskLooper_->PostTask([this, displayId]() { + WLOGFI("displayId %{public}" PRIu64"", displayId); + windowController_->MinimizeAllAppWindows(displayId); + }); } WMError WindowManagerService::ToggleShownStateForAllAppWindows() { - WM_SCOPED_TRACE("wms:ToggleShownStateForAllAppWindows"); - std::lock_guard lock(mutex_); - return windowController_->ToggleShownStateForAllAppWindows(); + return wmsTaskLooper_->ScheduleTask([this]() { + WM_SCOPED_TRACE("wms:ToggleShownStateForAllAppWindows"); + return windowController_->ToggleShownStateForAllAppWindows(); + }).get(); } WMError WindowManagerService::MaxmizeWindow(uint32_t windowId) { - WM_SCOPED_TRACE("wms:MaxmizeWindow"); - std::lock_guard lock(mutex_); - return windowController_->MaxmizeWindow(windowId); + return wmsTaskLooper_->ScheduleTask([this, windowId]() { + WM_SCOPED_TRACE("wms:MaxmizeWindow"); + return windowController_->MaxmizeWindow(windowId); + }).get(); } WMError WindowManagerService::GetTopWindowId(uint32_t mainWinId, uint32_t& topWinId) { - WM_SCOPED_TRACE("wms:GetTopWindowId(%u)", mainWinId); - std::lock_guard lock(mutex_); - return windowController_->GetTopWindowId(mainWinId, topWinId); + return wmsTaskLooper_->ScheduleTask([this, &topWinId, mainWinId]() { + WM_SCOPED_TRACE("wms:GetTopWindowId(%u)", mainWinId); + return windowController_->GetTopWindowId(mainWinId, topWinId); + }).get(); } WMError WindowManagerService::SetWindowLayoutMode(WindowLayoutMode mode) { - WLOGFI("layoutMode: %{public}u", mode); - WM_SCOPED_TRACE("wms:SetWindowLayoutMode"); - std::lock_guard lock(mutex_); - return windowController_->SetWindowLayoutMode(mode); + return wmsTaskLooper_->ScheduleTask([this, mode]() { + WLOGFI("layoutMode: %{public}u", mode); + WM_SCOPED_TRACE("wms:SetWindowLayoutMode"); + return windowController_->SetWindowLayoutMode(mode); + }).get(); } WMError WindowManagerService::UpdateProperty(sptr& windowProperty, PropertyChangeAction action) @@ -466,14 +499,15 @@ WMError WindowManagerService::UpdateProperty(sptr& windowPropert WLOGFE("property is invalid"); return WMError::WM_ERROR_NULLPTR; } - WM_SCOPED_TRACE("wms:UpdateProperty"); - std::lock_guard lock(mutex_); - WMError res = windowController_->UpdateProperty(windowProperty, action); - if (action == PropertyChangeAction::ACTION_UPDATE_RECT && res == WMError::WM_OK && - windowProperty->GetWindowSizeChangeReason() == WindowSizeChangeReason::MOVE) { - dragController_->UpdateDragInfo(windowProperty->GetWindowId()); - } - return res; + return wmsTaskLooper_->ScheduleTask([this, &windowProperty, action]() { + WM_SCOPED_TRACE("wms:UpdateProperty"); + WMError res = windowController_->UpdateProperty(windowProperty, action); + if (action == PropertyChangeAction::ACTION_UPDATE_RECT && res == WMError::WM_OK && + windowProperty->GetWindowSizeChangeReason() == WindowSizeChangeReason::MOVE) { + dragController_->UpdateDragInfo(windowProperty->GetWindowId()); + } + return res; + }).get(); } WMError WindowManagerService::GetAccessibilityWindowInfo(sptr& windowInfo) @@ -482,10 +516,10 @@ WMError WindowManagerService::GetAccessibilityWindowInfo(sptr lock(mutex_); - WMError res = windowRoot_->GetAccessibilityWindowInfo(windowInfo); - return res; + return wmsTaskLooper_->ScheduleTask([this, &windowInfo]() { + WM_SCOPED_TRACE("wms:GetAccessibilityWindowInfo"); + return windowRoot_->GetAccessibilityWindowInfo(windowInfo); + }).get(); } WMError WindowManagerService::GetSystemConfig(SystemConfig& systemConfig) diff --git a/wmserver/src/window_node.cpp b/wmserver/src/window_node.cpp index 2aaf4724..af2236dd 100644 --- a/wmserver/src/window_node.cpp +++ b/wmserver/src/window_node.cpp @@ -168,14 +168,14 @@ void WindowNode::SetWindowToken(sptr window) windowToken_ = window; } -void WindowNode::SetCallingPid() +void WindowNode::SetCallingPid(int32_t pid) { - callingPid_ = IPCSkeleton::GetCallingPid(); + property_->SetWindowPid(pid); } -void WindowNode::SetCallingUid() +void WindowNode::SetCallingUid(int32_t uid) { - callingUid_ = IPCSkeleton::GetCallingUid(); + property_->SetWindowPid(uid); } DisplayId WindowNode::GetDisplayId() const @@ -265,12 +265,12 @@ const sptr& WindowNode::GetWindowProperty() const int32_t WindowNode::GetCallingPid() const { - return callingPid_; + return property_->GetWindowPid(); } int32_t WindowNode::GetCallingUid() const { - return callingUid_; + return property_->GetWindowUid(); } const std::unordered_map& WindowNode::GetSystemBarProperty() const diff --git a/wmserver/src/window_root.cpp b/wmserver/src/window_root.cpp index c3da225c..dfd1c114 100644 --- a/wmserver/src/window_root.cpp +++ b/wmserver/src/window_root.cpp @@ -826,16 +826,15 @@ WMError WindowRoot::RaiseZOrderForAppWindow(sptr& node) return container->RaiseZOrderForAppWindow(node, parentNode); } +uint32_t WindowRoot::GetWindowIdByObject(const sptr& remoteObject) +{ + auto iter = windowIdMap_.find(remoteObject); + return iter == std::end(windowIdMap_) ? INVALID_WINDOW_ID : iter->second; +} + void WindowRoot::OnRemoteDied(const sptr& remoteObject) { - std::lock_guard lock(mutex_); - auto iter = windowIdMap_.find(remoteObject); - if (iter == windowIdMap_.end()) { - WLOGFE("window id could not be found"); - return; - } - uint32_t windowId = iter->second; - callback_(Event::REMOTE_DIED, windowId); + callback_(Event::REMOTE_DIED, remoteObject); } WMError WindowRoot::GetTopWindowId(uint32_t mainWinId, uint32_t& topWinId) diff --git a/wmserver/src/window_task_looper.cpp b/wmserver/src/window_task_looper.cpp new file mode 100644 index 00000000..914185e1 --- /dev/null +++ b/wmserver/src/window_task_looper.cpp @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "window_task_looper.h" + +namespace OHOS { +namespace Rosen { +void WindowTaskLooper::PostTask(const Task& task) +{ + { + std::lock_guard lock(mtx_); + taskQ_.emplace_back(task); + } + WakeUp(); +} + +void WindowTaskLooper::WaitTask() +{ + std::unique_lock lock(mtx_); + if (!wakeUp_ && taskQ_.empty()) { + taskCond_.wait( + lock, + [this] () { + return !taskQ_.empty() || wakeUp_; + }); + } + wakeUp_ = false; +} + +void WindowTaskLooper::WakeUp() +{ + std::lock_guard lock(mtx_); + wakeUp_ = true; + taskCond_.notify_one(); +} + +void WindowTaskLooper::Start() noexcept +{ + taskProcessThread_ = std::make_unique([this]() { + TaskProcessThread(); + }); + taskProcessThread_->detach(); +} + +void WindowTaskLooper::TaskProcessThread() +{ + if (running_) { + return; + } + running_ = true; + while (running_) { + WaitTask(); + ExecuteAllTask(); + } +} + +void WindowTaskLooper::ExecuteAllTask() +{ + std::vector tasks; + { + std::lock_guard lock(mtx_); + tasks.swap(taskQ_); + } + for (const auto& task : tasks) { + if (task != nullptr) { + task(); + } + } +} + +bool WindowTaskLooper::IsRunning() +{ + return running_; +} + +WindowTaskLooper::~WindowTaskLooper() +{ + std::lock_guard lock(mtx_); + running_ = false; + taskQ_.clear(); +} +} // namespace Rosen +} // namespace OHOS \ No newline at end of file diff --git a/wmserver/src/zidl/window_manager_stub.cpp b/wmserver/src/zidl/window_manager_stub.cpp index 2823f58c..c7c32da8 100644 --- a/wmserver/src/zidl/window_manager_stub.cpp +++ b/wmserver/src/zidl/window_manager_stub.cpp @@ -31,6 +31,8 @@ int32_t WindowManagerStub::OnRemoteRequest(uint32_t code, MessageParcel &data, M WLOGFE("InterfaceToken check failed"); return -1; } + int32_t pid = IPCSkeleton::GetCallingPid(); + int32_t uid = IPCSkeleton::GetCallingUid(); WindowManagerMessage msgId = static_cast(code); switch (msgId) { case WindowManagerMessage::TRANS_ID_CREATE_WINDOW: { @@ -45,6 +47,8 @@ int32_t WindowManagerStub::OnRemoteRequest(uint32_t code, MessageParcel &data, M } else { WLOGFI("accept token is nullptr"); } + windowProperty->SetWindowPid(pid); + windowProperty->SetWindowUid(uid); WMError errCode = CreateWindow(windowProxy, windowProperty, surfaceNode, windowId, token); reply.WriteUint32(windowId); reply.WriteInt32(static_cast(errCode)); @@ -52,6 +56,8 @@ int32_t WindowManagerStub::OnRemoteRequest(uint32_t code, MessageParcel &data, M } case WindowManagerMessage::TRANS_ID_ADD_WINDOW: { sptr windowProperty = data.ReadStrongParcelable(); + windowProperty->SetWindowPid(pid); + windowProperty->SetWindowUid(uid); WMError errCode = AddWindow(windowProperty); reply.WriteInt32(static_cast(errCode)); break;