增加窗口可见性注册监听接口

Signed-off-by: chenqinxin <chenqinxin1@huawei.com>
Change-Id: I86cd8f99a77e3ea157868fc366f48469c5ccc977
This commit is contained in:
chenqinxin 2022-02-17 17:02:01 +08:00
parent f06eb14701
commit 1a749e2466
20 changed files with 592 additions and 91 deletions

View File

@ -484,7 +484,7 @@ bool DisplayManager::SetScreenBrightness(uint64_t screenId, uint32_t level)
uint32_t DisplayManager::GetScreenBrightness(uint64_t screenId) const
{
uint32_t level = static_cast<uint32_t>(RSInterfaces::GetInstance().GetScreenBacklight(screenId));
WLOGFI("screenId:%{public}" PRIu64", level:%{public}u,", screenId, level);
WLOGFD("screenId:%{public}" PRIu64", level:%{public}u,", screenId, level);
return level;
}

View File

@ -49,6 +49,27 @@ public:
virtual void OnSystemBarPropertyChange(DisplayId displayId, const SystemBarRegionTints& tints) = 0;
};
class WindowVisibilityInfo : public Parcelable {
public:
WindowVisibilityInfo() = default;
WindowVisibilityInfo(uint32_t winId, int32_t pid, int32_t uid, bool visibility)
: windowId_(winId), pid_(pid), uid_(uid), isVisible_(visibility) {};
~WindowVisibilityInfo() = default;
virtual bool Marshalling(Parcel& parcel) const override;
static WindowVisibilityInfo* Unmarshalling(Parcel& parcel);
uint32_t windowId_ { INVALID_WINDOW_ID };
int32_t pid_ { 0 };
int32_t uid_ { 0 };
bool isVisible_ { false };
};
class IVisibilityChangedListener : public RefBase {
public:
virtual void OnWindowVisibilityChanged(const std::vector<sptr<WindowVisibilityInfo>>& windowVisibilityInfo) = 0;
};
class WindowInfo : public Parcelable {
public:
WindowInfo() = default;
@ -78,6 +99,8 @@ public:
void UnregisterSystemBarChangedListener(const sptr<ISystemBarChangedListener>& listener);
void RegisterWindowUpdateListener(const sptr<IWindowUpdateListener>& listener);
void UnregisterWindowUpdateListener(const sptr<IWindowUpdateListener>& listener);
void RegisterVisibilityChangedListener(const sptr<IVisibilityChangedListener>& listener);
void UnregisterVisibilityChangedListener(const sptr<IVisibilityChangedListener>& listener);
void MinimizeAllAppWindows(DisplayId displayId);
void SetWindowLayoutMode(WindowLayoutMode mode, DisplayId displayId);
@ -91,6 +114,8 @@ private:
DisplayId displayId, bool focused) const;
void UpdateSystemBarRegionTints(DisplayId displayId, const SystemBarRegionTints& tints) const;
void UpdateWindowStatus(const sptr<WindowInfo>& windowInfo, WindowUpdateType type);
void UpdateWindowVisibilityInfo(
const std::vector<sptr<WindowVisibilityInfo>>& windowVisibilityInfos) const;
};
} // namespace Rosen
} // namespace OHOS

View File

@ -124,10 +124,17 @@ struct Rect {
int32_t posY_;
uint32_t width_;
uint32_t height_;
bool operator == (const Rect& a) const
bool operator==(const Rect& a) const
{
return (posX_ == a.posX_ && posY_ == a.posY_ && width_ == a.width_ && height_ == a.height_);
}
bool IsInsideOf(const Rect& a) const
{
return (posX_ >= a.posX_ && posY_ >= a.posY_ &&
posX_ + width_ <= a.posX_ + a.width_ && posY_ + height_ <= a.posY_ + a.height_);
}
};
struct PointInfo {

View File

@ -30,6 +30,7 @@ public:
DisplayId displayId, bool focused) override;
void UpdateSystemBarRegionTints(DisplayId displayId, const SystemBarRegionTints& props) override;
void UpdateWindowStatus(const sptr<WindowInfo>& windowInfo, WindowUpdateType type) override;
void UpdateWindowVisibilityInfo(const std::vector<sptr<WindowVisibilityInfo>>& visibilityInfos) override;
};
} // namespace Rosen
} // namespace OHOS

View File

@ -26,6 +26,7 @@ enum class WindowManagerAgentType : uint32_t {
WINDOW_MANAGER_AGENT_TYPE_FOCUS,
WINDOW_MANAGER_AGENT_TYPE_SYSTEM_BAR,
WINDOW_MANAGER_AGENT_TYPE_WINDOW_UPDATE,
WINDOW_MANAGER_AGENT_TYPE_WINDOW_VISIBILITY,
};
class IWindowManagerAgent : public IRemoteBroker {
@ -36,12 +37,14 @@ public:
TRANS_ID_UPDATE_FOCUS_STATUS = 1,
TRANS_ID_UPDATE_SYSTEM_BAR_PROPS,
TRANS_ID_UPDATE_WINDOW_STATUS,
TRANS_ID_UPDATE_WINDOW_VISIBILITY,
};
virtual void UpdateFocusStatus(uint32_t windowId, const sptr<IRemoteObject>& abilityToken, WindowType windowType,
DisplayId displayId, bool focused) = 0;
virtual void UpdateSystemBarRegionTints(DisplayId displayId, const SystemBarRegionTints& tints) = 0;
virtual void UpdateWindowStatus(const sptr<WindowInfo>& windowInfo, WindowUpdateType type) = 0;
virtual void UpdateWindowVisibilityInfo(const std::vector<sptr<WindowVisibilityInfo>>& visibilityInfos) = 0;
};
} // namespace Rosen
} // namespace OHOS

