Commit e60b1697 authored by Kazuki Takise's avatar Kazuki Takise Committed by Commit Bot

Adjust bounds when entering PIP

As Android doesn't know about Chrome OS System UI, it can place the
PIP window at an incorrect position.
There were CTS concerns that disallow Chrome to adjust PIP initial
bounds, but we decided to workaround this on the Android side.

BUG=b:147790853
BUG=b:147791406
TEST=Manually confirmed PIP windows were located at the correct position
TEST=with hotseat on
TEST=android.server.am.ActivityManagerPinnedStackTests
TEST=#testEnterPictureInPictureSavePosition

Change-Id: Ibe962fc105584a1d457a3e3075e2dcabc23db129
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2022582
Commit-Queue: Kazuki Takise <takise@chromium.org>
Auto-Submit: Kazuki Takise <takise@chromium.org>
Reviewed-by: default avatarStefan Kuhne <skuhne@chromium.org>
Reviewed-by: default avatarMitsuru Oshima (slow in TOK) <oshima@chromium.org>
Cr-Commit-Position: refs/heads/master@{#736894}
parent 0812dd3d
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include "ash/root_window_controller.h" #include "ash/root_window_controller.h"
#include "ash/shell.h" #include "ash/shell.h"
#include "ash/wm/client_controlled_state.h" #include "ash/wm/client_controlled_state.h"
#include "ash/wm/collision_detection/collision_detection_utils.h"
#include "ash/wm/drag_details.h" #include "ash/wm/drag_details.h"
#include "ash/wm/splitview/split_view_controller.h" #include "ash/wm/splitview/split_view_controller.h"
#include "ash/wm/toplevel_window_event_handler.h" #include "ash/wm/toplevel_window_event_handler.h"
...@@ -866,6 +867,11 @@ void ClientControlledShellSurface::SetWidgetBounds(const gfx::Rect& bounds) { ...@@ -866,6 +867,11 @@ void ClientControlledShellSurface::SetWidgetBounds(const gfx::Rect& bounds) {
if (!is_display_move_pending) { if (!is_display_move_pending) {
ash::ClientControlledState::AdjustBoundsForMinimumWindowVisibility( ash::ClientControlledState::AdjustBoundsForMinimumWindowVisibility(
target_display.work_area(), &adjusted_bounds); target_display.work_area(), &adjusted_bounds);
if (GetWindowState()->IsPip()) {
adjusted_bounds = ash::CollisionDetectionUtils::GetRestingPosition(
target_display, adjusted_bounds,
ash::CollisionDetectionUtils::RelativePriority::kPictureInPicture);
}
} }
if (adjusted_bounds == widget_->GetWindowBoundsInScreen() && if (adjusted_bounds == widget_->GetWindowBoundsInScreen() &&
...@@ -1093,25 +1099,10 @@ void ClientControlledShellSurface::OnPostWidgetCommit() { ...@@ -1093,25 +1099,10 @@ void ClientControlledShellSurface::OnPostWidgetCommit() {
if (expected_orientation_ == orientation_) if (expected_orientation_ == orientation_)
orientation_compositor_lock_.reset(); orientation_compositor_lock_.reset();
ui::ZOrderLevel z_order_level = pending_always_on_top_
? ui::ZOrderLevel::kFloatingWindow
: ui::ZOrderLevel::kNormal;
ash::WindowState* window_state = GetWindowState();
if (window_state->IsPip()) {
// CTS requires a PIP window to stay at the initial position that Android
// calculates. UpdatePipBounds() is triggered by setting the window always
// on top, and depending on the density, it's adjusted by one pixel, which
// makes CTS fail.
// TODO(takise): Remove this workaround once ARC P is gone. See b/147847272
// for more detail.
base::AutoReset<bool> resetter(&ignore_bounds_change_request_, true);
widget_->GetNativeWindow()->SetProperty(aura::client::kZOrderingKey, widget_->GetNativeWindow()->SetProperty(aura::client::kZOrderingKey,
z_order_level); pending_always_on_top_
} else { ? ui::ZOrderLevel::kFloatingWindow
widget_->GetNativeWindow()->SetProperty(aura::client::kZOrderingKey, : ui::ZOrderLevel::kNormal);
z_order_level);
}
} }
void ClientControlledShellSurface::OnSurfaceDestroying(Surface* surface) { void ClientControlledShellSurface::OnSurfaceDestroying(Surface* surface) {
......
...@@ -2047,11 +2047,11 @@ TEST_F(ClientControlledShellSurfaceTest, SetPipWindowBoundsAnimates) { ...@@ -2047,11 +2047,11 @@ TEST_F(ClientControlledShellSurfaceTest, SetPipWindowBoundsAnimates) {
ui::ScopedAnimationDurationScaleMode animation_scale_mode( ui::ScopedAnimationDurationScaleMode animation_scale_mode(
ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION); ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
aura::Window* window = shell_surface->GetWidget()->GetNativeWindow(); aura::Window* window = shell_surface->GetWidget()->GetNativeWindow();
EXPECT_EQ(gfx::Rect(0, 0, 256, 256), window->layer()->GetTargetBounds()); EXPECT_EQ(gfx::Rect(8, 8, 256, 256), window->layer()->GetTargetBounds());
EXPECT_EQ(gfx::Rect(0, 0, 256, 256), window->layer()->bounds()); EXPECT_EQ(gfx::Rect(8, 8, 256, 256), window->layer()->bounds());
window->SetBounds(gfx::Rect(10, 10, 256, 256)); window->SetBounds(gfx::Rect(10, 10, 256, 256));
EXPECT_EQ(gfx::Rect(10, 10, 256, 256), window->layer()->GetTargetBounds()); EXPECT_EQ(gfx::Rect(8, 10, 256, 256), window->layer()->GetTargetBounds());
EXPECT_EQ(gfx::Rect(0, 0, 256, 256), window->layer()->bounds()); EXPECT_EQ(gfx::Rect(8, 8, 256, 256), window->layer()->bounds());
} }
TEST_F(ClientControlledShellSurfaceTest, PipWindowDragDoesNotAnimate) { TEST_F(ClientControlledShellSurfaceTest, PipWindowDragDoesNotAnimate) {
...@@ -2069,15 +2069,15 @@ TEST_F(ClientControlledShellSurfaceTest, PipWindowDragDoesNotAnimate) { ...@@ -2069,15 +2069,15 @@ TEST_F(ClientControlledShellSurfaceTest, PipWindowDragDoesNotAnimate) {
shell_surface->GetWidget()->Show(); shell_surface->GetWidget()->Show();
aura::Window* window = shell_surface->GetWidget()->GetNativeWindow(); aura::Window* window = shell_surface->GetWidget()->GetNativeWindow();
EXPECT_EQ(gfx::Rect(0, 0, 256, 256), window->layer()->GetTargetBounds()); EXPECT_EQ(gfx::Rect(8, 8, 256, 256), window->layer()->GetTargetBounds());
EXPECT_EQ(gfx::Rect(0, 0, 256, 256), window->layer()->bounds()); EXPECT_EQ(gfx::Rect(8, 8, 256, 256), window->layer()->bounds());
ui::ScopedAnimationDurationScaleMode animation_scale_mode( ui::ScopedAnimationDurationScaleMode animation_scale_mode(
ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION); ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
std::unique_ptr<ash::WindowResizer> resizer(ash::CreateWindowResizer( std::unique_ptr<ash::WindowResizer> resizer(ash::CreateWindowResizer(
window, gfx::PointF(), HTCAPTION, ::wm::WINDOW_MOVE_SOURCE_MOUSE)); window, gfx::PointF(), HTCAPTION, ::wm::WINDOW_MOVE_SOURCE_MOUSE));
resizer->Drag(gfx::PointF(10, 10), 0); resizer->Drag(gfx::PointF(10, 10), 0);
EXPECT_EQ(gfx::Rect(10, 10, 256, 256), window->layer()->GetTargetBounds()); EXPECT_EQ(gfx::Rect(18, 18, 256, 256), window->layer()->GetTargetBounds());
EXPECT_EQ(gfx::Rect(10, 10, 256, 256), window->layer()->bounds()); EXPECT_EQ(gfx::Rect(18, 18, 256, 256), window->layer()->bounds());
resizer->CompleteDrag(); resizer->CompleteDrag();
} }
...@@ -2101,15 +2101,15 @@ TEST_F(ClientControlledShellSurfaceTest, ...@@ -2101,15 +2101,15 @@ TEST_F(ClientControlledShellSurfaceTest,
surface->Commit(); surface->Commit();
aura::Window* window = shell_surface->GetWidget()->GetNativeWindow(); aura::Window* window = shell_surface->GetWidget()->GetNativeWindow();
EXPECT_EQ(gfx::Rect(0, 0, 256, 256), window->layer()->GetTargetBounds()); EXPECT_EQ(gfx::Rect(8, 8, 256, 256), window->layer()->GetTargetBounds());
EXPECT_EQ(gfx::Rect(0, 0, 256, 256), window->layer()->bounds()); EXPECT_EQ(gfx::Rect(8, 8, 256, 256), window->layer()->bounds());
ui::ScopedAnimationDurationScaleMode animation_scale_mode( ui::ScopedAnimationDurationScaleMode animation_scale_mode(
ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION); ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
std::unique_ptr<ash::WindowResizer> resizer(ash::CreateWindowResizer( std::unique_ptr<ash::WindowResizer> resizer(ash::CreateWindowResizer(
window, gfx::PointF(), HTCAPTION, ::wm::WINDOW_MOVE_SOURCE_MOUSE)); window, gfx::PointF(), HTCAPTION, ::wm::WINDOW_MOVE_SOURCE_MOUSE));
resizer->Drag(gfx::PointF(10, 10), 0); resizer->Drag(gfx::PointF(10, 10), 0);
EXPECT_EQ(gfx::Rect(10, 10, 256, 256), window->layer()->GetTargetBounds()); EXPECT_EQ(gfx::Rect(18, 18, 256, 256), window->layer()->GetTargetBounds());
EXPECT_EQ(gfx::Rect(10, 10, 256, 256), window->layer()->bounds()); EXPECT_EQ(gfx::Rect(18, 18, 256, 256), window->layer()->bounds());
EXPECT_FALSE(window->layer()->GetAnimator()->is_animating()); EXPECT_FALSE(window->layer()->GetAnimator()->is_animating());
resizer->CompleteDrag(); resizer->CompleteDrag();
} }
...@@ -2208,7 +2208,7 @@ TEST_F(ClientControlledShellSurfaceTest, DoNotReplayWindowStateRequest) { ...@@ -2208,7 +2208,7 @@ TEST_F(ClientControlledShellSurfaceTest, DoNotReplayWindowStateRequest) {
} }
TEST_F(ClientControlledShellSurfaceDisplayTest, TEST_F(ClientControlledShellSurfaceDisplayTest,
DoNotRequestBoundsChangeWithStateTransition) { RequestBoundsChangeOnceWithStateTransition) {
gfx::Size buffer_size(64, 64); gfx::Size buffer_size(64, 64);
auto buffer = std::make_unique<Buffer>( auto buffer = std::make_unique<Buffer>(
exo_test_helper()->CreateGpuMemoryBuffer(buffer_size)); exo_test_helper()->CreateGpuMemoryBuffer(buffer_size));
...@@ -2232,7 +2232,7 @@ TEST_F(ClientControlledShellSurfaceDisplayTest, ...@@ -2232,7 +2232,7 @@ TEST_F(ClientControlledShellSurfaceDisplayTest,
shell_surface->SetPip(); shell_surface->SetPip();
surface->Commit(); surface->Commit();
ASSERT_EQ(0, bounds_change_count()); ASSERT_EQ(1, bounds_change_count());
} }
TEST_F(ClientControlledShellSurfaceTest, TEST_F(ClientControlledShellSurfaceTest,
...@@ -2249,35 +2249,35 @@ TEST_F(ClientControlledShellSurfaceTest, ...@@ -2249,35 +2249,35 @@ TEST_F(ClientControlledShellSurfaceTest,
surface->Commit(); surface->Commit();
aura::Window* window = shell_surface->GetWidget()->GetNativeWindow(); aura::Window* window = shell_surface->GetWidget()->GetNativeWindow();
const gfx::Rect original_bounds(gfx::Point(10, 10), content_size); const gfx::Rect original_bounds(gfx::Point(8, 10), content_size);
shell_surface->SetGeometry(original_bounds); shell_surface->SetGeometry(original_bounds);
shell_surface->SetPip(); shell_surface->SetPip();
surface->Commit(); surface->Commit();
EXPECT_EQ(gfx::Rect(10, 10, 100, 100), window->bounds()); EXPECT_EQ(gfx::Rect(8, 10, 100, 100), window->bounds());
shell_surface->GetWidget()->Show(); shell_surface->GetWidget()->Show();
const gfx::Rect moved_bounds(gfx::Point(20, 20), content_size); const gfx::Rect moved_bounds(gfx::Point(8, 20), content_size);
shell_surface->SetGeometry(moved_bounds); shell_surface->SetGeometry(moved_bounds);
surface->Commit(); surface->Commit();
EXPECT_EQ(gfx::Rect(20, 20, 100, 100), window->bounds()); EXPECT_EQ(gfx::Rect(8, 20, 100, 100), window->bounds());
shell_surface->SetRestored(); shell_surface->SetRestored();
surface->Commit(); surface->Commit();
shell_surface->SetGeometry(original_bounds); shell_surface->SetGeometry(original_bounds);
shell_surface->SetPip(); shell_surface->SetPip();
surface->Commit(); surface->Commit();
EXPECT_EQ(gfx::Rect(10, 10, 100, 100), window->bounds()); EXPECT_EQ(gfx::Rect(8, 10, 100, 100), window->bounds());
shell_surface->SetGeometry(moved_bounds); shell_surface->SetGeometry(moved_bounds);
surface->Commit(); surface->Commit();
EXPECT_EQ(gfx::Rect(20, 20, 100, 100), window->bounds()); EXPECT_EQ(gfx::Rect(8, 20, 100, 100), window->bounds());
shell_surface->SetRestored(); shell_surface->SetRestored();
surface->Commit(); surface->Commit();
shell_surface->SetGeometry(moved_bounds); shell_surface->SetGeometry(moved_bounds);
shell_surface->SetPip(); shell_surface->SetPip();
surface->Commit(); surface->Commit();
EXPECT_EQ(gfx::Rect(20, 20, 100, 100), window->bounds()); EXPECT_EQ(gfx::Rect(8, 20, 100, 100), window->bounds());
} }
} // namespace exo } // namespace exo
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment