diff --git a/wmserver/BUILD.gn b/wmserver/BUILD.gn index 6637bc4c..f56c3b65 100644 --- a/wmserver/BUILD.gn +++ b/wmserver/BUILD.gn @@ -48,6 +48,7 @@ ohos_shared_library("libwms") { "src/minimize_app.cpp", "src/remote_animation.cpp", "src/starting_window.cpp", + "src/window_common_event.cpp", "src/window_controller.cpp", "src/window_dumper.cpp", "src/window_inner_manager.cpp", diff --git a/wmserver/include/window_common_event.h b/wmserver/include/window_common_event.h new file mode 100644 index 00000000..273a1170 --- /dev/null +++ b/wmserver/include/window_common_event.h @@ -0,0 +1,61 @@ +/* + * 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 WINDOW_COMMON_EVENT_H +#define WINDOW_COMMON_EVENT_H + +#include +#include +#include +#include + +#include "window_root.h" +#include "window_task_looper.h" + +namespace OHOS { +namespace Rosen { +class WindowCommonEvent : public RefBase, public std::enable_shared_from_this { +public: + WindowCommonEvent(); + ~WindowCommonEvent(); + void SubscriberEvent(); + void UnSubscriberEvent(); + void OnReceiveEvent(const EventFwk::CommonEventData& data); +private: + class EventSubscriber : public EventFwk::CommonEventSubscriber { + public: + EventSubscriber(const EventFwk::CommonEventSubscribeInfo &subscriberInfo, + const std::shared_ptr& eventHandler) + : EventFwk::CommonEventSubscriber(subscriberInfo), eventHandler_(eventHandler) {}; + ~EventSubscriber() = default; + void OnReceiveEvent(const EventFwk::CommonEventData& data) override + { + eventHandler_->OnReceiveEvent(data); + } + private: + std::shared_ptr eventHandler_; + }; + void SubscriberEventInner(int retry); + void HandleAccountSwitched(const EventFwk::CommonEventData& data) const; + + typedef void (WindowCommonEvent::*HandleCommonEventFunc)(const EventFwk::CommonEventData& data) const; + + std::map handleCommonEventFuncs_; + std::shared_ptr subscriber_; + std::shared_ptr eventHandler_; +}; +} // Rosen +} // OHOS +#endif // WINDOW_COMMON_EVENT_H \ No newline at end of file diff --git a/wmserver/include/window_manager_service.h b/wmserver/include/window_manager_service.h index 536c9812..87e762e0 100644 --- a/wmserver/include/window_manager_service.h +++ b/wmserver/include/window_manager_service.h @@ -29,6 +29,7 @@ #include "freeze_controller.h" #include "singleton_delegator.h" #include "wm_single_instance.h" +#include "window_common_event.h" #include "window_controller.h" #include "zidl/window_manager_stub.h" #include "window_dumper.h" @@ -65,6 +66,7 @@ WM_DECLARE_SINGLE_INSTANCE_BASE(WindowManagerService); public: void OnStart() override; void OnStop() override; + void OnAddSystemAbility(int32_t systemAbilityId, const std::string &deviceId) override; int Dump(int fd, const std::vector& args) override; WMError CreateWindow(sptr& window, sptr& property, @@ -103,6 +105,7 @@ public: void MinimizeWindowsByLauncher(std::vector windowIds, bool isAnimated, sptr& finishCallback) override; void GetWindowPreferredOrientation(DisplayId displayId, Orientation &orientation); + void OnAccountSwitched() const; protected: WindowManagerService(); virtual ~WindowManagerService() = default; @@ -132,6 +135,7 @@ private: SystemConfig systemConfig_; ModeChangeHotZonesConfig hotZonesConfig_ { false, 0, 0, 0 }; std::unique_ptr wmsTaskLooper_; + std::shared_ptr windowCommonEvent_; RSInterfaces& rsInterface_; bool startingOpen_ = true; }; diff --git a/wmserver/include/window_node_container.h b/wmserver/include/window_node_container.h index c98da05e..f4d55f91 100644 --- a/wmserver/include/window_node_container.h +++ b/wmserver/include/window_node_container.h @@ -110,6 +110,7 @@ public: void BeforeProcessWindowAvoidAreaChangeWhenDisplayChange() const; void ProcessWindowAvoidAreaChangeWhenDisplayChange() const; WindowLayoutMode GetCurrentLayoutMode() const; + void RemoveSingleUserWindowNodes(); private: void TraverseWindowNode(sptr& root, std::vector>& windowNodes) const; diff --git a/wmserver/include/window_root.h b/wmserver/include/window_root.h index 8e7128e9..c22d5969 100644 --- a/wmserver/include/window_root.h +++ b/wmserver/include/window_root.h @@ -97,6 +97,7 @@ public: void SetExitSplitRatios(const std::vector& exitSplitRatios); void MinimizeTargetWindows(std::vector& windowIds); WindowLayoutMode GetCurrentLayoutMode(DisplayId displayId); + void RemoveSingleUserWindowNodes(); private: void OnRemoteDied(const sptr& remoteObject); WMError DestroyWindowInner(sptr& node); diff --git a/wmserver/src/window_common_event.cpp b/wmserver/src/window_common_event.cpp new file mode 100644 index 00000000..3d15bcfa --- /dev/null +++ b/wmserver/src/window_common_event.cpp @@ -0,0 +1,96 @@ +/* + * 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_common_event.h" + +#include +#include +#include "common_event_subscribe_info.h" +#include "event_runner.h" +#include "skills.h" +#include "window_manager_hilog.h" +#include "window_manager_service.h" + +namespace OHOS { +namespace Rosen { +namespace { + constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "WindowCommonEvent"}; + constexpr int RETRY_MAX_COUNT = 3; + const std::string THREAD_ID = "window_common_event_handler"; +} + +WindowCommonEvent::WindowCommonEvent() +{ + handleCommonEventFuncs_.insert(make_pair(EventFwk::CommonEventSupport::COMMON_EVENT_USER_SWITCHED, + &WindowCommonEvent::HandleAccountSwitched)); + auto runner = AppExecFwk::EventRunner::Create(THREAD_ID); + eventHandler_ = std::make_shared(runner); +} + +WindowCommonEvent::~WindowCommonEvent() +{ +} + +void WindowCommonEvent::SubscriberEvent() +{ + EventFwk::MatchingSkills skills; + skills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_USER_SWITCHED); + EventFwk::CommonEventSubscribeInfo info(skills); + subscriber_ = std::make_shared(info, shared_from_this()); + int retry = RETRY_MAX_COUNT; + SubscriberEventInner(retry); +} + +void WindowCommonEvent::SubscriberEventInner(int retry) +{ + if (retry <= 0) { + return; + } + retry--; + WLOGFI("called action = %{public}d", retry); + if (EventFwk::CommonEventManager::SubscribeCommonEvent(subscriber_)) { + return; + } + std::function func = std::bind(&WindowCommonEvent::SubscriberEventInner, this, retry); + // post task delay 500ms + eventHandler_->PostTask(func, 500, AppExecFwk::EventQueue::Priority::HIGH); +} + +void WindowCommonEvent::UnSubscriberEvent() +{ + auto task = [this] { + EventFwk::CommonEventManager::UnSubscribeCommonEvent(subscriber_); + }; + eventHandler_->PostTask(task, AppExecFwk::EventQueue::Priority::HIGH); +} + +void WindowCommonEvent::OnReceiveEvent(const EventFwk::CommonEventData& data) +{ + auto task = [this, data] { + std::string action = data.GetWant().GetAction(); + WLOGFI("called action = %{public}s", action.c_str()); + if (handleCommonEventFuncs_.count(action)) { + (this->*handleCommonEventFuncs_[action])(data); + } + }; + eventHandler_->PostTask(task, AppExecFwk::EventQueue::Priority::HIGH); +} + +void WindowCommonEvent::HandleAccountSwitched(const EventFwk::CommonEventData& data) const +{ + WindowManagerService::GetInstance().OnAccountSwitched(); +} +} // Rosen +} // OHOS \ No newline at end of file diff --git a/wmserver/src/window_manager_service.cpp b/wmserver/src/window_manager_service.cpp index 7421b291..a477013b 100644 --- a/wmserver/src/window_manager_service.cpp +++ b/wmserver/src/window_manager_service.cpp @@ -57,6 +57,7 @@ WindowManagerService::WindowManagerService() : SystemAbility(WINDOW_MANAGER_SERV dragController_ = new DragController(windowRoot_); windowDumper_ = new WindowDumper(windowRoot_); freezeDisplayController_ = new FreezeController(); + windowCommonEvent_ = std::make_shared(); wmsTaskLooper_ = std::make_unique(); startingOpen_ = system::GetParameter("persist.window.sw.enabled", "1") == "1"; // startingWin default enabled } @@ -74,9 +75,26 @@ void WindowManagerService::OnStart() RegisterWindowManagerServiceHandler(); RegisterWindowVisibilityChangeCallback(); wmsTaskLooper_->Start(); + AddSystemAbilityListener(COMMON_EVENT_SERVICE_ID); } +void WindowManagerService::OnAddSystemAbility(int32_t systemAbilityId, const std::string &deviceId) +{ + WLOGFI(" %{public}d", systemAbilityId); + if (systemAbilityId == COMMON_EVENT_SERVICE_ID) { + windowCommonEvent_->SubscriberEvent(); + } +} + +void WindowManagerService::OnAccountSwitched() const +{ + wmsTaskLooper_->PostTask([this]() { + windowRoot_->RemoveSingleUserWindowNodes(); + }); + WLOGFI("called"); +} + void WindowManagerService::WindowVisibilityChangeCallback(std::shared_ptr occlusionData) { WLOGFD("NotifyWindowVisibilityChange: enter"); @@ -285,6 +303,7 @@ void WindowManagerService::ConfigureWindowManagerService() void WindowManagerService::OnStop() { + windowCommonEvent_->UnSubscriberEvent(); WindowInnerManager::GetInstance().Stop(); WLOGFI("ready to stop service."); } diff --git a/wmserver/src/window_node_container.cpp b/wmserver/src/window_node_container.cpp index 0a26923b..45750ac7 100644 --- a/wmserver/src/window_node_container.cpp +++ b/wmserver/src/window_node_container.cpp @@ -1892,5 +1892,24 @@ WindowLayoutMode WindowNodeContainer::GetCurrentLayoutMode() const { return layoutMode_; } + +void WindowNodeContainer::RemoveSingleUserWindowNodes() +{ + std::vector> windowNodes; + TraverseContainer(windowNodes); + for (auto& windowNode : windowNodes) { + if (windowNode->GetWindowType() == WindowType::WINDOW_TYPE_DESKTOP || + windowNode->GetWindowType() == WindowType::WINDOW_TYPE_STATUS_BAR || + windowNode->GetWindowType() == WindowType::WINDOW_TYPE_NAVIGATION_BAR || + windowNode->GetWindowType() == WindowType::WINDOW_TYPE_KEYGUARD || + windowNode->GetWindowType() == WindowType::WINDOW_TYPE_POINTER) { + continue; + } + WLOGFI("remove window %{public}s, windowId %{public}d", + windowNode->GetWindowName().c_str(), windowNode->GetWindowId()); + windowNode->GetWindowProperty()->SetAnimationFlag(static_cast(WindowAnimation::NONE)); + RemoveWindowNode(windowNode); + } +} } // namespace Rosen } // namespace OHOS diff --git a/wmserver/src/window_root.cpp b/wmserver/src/window_root.cpp index d13e9626..02fccb5a 100644 --- a/wmserver/src/window_root.cpp +++ b/wmserver/src/window_root.cpp @@ -19,6 +19,7 @@ #include #include #include + #include "display_manager_service_inner.h" #include "window_helper.h" #include "window_manager_hilog.h" @@ -1318,5 +1319,18 @@ WindowLayoutMode WindowRoot::GetCurrentLayoutMode(DisplayId displayId) } return container->GetCurrentLayoutMode(); } + +void WindowRoot::RemoveSingleUserWindowNodes() +{ + std::vector displayIds = GetAllDisplayIds(); + for (auto id : displayIds) { + sptr container = GetOrCreateWindowNodeContainer(id); + if (container == nullptr) { + WLOGFI("get container failed %{public}" PRIu64"", id); + continue; + } + container->RemoveSingleUserWindowNodes(); + } +} } // namespace Rosen } // namespace OHOS