View File

@ -31,6 +31,7 @@ public:
DisplayId displayId, bool focused) override;
void UpdateSystemBarRegionTints(DisplayId displayId, const SystemBarRegionTints& tints) override;
void UpdateWindowStatus(const sptr<WindowInfo>& windowInfo, WindowUpdateType type) override;
void UpdateWindowVisibilityInfo(const std::vector<sptr<WindowVisibilityInfo>>& visibilityInfos) override;
private:
static inline BrokerDelegator<WindowManagerAgentProxy> delegator_;

View File

@ -29,6 +29,24 @@ namespace {
constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "WindowManager"};
}
bool WindowVisibilityInfo::Marshalling(Parcel &parcel) const
{
return parcel.WriteUint32(windowId_) && parcel.WriteInt32(pid_) &&
parcel.WriteInt32(uid_) && parcel.WriteBool(isVisible_);
}
WindowVisibilityInfo* WindowVisibilityInfo::Unmarshalling(Parcel &parcel)
{
WindowVisibilityInfo* windowVisibilityInfo = new WindowVisibilityInfo();
bool res = parcel.ReadUint32(windowVisibilityInfo->windowId_) && parcel.ReadInt32(windowVisibilityInfo->pid_) &&
parcel.ReadInt32(windowVisibilityInfo->uid_) && parcel.ReadBool(windowVisibilityInfo->isVisible_);
if (!res) {
delete windowVisibilityInfo;
return nullptr;
}
return windowVisibilityInfo;
}
bool WindowInfo::Marshalling(Parcel &parcel) const
{
return parcel.WriteInt32(wid_) && parcel.WriteUint32(windowRect_.width_) &&
@ -40,13 +58,11 @@ bool WindowInfo::Marshalling(Parcel &parcel) const
WindowInfo* WindowInfo::Unmarshalling(Parcel &parcel)
{
WindowInfo* windowInfo = new WindowInfo();
if (windowInfo == nullptr) {
return nullptr;
}
bool res = parcel.ReadInt32(windowInfo->wid_) && parcel.ReadUint32(windowInfo->windowRect_.width_) &&
parcel.ReadUint32(windowInfo->windowRect_.height_) && parcel.ReadInt32(windowInfo->windowRect_.posX_) &&
parcel.ReadInt32(windowInfo->windowRect_.posY_) && parcel.ReadBool(windowInfo->focused_);
if (!res) {
delete windowInfo;
return nullptr;
}
windowInfo->mode_ = static_cast<WindowMode>(parcel.ReadUint32());
@ -64,6 +80,7 @@ public:
WindowType windowType, DisplayId displayId) const;
void NotifySystemBarChanged(DisplayId displayId, const SystemBarRegionTints& tints) const;
void NotifyWindowUpdate(const sptr<WindowInfo>& windowInfo, WindowUpdateType type) const;
void NotifyWindowVisibilityInfoChanged(const std::vector<sptr<WindowVisibilityInfo>>& windowVisibilityInfos) const;
static inline SingletonDelegator<WindowManager> delegator_;
std::recursive_mutex mutex_;
@ -73,6 +90,8 @@ public:
sptr<WindowManagerAgent> systemBarChangedListenerAgent_;
std::vector<sptr<IWindowUpdateListener>> windowUpdateListeners_;
sptr<WindowManagerAgent> windowUpdateListenerAgent_;
std::vector<sptr<IVisibilityChangedListener>> windowVisibilityListeners_;
sptr<WindowManagerAgent> windowVisibilityListenerAgent_;
};
void WindowManager::Impl::NotifyFocused(uint32_t windowId, const sptr<IRemoteObject>& abilityToken,
@ -122,6 +141,14 @@ void WindowManager::Impl::NotifyWindowUpdate(const sptr<WindowInfo>& windowInfo,
}
}
void WindowManager::Impl::NotifyWindowVisibilityInfoChanged(
const std::vector<sptr<WindowVisibilityInfo>>& windowVisibilityInfos) const
{
for (auto& listener : windowVisibilityListeners_) {
listener->OnWindowVisibilityChanged(windowVisibilityInfos);
}
}
WindowManager::WindowManager() : pImpl_(std::make_unique<Impl>())
{
}
@ -257,6 +284,41 @@ void WindowManager::UnregisterWindowUpdateListener(const sptr<IWindowUpdateListe
}
}
void WindowManager::RegisterVisibilityChangedListener(const sptr<IVisibilityChangedListener>& listener)
{
if (listener == nullptr) {
WLOGFE("listener could not be null");
return;
}
std::lock_guard<std::recursive_mutex> lock(pImpl_->mutex_);
pImpl_->windowVisibilityListeners_.emplace_back(listener);
if (pImpl_->windowVisibilityListenerAgent_ == nullptr) {
pImpl_->windowVisibilityListenerAgent_ = new WindowManagerAgent();
SingletonContainer::Get<WindowAdapter>().RegisterWindowManagerAgent(
WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_VISIBILITY,
pImpl_->windowVisibilityListenerAgent_);
}
}
void WindowManager::UnregisterVisibilityChangedListener(const sptr<IVisibilityChangedListener>& listener)
{
if (listener == nullptr) {
return;
}
std::lock_guard<std::recursive_mutex> lock(pImpl_->mutex_);
pImpl_->windowVisibilityListeners_.erase(std::remove_if(pImpl_->windowVisibilityListeners_.begin(),
pImpl_->windowVisibilityListeners_.end(), [listener](sptr<IVisibilityChangedListener> registeredListener) {
return registeredListener == listener;
}), pImpl_->windowVisibilityListeners_.end());
if (pImpl_->windowVisibilityListeners_.empty() && pImpl_->windowVisibilityListenerAgent_ != nullptr) {
SingletonContainer::Get<WindowAdapter>().UnregisterWindowManagerAgent(
WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_VISIBILITY,
pImpl_->windowVisibilityListenerAgent_);
pImpl_->windowVisibilityListenerAgent_ = nullptr;
}
}
void WindowManager::UpdateFocusStatus(uint32_t windowId, const sptr<IRemoteObject>& abilityToken, WindowType windowType,
DisplayId displayId, bool focused) const
{
@ -278,5 +340,11 @@ void WindowManager::UpdateWindowStatus(const sptr<WindowInfo>& windowInfo, Windo
{
pImpl_->NotifyWindowUpdate(windowInfo, type);
}
void WindowManager::UpdateWindowVisibilityInfo(
const std::vector<sptr<WindowVisibilityInfo>>& windowVisibilityInfos) const
{
pImpl_->NotifyWindowVisibilityInfoChanged(windowVisibilityInfos);
}
} // namespace Rosen
} // namespace OHOS

