窗口沉浸式模式改为组件自动避让实现回退

Change-Id: I883375bbe03ed9b3dc1ef1229639796b9d6b14fd
Signed-off-by: z00514981 <zhengjiangliang@huawei.com>
This commit is contained in:
z00514981 2023-03-23 20:56:51 +08:00
parent 6ec5663000
commit baf2e6460b
14 changed files with 130 additions and 12 deletions

View File

@ -55,6 +55,11 @@ sptr<Window> WindowTestUtils::CreateTestWindow(const TestWindowInfo& info)
if (info.parentId != INVALID_WINDOW_ID) {
option->SetParentId(info.parentId);
}
if (info.needAvoid) {
option->AddWindowFlag(WindowFlag::WINDOW_FLAG_NEED_AVOID);
} else {
option->RemoveWindowFlag(WindowFlag::WINDOW_FLAG_NEED_AVOID);
}
if (info.parentLimit) {
option->AddWindowFlag(WindowFlag::WINDOW_FLAG_PARENT_LIMIT);
} else {

View File

@ -705,7 +705,12 @@ WMError WindowImpl::SetLayoutFullScreen(bool status)
WLOGFE("invalid window or fullscreen mode is not be supported, winId:%{public}u", property_->GetWindowId());
return WMError::WM_ERROR_INVALID_WINDOW;
}
WMError ret = WMError::WM_OK;
WMError ret = SetWindowMode(WindowMode::WINDOW_MODE_FULLSCREEN);
if (ret != WMError::WM_OK) {
WLOGFE("SetWindowMode errCode:%{public}d winId:%{public}u",
static_cast<int32_t>(ret), property_->GetWindowId());
return ret;
}
if (status) {
ret = RemoveWindowFlag(WindowFlag::WINDOW_FLAG_NEED_AVOID);
if (ret != WMError::WM_OK) {
@ -3067,6 +3072,7 @@ void WindowImpl::SetDefaultOption()
break;
}
case WindowType::WINDOW_TYPE_KEYGUARD: {
RemoveWindowFlag(WindowFlag::WINDOW_FLAG_NEED_AVOID);
property_->SetWindowMode(WindowMode::WINDOW_MODE_FULLSCREEN);
break;
}
@ -3116,8 +3122,10 @@ bool WindowImpl::IsWindowValid() const
bool WindowImpl::IsLayoutFullScreen() const
{
uint32_t flags = GetWindowFlags();
auto mode = GetMode();
return (mode == WindowMode::WINDOW_MODE_FULLSCREEN);
bool needAvoid = (flags & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_NEED_AVOID));
return (mode == WindowMode::WINDOW_MODE_FULLSCREEN && !needAvoid);
}
bool WindowImpl::IsFullScreen() const

View File

