Commit 9ec18ef3 authored by Toni Barzic's avatar Toni Barzic Committed by Commit Bot

Swipe on home screen should invoke back action

Swipe from shelf generally means go to home, which would imply going
back if the home screen is showing search, or non-initial apps page.

BUG=1064739, 1057317

Change-Id: If9bb00a4879d4ec4c9605ac2d472912095ca1091
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2199182Reviewed-by: default avatarXiyuan Xia <xiyuan@chromium.org>
Reviewed-by: default avatarAlex Newcomer <newcomer@chromium.org>
Commit-Queue: Toni Baržić <tbarzic@chromium.org>
Cr-Commit-Position: refs/heads/master@{#768967}
parent 24cc123f
......@@ -4,8 +4,11 @@
#include "ash/home_screen/swipe_home_to_overview_controller.h"
#include "ash/app_list/app_list_controller_impl.h"
#include "ash/home_screen/drag_window_from_shelf_controller.h"
#include "ash/home_screen/home_screen_controller.h"
#include "ash/home_screen/home_screen_delegate.h"
#include "ash/public/cpp/app_list/app_list_config.h"
#include "ash/public/cpp/ash_features.h"
#include "ash/public/cpp/shelf_config.h"
#include "ash/session/session_controller_impl.h"
......@@ -50,8 +53,11 @@ constexpr base::TimeDelta kGestureCancelationDuration =
base::TimeDelta::FromMilliseconds(350);
void UpdateHomeAnimationForGestureCancel(
bool going_back,
ui::ScopedLayerAnimationSettings* settings) {
settings->SetTransitionDuration(kGestureCancelationDuration);
settings->SetTransitionDuration(
going_back ? AppListConfig::instance().page_transition_duration()
: kGestureCancelationDuration);
settings->SetTweenType(gfx::Tween::FAST_OUT_SLOW_IN);
settings->SetPreemptionStrategy(
ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
......@@ -139,9 +145,21 @@ void SwipeHomeToOverviewController::Drag(const gfx::PointF& location_in_screen,
void SwipeHomeToOverviewController::EndDrag(
const gfx::PointF& location_in_screen,
base::Optional<float> velocity_y) {
if (state_ != State::kTrackingDrag) {
state_ = State::kFinished;
return;
}
// Upward swipe should return to the home screen's initial state.
const bool go_back =
velocity_y &&
*velocity_y <
-DragWindowFromShelfController::kVelocityToHomeScreenThreshold;
// Overview is triggered by |overview_transition_timer_|. If EndDrag()
// is called before the timer fires, the gesture is canceled.
CancelDrag();
// is called before the timer fires, the result of the gesture should be
// staying on the home screen.
FinalizeDragAndStayOnHomeScreen(go_back);
}
void SwipeHomeToOverviewController::CancelDrag() {
......@@ -150,22 +168,7 @@ void SwipeHomeToOverviewController::CancelDrag() {
return;
}
overview_transition_timer_.Stop();
overview_transition_threshold_y_ = 0;
state_ = State::kFinished;
UMA_HISTOGRAM_ENUMERATION(kEnterOverviewHistogramName,
EnterOverviewFromHomeLauncher::kCanceled);
Shell::Get()
->home_screen_controller()
->delegate()
->UpdateScaleAndOpacityForHomeLauncher(
1.0f /*scale*/, 1.0f /*opacity*/, base::nullopt /*animation_info*/,
base::BindRepeating(&UpdateHomeAnimationForGestureCancel));
// No need to keep blur disabled for the drag - note that blur might remain
// disabled at this point due to the started home screen scale animation.
home_screen_blur_disabler_.reset();
FinalizeDragAndStayOnHomeScreen(/*go_back=*/false);
}
void SwipeHomeToOverviewController::ScheduleFinalizeDragAndShowOverview() {
......@@ -190,7 +193,11 @@ void SwipeHomeToOverviewController::FinalizeDragAndShowOverview() {
}
UMA_HISTOGRAM_ENUMERATION(kEnterOverviewHistogramName,
EnterOverviewFromHomeLauncher::kSuccess);
EnterOverviewFromHomeLauncher::kOverview);
// NOTE: No need to update the home launcher opacity and scale here - the
// HomeScreenController will update the home launcher state when it detects
// that the overview is starting.
Shell::Get()->overview_controller()->StartOverview();
// No need to keep blur disabled for the drag - note that blur might remain
......@@ -199,4 +206,34 @@ void SwipeHomeToOverviewController::FinalizeDragAndShowOverview() {
home_screen_blur_disabler_.reset();
}
void SwipeHomeToOverviewController::FinalizeDragAndStayOnHomeScreen(
bool go_back) {
overview_transition_timer_.Stop();
overview_transition_threshold_y_ = 0;
state_ = State::kFinished;
if (go_back) {
Shell::Get()->app_list_controller()->Back();
UMA_HISTOGRAM_ENUMERATION(kEnterOverviewHistogramName,
EnterOverviewFromHomeLauncher::kBack);
} else {
UMA_HISTOGRAM_ENUMERATION(kEnterOverviewHistogramName,
EnterOverviewFromHomeLauncher::kCanceled);
}
// Make sure the home launcher scale and opacity return to the initial state.
// Note that this is needed even if the gesture ended up in a fling, as early
// gesture handling might have updated the launcher scale.
Shell::Get()
->home_screen_controller()
->delegate()
->UpdateScaleAndOpacityForHomeLauncher(
1.0f /*scale*/, 1.0f /*opacity*/, base::nullopt /*animation_info*/,
base::BindRepeating(&UpdateHomeAnimationForGestureCancel, go_back));
// No need to keep blur disabled for the drag - note that blur might remain
// disabled at this point due to the started home screen scale animation.
home_screen_blur_disabler_.reset();
}
} // namespace ash
......@@ -64,6 +64,10 @@ class ASH_EXPORT SwipeHomeToOverviewController {
// moving the pointer - those events will be ignored.
void FinalizeDragAndShowOverview();
// Finalizes the drag sequence by staying on the home screen.
// |go_back| - if the gesture should invoke home screen back action.
void FinalizeDragAndStayOnHomeScreen(bool go_back);
const int64_t display_id_;
State state_ = State::kInitial;
......
......@@ -6,6 +6,7 @@
#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"
......@@ -112,6 +113,14 @@ class SwipeHomeToOverviewControllerTest : public AshTestBase {
}
}
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();
......@@ -191,7 +200,7 @@ TEST_F(SwipeHomeToOverviewControllerTest, BasicFlow) {
base::HistogramTester histogram_tester;
histogram_tester.ExpectBucketCount(
kEnterOverviewHistogramName, EnterOverviewFromHomeLauncher::kSuccess, 0);
kEnterOverviewHistogramName, EnterOverviewFromHomeLauncher::kOverview, 0);
StartDrag();
// Drag to a point within shelf bounds - verify that app list has not been
......@@ -207,7 +216,7 @@ TEST_F(SwipeHomeToOverviewControllerTest, BasicFlow) {
EXPECT_FALSE(OverviewTransitionTimerRunning());
EXPECT_FALSE(OverviewStarted());
histogram_tester.ExpectBucketCount(
kEnterOverviewHistogramName, EnterOverviewFromHomeLauncher::kSuccess, 0);
kEnterOverviewHistogramName, EnterOverviewFromHomeLauncher::kOverview, 0);
const int transition_threshold =
SwipeHomeToOverviewController::kVerticalThresholdForOverviewTransition;
......@@ -224,7 +233,7 @@ TEST_F(SwipeHomeToOverviewControllerTest, BasicFlow) {
EXPECT_FALSE(home_screen_window->transform().IsIdentityOrTranslation());
EXPECT_EQ(1.f, home_screen_window->layer()->opacity());
histogram_tester.ExpectBucketCount(
kEnterOverviewHistogramName, EnterOverviewFromHomeLauncher::kSuccess, 0);
kEnterOverviewHistogramName, EnterOverviewFromHomeLauncher::kOverview, 0);
// Move above the transition threshold - verify the overview transition timer
// has started.
......@@ -239,14 +248,14 @@ TEST_F(SwipeHomeToOverviewControllerTest, BasicFlow) {
EXPECT_TRUE(OverviewTransitionTimerRunning());
EXPECT_FALSE(OverviewStarted());
histogram_tester.ExpectBucketCount(
kEnterOverviewHistogramName, EnterOverviewFromHomeLauncher::kSuccess, 0);
kEnterOverviewHistogramName, EnterOverviewFromHomeLauncher::kOverview, 0);
// Fire overview transition timer, and verify the overview has started.
FireOverviewTransitionTimer();
EXPECT_TRUE(OverviewStarted());
histogram_tester.ExpectBucketCount(
kEnterOverviewHistogramName, EnterOverviewFromHomeLauncher::kSuccess, 1);
kEnterOverviewHistogramName, EnterOverviewFromHomeLauncher::kOverview, 1);
// Home screen is still scaled down, and not visible.
EXPECT_EQ(home_screen_window->transform(),
......@@ -262,7 +271,7 @@ TEST_F(SwipeHomeToOverviewControllerTest, BasicFlow) {
EXPECT_TRUE(OverviewStarted());
histogram_tester.ExpectBucketCount(
kEnterOverviewHistogramName, EnterOverviewFromHomeLauncher::kSuccess, 1);
kEnterOverviewHistogramName, EnterOverviewFromHomeLauncher::kOverview, 1);
// Home screen is still scaled down, and not visible.
EXPECT_EQ(home_screen_window->transform(),
......@@ -313,7 +322,108 @@ TEST_F(SwipeHomeToOverviewControllerTest, EndDragBeforeTimeout) {
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();
......@@ -350,6 +460,10 @@ TEST_F(SwipeHomeToOverviewControllerTest, CancelDragBeforeTimeout) {
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) {
......
......@@ -50,10 +50,13 @@ enum class EnterOverviewFromHomeLauncher {
kCanceled = 0,
// Succeed to enter overview mode from home launcher.
kSuccess = 1,
kOverview = 1,
// The gesture was detected as a swipe to the home screen initial state.
kBack = 2,
// New items should be added before to keep this one always the last.
kMaxState = 2,
kMaxState = 3,
kMaxValue = kMaxState
};
......
......@@ -65128,6 +65128,7 @@ would be helpful to identify which type is being sent.
<enum name="SwipeHomeToOverviewResult">
<int value="0" label="Remained on the home screen"/>
<int value="1" label="Transitioned to overview"/>
<int value="2" label="Went back on the home screen"/>
</enum>
<enum name="SwReporterRunningTimeRegistryError">
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