View File

@ -35,5 +35,10 @@ void WindowManagerAgent::UpdateWindowStatus(const sptr<WindowInfo>& windowInfo,
{
SingletonContainer::Get<WindowManager>().UpdateWindowStatus(windowInfo, type);
}
void WindowManagerAgent::UpdateWindowVisibilityInfo(const std::vector<sptr<WindowVisibilityInfo>>& visibilityInfos)
{
SingletonContainer::Get<WindowManager>().UpdateWindowVisibilityInfo(visibilityInfos);
}
} // namespace Rosen
} // namespace OHOS

View File

@ -131,6 +131,32 @@ void WindowManagerAgentProxy::UpdateWindowStatus(const sptr<WindowInfo>& windowI
WLOGFE("SendRequest failed");
}
}
void WindowManagerAgentProxy::UpdateWindowVisibilityInfo(
const std::vector<sptr<WindowVisibilityInfo>>& visibilityInfos)
{
MessageParcel data;
MessageParcel reply;
MessageOption option(MessageOption::TF_ASYNC);
if (!data.WriteInterfaceToken(GetDescriptor())) {
WLOGFE("WriteInterfaceToken failed");
return;
}
if (!data.WriteUint32(static_cast<uint32_t>(visibilityInfos.size()))) {
WLOGFE("write windowVisibilityInfos size failed");
return;
}
for (auto& info : visibilityInfos) {
if (!data.WriteParcelable(info)) {
WLOGFE("Write windowVisibilityInfo failed");
return;
}
}
if (Remote()->SendRequest(TRANS_ID_UPDATE_WINDOW_VISIBILITY, data, reply, option) != ERR_NONE) {
WLOGFE("SendRequest failed");
}
}
} // namespace Rosen
} // namespace OHOS

View File

@ -62,6 +62,16 @@ int WindowManagerAgentStub::OnRemoteRequest(uint32_t code, MessageParcel& data,
UpdateWindowStatus(windowInfo, type);
break;
}
case TRANS_ID_UPDATE_WINDOW_VISIBILITY: {
uint32_t size = data.ReadUint32();
std::vector<sptr<WindowVisibilityInfo>> windowVisibilityInfos;
for (uint32_t i = 0; i < size; ++i) {
sptr<WindowVisibilityInfo> info = data.ReadParcelable<WindowVisibilityInfo>();
windowVisibilityInfos.emplace_back(info);
}
UpdateWindowVisibilityInfo(windowVisibilityInfos);
break;
}
default:
break;
}

View File

