Commit d4af9eee authored by Mitsuru Oshima's avatar Mitsuru Oshima Committed by Commit Bot

Pause occlusion when the overview is closed by activation

I also added a unit test for occlusion tracker pause during
overview transition.

Bug: None
Test: covered by unittests.

Change-Id: I5e8441e176eaa0dc9793d22059edb22e357d899e
Reviewed-on: https://chromium-review.googlesource.com/c/1344888
Commit-Queue: Mitsuru Oshima <oshima@chromium.org>
Reviewed-by: default avatarSammie Quon <sammiequon@chromium.org>
Cr-Commit-Position: refs/heads/master@{#611323}
parent 04f0abb9
...@@ -252,7 +252,8 @@ class WindowSelectorController::OverviewBlurController ...@@ -252,7 +252,8 @@ class WindowSelectorController::OverviewBlurController
}; };
WindowSelectorController::WindowSelectorController() WindowSelectorController::WindowSelectorController()
: overview_blur_controller_(std::make_unique<OverviewBlurController>()), : occlusion_pause_duration_for_end_ms_(kOcclusionPauseDurationForEndMs),
overview_blur_controller_(std::make_unique<OverviewBlurController>()),
weak_ptr_factory_(this) { weak_ptr_factory_(this) {
Shell::Get()->activation_client()->AddObserver(this); Shell::Get()->activation_client()->AddObserver(this);
} }
...@@ -396,7 +397,7 @@ void WindowSelectorController::OnEndingAnimationComplete(bool canceled) { ...@@ -396,7 +397,7 @@ void WindowSelectorController::OnEndingAnimationComplete(bool canceled) {
&WindowSelectorController::ResetPauser, weak_ptr_factory_.GetWeakPtr())); &WindowSelectorController::ResetPauser, weak_ptr_factory_.GetWeakPtr()));
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
FROM_HERE, reset_pauser_task_.callback(), FROM_HERE, reset_pauser_task_.callback(),
base::TimeDelta::FromMilliseconds(kOcclusionPauseDurationForEndMs)); base::TimeDelta::FromMilliseconds(occlusion_pause_duration_for_end_ms_));
} }
void WindowSelectorController::ResetPauser() { void WindowSelectorController::ResetPauser() {
...@@ -540,6 +541,13 @@ void WindowSelectorController::OnSelectionEnded() { ...@@ -540,6 +541,13 @@ void WindowSelectorController::OnSelectionEnded() {
if (is_shutting_down_) if (is_shutting_down_)
return; return;
if (!occlusion_tracker_pauser_) {
reset_pauser_task_.Cancel();
occlusion_tracker_pauser_ =
std::make_unique<aura::WindowOcclusionTracker::ScopedPause>(
Shell::Get()->aura_env());
}
if (!start_animations_.empty()) if (!start_animations_.empty())
OnStartingAnimationComplete(/*canceled=*/true); OnStartingAnimationComplete(/*canceled=*/true);
start_animations_.clear(); start_animations_.clear();
......
...@@ -98,6 +98,10 @@ class ASH_EXPORT WindowSelectorController ...@@ -98,6 +98,10 @@ class ASH_EXPORT WindowSelectorController
WindowSelector* window_selector() { return window_selector_.get(); } WindowSelector* window_selector() { return window_selector_.get(); }
void set_occlusion_pause_duration_for_end_ms_for_test(int duration) {
occlusion_pause_duration_for_end_ms_ = duration;
}
private: private:
class OverviewBlurController; class OverviewBlurController;
friend class WindowSelectorTest; friend class WindowSelectorTest;
...@@ -133,6 +137,8 @@ class ASH_EXPORT WindowSelectorController ...@@ -133,6 +137,8 @@ class ASH_EXPORT WindowSelectorController
// If we are in middle of ending overview mode. // If we are in middle of ending overview mode.
bool is_shutting_down_ = false; bool is_shutting_down_ = false;
int occlusion_pause_duration_for_end_ms_;
// Handles blurring of the wallpaper when entering or exiting overview mode. // Handles blurring of the wallpaper when entering or exiting overview mode.
// Animates the blurring if necessary. // Animates the blurring if necessary.
std::unique_ptr<OverviewBlurController> overview_blur_controller_; std::unique_ptr<OverviewBlurController> overview_blur_controller_;
......
...@@ -69,6 +69,16 @@ class TestShellObserver : public ShellObserver { ...@@ -69,6 +69,16 @@ class TestShellObserver : public ShellObserver {
ending_animation_state_ = UNKNOWN; ending_animation_state_ = UNKNOWN;
} }
void WaitForStartingAnimationComplete() {
while (starting_animation_state_ != COMPLETED)
base::RunLoop().RunUntilIdle();
}
void WaitForEndingAnimationComplete() {
while (ending_animation_state_ != COMPLETED)
base::RunLoop().RunUntilIdle();
}
bool is_ended() const { return ending_animation_state_ != UNKNOWN; } bool is_ended() const { return ending_animation_state_ != UNKNOWN; }
bool is_started() const { return starting_animation_state_ != UNKNOWN; } bool is_started() const { return starting_animation_state_ != UNKNOWN; }
AnimationState starting_animation_state() const { AnimationState starting_animation_state() const {
...@@ -99,6 +109,12 @@ class TestShellObserver : public ShellObserver { ...@@ -99,6 +109,12 @@ class TestShellObserver : public ShellObserver {
DISALLOW_COPY_AND_ASSIGN(TestShellObserver); DISALLOW_COPY_AND_ASSIGN(TestShellObserver);
}; };
void WaitForOcclusionStateChange(aura::Window* window) {
auto current_state = window->occlusion_state();
while (window->occlusion_state() == current_state)
base::RunLoop().RunUntilIdle();
}
} // namespace } // namespace
using WindowSelectorControllerTest = AshTestBase; using WindowSelectorControllerTest = AshTestBase;
...@@ -133,8 +149,7 @@ TEST_F(WindowSelectorControllerTest, AnimationCallbacks) { ...@@ -133,8 +149,7 @@ TEST_F(WindowSelectorControllerTest, AnimationCallbacks) {
EXPECT_FALSE(Shell::Get()->window_selector_controller()->IsSelecting()); EXPECT_FALSE(Shell::Get()->window_selector_controller()->IsSelecting());
EXPECT_EQ(TestShellObserver::UNKNOWN, observer.ending_animation_state()); EXPECT_EQ(TestShellObserver::UNKNOWN, observer.ending_animation_state());
while (!observer.is_ended()) observer.WaitForEndingAnimationComplete();
base::RunLoop().RunUntilIdle();
EXPECT_EQ(TestShellObserver::COMPLETED, observer.ending_animation_state()); EXPECT_EQ(TestShellObserver::COMPLETED, observer.ending_animation_state());
gfx::Rect bounds(0, 0, 100, 100); gfx::Rect bounds(0, 0, 100, 100);
...@@ -152,7 +167,7 @@ TEST_F(WindowSelectorControllerTest, AnimationCallbacks) { ...@@ -152,7 +167,7 @@ TEST_F(WindowSelectorControllerTest, AnimationCallbacks) {
EXPECT_TRUE(Shell::Get()->window_selector_controller()->IsSelecting()); EXPECT_TRUE(Shell::Get()->window_selector_controller()->IsSelecting());
EXPECT_EQ(TestShellObserver::UNKNOWN, observer.starting_animation_state()); EXPECT_EQ(TestShellObserver::UNKNOWN, observer.starting_animation_state());
// Exit with windows. // Exit with windows before starting animation ends.
Shell::Get()->window_selector_controller()->ToggleOverview(); Shell::Get()->window_selector_controller()->ToggleOverview();
EXPECT_FALSE(Shell::Get()->window_selector_controller()->IsSelecting()); EXPECT_FALSE(Shell::Get()->window_selector_controller()->IsSelecting());
EXPECT_EQ(TestShellObserver::CANCELED, observer.starting_animation_state()); EXPECT_EQ(TestShellObserver::CANCELED, observer.starting_animation_state());
...@@ -160,7 +175,7 @@ TEST_F(WindowSelectorControllerTest, AnimationCallbacks) { ...@@ -160,7 +175,7 @@ TEST_F(WindowSelectorControllerTest, AnimationCallbacks) {
observer.Reset(); observer.Reset();
// Enter again. // Enter again before exit animation ends.
Shell::Get()->window_selector_controller()->ToggleOverview(); Shell::Get()->window_selector_controller()->ToggleOverview();
EXPECT_TRUE(Shell::Get()->window_selector_controller()->IsSelecting()); EXPECT_TRUE(Shell::Get()->window_selector_controller()->IsSelecting());
EXPECT_EQ(TestShellObserver::CANCELED, observer.ending_animation_state()); EXPECT_EQ(TestShellObserver::CANCELED, observer.ending_animation_state());
...@@ -224,6 +239,77 @@ TEST_F(WindowSelectorControllerTest, OverviewEnterExitAnimationTablet) { ...@@ -224,6 +239,77 @@ TEST_F(WindowSelectorControllerTest, OverviewEnterExitAnimationTablet) {
EXPECT_TRUE(observer.last_animation_was_slide()); EXPECT_TRUE(observer.last_animation_was_slide());
} }
TEST_F(WindowSelectorControllerTest, OcclusionTest) {
using OcclusionState = aura::Window::OcclusionState;
Shell::Get()
->window_selector_controller()
->set_occlusion_pause_duration_for_end_ms_for_test(50);
TestShellObserver observer(/*should_monitor_animation_state = */ true);
ui::ScopedAnimationDurationScaleMode non_zero(
ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
gfx::Rect bounds(0, 0, 100, 100);
std::unique_ptr<aura::Window> window1(
CreateTestWindowInShellWithBounds(bounds));
std::unique_ptr<aura::Window> window2(
CreateTestWindowInShellWithBounds(bounds));
window1->TrackOcclusionState();
window2->TrackOcclusionState();
EXPECT_EQ(OcclusionState::OCCLUDED, window1->occlusion_state());
EXPECT_EQ(OcclusionState::VISIBLE, window2->occlusion_state());
// Enter with windows.
Shell::Get()->window_selector_controller()->ToggleOverview();
EXPECT_EQ(OcclusionState::OCCLUDED, window1->occlusion_state());
EXPECT_EQ(OcclusionState::VISIBLE, window2->occlusion_state());
observer.WaitForStartingAnimationComplete();
// Occlusion tracking is paused.
EXPECT_EQ(OcclusionState::OCCLUDED, window1->occlusion_state());
EXPECT_EQ(OcclusionState::VISIBLE, window2->occlusion_state());
WaitForOcclusionStateChange(window1.get());
EXPECT_EQ(OcclusionState::VISIBLE, window1->occlusion_state());
// Exit with windows.
Shell::Get()->window_selector_controller()->ToggleOverview();
EXPECT_EQ(OcclusionState::VISIBLE, window1->occlusion_state());
EXPECT_EQ(OcclusionState::VISIBLE, window2->occlusion_state());
observer.WaitForEndingAnimationComplete();
EXPECT_EQ(OcclusionState::VISIBLE, window1->occlusion_state());
EXPECT_EQ(OcclusionState::VISIBLE, window2->occlusion_state());
WaitForOcclusionStateChange(window1.get());
EXPECT_EQ(OcclusionState::OCCLUDED, window1->occlusion_state());
observer.Reset();
// Enter again.
Shell::Get()->window_selector_controller()->ToggleOverview();
EXPECT_EQ(OcclusionState::OCCLUDED, window1->occlusion_state());
EXPECT_EQ(OcclusionState::VISIBLE, window2->occlusion_state());
auto* active = wm::GetActiveWindow();
EXPECT_EQ(window2.get(), active);
observer.WaitForStartingAnimationComplete();
// Window 1 is still occluded because tracker is paused.
EXPECT_EQ(OcclusionState::OCCLUDED, window1->occlusion_state());
EXPECT_EQ(OcclusionState::VISIBLE, window2->occlusion_state());
WaitForOcclusionStateChange(window1.get());
EXPECT_EQ(OcclusionState::VISIBLE, window1->occlusion_state());
wm::ActivateWindow(window1.get());
observer.WaitForEndingAnimationComplete();
// Windows are visible because tracker is paused.
EXPECT_FALSE(Shell::Get()->window_selector_controller()->IsSelecting());
EXPECT_EQ(OcclusionState::VISIBLE, window2->occlusion_state());
EXPECT_EQ(OcclusionState::VISIBLE, window1->occlusion_state());
WaitForOcclusionStateChange(window2.get());
EXPECT_EQ(OcclusionState::VISIBLE, window1->occlusion_state());
EXPECT_EQ(OcclusionState::OCCLUDED, window2->occlusion_state());
}
class OverviewVirtualKeyboardTest : public WindowSelectorControllerTest { class OverviewVirtualKeyboardTest : public WindowSelectorControllerTest {
protected: protected:
void SetUp() override { void SetUp() override {
......
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