@ -21,6 +21,7 @@ namespace OHOS {
namespace Rosen {
WindowOption::WindowOption(): windowTag_(WindowTag::SYSTEM_WINDOW)
{
AddWindowFlag(WindowFlag::WINDOW_FLAG_NEED_AVOID);
}
void WindowOption::SetWindowRect(const struct Rect& rect)

View File

@ -2173,21 +2173,29 @@ HWTEST_F(WindowImplTest, SetLayoutFullScreen, Function | SmallTest | Level3)
EXPECT_CALL(m->Mock(), UpdateProperty(_, _)).Times(1).WillOnce(Return(WMError::WM_DO_NOTHING));
ASSERT_EQ(WMError::WM_DO_NOTHING, window->SetLayoutFullScreen(true));
window->property_->SetWindowFlags(window->property_->GetWindowFlags() |
(static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_NEED_AVOID)));
EXPECT_CALL(m->Mock(), UpdateProperty(_, _)).Times(2)
.WillOnce(Return(WMError::WM_OK))
.WillOnce(Return(WMError::WM_OK));
ASSERT_EQ(WMError::WM_OK, window->SetLayoutFullScreen(true));
window->property_->SetWindowFlags(window->property_->GetWindowFlags() |
(static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_NEED_AVOID)));
EXPECT_CALL(m->Mock(), UpdateProperty(_, _)).Times(2)
.WillOnce(Return(WMError::WM_OK))
.WillOnce(Return(WMError::WM_DO_NOTHING));
ASSERT_EQ(WMError::WM_DO_NOTHING, window->SetLayoutFullScreen(true));
window->property_->SetWindowFlags(window->property_->GetWindowFlags() &
(~static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_NEED_AVOID)));
EXPECT_CALL(m->Mock(), UpdateProperty(_, _)).Times(2)
.WillOnce(Return(WMError::WM_OK))
.WillOnce(Return(WMError::WM_OK));
ASSERT_EQ(WMError::WM_OK, window->SetLayoutFullScreen(false));
window->property_->SetWindowFlags(window->property_->GetWindowFlags() &
(~static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_NEED_AVOID)));
EXPECT_CALL(m->Mock(), UpdateProperty(_, _)).Times(2)
.WillOnce(Return(WMError::WM_OK))
.WillOnce(Return(WMError::WM_DO_NOTHING));
@ -2222,17 +2230,23 @@ HWTEST_F(WindowImplTest, SetFullScreen, Function | SmallTest | Level3)
window->property_->sysBarPropMap_[WindowType::WINDOW_TYPE_STATUS_BAR].enable_ = true;
window->property_->sysBarPropMap_[WindowType::WINDOW_TYPE_NAVIGATION_BAR].enable_ = true;
window->property_->SetWindowFlags(window->property_->GetWindowFlags() |
(static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_NEED_AVOID)));
EXPECT_CALL(m->Mock(), UpdateProperty(_, _)).Times(3).WillRepeatedly(Return(WMError::WM_OK));
ASSERT_EQ(WMError::WM_OK, window->SetFullScreen(true));
window->property_->sysBarPropMap_[WindowType::WINDOW_TYPE_STATUS_BAR].enable_ = false;
window->property_->sysBarPropMap_[WindowType::WINDOW_TYPE_NAVIGATION_BAR].enable_ = false;
window->property_->SetWindowFlags(window->property_->GetWindowFlags() &
(~static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_NEED_AVOID)));
EXPECT_CALL(m->Mock(), UpdateProperty(_, _)).Times(3)
.WillRepeatedly(Return(WMError::WM_OK));
ASSERT_EQ(WMError::WM_OK, window->SetFullScreen(false));
window->property_->sysBarPropMap_[WindowType::WINDOW_TYPE_STATUS_BAR].enable_ = true;
window->property_->sysBarPropMap_[WindowType::WINDOW_TYPE_NAVIGATION_BAR].enable_ = true;
window->property_->SetWindowFlags(window->property_->GetWindowFlags() |
(static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_NEED_AVOID)));
EXPECT_CALL(m->Mock(), UpdateProperty(_, _)).Times(2)
.WillOnce(Return(WMError::WM_OK))
.WillOnce(Return(WMError::WM_DO_NOTHING));
@ -2240,6 +2254,8 @@ HWTEST_F(WindowImplTest, SetFullScreen, Function | SmallTest | Level3)
window->property_->sysBarPropMap_[WindowType::WINDOW_TYPE_STATUS_BAR].enable_ = true;
window->property_->sysBarPropMap_[WindowType::WINDOW_TYPE_NAVIGATION_BAR].enable_ = true;
window->property_->SetWindowFlags(window->property_->GetWindowFlags() |
(static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_NEED_AVOID)));
EXPECT_CALL(m->Mock(), UpdateProperty(_, _)).Times(3)
.WillOnce(Return(WMError::WM_DO_NOTHING))
.WillOnce(Return(WMError::WM_OK))

View File

