0

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/+/2199182
Reviewed-by: Xiyuan Xia <xiyuan@chromium.org>
Reviewed-by: Alex Newcomer <newcomer@chromium.org>
Commit-Queue: Toni Baržić <tbarzic@chromium.org>
Cr-Commit-Position: refs/heads/master@{#768967}
This commit is contained in:
Toni Barzic
2020-05-14 21:11:21 +00:00
committed by Commit Bot
parent 24cc123f70
commit 9ec18ef3b0
5 changed files with 187 additions and 28 deletions

@ -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">