Skip to content

Commit

Permalink
Pause occlusion when the overview is closed by activation
Browse files Browse the repository at this point in the history
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 <[email protected]>
Reviewed-by: Sammie Quon <[email protected]>
Cr-Commit-Position: refs/heads/master@{#611323}
  • Loading branch information
mitoshima authored and Commit Bot committed Nov 27, 2018
1 parent 04f0abb commit d4af9ee
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 6 deletions.
12 changes: 10 additions & 2 deletions ash/wm/overview/window_selector_controller.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down Expand Up @@ -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() {
Expand Down Expand Up @@ -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();
Expand Down
6 changes: 6 additions & 0 deletions ash/wm/overview/window_selector_controller.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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_;
Expand Down
94 changes: 90 additions & 4 deletions ash/wm/overview/window_selector_controller_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand All @@ -152,15 +167,15 @@ 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());
EXPECT_EQ(TestShellObserver::UNKNOWN, observer.ending_animation_state());

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());
Expand Down Expand Up @@ -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 {
Expand Down

0 comments on commit d4af9ee

Please sign in to comment.