blob: 070282d012118a5731d4310cb1bbfcf7c7bf72c6 [file] [log] [blame]
// 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(&current_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(&current_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(&current_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