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
};
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) {
Shell::Get()->activation_client()->AddObserver(this);
}
......@@ -396,7 +397,7 @@ void WindowSelectorController::OnEndingAnimationComplete(bool canceled) {
&WindowSelectorController::ResetPauser, weak_ptr_factory_.GetWeakPtr()));
base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
FROM_HERE, reset_pauser_task_.callback(),
base::TimeDelta::FromMilliseconds(kOcclusionPauseDurationForEndMs));
base::TimeDelta::FromMilliseconds(occlusion_pause_duration_for_end_ms_));
}
void WindowSelectorController::ResetPauser() {
......@@ -540,6 +541,13 @@ void WindowSelectorController::OnSelectionEnded() {
if (is_shutting_down_)
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())
OnStartingAnimationComplete(/*canceled=*/true);
start_animations_.clear();
......
......@@ -98,6 +98,10 @@ class ASH_EXPORT WindowSelectorController
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:
class OverviewBlurController;
friend class WindowSelectorTest;
......@@ -133,6 +137,8 @@ class ASH_EXPORT WindowSelectorController
// If we are in middle of ending overview mode.
bool is_shutting_down_ = false;
int occlusion_pause_duration_for_end_ms_;
// Handles blurring of the wallpaper when entering or exiting overview mode.
// Animates the blurring if necessary.
std::unique_ptr<OverviewBlurController> overview_blur_controller_;
......
......@@ -69,6 +69,16 @@ class TestShellObserver : public ShellObserver {
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_started() const { return starting_animation_state_ != UNKNOWN; }
AnimationState starting_animation_state() const {
......@@ -99,6 +109,12 @@ class TestShellObserver : public ShellObserver {
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
using WindowSelectorControllerTest = AshTestBase;
......@@ -133,8 +149,7 @@ TEST_F(WindowSelectorControllerTest, AnimationCallbacks) {
EXPECT_FALSE(Shell::Get()->window_selector_controller()->IsSelecting());
EXPECT_EQ(TestShellObserver::UNKNOWN, observer.ending_animation_state());
while (!observer.is_ended())
base::RunLoop().RunUntilIdle();
observer.WaitForEndingAnimationComplete();
EXPECT_EQ(TestShellObserver::COMPLETED, observer.ending_animation_state());
gfx::Rect bounds(0, 0, 100, 100);
......@@ -152,7 +167,7 @@ TEST_F(WindowSelectorControllerTest, AnimationCallbacks) {
EXPECT_TRUE(Shell::Get()->window_selector_controller()->IsSelecting());
EXPECT_EQ(TestShellObserver::UNKNOWN, observer.starting_animation_state());
// Exit with windows.
// Exit with windows before starting animation ends.
Shell::Get()->window_selector_controller()->ToggleOverview();
EXPECT_FALSE(Shell::Get()->window_selector_controller()->IsSelecting());
EXPECT_EQ(TestShellObserver::CANCELED, observer.starting_animation_state());
......@@ -160,7 +175,7 @@ TEST_F(WindowSelectorControllerTest, AnimationCallbacks) {
observer.Reset();
// Enter again.
// Enter again before exit animation ends.
Shell::Get()->window_selector_controller()->ToggleOverview();
EXPECT_TRUE(Shell::Get()->window_selector_controller()->IsSelecting());
EXPECT_EQ(TestShellObserver::CANCELED, observer.ending_animation_state());
......@@ -224,6 +239,77 @@ TEST_F(WindowSelectorControllerTest, OverviewEnterExitAnimationTablet) {
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 {
protected:
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