@ -30,6 +30,7 @@ group("systemtest") {
":wm_window_split_immersive_test",
":wm_window_split_test",
":wm_window_subwindow_test",
":wm_window_visibility_info_test",
]
}
@ -154,6 +155,17 @@ ohos_systemtest("wm_window_gamut_test") {
## SystemTest window_gamut_test }}}
## SystemTest wm_window_visibility_info_test {{{
ohos_systemtest("wm_window_visibility_info_test") {
module_out_path = module_out_path
sources = [ "window_visibility_info_test.cpp" ]
deps = [ ":wm_systemtest_common" ]
}
## SystemTest wm_window_visibility_info_test }}}
## Build wm_systemtest_common.a {{{
config("wm_systemtest_common_public_config") {
include_dirs = [

View File

@ -0,0 +1,245 @@
/*
* 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.
*/
// gtest
#include <gtest/gtest.h>
#include "wm_common.h"
#include "window_manager.h"
#include "window_test_utils.h"
using namespace testing;
using namespace testing::ext;
namespace OHOS {
namespace Rosen {
namespace {
constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "WindowVisibilityInfoTest"};
}
using utils = WindowTestUtils;
constexpr int WAIT_ASYNC_US = 200000; // 200ms
class VisibilityChangedListenerImpl : public IVisibilityChangedListener {
public:
void OnWindowVisibilityChanged(const std::vector<sptr<WindowVisibilityInfo>>& windowVisibilityInfo) override;
std::vector<sptr<WindowVisibilityInfo>> windowVisibilityInfos_;
};
void VisibilityChangedListenerImpl::OnWindowVisibilityChanged(
const std::vector<sptr<WindowVisibilityInfo>>& windowVisibilityInfo)
{
WLOGFI("size:%{public}zu", windowVisibilityInfo.size());
windowVisibilityInfos_ = std::move(windowVisibilityInfo);
for (auto& info : windowVisibilityInfos_) {
WLOGFI("windowId:%{public}u, covered:%{public}d, pid:%{public}d, uid:%{public}d", info->windowId_,
info->isVisible_, info->pid_, info->uid_);
}
}
class WindowVisibilityInfoTest : public testing::Test {
public:
static void SetUpTestCase();
static void TearDownTestCase();
virtual void SetUp() override;
virtual void TearDown() override;
static inline sptr<VisibilityChangedListenerImpl> visibilityChangedListener_ = new VisibilityChangedListenerImpl();
utils::TestWindowInfo fullScreenAppInfo_;
utils::TestWindowInfo floatAppInfo_;
utils::TestWindowInfo subAppInfo_;
};
void WindowVisibilityInfoTest::SetUpTestCase()
{
auto display = DisplayManager::GetInstance().GetDisplayById(0);
if (display == nullptr) {
WLOGFE("GetDefaultDisplay: failed!");
} else {
WLOGFI("GetDefaultDisplay: id %{public}" PRIu64", w %{public}d, h %{public}d, fps %{public}u",
display->GetId(), display->GetWidth(), display->GetHeight(), display->GetFreshRate());
}
Rect displayRect = {0, 0,
static_cast<uint32_t>(display->GetWidth()), static_cast<uint32_t>(display->GetHeight())};
utils::InitByDisplayRect(displayRect);
WindowManager::GetInstance().RegisterVisibilityChangedListener(visibilityChangedListener_);
}
void WindowVisibilityInfoTest::TearDownTestCase()
{
WindowManager::GetInstance().UnregisterVisibilityChangedListener(visibilityChangedListener_);
}
void WindowVisibilityInfoTest::SetUp()
{
fullScreenAppInfo_ = {
.name = "FullWindow",
.rect = utils::customAppRect_,
.type = WindowType::WINDOW_TYPE_APP_MAIN_WINDOW,
.mode = WindowMode::WINDOW_MODE_FULLSCREEN,
.needAvoid = false,
.parentLimit = false,
.parentName = "",
};
floatAppInfo_ = {
.name = "ParentWindow",
.rect = utils::customAppRect_,
.type = WindowType::WINDOW_TYPE_APP_MAIN_WINDOW,
.mode = WindowMode::WINDOW_MODE_FLOATING,
.needAvoid = false,
.parentLimit = false,
.parentName = "",
};
subAppInfo_ = {
.name = "SubWindow",
.rect = utils::customAppRect_,
.type = WindowType::WINDOW_TYPE_APP_SUB_WINDOW,
.mode = WindowMode::WINDOW_MODE_FLOATING,
.needAvoid = false,
.parentLimit = false,
.parentName = "",
};
}
void WindowVisibilityInfoTest::TearDown()
{
}
namespace {
/**
* @tc.name: WindowVisibilityInfoTest01
* @tc.desc: add main window and sub window, show and hide and test callback
* @tc.type: FUNC
*/
HWTEST_F(WindowVisibilityInfoTest, WindowVisibilityInfoTest01, Function | MediumTest | Level1)
{
floatAppInfo_.name = "window1";
floatAppInfo_.rect = {250, 150, 300, 500};
sptr<Window> window1 = utils::CreateTestWindow(floatAppInfo_);
subAppInfo_.name = "subWindow1";
subAppInfo_.rect = {400, 200, 100, 100};
subAppInfo_.parentName = window1->GetWindowName();
sptr<Window> subWindow1 = utils::CreateTestWindow(subAppInfo_);
ASSERT_EQ(WMError::WM_OK, window1->Show());
usleep(WAIT_ASYNC_US);
ASSERT_EQ(1, visibilityChangedListener_->windowVisibilityInfos_.size());
ASSERT_EQ(WMError::WM_OK, subWindow1->Show());
usleep(WAIT_ASYNC_US);
ASSERT_EQ(1, visibilityChangedListener_->windowVisibilityInfos_.size());
ASSERT_EQ(WMError::WM_OK, window1->Hide());
usleep(WAIT_ASYNC_US);
ASSERT_EQ(2, visibilityChangedListener_->windowVisibilityInfos_.size());
ASSERT_EQ(WMError::WM_OK, window1->Show());
usleep(WAIT_ASYNC_US);
ASSERT_EQ(2, visibilityChangedListener_->windowVisibilityInfos_.size());
ASSERT_EQ(WMError::WM_OK, subWindow1->Hide());
usleep(WAIT_ASYNC_US);
ASSERT_EQ(1, visibilityChangedListener_->windowVisibilityInfos_.size());
ASSERT_EQ(WMError::WM_OK, window1->Hide());
usleep(WAIT_ASYNC_US);
ASSERT_EQ(1, visibilityChangedListener_->windowVisibilityInfos_.size());
ASSERT_EQ(WMError::WM_OK, window1->Show());
usleep(WAIT_ASYNC_US);
ASSERT_EQ(1, visibilityChangedListener_->windowVisibilityInfos_.size());
window1->Destroy();
subWindow1->Destroy();
}
/**
* @tc.name: WindowVisibilityInfoTest02
* @tc.desc: add two fullscreen main window, test callback
* @tc.type: FUNC
*/
HWTEST_F(WindowVisibilityInfoTest, WindowVisibilityInfoTest02, Function | MediumTest | Level1)
{
fullScreenAppInfo_.name = "window1";
sptr<Window> window1 = utils::CreateTestWindow(fullScreenAppInfo_);
fullScreenAppInfo_.name = "window2";
sptr<Window> window2 = utils::CreateTestWindow(fullScreenAppInfo_);
ASSERT_EQ(WMError::WM_OK, window1->Show());
usleep(WAIT_ASYNC_US);
ASSERT_EQ(2, visibilityChangedListener_->windowVisibilityInfos_.size());
ASSERT_EQ(WMError::WM_OK, window2->Show());
usleep(WAIT_ASYNC_US);
ASSERT_EQ(2, visibilityChangedListener_->windowVisibilityInfos_.size());
window1->Destroy();
window2->Destroy();
}
/**
* @tc.name: WindowVisibilityInfoTest03
* @tc.desc: add two main window and sub windows and test callback
* @tc.type: FUNC
*/
HWTEST_F(WindowVisibilityInfoTest, WindowVisibilityInfoTest03, Function | MediumTest | Level1)
{
floatAppInfo_.name = "window1";
floatAppInfo_.rect = {0, 0, 300, 600};
sptr<Window> window1 = utils::CreateTestWindow(floatAppInfo_);
subAppInfo_.name = "subWindow1";
subAppInfo_.rect = {400, 200, 100, 100};
subAppInfo_.parentName = window1->GetWindowName();
sptr<Window> subWindow1 = utils::CreateTestWindow(subAppInfo_);
floatAppInfo_.name = "window2";
floatAppInfo_.rect = {50, 150, 240, 426};
sptr<Window> window2 = utils::CreateTestWindow(floatAppInfo_);
subAppInfo_.name = "subWindow2";
subAppInfo_.type = WindowType::WINDOW_TYPE_MEDIA;
subAppInfo_.parentName = window2->GetWindowName();
sptr<Window> subWindow2 = utils::CreateTestWindow(subAppInfo_);
ASSERT_EQ(WMError::WM_OK, window2->Show());
usleep(WAIT_ASYNC_US);
ASSERT_EQ(1, visibilityChangedListener_->windowVisibilityInfos_.size());
ASSERT_EQ(WMError::WM_OK, subWindow2->Show());
usleep(WAIT_ASYNC_US);
ASSERT_EQ(1, visibilityChangedListener_->windowVisibilityInfos_.size());
ASSERT_EQ(WMError::WM_OK, window1->Show());
usleep(WAIT_ASYNC_US);
ASSERT_EQ(2, visibilityChangedListener_->windowVisibilityInfos_.size());
ASSERT_EQ(WMError::WM_OK, subWindow1->Show());
usleep(WAIT_ASYNC_US);
ASSERT_EQ(2, visibilityChangedListener_->windowVisibilityInfos_.size());
window1->Destroy();
subWindow1->Destroy();
window2->Destroy();
subWindow2->Destroy();
}
}
} // namespace Rosen
} // namespace OHOS

View File

@ -35,6 +35,7 @@ public:
DisplayId displayId, bool focused);
void UpdateSystemBarRegionTints(DisplayId displayId, const SystemBarRegionTints& tints);
void UpdateWindowStatus(const sptr<WindowInfo>& windowInfo, WindowUpdateType type);
void UpdateWindowVisibilityInfo(const std::vector<sptr<WindowVisibilityInfo>>& windowVisibilityInfos);
private:
WindowManagerAgentController() {}

View File

@ -81,7 +81,8 @@ public:
int32_t priority_ { 0 };
bool requestedVisibility_ { false };
bool currentVisibility_ { false };
bool hasDecorated_ = false;
bool hasDecorated_ { false };
bool isCovered_ { true }; // initial value true to ensure notification when this window is shown
private:
// colorspace, gamut

View File

@ -27,6 +27,7 @@
namespace OHOS {
namespace Rosen {
using WindowNodeOperationFunc = std::function<bool(sptr<WindowNode>)>; // return true indicates to stop traverse
class WindowNodeContainer : public RefBase {
public:
WindowNodeContainer(DisplayId displayId, uint32_t width, uint32_t height);
@ -50,7 +51,6 @@ public:
void UpdateDisplayRect(uint32_t width, uint32_t height);
void OnAvoidAreaChange(const std::vector<Rect>& avoidAreas);
void LayoutDividerWindow(sptr<WindowNode>& node);
bool isVerticalDisplay() const;
WMError RaiseZOrderForAppWindow(sptr<WindowNode>& node, sptr<WindowNode>& parentNode);
sptr<WindowNode> GetNextFocusableWindow(uint32_t windowId) const;
@ -63,13 +63,10 @@ public:
WMError ExitSplitWindowMode(sptr<WindowNode>& node);
WMError SwitchLayoutPolicy(WindowLayoutMode mode, bool reorder = false);
void MoveWindowNode(sptr<WindowNodeContainer>& container);
sptr<WindowNode> GetBelowAppWindowNode() const;
sptr<WindowNode> GetAppWindowNode() const;
sptr<WindowNode> GetAboveAppWindowNode() const;
float GetVirtualPixelRatio() const;
void TraverseWindowTree(const WindowNodeOperationFunc& func, bool isFromTopToBottom = true) const;
private:
void AssignZOrder(sptr<WindowNode>& node);
void TraverseWindowNode(sptr<WindowNode>& root, std::vector<sptr<WindowNode>>& windowNodes) const;
sptr<WindowNode> FindRoot(WindowType type) const;
sptr<WindowNode> FindWindowNodeById(uint32_t id) const;
@ -92,6 +89,11 @@ private:
void ResetLayoutPolicy();
bool IsFullImmersiveNode(sptr<WindowNode> node) const;
bool IsSplitImmersiveNode(sptr<WindowNode> node) const;
bool TraverseFromTopToBottom(sptr<WindowNode> node, const WindowNodeOperationFunc& func) const;
bool TraverseFromBottomToTop(sptr<WindowNode> node, const WindowNodeOperationFunc& func) const;
// cannot determine in case of a window covered by union of several windows or with transparent value
void UpdateWindowVisibilityInfos(std::vector<sptr<WindowVisibilityInfo>>& infos);
sptr<AvoidAreaController> avoidController_;
sptr<WindowZorderPolicy> zorderPolicy_ = new WindowZorderPolicy();
@ -101,6 +103,7 @@ private:
std::vector<uint32_t> removedIds_;
DisplayId displayId_ = 0;
Rect displayRect_;
std::vector<Rect> currentCoveredArea_;
std::unordered_map<WindowType, sptr<WindowNode>> sysBarNodeMap_ {
{ WindowType::WINDOW_TYPE_STATUS_BAR, nullptr },
{ WindowType::WINDOW_TYPE_NAVIGATION_BAR, nullptr },

View File

@ -59,7 +59,7 @@ public:
void NotifyWindowStateChange(WindowState state, WindowStateChangeReason reason);
void NotifyDisplayChange(sptr<AbstractDisplay> abstractDisplay);
void NotifyDisplayDestory(DisplayId displayId);
void NotifyDisplayDestroy(DisplayId displayId);
void NotifySystemBarTints();
WMError RaiseZOrderForAppWindow(sptr<WindowNode>& node);
float GetVirtualPixelRatio(DisplayId displayId) const;

View File

@ -259,7 +259,7 @@ void WindowController::NotifyDisplayStateChange(DisplayId displayId, DisplayStat
break;
}
case DisplayStateChangeType::DESTROY: {
windowRoot_->NotifyDisplayDestory(displayId);
windowRoot_->NotifyDisplayDestroy(displayId);
break;
}
default: {

View File

@ -65,5 +65,15 @@ void WindowManagerAgentController::UpdateWindowStatus(const sptr<WindowInfo>& wi
agent->UpdateWindowStatus(windowInfo, type);
}
}
void WindowManagerAgentController::UpdateWindowVisibilityInfo(
const std::vector<sptr<WindowVisibilityInfo>>& windowVisibilityInfos)
{
WLOGFD("UpdateWindowVisibilityInfo size:%{public}zu", windowVisibilityInfos.size());
for (auto& agent : wmAgentContainer_.GetAgentsByType(
WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_VISIBILITY)) {
agent->UpdateWindowVisibilityInfo(windowVisibilityInfos);
}
}
}
}

View File

@ -18,6 +18,7 @@
#include <ability_manager_client.h>
#include <algorithm>
#include <cinttypes>
#include <ctime>
#include "common_event_manager.h"
#include "display_manager_service_inner.h"
@ -122,7 +123,6 @@ WMError WindowNodeContainer::AddWindowNode(sptr<WindowNode>& node, sptr<WindowNo
}
}
UpdateWindowTree(node);
UpdateRSTree(node, true);
AssignZOrder();
layoutPolicy_->AddWindowNode(node);
@ -132,6 +132,8 @@ WMError WindowNodeContainer::AddWindowNode(sptr<WindowNode>& node, sptr<WindowNo
} else {
NotifyIfSystemBarTintChanged();
}
std::vector<sptr<WindowVisibilityInfo>> infos;
UpdateWindowVisibilityInfos(infos);
DumpScreenWindowTree();
UpdateWindowStatus(node, WindowUpdateType::WINDOW_UPDATE_ADDED);
WLOGFI("AddWindowNode windowId: %{public}d end", node->GetWindowId());
@ -256,8 +258,16 @@ WMError WindowNodeContainer::RemoveWindowNode(sptr<WindowNode>& node)
node->requestedVisibility_ = false;
node->currentVisibility_ = false;
node->hasDecorated_ = false;
node->isCovered_ = true;
std::vector<sptr<WindowVisibilityInfo>> infos = {new WindowVisibilityInfo(node->GetWindowId(),
node->GetCallingPid(), node->GetCallingUid(), false)};
for (auto& child : node->children_) {
child->currentVisibility_ = false;
if (child->currentVisibility_) {
child->currentVisibility_ = false;
child->isCovered_ = true;
infos.emplace_back(new WindowVisibilityInfo(child->GetWindowId(), child->GetCallingPid(),
child->GetCallingUid(), false));
}
}
if (node->IsSplitMode()) {
@ -276,6 +286,7 @@ WMError WindowNodeContainer::RemoveWindowNode(sptr<WindowNode>& node)
} else {
NotifyIfSystemBarTintChanged();
}
UpdateWindowVisibilityInfos(infos);
DumpScreenWindowTree();
UpdateWindowStatus(node, WindowUpdateType::WINDOW_UPDATE_REMOVED);
WLOGFI("RemoveWindowNode windowId: %{public}d end", node->GetWindowId());
@ -347,43 +358,16 @@ void WindowNodeContainer::UpdateFocusStatus(uint32_t id, bool focused) const
void WindowNodeContainer::AssignZOrder()
{
zOrder_ = 0;
for (auto& node : belowAppWindowNode_->children_) {
AssignZOrder(node);
}
for (auto& node : appWindowNode_->children_) {
AssignZOrder(node);
}
for (auto& node : aboveAppWindowNode_->children_) {
AssignZOrder(node);
}
}
void WindowNodeContainer::AssignZOrder(sptr<WindowNode>& node)
{
if (node == nullptr) {
return;
}
auto iter = node->children_.begin();
for (; iter < node->children_.end(); ++iter) {
if ((*iter)->priority_ < 0) {
if ((*iter)->surfaceNode_) {
(*iter)->surfaceNode_->SetPositionZ(zOrder_);
++zOrder_;
}
} else {
break;
WindowNodeOperationFunc func = [this](sptr<WindowNode> node) {
if (node->surfaceNode_ == nullptr) {
WLOGE("AssignZOrder: surfaceNode is nullptr, window Id:%{public}u", node->GetWindowId());
return false;
}
}
if (node->surfaceNode_) {
node->surfaceNode_->SetPositionZ(zOrder_);
++zOrder_;
}
for (; iter < node->children_.end(); ++iter) {
if ((*iter)->surfaceNode_) {
(*iter)->surfaceNode_->SetPositionZ(zOrder_);
++zOrder_;
}
}
return false;
};
TraverseWindowTree(func, false);
}
WMError WindowNodeContainer::SetFocusWindow(uint32_t windowId)
@ -636,18 +620,18 @@ void WindowNodeContainer::DumpScreenWindowTree()
{
WLOGFI("-------- display %{public}" PRIu64" dump window info begin---------", displayId_);
WLOGFI("WindowName WinId Type Mode Flag ZOrd [ x y w h]");
std::vector<sptr<WindowNode>> windowNodes;
TraverseContainer(windowNodes);
int32_t zOrder = static_cast<int32_t>(windowNodes.size());
for (auto node : windowNodes) {
uint32_t zOrder = zOrder_;
WindowNodeOperationFunc func = [&zOrder](sptr<WindowNode> node) {
Rect rect = node->GetLayoutRect();
const std::string& windowName = node->GetWindowName().size() < WINDOW_NAME_MAX_LENGTH ?
node->GetWindowName() : node->GetWindowName().substr(0, WINDOW_NAME_MAX_LENGTH);
WLOGFI("%{public}10s %{public}5d %{public}4d %{public}4d %{public}4d %{public}4d [%{public}4d %{public}4d " \
"%{public}4d %{public}4d]", windowName.c_str(), node->GetWindowId(), node->GetWindowType(),
node->GetWindowMode(), node->GetWindowFlags(),
--zOrder, rect.posX_, rect.posY_, rect.width_, rect.height_);
}
WLOGI("DumpScreenWindowTree: %{public}10s %{public}5d %{public}4d %{public}4d %{public}4d %{public}4d " \
"[%{public}4d %{public}4d %{public}4d %{public}4d]",
windowName.c_str(), node->GetWindowId(), node->GetWindowType(), node->GetWindowMode(),
node->GetWindowFlags(), --zOrder, rect.posX_, rect.posY_, rect.width_, rect.height_);
return false;
};
TraverseWindowTree(func, true);
WLOGFI("-------- display %{public}" PRIu64" dump window info end ---------", displayId_);
}
@ -780,22 +764,21 @@ WMError WindowNodeContainer::RaiseZOrderForAppWindow(sptr<WindowNode>& node, spt
sptr<WindowNode> WindowNodeContainer::GetNextFocusableWindow(uint32_t windowId) const
{
std::vector<sptr<WindowNode>> windowNodes;
TraverseContainer(windowNodes);
auto iter = std::find_if(windowNodes.begin(), windowNodes.end(),
[windowId](sptr<WindowNode>& node) {
return node->GetWindowId() == windowId;
});
if (iter != windowNodes.end()) {
int index = std::distance(windowNodes.begin(), iter);
for (int i = index + 1; i < windowNodes.size(); i++) {
if (windowNodes[i]->GetWindowProperty()->GetFocusable()) {
return windowNodes[i];
}
sptr<WindowNode> nextFocusableWindow;
bool previousFocusedWindowFound = false;
WindowNodeOperationFunc func = [windowId, &nextFocusableWindow, &previousFocusedWindowFound](
sptr<WindowNode> node) {
if (previousFocusedWindowFound && node->GetWindowProperty()->GetFocusable()) {
nextFocusableWindow = node;
return true;
}
}
WLOGFI("could not get next focusable window");
return nullptr;
if (node->GetWindowId() == windowId) {
previousFocusedWindowFound = true;
}
return false;
};
TraverseWindowTree(func, true);
return nextFocusableWindow;
}
void WindowNodeContainer::MinimizeAllAppWindows()
@ -1027,39 +1010,136 @@ void WindowNodeContainer::MoveWindowNode(sptr<WindowNodeContainer>& container)
{
WLOGFI("MoveWindowNode: disconnect expand display: %{public}" PRId64 ", move window node to display: "
"%{public}" PRId64 "", container->GetDisplayId(), displayId_);
sptr<WindowNode> belowAppNode = container->GetBelowAppWindowNode();
sptr<WindowNode> appNode = container->GetAppWindowNode();
sptr<WindowNode> aboveAppNode = container->GetAboveAppWindowNode();
for (auto& node : belowAppNode->children_) {
for (auto& node : container->belowAppWindowNode_->children_) {
WLOGFI("belowAppWindowNode_: move windowNode: {public}%d", node->GetWindowId());
node->SetDisplayId(displayId_);
belowAppWindowNode_->children_.push_back(node);
}
for (auto& node : appNode->children_) {
for (auto& node : container->appWindowNode_->children_) {
WLOGFI("appWindowNode_: move windowNode: {public}%d", node->GetWindowId());
node->SetDisplayId(displayId_);
appWindowNode_->children_.push_back(node);
}
for (auto& node : aboveAppNode->children_) {
for (auto& node : container->aboveAppWindowNode_->children_) {
WLOGFI("aboveAppWindowNode_: move windowNode: {public}%d", node->GetWindowId());
node->SetDisplayId(displayId_);
aboveAppWindowNode_->children_.push_back(node);
}
}
sptr<WindowNode> WindowNodeContainer::GetBelowAppWindowNode() const
void WindowNodeContainer::TraverseWindowTree(const WindowNodeOperationFunc& func, bool isFromTopToBottom) const
{
return belowAppWindowNode_;
std::vector<sptr<WindowNode>> rootNodes = { belowAppWindowNode_, appWindowNode_, aboveAppWindowNode_ };
if (isFromTopToBottom) {
std::reverse(rootNodes.begin(), rootNodes.end());
}
for (auto& node : rootNodes) {
if (isFromTopToBottom) {
for (auto iter = node->children_.rbegin(); iter != node->children_.rend(); ++iter) {
if (TraverseFromTopToBottom(*iter, func)) {
return;
}
}
} else {
for (auto iter = node->children_.begin(); iter != node->children_.end(); ++iter) {
if (TraverseFromBottomToTop(*iter, func)) {
return;
}
}
}
}
}
sptr<WindowNode> WindowNodeContainer::GetAppWindowNode() const
bool WindowNodeContainer::TraverseFromTopToBottom(sptr<WindowNode> node, const WindowNodeOperationFunc& func) const
{
return appWindowNode_;
if (node == nullptr) {
return false;
}
auto iterBegin = node->children_.rbegin();
for (; iterBegin != node->children_.rend(); ++iterBegin) {
if ((*iterBegin)->priority_ <= 0) {
break;
}
if (func(*iterBegin)) {
return true;
}
}
if (func(node)) {
return true;
}
for (; iterBegin != node->children_.rend(); ++iterBegin) {
if (func(*iterBegin)) {
return true;
}
}
return false;
}
sptr<WindowNode> WindowNodeContainer::GetAboveAppWindowNode() const
bool WindowNodeContainer::TraverseFromBottomToTop(sptr<WindowNode> node, const WindowNodeOperationFunc& func) const
{
return aboveAppWindowNode_;
if (node == nullptr) {
return false;
}
auto iterBegin = node->children_.begin();
for (; iterBegin != node->children_.end(); ++iterBegin) {
if ((*iterBegin)->priority_ >= 0) {
break;
}
if (func(*iterBegin)) {
return true;
}
}
if (func(node)) {
return true;
}
for (; iterBegin != node->children_.end(); ++iterBegin) {
if (func(*iterBegin)) {
return true;
}
}
return false;
}
void WindowNodeContainer::UpdateWindowVisibilityInfos(std::vector<sptr<WindowVisibilityInfo>>& infos)
{
currentCoveredArea_.clear();
WindowNodeOperationFunc func = [this, &infos](sptr<WindowNode> node) {
if (node == nullptr) {
return false;
}
Rect layoutRect = node->GetLayoutRect();
int32_t nodeX = std::max(0, layoutRect.posX_);
int32_t nodeY = std::max(0, layoutRect.posY_);
int32_t nodeXEnd = std::min(displayRect_.posX_ + static_cast<int32_t>(displayRect_.width_),
layoutRect.posX_ + static_cast<int32_t>(layoutRect.width_));
int32_t nodeYEnd = std::min(displayRect_.posY_ + static_cast<int32_t>(displayRect_.height_),
layoutRect.posY_ + static_cast<int32_t>(layoutRect.height_));
Rect rectInDisplay = {nodeX, nodeY,
static_cast<uint32_t>(nodeXEnd - nodeX), static_cast<uint32_t>(nodeYEnd - nodeY)};
bool isCovered = false;
for (auto& rect : currentCoveredArea_) {
if (rectInDisplay.IsInsideOf(rect)) {
isCovered = true;
WLOGD("UpdateWindowVisibilityInfos: find covered window:%{public}u", node->GetWindowId());
break;
}
}
if (!isCovered) {
currentCoveredArea_.emplace_back(rectInDisplay);
}
if (isCovered != node->isCovered_) {
node->isCovered_ = isCovered;
infos.emplace_back(new WindowVisibilityInfo(node->GetWindowId(), node->GetCallingPid(),
node->GetCallingUid(), !isCovered));
WLOGD("UpdateWindowVisibilityInfos: covered status changed window:%{public}u, covered:%{public}d",
node->GetWindowId(), isCovered);
}
return false;
};
TraverseWindowTree(func, true);
WindowManagerAgentController::GetInstance().UpdateWindowVisibilityInfo(infos);
}
float WindowNodeContainer::GetVirtualPixelRatio() const

View File

@ -467,14 +467,17 @@ WMError WindowRoot::SetWindowLayoutMode(DisplayId displayId, WindowLayoutMode mo
return ret;
}
void WindowRoot::NotifyDisplayDestory(DisplayId expandDisplayId)
void WindowRoot::NotifyDisplayDestroy(DisplayId expandDisplayId)
{
WLOGFW("disconnect expand display, get default and expand display container");
WLOGFD("disconnect expand display, get default and expand display container");
DisplayId defaultDisplayId = DisplayManagerServiceInner::GetInstance().GetDefaultDisplayId();
auto expandDisplaycontainer = GetOrCreateWindowNodeContainer(expandDisplayId);
auto defaultDisplaycontainer = GetOrCreateWindowNodeContainer(defaultDisplayId);
defaultDisplaycontainer->MoveWindowNode(expandDisplaycontainer);
auto expandDisplayContainer = GetOrCreateWindowNodeContainer(expandDisplayId);
auto defaultDisplayContainer = GetOrCreateWindowNodeContainer(defaultDisplayId);
if (expandDisplayContainer == nullptr || defaultDisplayContainer == nullptr) {
WLOGFE("window node container is nullptr!");
return;
}
defaultDisplayContainer->MoveWindowNode(expandDisplayContainer);
NotifyDisplayRemoved(expandDisplayId);
}