mirror of
https://github.com/openharmony/windowmanager.git
synced 2026-07-19 17:08:11 -04:00
解决用户切换原用户窗口不消失问题
Signed-off-by: dubj <dubingjian@huawei.com> Change-Id: I4d6983bd670944ef80795ca0557f005a04c7602d
This commit is contained in:
@@ -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",
|
||||
|
||||
@@ -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 <common_event_data.h>
|
||||
#include <common_event_manager.h>
|
||||
#include <common_event_support.h>
|
||||
#include <event_handler.h>
|
||||
|
||||
#include "window_root.h"
|
||||
#include "window_task_looper.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Rosen {
|
||||
class WindowCommonEvent : public RefBase, public std::enable_shared_from_this<WindowCommonEvent> {
|
||||
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<WindowCommonEvent>& eventHandler)
|
||||
: EventFwk::CommonEventSubscriber(subscriberInfo), eventHandler_(eventHandler) {};
|
||||
~EventSubscriber() = default;
|
||||
void OnReceiveEvent(const EventFwk::CommonEventData& data) override
|
||||
{
|
||||
eventHandler_->OnReceiveEvent(data);
|
||||
}
|
||||
private:
|
||||
std::shared_ptr<WindowCommonEvent> eventHandler_;
|
||||
};
|
||||
void SubscriberEventInner(int retry);
|
||||
void HandleAccountSwitched(const EventFwk::CommonEventData& data) const;
|
||||
|
||||
typedef void (WindowCommonEvent::*HandleCommonEventFunc)(const EventFwk::CommonEventData& data) const;
|
||||
|
||||
std::map<std::string, HandleCommonEventFunc> handleCommonEventFuncs_;
|
||||
std::shared_ptr<EventSubscriber> subscriber_;
|
||||
std::shared_ptr<AppExecFwk::EventHandler> eventHandler_;
|
||||
};
|
||||
} // Rosen
|
||||
} // OHOS
|
||||
#endif // WINDOW_COMMON_EVENT_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<std::u16string>& args) override;
|
||||
|
||||
WMError CreateWindow(sptr<IWindow>& window, sptr<WindowProperty>& property,
|
||||
@@ -103,6 +105,7 @@ public:
|
||||
void MinimizeWindowsByLauncher(std::vector<uint32_t> windowIds, bool isAnimated,
|
||||
sptr<RSIWindowAnimationFinishedCallback>& 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<WindowTaskLooper> wmsTaskLooper_;
|
||||
std::shared_ptr<WindowCommonEvent> windowCommonEvent_;
|
||||
RSInterfaces& rsInterface_;
|
||||
bool startingOpen_ = true;
|
||||
};
|
||||
|
||||
@@ -110,6 +110,7 @@ public:
|
||||
void BeforeProcessWindowAvoidAreaChangeWhenDisplayChange() const;
|
||||
void ProcessWindowAvoidAreaChangeWhenDisplayChange() const;
|
||||
WindowLayoutMode GetCurrentLayoutMode() const;
|
||||
void RemoveSingleUserWindowNodes();
|
||||
|
||||
private:
|
||||
void TraverseWindowNode(sptr<WindowNode>& root, std::vector<sptr<WindowNode>>& windowNodes) const;
|
||||
|
||||
@@ -97,6 +97,7 @@ public:
|
||||
void SetExitSplitRatios(const std::vector<float>& exitSplitRatios);
|
||||
void MinimizeTargetWindows(std::vector<uint32_t>& windowIds);
|
||||
WindowLayoutMode GetCurrentLayoutMode(DisplayId displayId);
|
||||
void RemoveSingleUserWindowNodes();
|
||||
private:
|
||||
void OnRemoteDied(const sptr<IRemoteObject>& remoteObject);
|
||||
WMError DestroyWindowInner(sptr<WindowNode>& node);
|
||||
|
||||
@@ -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 <thread>
|
||||
#include <want.h>
|
||||
#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<AppExecFwk::EventHandler>(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<EventSubscriber>(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<void()> 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
|
||||
@@ -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<WindowCommonEvent>();
|
||||
wmsTaskLooper_ = std::make_unique<WindowTaskLooper>();
|
||||
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<RSOcclusionData> occlusionData)
|
||||
{
|
||||
WLOGFD("NotifyWindowVisibilityChange: enter");
|
||||
@@ -285,6 +303,7 @@ void WindowManagerService::ConfigureWindowManagerService()
|
||||
|
||||
void WindowManagerService::OnStop()
|
||||
{
|
||||
windowCommonEvent_->UnSubscriberEvent();
|
||||
WindowInnerManager::GetInstance().Stop();
|
||||
WLOGFI("ready to stop service.");
|
||||
}
|
||||
|
||||
@@ -1892,5 +1892,24 @@ WindowLayoutMode WindowNodeContainer::GetCurrentLayoutMode() const
|
||||
{
|
||||
return layoutMode_;
|
||||
}
|
||||
|
||||
void WindowNodeContainer::RemoveSingleUserWindowNodes()
|
||||
{
|
||||
std::vector<sptr<WindowNode>> 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<uint32_t>(WindowAnimation::NONE));
|
||||
RemoveWindowNode(windowNode);
|
||||
}
|
||||
}
|
||||
} // namespace Rosen
|
||||
} // namespace OHOS
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <display_power_mgr_client.h>
|
||||
#include <hisysevent.h>
|
||||
#include <transaction/rs_transaction.h>
|
||||
|
||||
#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<DisplayId> displayIds = GetAllDisplayIds();
|
||||
for (auto id : displayIds) {
|
||||
sptr<WindowNodeContainer> container = GetOrCreateWindowNodeContainer(id);
|
||||
if (container == nullptr) {
|
||||
WLOGFI("get container failed %{public}" PRIu64"", id);
|
||||
continue;
|
||||
}
|
||||
container->RemoveSingleUserWindowNodes();
|
||||
}
|
||||
}
|
||||
} // namespace Rosen
|
||||
} // namespace OHOS
|
||||
|
||||
Reference in New Issue
Block a user