| // Copyright 2019 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "ash/home_screen/swipe_home_to_overview_controller.h" |
| |
| #include "ash/app_list/test/app_list_test_helper.h" |
| #include "ash/app_list/views/app_list_view.h" |
| #include "ash/app_list/views/search_box_view.h" |
| #include "ash/home_screen/home_screen_controller.h" |
| #include "ash/home_screen/home_screen_delegate.h" |
| #include "ash/public/cpp/ash_features.h" |
| #include "ash/root_window_controller.h" |
| #include "ash/shelf/shelf.h" |
| #include "ash/shelf/shelf_metrics.h" |
| #include "ash/shelf/shelf_test_util.h" |
| #include "ash/shell.h" |
| #include "ash/test/ash_test_base.h" |
| #include "ash/wm/overview/overview_controller.h" |
| #include "ash/wm/tablet_mode/tablet_mode_controller_test_api.h" |
| #include "base/macros.h" |
| #include "base/optional.h" |
| #include "base/run_loop.h" |
| #include "base/test/metrics/histogram_tester.h" |
| #include "base/test/simple_test_tick_clock.h" |
| #include "ui/compositor/scoped_animation_duration_scale_mode.h" |
| #include "ui/compositor/test/test_utils.h" |
| #include "ui/gfx/geometry/point_f.h" |
| #include "ui/gfx/geometry/rect_f.h" |
| |
| namespace ash { |
| |
| namespace { |
| |
| gfx::Rect GetShelfBounds() { |
| return Shelf::ForWindow(Shell::GetPrimaryRootWindow())->GetIdealBounds(); |
| } |
| |
| gfx::RectF GetShelfBoundsInFloat() { |
| return gfx::RectF(GetShelfBounds()); |
| } |
| |
| } // namespace |
| |
| class SwipeHomeToOverviewControllerTest : public AshTestBase { |
| public: |
| SwipeHomeToOverviewControllerTest() {} |
| ~SwipeHomeToOverviewControllerTest() override = default; |
| |
| // AshTestBase: |
| void SetUp() override { |
| AshTestBase::SetUp(); |
| UpdateDisplay("1000x756"); |
| |
| TabletModeControllerTestApi().EnterTabletMode(); |
| base::RunLoop().RunUntilIdle(); |
| |
| // Advance tick clock by arbitrary non-zero amount. |
| tick_clock_.Advance(base::TimeDelta::FromSeconds(1000)); |
| } |
| void TearDown() override { |
| home_to_overview_controller_.reset(); |
| AshTestBase::TearDown(); |
| } |
| |
| void StartDrag() { |
| home_to_overview_controller_ = |
| std::make_unique<SwipeHomeToOverviewController>( |
| GetPrimaryDisplay().id(), &tick_clock_); |
| } |
| |
| void Drag(const gfx::PointF& location_in_screen, |
| float scroll_x, |
| float scroll_y) { |
| home_to_overview_controller_->Drag(location_in_screen, scroll_x, scroll_y); |
| } |
| |
| void EndDrag(const gfx::PointF& location_in_screen, |
| base::Optional<float> velocity_y) { |
| home_to_overview_controller_->EndDrag(location_in_screen, velocity_y); |
| } |
| |
| void CancelDrag() { home_to_overview_controller_->CancelDrag(); } |
| |
| HomeScreenDelegate* home_screen_delegate() { |
| return Shell::Get()->home_screen_controller()->delegate(); |
| } |
| |
| bool OverviewTransitionTimerRunning() const { |
| return home_to_overview_controller_->overview_transition_timer_for_testing() |
| ->IsRunning(); |
| } |
| |
| void FireOverviewTransitionTimer() { |
| return home_to_overview_controller_->overview_transition_timer_for_testing() |
| ->FireNow(); |
| } |
| |
| void WaitForHomeLauncherAnimationToFinish() { |
| auto* compositor = |
| Shell::GetPrimaryRootWindowController()->GetHost()->compositor(); |
| // Wait until home launcher animation finishes. |
| while (GetAppListTestHelper() |
| ->GetAppListView() |
| ->GetWidget() |
| ->GetLayer() |
| ->GetAnimator() |
| ->is_animating()) { |
| EXPECT_TRUE(ui::WaitForNextFrameToBePresented(compositor)); |
| } |
| |
| // Ensure there is one more frame presented after animation finishes |
| // to allow animation throughput data is passed from cc to ui. |
| ignore_result(ui::WaitForNextFrameToBePresented( |
| compositor, base::TimeDelta::FromMilliseconds(200))); |
| } |
| |
| void TapOnHomeLauncherSearchBox() { |
| GetEventGenerator()->GestureTapAt(GetAppListTestHelper() |
| ->GetAppListView() |
| ->search_box_view() |
| ->GetBoundsInScreen() |
| .CenterPoint()); |
| } |
| |
| base::TimeTicks GetTimerDesiredRunTime() const { |
| return home_to_overview_controller_->overview_transition_timer_for_testing() |
| ->desired_run_time(); |
| } |
| |
| bool OverviewStarted() const { |
| return Shell::Get()->overview_controller()->InOverviewSession(); |
| } |
| |
| protected: |
| base::SimpleTestTickClock tick_clock_; |
| |
| private: |
| std::unique_ptr<SwipeHomeToOverviewController> home_to_overview_controller_; |
| |
| DISALLOW_COPY_AND_ASSIGN(SwipeHomeToOverviewControllerTest); |
| }; |
| |
| // Verify that the metrics of home launcher animation are recorded correctly |
| // when entering/exiting overview mode. |
| // The test is flaky (see https://crbug.com/1126904). |
| TEST_F(SwipeHomeToOverviewControllerTest, DISABLED_VerifyHomeLauncherMetrics) { |
| // Set non-zero animation duration to report animation metrics. |
| ui::ScopedAnimationDurationScaleMode non_zero_duration_mode( |
| ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION); |
| |
| const gfx::Rect shelf_bounds = GetShelfBounds(); |
| const int transition_threshold = |
| SwipeHomeToOverviewController::kVerticalThresholdForOverviewTransition; |
| |
| base::HistogramTester histogram_tester; |
| |
| // Enter overview mode by gesture swipe on shelf. |
| { |
| GetEventGenerator()->set_current_screen_location( |
| shelf_bounds.CenterPoint()); |
| GetEventGenerator()->PressTouch(); |
| GetEventGenerator()->MoveTouchBy( |
| 0, -transition_threshold - shelf_bounds.height() / 2 - 10); |
| |
| // Move touch location by a tiny distance to ensure the slow scroll speed |
| // which is required to trigger the overview animation. |
| GetEventGenerator()->MoveTouchBy(0, -1); |
| |
| // Wait until overview animation finishes. |
| WaitForOverviewAnimation(/*enter=*/true); |
| |
| GetEventGenerator()->ReleaseTouch(); |
| WaitForHomeLauncherAnimationToFinish(); |
| } |
| |
| // Verify that the animation to hide the home launcher is recorded. |
| histogram_tester.ExpectTotalCount( |
| "Apps.HomeLauncherTransition.AnimationSmoothness.FadeInOverview", 1); |
| histogram_tester.ExpectTotalCount( |
| "Apps.HomeLauncherTransition.AnimationSmoothness.FadeOutOverview", 0); |
| |
| // Exit overview mode by gesture tap. |
| GetEventGenerator()->GestureTapAt( |
| GetContext()->GetBoundsInScreen().top_center()); |
| |
| // Wait until overview animation finishes. |
| WaitForOverviewAnimation(/*enter=*/false); |
| WaitForHomeLauncherAnimationToFinish(); |
| |
| // Verify that the animation to show the home launcher is recorded. |
| histogram_tester.ExpectTotalCount( |
| "Apps.HomeLauncherTransition.AnimationSmoothness.FadeInOverview", 1); |
| histogram_tester.ExpectTotalCount( |
| "Apps.HomeLauncherTransition.AnimationSmoothness.FadeOutOverview", 1); |
| } |
| |
| TEST_F(SwipeHomeToOverviewControllerTest, BasicFlow) { |
| const gfx::RectF shelf_bounds = GetShelfBoundsInFloat(); |
| |
| base::HistogramTester histogram_tester; |
| histogram_tester.ExpectBucketCount( |
| kEnterOverviewHistogramName, EnterOverviewFromHomeLauncher::kOverview, 0); |
| |
| StartDrag(); |
| // Drag to a point within shelf bounds - verify that app list has not been |
| // scaled, and the transition to overview transition timer has not started. |
| Drag(shelf_bounds.CenterPoint(), 0.f, 1.f); |
| |
| aura::Window* home_screen_window = |
| home_screen_delegate()->GetHomeScreenWindow(); |
| ASSERT_TRUE(home_screen_window); |
| |
| EXPECT_EQ(gfx::Transform(), |
| home_screen_window->layer()->GetTargetTransform()); |
| EXPECT_FALSE(OverviewTransitionTimerRunning()); |
| EXPECT_FALSE(OverviewStarted()); |
| histogram_tester.ExpectBucketCount( |
| kEnterOverviewHistogramName, EnterOverviewFromHomeLauncher::kOverview, 0); |
| |
| const int transition_threshold = |
| SwipeHomeToOverviewController::kVerticalThresholdForOverviewTransition; |
| |
| // Move above the shelf but not far enough to trigger transition to overview. |
| // The home window is expected to be scaled at this point, but the overview |
| // transition timer to should not yet be running. |
| Drag(shelf_bounds.top_center() - gfx::Vector2d(0, transition_threshold / 2), |
| 0.f, 1.f); |
| |
| EXPECT_EQ(home_screen_window->transform(), |
| home_screen_window->layer()->GetTargetTransform()); |
| EXPECT_TRUE(home_screen_window->transform().IsScaleOrTranslation()); |
| EXPECT_FALSE(home_screen_window->transform().IsIdentityOrTranslation()); |
| EXPECT_EQ(1.f, home_screen_window->layer()->opacity()); |
| histogram_tester.ExpectBucketCount( |
| kEnterOverviewHistogramName, EnterOverviewFromHomeLauncher::kOverview, 0); |
| |
| // Move above the transition threshold - verify the overview transition timer |
| // has started. |
| Drag(shelf_bounds.top_center() - gfx::Vector2d(0, transition_threshold + 10), |
| 0.f, 1.f); |
| |
| EXPECT_EQ(home_screen_window->transform(), |
| home_screen_window->layer()->GetTargetTransform()); |
| EXPECT_TRUE(home_screen_window->transform().IsScaleOrTranslation()); |
| EXPECT_FALSE(home_screen_window->transform().IsIdentityOrTranslation()); |
| |
| EXPECT_TRUE(OverviewTransitionTimerRunning()); |
| EXPECT_FALSE(OverviewStarted()); |
| histogram_tester.ExpectBucketCount( |
| kEnterOverviewHistogramName, EnterOverviewFromHomeLauncher::kOverview, 0); |
| |
| // Fire overview transition timer, and verify the overview has started. |
| FireOverviewTransitionTimer(); |
| |
| EXPECT_TRUE(OverviewStarted()); |
| histogram_tester.ExpectBucketCount( |
| kEnterOverviewHistogramName, EnterOverviewFromHomeLauncher::kOverview, 1); |
| |
| // Home screen is still scaled down, and not visible. |
| EXPECT_EQ(home_screen_window->transform(), |
| home_screen_window->layer()->GetTargetTransform()); |
| EXPECT_TRUE(home_screen_window->transform().IsScaleOrTranslation()); |
| EXPECT_FALSE(home_screen_window->transform().IsIdentityOrTranslation()); |
| EXPECT_EQ(0.f, home_screen_window->layer()->opacity()); |
| |
| // The user ending drag after this point should be no-op. |
| EndDrag( |
| shelf_bounds.top_center() - gfx::Vector2d(0, transition_threshold + 10), |
| 1.f); |
| |
| EXPECT_TRUE(OverviewStarted()); |
| histogram_tester.ExpectBucketCount( |
| kEnterOverviewHistogramName, EnterOverviewFromHomeLauncher::kOverview, 1); |
| |
| // Home screen is still scaled down, and not visible. |
| EXPECT_EQ(home_screen_window->transform(), |
| home_screen_window->layer()->GetTargetTransform()); |
| EXPECT_TRUE(home_screen_window->transform().IsScaleOrTranslation()); |
| EXPECT_FALSE(home_screen_window->transform().IsIdentityOrTranslation()); |
| EXPECT_EQ(0.f, home_screen_window->layer()->opacity()); |
| } |
| |
| TEST_F(SwipeHomeToOverviewControllerTest, EndDragBeforeTimeout) { |
| const gfx::RectF shelf_bounds = GetShelfBoundsInFloat(); |
| |
| StartDrag(); |
| |
| aura::Window* home_screen_window = |
| home_screen_delegate()->GetHomeScreenWindow(); |
| ASSERT_TRUE(home_screen_window); |
| |
| const int transition_threshold = |
| SwipeHomeToOverviewController::kVerticalThresholdForOverviewTransition; |
| |
| // Move above the transition threshold - verify the overview transition timer |
| // has started. |
| Drag(shelf_bounds.top_center() - gfx::Vector2d(0, transition_threshold / 2), |
| 0.f, 1.f); |
| Drag(shelf_bounds.top_center() - gfx::Vector2d(0, transition_threshold + 10), |
| 0.f, 1.f); |
| |
| EXPECT_EQ(home_screen_window->transform(), |
| home_screen_window->layer()->GetTargetTransform()); |
| EXPECT_TRUE(home_screen_window->transform().IsScaleOrTranslation()); |
| EXPECT_FALSE(home_screen_window->transform().IsIdentityOrTranslation()); |
| |
| EXPECT_TRUE(OverviewTransitionTimerRunning()); |
| EXPECT_FALSE(OverviewStarted()); |
| |
| // The user ending drag should reset the home view state. |
| EndDrag( |
| shelf_bounds.top_center() - gfx::Vector2d(0, transition_threshold + 10), |
| 1.f); |
| |
| EXPECT_EQ(home_screen_window->transform(), |
| home_screen_window->layer()->GetTargetTransform()); |
| EXPECT_EQ(gfx::Transform(), home_screen_window->transform()); |
| EXPECT_EQ(1.f, home_screen_window->layer()->opacity()); |
| |
| EXPECT_FALSE(OverviewTransitionTimerRunning()); |
| EXPECT_FALSE(OverviewStarted()); |
| } |
| |
| TEST_F(SwipeHomeToOverviewControllerTest, GoBackOnHomeLauncher) { |
| // Show home screen search results page. |
| GetAppListTestHelper()->CheckVisibility(true); |
| TapOnHomeLauncherSearchBox(); |
| GetAppListTestHelper()->CheckState(AppListViewState::kFullscreenSearch); |
| |
| const gfx::RectF shelf_bounds = GetShelfBoundsInFloat(); |
| |
| StartDrag(); |
| |
| aura::Window* home_screen_window = |
| home_screen_delegate()->GetHomeScreenWindow(); |
| ASSERT_TRUE(home_screen_window); |
| |
| const int transition_threshold = |
| SwipeHomeToOverviewController::kVerticalThresholdForOverviewTransition; |
| |
| // Move above the transition threshold - verify the overview transition timer |
| // has started. |
| Drag(shelf_bounds.top_center() - gfx::Vector2d(0, transition_threshold / 2), |
| 0.f, 1.f); |
| Drag(shelf_bounds.top_center() - gfx::Vector2d(0, transition_threshold + 10), |
| 0.f, 1.f); |
| |
| EXPECT_EQ(home_screen_window->transform(), |
| home_screen_window->layer()->GetTargetTransform()); |
| EXPECT_TRUE(home_screen_window->transform().IsScaleOrTranslation()); |
| EXPECT_FALSE(home_screen_window->transform().IsIdentityOrTranslation()); |
| |
| EXPECT_TRUE(OverviewTransitionTimerRunning()); |
| EXPECT_FALSE(OverviewStarted()); |
| |
| // The user ending drag with a fling should move home to the initial state - |
| // fullscreen all apps. |
| EndDrag( |
| shelf_bounds.top_center() - gfx::Vector2d(0, transition_threshold + 10), |
| -1500.f); |
| |
| EXPECT_EQ(home_screen_window->transform(), |
| home_screen_window->layer()->GetTargetTransform()); |
| EXPECT_EQ(gfx::Transform(), home_screen_window->transform()); |
| EXPECT_EQ(1.f, home_screen_window->layer()->opacity()); |
| |
| EXPECT_FALSE(OverviewTransitionTimerRunning()); |
| EXPECT_FALSE(OverviewStarted()); |
| GetAppListTestHelper()->CheckState(AppListViewState::kFullscreenAllApps); |
| } |
| |
| TEST_F(SwipeHomeToOverviewControllerTest, FlingOnAppsPage) { |
| // Show home screen search results page. |
| GetAppListTestHelper()->CheckVisibility(true); |
| GetAppListTestHelper()->CheckState(AppListViewState::kFullscreenAllApps); |
| |
| const gfx::RectF shelf_bounds = GetShelfBoundsInFloat(); |
| |
| StartDrag(); |
| |
| aura::Window* home_screen_window = |
| home_screen_delegate()->GetHomeScreenWindow(); |
| ASSERT_TRUE(home_screen_window); |
| |
| const int transition_threshold = |
| SwipeHomeToOverviewController::kVerticalThresholdForOverviewTransition; |
| |
| // Move above the transition threshold - verify the overview transition timer |
| // has started. |
| Drag(shelf_bounds.top_center() - gfx::Vector2d(0, transition_threshold / 2), |
| 0.f, 1.f); |
| Drag(shelf_bounds.top_center() - gfx::Vector2d(0, transition_threshold + 10), |
| 0.f, 1.f); |
| |
| EXPECT_EQ(home_screen_window->transform(), |
| home_screen_window->layer()->GetTargetTransform()); |
| EXPECT_TRUE(home_screen_window->transform().IsScaleOrTranslation()); |
| EXPECT_FALSE(home_screen_window->transform().IsIdentityOrTranslation()); |
| |
| EXPECT_TRUE(OverviewTransitionTimerRunning()); |
| EXPECT_FALSE(OverviewStarted()); |
| |
| // The user ending drag with a fling should move home to the initial state - |
| // fullscreen all apps. |
| EndDrag( |
| shelf_bounds.top_center() - gfx::Vector2d(0, transition_threshold + 10), |
| -1500.f); |
| |
| EXPECT_EQ(home_screen_window->transform(), |
| home_screen_window->layer()->GetTargetTransform()); |
| EXPECT_EQ(gfx::Transform(), home_screen_window->transform()); |
| EXPECT_EQ(1.f, home_screen_window->layer()->opacity()); |
| |
| EXPECT_FALSE(OverviewTransitionTimerRunning()); |
| EXPECT_FALSE(OverviewStarted()); |
| |
| GetAppListTestHelper()->CheckState(AppListViewState::kFullscreenAllApps); |
| } |
| |
| TEST_F(SwipeHomeToOverviewControllerTest, CancelDragBeforeTimeout) { |
| // Show home screen search results page. |
| GetAppListTestHelper()->CheckVisibility(true); |
| TapOnHomeLauncherSearchBox(); |
| GetAppListTestHelper()->CheckState(AppListViewState::kFullscreenSearch); |
| |
| const gfx::RectF shelf_bounds = GetShelfBoundsInFloat(); |
| |
| StartDrag(); |
| |
| aura::Window* home_screen_window = |
| home_screen_delegate()->GetHomeScreenWindow(); |
| ASSERT_TRUE(home_screen_window); |
| |
| const int transition_threshold = |
| SwipeHomeToOverviewController::kVerticalThresholdForOverviewTransition; |
| |
| // Move above the transition threshold - verify the overview transition timer |
| // has started. |
| Drag(shelf_bounds.top_center() - gfx::Vector2d(0, transition_threshold / 2), |
| 0.f, 1.f); |
| Drag(shelf_bounds.top_center() - gfx::Vector2d(0, transition_threshold + 10), |
| 0.f, 1.f); |
| |
| EXPECT_EQ(home_screen_window->transform(), |
| home_screen_window->layer()->GetTargetTransform()); |
| EXPECT_TRUE(home_screen_window->transform().IsScaleOrTranslation()); |
| EXPECT_FALSE(home_screen_window->transform().IsIdentityOrTranslation()); |
| |
| EXPECT_TRUE(OverviewTransitionTimerRunning()); |
| EXPECT_FALSE(OverviewStarted()); |
| |
| // Drag gesture getting canceled should reset the home view state. |
| CancelDrag(); |
| |
| EXPECT_EQ(home_screen_window->transform(), |
| home_screen_window->layer()->GetTargetTransform()); |
| EXPECT_EQ(gfx::Transform(), home_screen_window->transform()); |
| EXPECT_EQ(1.f, home_screen_window->layer()->opacity()); |
| |
| EXPECT_FALSE(OverviewTransitionTimerRunning()); |
| EXPECT_FALSE(OverviewStarted()); |
| |
| // The gesture was not a fling - the home screen should have stayed in the |
| // fullscreen search state. |
| GetAppListTestHelper()->CheckState(AppListViewState::kFullscreenSearch); |
| } |
| |
| TEST_F(SwipeHomeToOverviewControllerTest, DragMovementRestartsTimeout) { |
| const gfx::RectF shelf_bounds = GetShelfBoundsInFloat(); |
| |
| StartDrag(); |
| |
| const int transition_threshold = |
| SwipeHomeToOverviewController::kVerticalThresholdForOverviewTransition; |
| |
| // Move above the transition threshold - verify the overview transition timer |
| // has started. |
| Drag(shelf_bounds.top_center() - gfx::Vector2d(0, transition_threshold / 2), |
| 0.f, 1.f); |
| Drag(shelf_bounds.top_center() - gfx::Vector2d(0, transition_threshold), 0.f, |
| 1.f); |
| |
| EXPECT_TRUE(OverviewTransitionTimerRunning()); |
| EXPECT_FALSE(OverviewStarted()); |
| |
| const base::TimeDelta delay = |
| GetTimerDesiredRunTime() - tick_clock_.NowTicks(); |
| EXPECT_GT(delay, base::TimeDelta()); |
| |
| const float max_allowed_velocity = |
| SwipeHomeToOverviewController::kMovementVelocityThreshold; |
| // Advance clock, and simulate another drag whose speed is above the max |
| // allowed. |
| tick_clock_.Advance(base::TimeDelta::FromMilliseconds(1)); |
| Drag(shelf_bounds.top_center() - gfx::Vector2d(0, 2 * transition_threshold), |
| 0.f, max_allowed_velocity + 10); |
| |
| // Verify the timer was stopped. |
| EXPECT_FALSE(OverviewTransitionTimerRunning()); |
| EXPECT_FALSE(OverviewStarted()); |
| |
| tick_clock_.Advance(base::TimeDelta::FromMilliseconds(1)); |
| |
| // Another slow drag should restart the timer. |
| Drag(shelf_bounds.top_center() - gfx::Vector2d(0, 2 * transition_threshold), |
| 0.f, max_allowed_velocity / 2); |
| |
| EXPECT_TRUE(OverviewTransitionTimerRunning()); |
| EXPECT_FALSE(OverviewStarted()); |
| |
| EXPECT_EQ(delay, GetTimerDesiredRunTime() - tick_clock_.NowTicks()); |
| } |
| |
| TEST_F(SwipeHomeToOverviewControllerTest, |
| SmallDragMovementDoesNotRestartTimeout) { |
| const gfx::RectF shelf_bounds = GetShelfBoundsInFloat(); |
| |
| StartDrag(); |
| |
| const int transition_threshold = |
| SwipeHomeToOverviewController::kVerticalThresholdForOverviewTransition; |
| |
| // Move just below the transition threshold - verify overview transition timer |
| // has not started. |
| Drag(shelf_bounds.top_center() - gfx::Vector2d(0, transition_threshold - 1), |
| 0.f, 1.f); |
| |
| EXPECT_FALSE(OverviewTransitionTimerRunning()); |
| EXPECT_FALSE(OverviewStarted()); |
| |
| // Move a little to reach the transition threshold - the timer should start at |
| // this point. |
| Drag(shelf_bounds.top_center() - gfx::Vector2d(0, transition_threshold), 0.f, |
| 1.f); |
| |
| EXPECT_TRUE(OverviewTransitionTimerRunning()); |
| EXPECT_FALSE(OverviewStarted()); |
| |
| const base::TimeDelta delay = |
| GetTimerDesiredRunTime() - tick_clock_.NowTicks(); |
| EXPECT_GT(delay, base::TimeDelta()); |
| |
| const float movement_threshold = |
| SwipeHomeToOverviewController::kMovementVelocityThreshold; |
| |
| // Advance clock, and simulate another drag, for an amount below the movement |
| // threshold. |
| tick_clock_.Advance(base::TimeDelta::FromMilliseconds(1)); |
| Drag(shelf_bounds.top_center() - |
| gfx::Vector2d(0, transition_threshold + movement_threshold - 1), |
| 0.f, movement_threshold / 2); |
| |
| // Verify the expected timer run time was not updated. |
| EXPECT_TRUE(OverviewTransitionTimerRunning()); |
| EXPECT_FALSE(OverviewStarted()); |
| |
| EXPECT_EQ(delay - base::TimeDelta::FromMilliseconds(1), |
| GetTimerDesiredRunTime() - tick_clock_.NowTicks()); |
| |
| // Movement with velocity above the allowed threshold restarts the timer. |
| Drag(shelf_bounds.top_center() - |
| gfx::Vector2d(0, transition_threshold + movement_threshold - 1), |
| 0.f, movement_threshold + 1); |
| |
| EXPECT_FALSE(OverviewTransitionTimerRunning()); |
| EXPECT_FALSE(OverviewStarted()); |
| } |
| |
| TEST_F(SwipeHomeToOverviewControllerTest, DragBellowThresholdStopsTimer) { |
| const gfx::RectF shelf_bounds = GetShelfBoundsInFloat(); |
| |
| StartDrag(); |
| Drag(shelf_bounds.CenterPoint(), 0.f, 1.f); |
| |
| const int transition_threshold = |
| SwipeHomeToOverviewController::kVerticalThresholdForOverviewTransition; |
| |
| // Move above the transition threshold - verify the overview transition timer |
| // has started. |
| Drag(shelf_bounds.top_center() - gfx::Vector2d(0, transition_threshold / 2), |
| 0.f, 1.f); |
| Drag(shelf_bounds.top_center() - gfx::Vector2d(0, transition_threshold + 10), |
| 0.f, 1.f); |
| |
| aura::Window* home_screen_window = |
| home_screen_delegate()->GetHomeScreenWindow(); |
| ASSERT_TRUE(home_screen_window); |
| |
| EXPECT_EQ(home_screen_window->transform(), |
| home_screen_window->layer()->GetTargetTransform()); |
| EXPECT_TRUE(home_screen_window->transform().IsScaleOrTranslation()); |
| EXPECT_FALSE(home_screen_window->transform().IsIdentityOrTranslation()); |
| |
| EXPECT_TRUE(OverviewTransitionTimerRunning()); |
| EXPECT_FALSE(OverviewStarted()); |
| |
| // Move bellow threshold, verify the timer has stopped. |
| Drag(shelf_bounds.top_center() - gfx::Vector2d(0, transition_threshold - 10), |
| 0.f, 1.f); |
| |
| EXPECT_EQ(home_screen_window->transform(), |
| home_screen_window->layer()->GetTargetTransform()); |
| EXPECT_TRUE(home_screen_window->transform().IsScaleOrTranslation()); |
| EXPECT_FALSE(home_screen_window->transform().IsIdentityOrTranslation()); |
| |
| EXPECT_FALSE(OverviewTransitionTimerRunning()); |
| EXPECT_FALSE(OverviewStarted()); |
| |
| // Move further down, under the shelf. |
| Drag(shelf_bounds.CenterPoint(), 0.f, 1.f); |
| |
| EXPECT_EQ(home_screen_window->transform(), |
| home_screen_window->layer()->GetTargetTransform()); |
| EXPECT_EQ(gfx::Transform(), home_screen_window->transform()); |
| EXPECT_FALSE(OverviewTransitionTimerRunning()); |
| EXPECT_FALSE(OverviewStarted()); |
| |
| // Move above the transition threshold again, the timer should be restarted.. |
| Drag(shelf_bounds.top_center() - gfx::Vector2d(0, transition_threshold + 10), |
| 0.f, 1.f); |
| |
| EXPECT_EQ(home_screen_window->transform(), |
| home_screen_window->layer()->GetTargetTransform()); |
| EXPECT_TRUE(home_screen_window->transform().IsScaleOrTranslation()); |
| EXPECT_FALSE(home_screen_window->transform().IsIdentityOrTranslation()); |
| |
| EXPECT_TRUE(OverviewTransitionTimerRunning()); |
| EXPECT_FALSE(OverviewStarted()); |
| |
| // Fire overview transition timer, and verify the overview has started. |
| FireOverviewTransitionTimer(); |
| |
| EXPECT_FALSE(OverviewTransitionTimerRunning()); |
| EXPECT_TRUE(OverviewStarted()); |
| |
| // Home screen is still scaled down, and not visible. |
| EXPECT_EQ(home_screen_window->transform(), |
| home_screen_window->layer()->GetTargetTransform()); |
| EXPECT_TRUE(home_screen_window->transform().IsScaleOrTranslation()); |
| EXPECT_FALSE(home_screen_window->transform().IsIdentityOrTranslation()); |
| EXPECT_EQ(0.f, home_screen_window->layer()->opacity()); |
| } |
| |
| TEST_F(SwipeHomeToOverviewControllerTest, ScaleChangesDuringDrag) { |
| const gfx::RectF shelf_bounds = GetShelfBoundsInFloat(); |
| |
| StartDrag(); |
| Drag(shelf_bounds.CenterPoint(), 0.f, 1.f); |
| |
| aura::Window* home_screen_window = |
| home_screen_delegate()->GetHomeScreenWindow(); |
| ASSERT_TRUE(home_screen_window); |
| const gfx::RectF original_home_bounds(home_screen_window->bounds()); |
| |
| const int transition_threshold = |
| SwipeHomeToOverviewController::kVerticalThresholdForOverviewTransition; |
| // Moving up should shrink home bounds. |
| Drag(shelf_bounds.top_center() - gfx::Vector2d(0, transition_threshold - 50), |
| 0.f, 1.f); |
| |
| gfx::RectF last_home_bounds = original_home_bounds; |
| home_screen_window->transform().TransformRect(&last_home_bounds); |
| EXPECT_GT(original_home_bounds.width(), last_home_bounds.width()); |
| |
| // Moving up should shrink home bounds further. |
| Drag(shelf_bounds.top_center() - gfx::Vector2d(0, transition_threshold + 10), |
| 0.f, 1.f); |
| |
| gfx::RectF current_home_bounds = original_home_bounds; |
| home_screen_window->transform().TransformRect(¤t_home_bounds); |
| EXPECT_GT(last_home_bounds.width(), current_home_bounds.width()); |
| last_home_bounds = current_home_bounds; |
| |
| // Moving down should expand bounds. |
| Drag(shelf_bounds.top_center() - gfx::Vector2d(0, transition_threshold - 40), |
| 0.f, 1.f); |
| |
| current_home_bounds = original_home_bounds; |
| home_screen_window->transform().TransformRect(¤t_home_bounds); |
| EXPECT_LT(last_home_bounds.width(), current_home_bounds.width()); |
| last_home_bounds = current_home_bounds; |
| |
| // Horizontal movement should not change bounds. |
| Drag(shelf_bounds.top_center() - gfx::Vector2d(50, transition_threshold - 40), |
| 1.f, 0.f); |
| current_home_bounds = original_home_bounds; |
| home_screen_window->transform().TransformRect(¤t_home_bounds); |
| EXPECT_EQ(last_home_bounds, current_home_bounds); |
| |
| // At shelf top the home window should have no transform. |
| Drag(shelf_bounds.top_center(), 0.f, 1.f); |
| EXPECT_EQ(gfx::Transform(), home_screen_window->transform()); |
| } |
| |
| } // namespace ash |