@ -239,8 +239,8 @@ HWTEST_F(WindowOptionTest, WindowFlag01, Function | SmallTest | Level2)
HWTEST_F(WindowOptionTest, WindowFlag02, Function | SmallTest | Level2)
{
sptr<WindowOption> option = new WindowOption();
option->AddWindowFlag(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED);
ASSERT_EQ(static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED), option->GetWindowFlags());
option->AddWindowFlag(WindowFlag::WINDOW_FLAG_NEED_AVOID);
ASSERT_EQ(static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_NEED_AVOID), option->GetWindowFlags());
}
/**
@ -251,9 +251,9 @@ HWTEST_F(WindowOptionTest, WindowFlag02, Function | SmallTest | Level2)
HWTEST_F(WindowOptionTest, WindowFlag03, Function | SmallTest | Level2)
{
sptr<WindowOption> option = new WindowOption();
option->AddWindowFlag(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED);
option->AddWindowFlag(WindowFlag::WINDOW_FLAG_NEED_AVOID);
option->AddWindowFlag(WindowFlag::WINDOW_FLAG_PARENT_LIMIT);
option->RemoveWindowFlag(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED);
option->RemoveWindowFlag(WindowFlag::WINDOW_FLAG_NEED_AVOID);
ASSERT_EQ(static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_PARENT_LIMIT), option->GetWindowFlags());
}

View File

@ -89,6 +89,7 @@ private:
static sptr<RSWindowAnimationFinishedCallback> CreateHideAnimationFinishedCallback(
const sptr<WindowNode>& srcNode, TransitionEvent event);
static void ProcessNodeStateTask(sptr<WindowNode>& node);
static void GetExpectRect(const sptr<WindowNode>& dstNode, const sptr<RSWindowAnimationTarget>& dstTarget);
static void PostProcessShowCallback(const sptr<WindowNode>& node);
static void ExecuteFinalStateTask(sptr<WindowNode>& node);
static void GetAnimationTargetsForHome(std::vector<sptr<RSWindowAnimationTarget>>& animationTargets,

View File

@ -76,6 +76,7 @@ sptr<Window> FreezeController::CreateCoverWindow(DisplayId displayId)
option->SetWindowType(WindowType::WINDOW_TYPE_FREEZE_DISPLAY);
option->SetFocusable(false);
option->SetMainHandlerAvailable(false);
option->RemoveWindowFlag(WindowFlag::WINDOW_FLAG_NEED_AVOID);
option->SetDisplayId(displayId);
sptr<Window> window = Window::Create("freeze" + std::to_string(displayId), option);
if (window == nullptr) {

View File

@ -305,6 +305,36 @@ WMError RemoteAnimation::NotifyAnimationStartApp(sptr<WindowTransitionInfo> srcI
return WMError::WM_OK;
}
void RemoteAnimation::GetExpectRect(const sptr<WindowNode>& dstNode, const sptr<RSWindowAnimationTarget>& dstTarget)
{
// when exit immersive, startingWindow (0,0,w,h), but app need avoid
bool needAvoid = (dstNode->GetWindowFlags() & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_NEED_AVOID));
auto winRoot = windowRoot_.promote();
if (needAvoid && winRoot) {
auto avoidRect = winRoot->GetDisplayRectWithoutSystemBarAreas(dstNode);
if (WindowHelper::IsEmptyRect(avoidRect)) {
return;
}
WLOGFI("name:%{public}s id:%{public}u avoidRect:[x:%{public}d, y:%{public}d, w:%{public}d, h:%{public}d]",
dstNode->GetWindowName().c_str(), dstNode->GetWindowId(),
avoidRect.posX_, avoidRect.posY_, avoidRect.width_, avoidRect.height_);
if (WindowHelper::IsMainFullScreenWindow(dstNode->GetWindowType(), dstNode->GetWindowMode())) {
auto boundsRect = RectF(avoidRect.posX_, avoidRect.posY_, avoidRect.width_, avoidRect.height_);
auto displayInfo = DisplayGroupInfo::GetInstance().GetDisplayInfo(dstNode->GetDisplayId());
if (displayInfo && WmsUtils::IsExpectedRotatableWindow(dstNode->GetRequestedOrientation(),
displayInfo->GetDisplayOrientation(), dstNode->GetWindowFlags())) {
WLOGFD("[FixOrientation] window %{public}u expected rotatable, pre-cal bounds", dstNode->GetWindowId());
boundsRect = RectF(avoidRect.posX_, avoidRect.posY_, avoidRect.height_, avoidRect.width_);
}
dstTarget->windowBounds_.rect_ = boundsRect;
if (dstNode->leashWinSurfaceNode_) {
dstNode->leashWinSurfaceNode_->SetBounds(avoidRect.posX_, avoidRect.posY_,
avoidRect.width_, avoidRect.height_);
}
}
}
}
WMError RemoteAnimation::NotifyAnimationTransition(sptr<WindowTransitionInfo> srcInfo,
sptr<WindowTransitionInfo> dstInfo, const sptr<WindowNode>& srcNode,
const sptr<WindowNode>& dstNode)
@ -331,6 +361,8 @@ WMError RemoteAnimation::NotifyAnimationTransition(sptr<WindowTransitionInfo> sr
}
ResSchedReport::GetInstance().ResSchedDataReport(
Rosen::RES_TYPE_SHOW_REMOTE_ANIMATION, Rosen::REMOTE_ANIMATION_BEGIN, payload);
// when exit immersive, startingWindow (0,0,w,h), but app need avoid
GetExpectRect(dstNode, dstTarget);
dstNode->isPlayAnimationShow_ = true;
// Transition to next state and update task count will success when enable animationFirst_
dstNode->stateMachine_.TransitionTo(WindowNodeState::SHOW_ANIMATION_PLAYING);

View File

@ -87,6 +87,11 @@ sptr<WindowNode> StartingWindow::CreateWindowNode(const sptr<WindowTransitionInf
property->SetDisplayId(info->GetDisplayId());
property->SetWindowType(info->GetWindowType());
auto displayInfo = DisplayGroupInfo::GetInstance().GetDisplayInfo(info->GetDisplayId());
if (!(displayInfo && WmsUtils::IsExpectedRotatableWindow(orientation,
displayInfo->GetDisplayOrientation(), property->GetWindowMode(), property->GetWindowFlags(), false))) {
property->AddWindowFlag(WindowFlag::WINDOW_FLAG_NEED_AVOID);
}
if (info->GetShowFlagWhenLocked()) {
property->AddWindowFlag(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED);
}

View File

@ -437,7 +437,8 @@ void WindowLayoutPolicyCascade::UpdateLayoutRect(const sptr<WindowNode>& node)
winRect = cascadeRectsMap_[displayId].secondaryRect_;
break;
case WindowMode::WINDOW_MODE_FULLSCREEN: {
winRect = DisplayGroupInfo::GetInstance().GetDisplayRect(displayId);
bool needAvoid = (node->GetWindowFlags() & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_NEED_AVOID));
winRect = needAvoid ? limitRectMap_[displayId] : DisplayGroupInfo::GetInstance().GetDisplayRect(displayId);
auto displayInfo = DisplayGroupInfo::GetInstance().GetDisplayInfo(displayId);
if (displayInfo && WmsUtils::IsExpectedRotatableWindow(node->GetRequestedOrientation(),
displayInfo->GetDisplayOrientation(), node->GetWindowFlags())) {

View File

@ -347,6 +347,7 @@ void WindowLayoutPolicyTile::UpdateLayoutRect(const sptr<WindowNode>& node)
{
UpdateWindowSizeLimits(node);
bool floatingWindow = (node->GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING);
bool needAvoid = (node->GetWindowFlags() & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_NEED_AVOID));
Rect lastRect = node->GetWindowRect();
Rect winRect = node->GetRequestRect();
WLOGI("[Before TileLayout] windowId: %{public}u, mode: %{public}u, type: %{public}u requestRect: [%{public}d, "
@ -354,7 +355,9 @@ void WindowLayoutPolicyTile::UpdateLayoutRect(const sptr<WindowNode>& node)
winRect.posX_, winRect.posY_, winRect.width_, winRect.height_);
if (!floatingWindow) { // fullscreen window
winRect = DisplayGroupInfo::GetInstance().GetDisplayRect(node->GetDisplayId());
const auto& displayRect = DisplayGroupInfo::GetInstance().GetDisplayRect(node->GetDisplayId());
const auto& limitDisplayRect = limitRectMap_[node->GetDisplayId()];
winRect = needAvoid ? limitDisplayRect : displayRect;
}
WLOGI("[After TileLayout] windowId: %{public}u, isDecor: %{public}u, winRect: [%{public}d, %{public}d, "

View File

@ -207,6 +207,8 @@ void WindowNodeContainer::LayoutWhenAddWindowNode(sptr<WindowNode>& node, bool a
{
if (afterAnimation) {
layoutPolicy_->PerformWindowLayout(node, WindowUpdateType::WINDOW_UPDATE_ADDED);
// tile layout will change window mode from fullscreen to float
// notify systembar window to change color
NotifyIfAvoidAreaChanged(node, AvoidControlType::AVOID_NODE_ADD);
DumpScreenWindowTreeByWinId(node->GetWindowId());
return;
@ -230,6 +232,8 @@ void WindowNodeContainer::LayoutWhenAddWindowNode(sptr<WindowNode>& node, bool a
node->SetWindowSizeChangeReason(WindowSizeChangeReason::CUSTOM_ANIMATION_SHOW);
}
layoutPolicy_->PerformWindowLayout(node, WindowUpdateType::WINDOW_UPDATE_ADDED);
// tile layout will change window mode from fullscreen to float
// notify systembar window to change color
NotifyIfAvoidAreaChanged(node, AvoidControlType::AVOID_NODE_ADD);
DumpScreenWindowTreeByWinId(node->GetWindowId());
}

View File

@ -608,6 +608,47 @@ HWTEST_F(RemoteAnimationTest, GetTransitionEvent02, Function | SmallTest | Level
EXPECT_EQ(TransitionEvent::UNKNOWN, event);
}
/**
* @tc.name: GetExpectRect01
* @tc.desc: GetExpectRect
* @tc.type: FUNC
*/
HWTEST_F(RemoteAnimationTest, GetExpectRect01, Function | SmallTest | Level2)
{
auto target = RemoteAnimation::CreateWindowAnimationTarget(transitionInfo_, node_);
RemoteAnimation::GetExpectRect(node_, target);
Rect actualRect = GetSurfaceBoundsRect(node_);
EXPECT_EQ(node_->GetWindowRect(), actualRect); // avoidRect is empty thus return
sptr<WindowNode> statusBar = new WindowNode(CreateWindowProperty(0));
ASSERT_NE(nullptr, statusBar);
statusBar->GetWindowProperty()->SetWindowType(WindowType::WINDOW_TYPE_STATUS_BAR);
statusBar->SetWindowRect({0, 0, 100, 100});
windowRoot_->windowNodeMap_[0] = statusBar;
Rect avoidRect = windowRoot_->GetDisplayRectWithoutSystemBarAreas(node_);
EXPECT_FALSE(WindowHelper::IsEmptyRect(avoidRect));
RemoteAnimation::GetExpectRect(node_, target);
actualRect = GetSurfaceBoundsRect(node_);
EXPECT_EQ(avoidRect, actualRect); // get expect rect
node_->leashWinSurfaceNode_ = nullptr;
RemoteAnimation::GetExpectRect(node_, target);
node_->GetWindowProperty()->SetWindowMode(WindowMode::WINDOW_MODE_FLOATING);
RemoteAnimation::GetExpectRect(node_, target);
EXPECT_FALSE(WindowHelper::IsMainFullScreenWindow(node_->GetWindowType(), node_->GetWindowMode()));
RemoteAnimation::windowRoot_ = nullptr;
RemoteAnimation::GetExpectRect(node_, target);
node_->GetWindowProperty()->SetWindowFlags(0);
RemoteAnimation::GetExpectRect(node_, target);
bool needAvoid = (node_->GetWindowFlags() & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_NEED_AVOID));
EXPECT_EQ(false, needAvoid);
}
/**
* @tc.name: NotifyAnimationTransition01
* @tc.desc: NotifyAnimationTransition failed

View File

@ -254,7 +254,7 @@ HWTEST_F(WindowPairTest, IsForbidDockSliceMove02, Function | SmallTest | Level2)
sptr<WindowPair> windowPair = new WindowPair(0);
windowPair->status_ = WindowPairStatus::PAIRED_DONE;
sptr<WindowProperty> property1 = new WindowProperty();
property1->SetWindowFlags(static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED));
property1->SetWindowFlags(static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_NEED_AVOID));
windowPair->primary_ = new WindowNode(property1);
windowPair->secondary_ = new WindowNode(property1);
ASSERT_EQ(false, windowPair->IsForbidDockSliceMove());
@ -270,7 +270,7 @@ HWTEST_F(WindowPairTest, IsForbidDockSliceMove03, Function | SmallTest | Level2)
sptr<WindowPair> windowPair = new WindowPair(0);
windowPair->status_ = WindowPairStatus::PAIRED_DONE;
sptr<WindowProperty> property1 = new WindowProperty();
property1->SetWindowFlags(static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED));
property1->SetWindowFlags(static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_NEED_AVOID));
windowPair->primary_ = nullptr;
windowPair->secondary_ = new WindowNode(property1);
ASSERT_EQ(true, windowPair->IsForbidDockSliceMove());
@ -302,7 +302,7 @@ HWTEST_F(WindowPairTest, IsForbidDockSliceMove05, Function | SmallTest | Level2)
sptr<WindowPair> windowPair = new WindowPair(0);
windowPair->status_ = WindowPairStatus::PAIRED_DONE;
sptr<WindowProperty> property1 = new WindowProperty();
property1->SetWindowFlags(static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED));
property1->SetWindowFlags(static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_NEED_AVOID));
windowPair->primary_ = new WindowNode(property1);
windowPair->secondary_ = nullptr;
ASSERT_EQ(true, windowPair->IsForbidDockSliceMove());
@ -318,7 +318,7 @@ HWTEST_F(WindowPairTest, IsForbidDockSliceMove06, Function | SmallTest | Level2)
sptr<WindowPair> windowPair = new WindowPair(0);
windowPair->status_ = WindowPairStatus::PAIRED_DONE;
sptr<WindowProperty> property1 = new WindowProperty();
property1->SetWindowFlags(static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED));
property1->SetWindowFlags(static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_NEED_AVOID));
sptr<WindowProperty> property2 = new WindowProperty();
property2->SetWindowFlags(static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_FORBID_SPLIT_MOVE));
windowPair->primary_ = new WindowNode(property1);