123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920 |
- // Copyright 2020 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/app_list/test/app_list_test_helper.h"
- #include "ash/constants/ash_features.h"
- #include "ash/constants/ash_pref_names.h"
- #include "ash/controls/contextual_tooltip.h"
- #include "ash/public/cpp/shelf_types.h"
- #include "ash/session/session_controller_impl.h"
- #include "ash/shelf/drag_handle.h"
- #include "ash/shelf/drag_window_from_shelf_controller.h"
- #include "ash/shelf/drag_window_from_shelf_controller_test_api.h"
- #include "ash/shelf/shelf_layout_manager.h"
- #include "ash/shelf/test/shelf_layout_manager_test_base.h"
- #include "ash/shell.h"
- #include "ash/test/ash_test_base.h"
- #include "ash/wm/tablet_mode/tablet_mode_controller_test_api.h"
- #include "base/bind.h"
- #include "base/test/metrics/histogram_tester.h"
- #include "base/test/scoped_feature_list.h"
- #include "base/test/simple_test_clock.h"
- #include "ui/compositor/scoped_animation_duration_scale_mode.h"
- #include "ui/wm/core/window_util.h"
- namespace ash {
- namespace {
- ShelfWidget* GetShelfWidget() {
- return AshTestBase::GetPrimaryShelf()->shelf_widget();
- }
- ShelfLayoutManager* GetShelfLayoutManager() {
- return AshTestBase::GetPrimaryShelf()->shelf_layout_manager();
- }
- } // namespace
- // Test base for unit test related to drag handle contextual nudges.
- class DragHandleContextualNudgeTest : public ShelfLayoutManagerTestBase {
- public:
- DragHandleContextualNudgeTest() {
- scoped_feature_list_.InitWithFeatures(
- {ash::features::kContextualNudges,
- ash::features::kHideShelfControlsInTabletMode},
- {});
- }
- ~DragHandleContextualNudgeTest() override = default;
- DragHandleContextualNudgeTest(const DragHandleContextualNudgeTest& other) =
- delete;
- DragHandleContextualNudgeTest& operator=(
- const DragHandleContextualNudgeTest& other) = delete;
- // ShelfLayoutManagerTestBase:
- void SetUp() override {
- ShelfLayoutManagerTestBase::SetUp();
- test_clock_.Advance(base::Hours(2));
- contextual_tooltip::OverrideClockForTesting(&test_clock_);
- }
- void TearDown() override {
- contextual_tooltip::ClearClockOverrideForTesting();
- AshTestBase::TearDown();
- }
- base::SimpleTestClock test_clock_;
- private:
- base::test::ScopedFeatureList scoped_feature_list_;
- };
- class DragHandleContextualNudgeTestA11yPrefs
- : public DragHandleContextualNudgeTest,
- public ::testing::WithParamInterface<std::string> {};
- INSTANTIATE_TEST_SUITE_P(
- All,
- DragHandleContextualNudgeTestA11yPrefs,
- testing::Values(prefs::kAccessibilityAutoclickEnabled,
- prefs::kAccessibilitySpokenFeedbackEnabled,
- prefs::kAccessibilitySwitchAccessEnabled));
- TEST_F(DragHandleContextualNudgeTest, ShowDragHandleNudgeWithTimer) {
- // Creates a widget to put shelf into in-app state.
- views::Widget* widget = CreateTestWidget();
- widget->Maximize();
- TabletModeControllerTestApi().EnterTabletMode();
- EXPECT_EQ(ShelfBackgroundType::kInApp, GetShelfWidget()->GetBackgroundType());
- // The drag handle should be showing but the nudge should not. A timer to show
- // the nudge should be initialized.
- EXPECT_TRUE(GetShelfWidget()->GetDragHandle()->GetVisible());
- EXPECT_FALSE(
- GetShelfWidget()->GetDragHandle()->gesture_nudge_target_visibility());
- // Firing the timer should show the drag handle nudge.
- GetShelfWidget()->GetDragHandle()->fire_show_drag_handle_timer_for_testing();
- EXPECT_TRUE(GetShelfWidget()->GetDragHandle()->GetVisible());
- EXPECT_TRUE(
- GetShelfWidget()->GetDragHandle()->gesture_nudge_target_visibility());
- }
- TEST_F(DragHandleContextualNudgeTest, HideDragHandleNudgeHiddenOnMinimize) {
- base::HistogramTester histogram_tester;
- // Creates a test window to put shelf into in-app state.
- views::Widget* widget = CreateTestWidget();
- widget->Maximize();
- TabletModeControllerTestApi().EnterTabletMode();
- EXPECT_EQ(ShelfBackgroundType::kInApp, GetShelfWidget()->GetBackgroundType());
- // The drag handle and nudge should be showing after the timer fires.
- GetShelfWidget()->GetDragHandle()->fire_show_drag_handle_timer_for_testing();
- EXPECT_TRUE(GetShelfWidget()->GetDragHandle()->GetVisible());
- EXPECT_TRUE(
- GetShelfWidget()->GetDragHandle()->gesture_nudge_target_visibility());
- // Minimizing the widget should hide the drag handle and nudge.
- widget->Minimize();
- EXPECT_FALSE(GetShelfWidget()->GetDragHandle()->GetVisible());
- EXPECT_FALSE(
- GetShelfWidget()->GetDragHandle()->gesture_nudge_target_visibility());
- }
- // Tests that the drag handle nudge nudge is hidden when closing the widget and
- // setting the ShelfBackgroundType to kHomeLauncher.
- TEST_F(DragHandleContextualNudgeTest, DragHandleNudgeHiddenOnClose) {
- // Creates a widget to put shelf into in-app state.
- views::Widget* widget = CreateTestWidget();
- widget->Maximize();
- TabletModeControllerTestApi().EnterTabletMode();
- EXPECT_EQ(ShelfBackgroundType::kInApp, GetShelfWidget()->GetBackgroundType());
- DragHandle* const drag_handle = GetShelfWidget()->GetDragHandle();
- ASSERT_TRUE(drag_handle->has_show_drag_handle_timer_for_testing());
- drag_handle->fire_show_drag_handle_timer_for_testing();
- EXPECT_TRUE(drag_handle->gesture_nudge_target_visibility());
- // Close the widget.
- widget->CloseWithReason(views::Widget::ClosedReason::kCloseButtonClicked);
- EXPECT_FALSE(drag_handle->GetVisible());
- EXPECT_FALSE(drag_handle->gesture_nudge_target_visibility());
- }
- // Checks that the shelf cannot be auto hidden while animating shelf drag handle
- // nudge.
- TEST_F(DragHandleContextualNudgeTest,
- HideDragHandleDoesNotInteruptShowNudgeAnimation) {
- GetPrimaryShelf()->SetAutoHideBehavior(ShelfAutoHideBehavior::kAlways);
- // Creates a widget to put shelf into in-app state.
- views::Widget* widget = CreateTestWidget();
- widget->Maximize();
- TabletModeControllerTestApi().EnterTabletMode();
- EXPECT_EQ(ShelfBackgroundType::kInApp, GetShelfWidget()->GetBackgroundType());
- ui::ScopedAnimationDurationScaleMode normal_animation_duration(
- ui::ScopedAnimationDurationScaleMode::SLOW_DURATION);
- GetShelfWidget()->GetDragHandle()->MaybeShowDragHandleNudge();
- EXPECT_TRUE(GetShelfWidget()->GetDragHandle()->GetVisible());
- EXPECT_TRUE(
- GetShelfWidget()->GetDragHandle()->show_nudge_animation_in_progress());
- GetShelfLayoutManager()->UpdateAutoHideState();
- // Shelf auto hide should not interrupt animations to show drag handle nudge.
- // Showing the nudge while hiding the shelf is not intended behavior.
- EXPECT_TRUE(GetShelfWidget()->GetDragHandle()->GetVisible());
- EXPECT_TRUE(
- GetShelfWidget()->GetDragHandle()->show_nudge_animation_in_progress());
- }
- // Checks that the drag handle nudge is not shown when entering kInApp with
- // shelf autohide turned on.
- TEST_F(DragHandleContextualNudgeTest, DragHandleNotShownForAutoHideShelf) {
- GetPrimaryShelf()->SetAutoHideBehavior(ShelfAutoHideBehavior::kAlways);
- // Creates a widget to put shelf into in-app state.
- views::Widget* widget = CreateTestWidget();
- widget->Maximize();
- TabletModeControllerTestApi().EnterTabletMode();
- EXPECT_FALSE(
- GetShelfWidget()->GetDragHandle()->show_nudge_animation_in_progress());
- EXPECT_FALSE(
- GetShelfWidget()->GetDragHandle()->gesture_nudge_target_visibility());
- }
- TEST_F(DragHandleContextualNudgeTest, DoNotShowNudgeWithoutDragHandle) {
- // Creates a widget to put shelf into in-app state.
- views::Widget* widget = CreateTestWidget();
- widget->Maximize();
- TabletModeControllerTestApi().EnterTabletMode();
- EXPECT_EQ(ShelfBackgroundType::kInApp, GetShelfWidget()->GetBackgroundType());
- // Minimizing the widget should hide the drag handle and nudge.
- widget->Minimize();
- EXPECT_FALSE(GetShelfWidget()->GetDragHandle()->GetVisible());
- EXPECT_FALSE(
- GetShelfWidget()->GetDragHandle()->gesture_nudge_target_visibility());
- }
- TEST_F(DragHandleContextualNudgeTest,
- ContinueShowingDragHandleNudgeOnActiveWidgetChanged) {
- // Creates a widget to put shelf into in-app state.
- views::Widget* widget = CreateTestWidget();
- widget->Maximize();
- TabletModeControllerTestApi().EnterTabletMode();
- EXPECT_EQ(ShelfBackgroundType::kInApp, GetShelfWidget()->GetBackgroundType());
- GetShelfWidget()->GetDragHandle()->fire_show_drag_handle_timer_for_testing();
- EXPECT_TRUE(GetShelfWidget()->GetDragHandle()->GetVisible());
- EXPECT_TRUE(
- GetShelfWidget()->GetDragHandle()->gesture_nudge_target_visibility());
- // Maximizing and showing a different widget should not hide the drag handle
- // or nudge.
- views::Widget* new_widget = CreateTestWidget();
- new_widget->Maximize();
- EXPECT_TRUE(GetShelfWidget()->GetDragHandle()->GetVisible());
- EXPECT_TRUE(
- GetShelfWidget()->GetDragHandle()->gesture_nudge_target_visibility());
- }
- TEST_F(DragHandleContextualNudgeTest, DragHandleNudgeShownInAppShelf) {
- base::HistogramTester histogram_tester;
- // Creates a widget to put shelf into in-app state.
- views::Widget* widget = CreateTestWidget();
- widget->Maximize();
- // Drag handle and nudge should not be shown in clamshell mode.
- EXPECT_FALSE(GetShelfWidget()->GetDragHandle()->GetVisible());
- EXPECT_FALSE(
- GetShelfWidget()->GetDragHandle()->gesture_nudge_target_visibility());
- // Test that the first time a user transitions into tablet mode with a
- // maximized window will show the drag nudge immedietly. The drag handle nudge
- // should not be visible yet and the timer to show it should be set.
- TabletModeControllerTestApi().EnterTabletMode();
- EXPECT_EQ(ShelfBackgroundType::kInApp, GetShelfWidget()->GetBackgroundType());
- EXPECT_TRUE(GetShelfWidget()->GetDragHandle()->GetVisible());
- EXPECT_FALSE(
- GetShelfWidget()->GetDragHandle()->gesture_nudge_target_visibility());
- EXPECT_TRUE(GetShelfWidget()
- ->GetDragHandle()
- ->has_show_drag_handle_timer_for_testing());
- // Firing the timer should show the nudge for the first time. The nudge should
- // remain visible until the shelf state changes so the timer to hide it should
- // not be set.
- GetShelfWidget()->GetDragHandle()->fire_show_drag_handle_timer_for_testing();
- EXPECT_TRUE(
- GetShelfWidget()->GetDragHandle()->gesture_nudge_target_visibility());
- EXPECT_FALSE(GetShelfWidget()
- ->GetDragHandle()
- ->has_hide_drag_handle_timer_for_testing());
- // Leaving tablet mode should hide the nudge.
- TabletModeControllerTestApi().LeaveTabletMode();
- EXPECT_FALSE(GetShelfWidget()->GetDragHandle()->GetVisible());
- EXPECT_FALSE(
- GetShelfWidget()->GetDragHandle()->gesture_nudge_target_visibility());
- // Reentering tablet mode should show the drag handle but the nudge should
- // not. No timer should be set to show the nudge.
- TabletModeControllerTestApi().EnterTabletMode();
- EXPECT_TRUE(GetShelfWidget()->GetDragHandle()->GetVisible());
- EXPECT_FALSE(
- GetShelfWidget()->GetDragHandle()->gesture_nudge_target_visibility());
- EXPECT_FALSE(GetShelfWidget()
- ->GetDragHandle()
- ->has_show_drag_handle_timer_for_testing());
- // Advance time for more than a day (which should enable the nudge again).
- test_clock_.Advance(base::Hours(25));
- // Reentering tablet mode with a maximized widget should immedietly show the
- // drag handle and set a timer to show the nudge.
- TabletModeControllerTestApi().LeaveTabletMode();
- TabletModeControllerTestApi().EnterTabletMode();
- EXPECT_TRUE(GetShelfWidget()->GetDragHandle()->GetVisible());
- EXPECT_FALSE(
- GetShelfWidget()->GetDragHandle()->gesture_nudge_target_visibility());
- // Firing the timer should show the nudge.
- EXPECT_TRUE(GetShelfWidget()
- ->GetDragHandle()
- ->has_show_drag_handle_timer_for_testing());
- GetShelfWidget()->GetDragHandle()->fire_show_drag_handle_timer_for_testing();
- EXPECT_TRUE(
- GetShelfWidget()->GetDragHandle()->gesture_nudge_target_visibility());
- EXPECT_FALSE(GetShelfWidget()
- ->GetDragHandle()
- ->has_show_drag_handle_timer_for_testing());
- // On subsequent shows, the nudge should be hidden after a timeout.
- EXPECT_TRUE(GetShelfWidget()
- ->GetDragHandle()
- ->has_hide_drag_handle_timer_for_testing());
- }
- TEST_F(DragHandleContextualNudgeTest, DragHandleNudgeShownOnTap) {
- // Creates a widget to put shelf into in-app state.
- views::Widget* widget = CreateTestWidget();
- widget->Maximize();
- TabletModeControllerTestApi().EnterTabletMode();
- EXPECT_EQ(ShelfBackgroundType::kInApp, GetShelfWidget()->GetBackgroundType());
- EXPECT_TRUE(GetShelfWidget()->GetDragHandle()->GetVisible());
- EXPECT_FALSE(
- GetShelfWidget()->GetDragHandle()->gesture_nudge_target_visibility());
- EXPECT_TRUE(GetShelfWidget()
- ->GetDragHandle()
- ->has_show_drag_handle_timer_for_testing());
- GetShelfWidget()->GetDragHandle()->fire_show_drag_handle_timer_for_testing();
- EXPECT_TRUE(
- GetShelfWidget()->GetDragHandle()->gesture_nudge_target_visibility());
- // Exiting and re-entering tablet should hide the nudge and put the shelf into
- // the default kInApp shelf state.
- TabletModeControllerTestApi().LeaveTabletMode();
- TabletModeControllerTestApi().EnterTabletMode();
- EXPECT_TRUE(GetShelfWidget()->GetDragHandle()->GetVisible());
- EXPECT_FALSE(
- GetShelfWidget()->GetDragHandle()->gesture_nudge_target_visibility());
- // Tapping the drag handle should show the drag handle nudge immedietly and
- // the show nudge timer should be set.
- GetEventGenerator()->GestureTapAt(
- GetShelfWidget()->GetDragHandle()->GetBoundsInScreen().CenterPoint());
- EXPECT_FALSE(GetShelfWidget()
- ->GetDragHandle()
- ->has_show_drag_handle_timer_for_testing());
- EXPECT_TRUE(GetShelfWidget()->GetDragHandle()->GetVisible());
- EXPECT_TRUE(
- GetShelfWidget()->GetDragHandle()->gesture_nudge_target_visibility());
- EXPECT_TRUE(GetShelfWidget()
- ->GetDragHandle()
- ->has_hide_drag_handle_timer_for_testing());
- }
- TEST_F(DragHandleContextualNudgeTest, DragHandleNudgeNotShownForHiddenShelf) {
- GetPrimaryShelf()->SetAutoHideBehavior(ShelfAutoHideBehavior::kAlways);
- TabletModeControllerTestApi().EnterTabletMode();
- // Creates a widget to put shelf into in-app state.
- views::Widget* widget = CreateTestWidget();
- widget->Maximize();
- ShelfWidget* const shelf_widget = GetShelfWidget();
- DragHandle* const drag_handle = shelf_widget->GetDragHandle();
- // The shelf is hidden, so the drag handle nudge should not be shown.
- EXPECT_TRUE(drag_handle->GetVisible());
- EXPECT_FALSE(drag_handle->gesture_nudge_target_visibility());
- EXPECT_FALSE(drag_handle->has_show_drag_handle_timer_for_testing());
- PrefService* const prefs =
- Shell::Get()->session_controller()->GetLastActiveUserPrefService();
- // Back gesture nudge should be allowed if the shelf is hidden.
- EXPECT_TRUE(contextual_tooltip::ShouldShowNudge(
- prefs, contextual_tooltip::TooltipType::kBackGesture, nullptr));
- // Swipe up to show the shelf - this should schedule the drag handle nudge.
- SwipeUpOnShelf();
- // Back gesture nudge should be disallowed at this time, given that the drag
- // handle nudge can be shown.
- EXPECT_FALSE(contextual_tooltip::ShouldShowNudge(
- prefs, contextual_tooltip::TooltipType::kBackGesture, nullptr));
- ASSERT_TRUE(drag_handle->has_show_drag_handle_timer_for_testing());
- drag_handle->fire_show_drag_handle_timer_for_testing();
- EXPECT_TRUE(drag_handle->gesture_nudge_target_visibility());
- }
- // Tapping the drag handle nudge when auto hide shelf is enabled should hide the
- // drag handle nudge but should not hide the shelf or hotseat.
- TEST_F(DragHandleContextualNudgeTest,
- DragHandleNudgeTapDoesNotHideAutoHiddenShelf) {
- // Sets shelf auto hide behavior.
- GetPrimaryShelf()->SetAutoHideBehavior(ShelfAutoHideBehavior::kAlways);
- TabletModeControllerTestApi().EnterTabletMode();
- // Creates a widget to put shelf into in-app state.
- views::Widget* widget = CreateTestWidget();
- widget->Maximize();
- ShelfWidget* const shelf_widget = GetShelfWidget();
- DragHandle* const drag_handle = shelf_widget->GetDragHandle();
- // The shelf and drag handle should be hidden and the nudge should not be
- // scheduled because shelf auto hide is set.
- EXPECT_TRUE(GetPrimaryShelf()->GetAutoHideState() ==
- ShelfAutoHideState::SHELF_AUTO_HIDE_HIDDEN);
- EXPECT_FALSE(drag_handle->gesture_nudge_target_visibility());
- EXPECT_FALSE(drag_handle->has_show_drag_handle_timer_for_testing());
- // Swipe up to show the shelf. This should show the shelf, extend the hotseat,
- // and schedule the drag handle nudge.
- SwipeUpOnShelf();
- EXPECT_TRUE(GetPrimaryShelf()->GetAutoHideState() ==
- ShelfAutoHideState::SHELF_AUTO_HIDE_SHOWN);
- EXPECT_EQ(HotseatState::kExtended, GetShelfLayoutManager()->hotseat_state());
- ASSERT_TRUE(drag_handle->has_show_drag_handle_timer_for_testing());
- // Firing the show timer should create the nudge set the target visibility for
- // animations..
- drag_handle->fire_show_drag_handle_timer_for_testing();
- EXPECT_TRUE(drag_handle->gesture_nudge_target_visibility());
- EXPECT_TRUE(drag_handle->drag_handle_nudge() != nullptr);
- // Tapping the drag handle nudge should hide the nudge but not affect the
- // visibility of the shelf or hotseat.
- GetEventGenerator()->GestureTapAt(
- drag_handle->drag_handle_nudge()->GetBoundsInScreen().CenterPoint());
- EXPECT_FALSE(drag_handle->gesture_nudge_target_visibility());
- EXPECT_TRUE(GetPrimaryShelf()->GetAutoHideState() ==
- ShelfAutoHideState::SHELF_AUTO_HIDE_SHOWN);
- EXPECT_EQ(HotseatState::kExtended, GetShelfLayoutManager()->hotseat_state());
- // Swiping down on shelf should hide the shelf and hotseat.
- SwipeDownOnShelf();
- EXPECT_EQ(HotseatState::kHidden, GetShelfLayoutManager()->hotseat_state());
- EXPECT_TRUE(GetPrimaryShelf()->GetAutoHideState() ==
- ShelfAutoHideState::SHELF_AUTO_HIDE_HIDDEN);
- // Swiping up on shelf should show the shelf and drag handle but not the
- // nudge or hotseat.
- SwipeUpOnShelf();
- EXPECT_TRUE(GetPrimaryShelf()->GetAutoHideState() ==
- ShelfAutoHideState::SHELF_AUTO_HIDE_SHOWN);
- EXPECT_FALSE(drag_handle->has_show_drag_handle_timer_for_testing());
- EXPECT_TRUE(drag_handle->drag_handle_nudge() == nullptr);
- EXPECT_EQ(HotseatState::kExtended, GetShelfLayoutManager()->hotseat_state());
- }
- // Tests that drag handle show is canceled when the shelf is hidden while the
- // drag handle is scheduled to be shown.
- TEST_F(DragHandleContextualNudgeTest, HidingShelfCancelsDragHandleShow) {
- GetPrimaryShelf()->SetAutoHideBehavior(ShelfAutoHideBehavior::kAlways);
- TabletModeControllerTestApi().EnterTabletMode();
- // Creates a widget to put shelf into in-app state.
- views::Widget* widget = CreateTestWidget();
- widget->Maximize();
- ShelfWidget* const shelf_widget = GetShelfWidget();
- DragHandle* const drag_handle = shelf_widget->GetDragHandle();
- // The shelf is hidden, so the drag handle nudge should not be shown.
- EXPECT_TRUE(drag_handle->GetVisible());
- EXPECT_FALSE(drag_handle->gesture_nudge_target_visibility());
- EXPECT_FALSE(drag_handle->has_show_drag_handle_timer_for_testing());
- // Swipe up to show the shelf - this should schedule the drag handle nudge.
- SwipeUpOnShelf();
- EXPECT_TRUE(drag_handle->has_show_drag_handle_timer_for_testing());
- // Hide the shelf, and verify the drag handle show is canceled.
- SwipeDownOnShelf();
- EXPECT_FALSE(drag_handle->has_show_drag_handle_timer_for_testing());
- EXPECT_FALSE(drag_handle->gesture_nudge_target_visibility());
- PrefService* const prefs =
- Shell::Get()->session_controller()->GetLastActiveUserPrefService();
- // Back gesture nudge should be allowed if the shelf is hidden.
- EXPECT_TRUE(contextual_tooltip::ShouldShowNudge(
- prefs, contextual_tooltip::TooltipType::kBackGesture, nullptr));
- }
- // Tests that the drag handle nudge is not hidden when the user extends the
- // hotseat.
- TEST_F(DragHandleContextualNudgeTest,
- DragHandleNudgeNotHiddenByExtendingHotseat) {
- TabletModeControllerTestApi().EnterTabletMode();
- // Creates a widget to put shelf into in-app state.
- views::Widget* widget = CreateTestWidget();
- widget->Maximize();
- ShelfWidget* const shelf_widget = GetShelfWidget();
- DragHandle* const drag_handle = shelf_widget->GetDragHandle();
- ASSERT_TRUE(drag_handle->has_show_drag_handle_timer_for_testing());
- drag_handle->fire_show_drag_handle_timer_for_testing();
- EXPECT_TRUE(drag_handle->gesture_nudge_target_visibility());
- // Swipe up to extend the hotseat - verify that the drag handle remain
- // visible.
- SwipeUpOnShelf();
- EXPECT_TRUE(drag_handle->GetVisible());
- EXPECT_TRUE(drag_handle->gesture_nudge_target_visibility());
- }
- // Tests that the drag handle nudge is horizontally centered in screen, and
- // drawn above the shelf drag handle, even after display bounds are updated.
- TEST_F(DragHandleContextualNudgeTest, DragHandleNudgeBoundsInScreen) {
- UpdateDisplay("675x1200");
- TabletModeControllerTestApi().EnterTabletMode();
- views::Widget* widget = CreateTestWidget();
- widget->Maximize();
- ShelfWidget* const shelf_widget = GetShelfWidget();
- DragHandle* const drag_handle = shelf_widget->GetDragHandle();
- EXPECT_TRUE(drag_handle->GetVisible());
- ASSERT_TRUE(drag_handle->has_show_drag_handle_timer_for_testing());
- drag_handle->fire_show_drag_handle_timer_for_testing();
- EXPECT_TRUE(drag_handle->gesture_nudge_target_visibility());
- // Calculates absolute difference between horizontal margins of |inner| rect
- // within |outer| rect.
- auto margin_diff = [](const gfx::Rect& inner, const gfx::Rect& outer) -> int {
- const int left = inner.x() - outer.x();
- EXPECT_GE(left, 0);
- const int right = outer.right() - inner.right();
- EXPECT_GE(right, 0);
- return std::abs(left - right);
- };
- // Verify that nudge widget is centered in shelf.
- gfx::Rect shelf_bounds = shelf_widget->GetWindowBoundsInScreen();
- gfx::Rect nudge_bounds =
- drag_handle->drag_handle_nudge()->label()->GetBoundsInScreen();
- EXPECT_LE(margin_diff(nudge_bounds, shelf_bounds), 1);
- // Verify that the nudge vertical bounds - within the shelf bounds, and above
- // the drag handle.
- gfx::Rect drag_handle_bounds = drag_handle->GetBoundsInScreen();
- EXPECT_LE(shelf_bounds.y(), nudge_bounds.y());
- EXPECT_LE(nudge_bounds.bottom(), drag_handle_bounds.y());
- // Change the display bounds, and verify the updated drag handle bounds.
- UpdateDisplay("1200x675");
- EXPECT_TRUE(
- GetShelfWidget()->GetDragHandle()->gesture_nudge_target_visibility());
- // Verify that nudge widget is centered in shelf.
- shelf_bounds = shelf_widget->GetWindowBoundsInScreen();
- nudge_bounds = drag_handle->drag_handle_nudge()->label()->GetBoundsInScreen();
- EXPECT_LE(margin_diff(nudge_bounds, shelf_bounds), 1);
- // Verify that the nudge vertical bounds - within the shelf bounds, and above
- // the drag handle.
- drag_handle_bounds = drag_handle->GetBoundsInScreen();
- EXPECT_LE(shelf_bounds.y(), nudge_bounds.y());
- EXPECT_LE(nudge_bounds.bottom(), drag_handle_bounds.y());
- }
- // Tests that drag handle does not hide during the window drag from shelf
- // gesture.
- TEST_F(DragHandleContextualNudgeTest,
- DragHandleNudgeNotHiddenDuringWindowDragFromShelf) {
- TabletModeControllerTestApi().EnterTabletMode();
- // Creates a widget to put shelf into in-app state.
- views::Widget* widget = CreateTestWidget();
- widget->Maximize();
- ShelfWidget* const shelf_widget = GetShelfWidget();
- DragHandle* const drag_handle = shelf_widget->GetDragHandle();
- ASSERT_TRUE(drag_handle->has_show_drag_handle_timer_for_testing());
- drag_handle->fire_show_drag_handle_timer_for_testing();
- EXPECT_TRUE(drag_handle->gesture_nudge_target_visibility());
- TabletModeControllerTestApi().LeaveTabletMode();
- // Advance time for more than a day (which should enable the nudge again).
- test_clock_.Advance(base::Hours(25));
- TabletModeControllerTestApi().EnterTabletMode();
- EXPECT_TRUE(drag_handle->has_show_drag_handle_timer_for_testing());
- drag_handle->fire_show_drag_handle_timer_for_testing();
- EXPECT_TRUE(drag_handle->has_hide_drag_handle_timer_for_testing());
- const gfx::Point start = drag_handle->GetBoundsInScreen().CenterPoint();
- // Simulates window drag from shelf gesture, and verifies that the timer to
- // hide the drag handle nudge is canceled when the window drag from shelf
- // starts.
- GetEventGenerator()->GestureScrollSequenceWithCallback(
- start, start + gfx::Vector2d(0, -200), base::Milliseconds(50),
- /*num_steps = */ 6,
- base::BindRepeating(
- [](DragHandle* drag_handle, ui::EventType type,
- const gfx::Vector2dF& offset) {
- DragWindowFromShelfController* window_drag_controller =
- GetShelfLayoutManager()->window_drag_controller_for_testing();
- if (window_drag_controller &&
- window_drag_controller->dragged_window()) {
- EXPECT_FALSE(
- drag_handle->has_hide_drag_handle_timer_for_testing());
- }
- const bool scroll_end = type == ui::ET_GESTURE_SCROLL_END;
- EXPECT_EQ(!scroll_end,
- drag_handle->gesture_nudge_target_visibility());
- },
- drag_handle));
- // The nudge should be hidden when the gesture completes.
- EXPECT_FALSE(drag_handle->gesture_nudge_target_visibility());
- }
- // Tests that window drag from shelf cancels drag handle contextual nudge from
- // showing.
- TEST_F(DragHandleContextualNudgeTest,
- DragHandleNudgeNotShownDuringWindowDragFromShelf) {
- TabletModeControllerTestApi().EnterTabletMode();
- // Creates a widget to put shelf into in-app state.
- views::Widget* widget = CreateTestWidget();
- widget->Maximize();
- ShelfWidget* const shelf_widget = GetShelfWidget();
- DragHandle* const drag_handle = shelf_widget->GetDragHandle();
- EXPECT_TRUE(drag_handle->has_show_drag_handle_timer_for_testing());
- const gfx::Point start =
- GetShelfWidget()->GetWindowBoundsInScreen().CenterPoint();
- // Simulates window drag from shelf gesture, and verifies that the timer to
- // show the drag handle nudge is canceled when the window drag from shelf
- // starts.
- GetEventGenerator()->GestureScrollSequenceWithCallback(
- start, start + gfx::Vector2d(0, -200), base::Milliseconds(50),
- /*num_steps = */ 6,
- base::BindRepeating(
- [](DragHandle* drag_handle, ui::EventType type,
- const gfx::Vector2dF& offset) {
- DragWindowFromShelfController* window_drag_controller =
- GetShelfLayoutManager()->window_drag_controller_for_testing();
- if (window_drag_controller &&
- window_drag_controller->dragged_window()) {
- EXPECT_FALSE(
- drag_handle->has_show_drag_handle_timer_for_testing());
- // Attempt to schedule the nudge should fail.
- if (type != ui::ET_GESTURE_SCROLL_END) {
- drag_handle->ScheduleShowDragHandleNudge();
- EXPECT_FALSE(
- drag_handle->has_show_drag_handle_timer_for_testing());
- }
- }
- EXPECT_FALSE(drag_handle->gesture_nudge_target_visibility());
- },
- drag_handle));
- // The nudge should be hidden when the gesture completes.
- EXPECT_FALSE(drag_handle->gesture_nudge_target_visibility());
- }
- TEST_F(DragHandleContextualNudgeTest, GestureSwipeHidesDragHandleNudge) {
- base::HistogramTester histogram_tester;
- TabletModeControllerTestApi().EnterTabletMode();
- // Creates a widget to put shelf into in-app state.
- views::Widget* widget = CreateTestWidget();
- widget->Maximize();
- ShelfWidget* const shelf_widget = GetShelfWidget();
- DragHandle* const drag_handle = shelf_widget->GetDragHandle();
- ASSERT_TRUE(drag_handle->has_show_drag_handle_timer_for_testing());
- drag_handle->fire_show_drag_handle_timer_for_testing();
- EXPECT_TRUE(drag_handle->gesture_nudge_target_visibility());
- const gfx::Point start = drag_handle->GetBoundsInScreen().CenterPoint();
- // Simulates a swipe up from the drag handle to perform the in app to home
- // gesture.
- GetEventGenerator()->GestureScrollSequence(
- start, start + gfx::Vector2d(0, -300), base::Milliseconds(10),
- /*num_steps = */ 5);
- // The nudge should be hidden when the gesture completes.
- EXPECT_FALSE(drag_handle->gesture_nudge_target_visibility());
- GetAppListTestHelper()->CheckVisibility(true);
- }
- // Tests that drag handle nudge gets hidden when the user performs window drag
- // from shelf to home.
- TEST_F(DragHandleContextualNudgeTest, FlingFromShelfToHomeHidesTheNudge) {
- TabletModeControllerTestApi().EnterTabletMode();
- // Creates a widget to put shelf into in-app state.
- views::Widget* widget = CreateTestWidget();
- widget->Maximize();
- ShelfWidget* const shelf_widget = GetShelfWidget();
- DragHandle* const drag_handle = shelf_widget->GetDragHandle();
- ASSERT_TRUE(drag_handle->has_show_drag_handle_timer_for_testing());
- drag_handle->fire_show_drag_handle_timer_for_testing();
- EXPECT_TRUE(drag_handle->gesture_nudge_target_visibility());
- const gfx::Point start = drag_handle->GetBoundsInScreen().CenterPoint();
- // Simulates window drag from shelf gesture, and verifies that the timer to
- // hide the drag handle nudge is canceled when the window drag from shelf
- // starts.
- GetEventGenerator()->GestureScrollSequenceWithCallback(
- start, start + gfx::Vector2d(0, -300), base::Milliseconds(10),
- /*num_steps = */ 6,
- base::BindRepeating(
- [](DragHandle* drag_handle, ui::EventType type,
- const gfx::Vector2dF& offset) {
- const bool scroll_end = type == ui::ET_GESTURE_SCROLL_END;
- EXPECT_EQ(!scroll_end,
- drag_handle->gesture_nudge_target_visibility());
- },
- drag_handle));
- // The nudge should be hidden when the gesture completes.
- EXPECT_FALSE(drag_handle->gesture_nudge_target_visibility());
- GetAppListTestHelper()->CheckVisibility(true);
- }
- // Tests that drag handle nudge gets hidden when the user performs window drag
- // from shelf, even if the gesture does not end up going home.
- TEST_F(DragHandleContextualNudgeTest, DragFromShelfToHomeHidesTheNudge) {
- TabletModeControllerTestApi().EnterTabletMode();
- // Creates a widget to put shelf into in-app state.
- views::Widget* widget = CreateTestWidget();
- widget->Maximize();
- ShelfWidget* const shelf_widget = GetShelfWidget();
- DragHandle* const drag_handle = shelf_widget->GetDragHandle();
- ASSERT_TRUE(drag_handle->has_show_drag_handle_timer_for_testing());
- drag_handle->fire_show_drag_handle_timer_for_testing();
- EXPECT_TRUE(drag_handle->gesture_nudge_target_visibility());
- const gfx::Point start = drag_handle->GetBoundsInScreen().CenterPoint();
- // Simulates window drag from shelf gesture, and verifies that the timer to
- // hide the drag handle nudge is canceled when the window drag from shelf
- // starts.
- GetEventGenerator()->GestureScrollSequenceWithCallback(
- start, start + gfx::Vector2d(0, -150), base::Milliseconds(500),
- /*num_steps = */ 20,
- base::BindRepeating(
- [](DragHandle* drag_handle, ui::EventType type,
- const gfx::Vector2dF& offset) {
- DragWindowFromShelfController* window_drag_controller =
- GetShelfLayoutManager()->window_drag_controller_for_testing();
- if (window_drag_controller &&
- window_drag_controller->dragged_window()) {
- DragWindowFromShelfControllerTestApi().WaitUntilOverviewIsShown(
- window_drag_controller);
- }
- const bool scroll_end = type == ui::ET_GESTURE_SCROLL_END;
- EXPECT_EQ(!scroll_end,
- drag_handle->gesture_nudge_target_visibility());
- },
- drag_handle));
- // The nudge should be hidden when the gesture completes.
- EXPECT_FALSE(drag_handle->gesture_nudge_target_visibility());
- GetAppListTestHelper()->CheckVisibility(false);
- EXPECT_TRUE(Shell::Get()->overview_controller()->InOverviewSession());
- }
- // Tests that scheduled drag handle nudge show is canceled when overview starts.
- TEST_F(DragHandleContextualNudgeTest, OverviewCancelsNudgeShow) {
- TabletModeControllerTestApi().EnterTabletMode();
- // Creates a widget to put shelf into in-app state.
- views::Widget* widget = CreateTestWidget();
- widget->Maximize();
- ShelfWidget* const shelf_widget = GetShelfWidget();
- DragHandle* const drag_handle = shelf_widget->GetDragHandle();
- ASSERT_TRUE(drag_handle->has_show_drag_handle_timer_for_testing());
- EnterOverview();
- ASSERT_FALSE(drag_handle->has_show_drag_handle_timer_for_testing());
- }
- // Tests that tapping the drag handle can shown drag handle nudge in overview.
- TEST_F(DragHandleContextualNudgeTest, DragHandleTapShowNudgeInOverview) {
- TabletModeControllerTestApi().EnterTabletMode();
- // Creates a widget to put shelf into in-app state.
- views::Widget* widget = CreateTestWidget();
- widget->Maximize();
- ShelfWidget* const shelf_widget = GetShelfWidget();
- DragHandle* const drag_handle = shelf_widget->GetDragHandle();
- ASSERT_TRUE(drag_handle->has_show_drag_handle_timer_for_testing());
- drag_handle->fire_show_drag_handle_timer_for_testing();
- EXPECT_TRUE(drag_handle->gesture_nudge_target_visibility());
- TabletModeControllerTestApi().LeaveTabletMode();
- TabletModeControllerTestApi().EnterTabletMode();
- EnterOverview();
- ASSERT_FALSE(drag_handle->has_show_drag_handle_timer_for_testing());
- GetEventGenerator()->GestureTapAt(
- drag_handle->GetBoundsInScreen().CenterPoint());
- EXPECT_TRUE(drag_handle->GetVisible());
- EXPECT_TRUE(drag_handle->gesture_nudge_target_visibility());
- EXPECT_TRUE(drag_handle->has_hide_drag_handle_timer_for_testing());
- drag_handle->fire_hide_drag_handle_timer_for_testing();
- EXPECT_FALSE(drag_handle->gesture_nudge_target_visibility());
- // Tapping the drag handle again will show the nudge again.
- GetEventGenerator()->GestureTapAt(
- drag_handle->GetBoundsInScreen().CenterPoint());
- EXPECT_TRUE(drag_handle->gesture_nudge_target_visibility());
- }
- // Tests that tapping the drag handle in split screen does not show nudge.
- TEST_F(DragHandleContextualNudgeTest,
- DragHandleTapDoesNotShowNudgeForSplitScreen) {
- TabletModeControllerTestApi().EnterTabletMode();
- std::unique_ptr<aura::Window> window =
- AshTestBase::CreateTestWindow(gfx::Rect(0, 0, 400, 400));
- wm::ActivateWindow(window.get());
- ShelfWidget* const shelf_widget = GetShelfWidget();
- DragHandle* const drag_handle = shelf_widget->GetDragHandle();
- // Go into split view mode by first going into overview, and then snapping
- // the open window on one side.
- EnterOverview();
- SplitViewController* split_view_controller =
- SplitViewController::Get(shelf_widget->GetNativeWindow());
- split_view_controller->SnapWindow(window.get(), SplitViewController::LEFT);
- EXPECT_TRUE(split_view_controller->InSplitViewMode());
- // Tapping the drag handle will not show the drag handle.
- GetEventGenerator()->GestureTapAt(
- drag_handle->GetBoundsInScreen().CenterPoint());
- EXPECT_FALSE(drag_handle->gesture_nudge_target_visibility());
- }
- // Tests that entering split screen hides the drag handle nudge.
- TEST_F(DragHandleContextualNudgeTest, DragHandleNudgeHiddenOnSplitScreen) {
- TabletModeControllerTestApi().EnterTabletMode();
- std::unique_ptr<aura::Window> window =
- AshTestBase::CreateTestWindow(gfx::Rect(0, 0, 400, 400));
- wm::ActivateWindow(window.get());
- ShelfWidget* const shelf_widget = GetShelfWidget();
- DragHandle* const drag_handle = shelf_widget->GetDragHandle();
- // Tapping the drag handle should show the drag handle.
- GetEventGenerator()->GestureTapAt(
- drag_handle->GetBoundsInScreen().CenterPoint());
- EXPECT_TRUE(drag_handle->gesture_nudge_target_visibility());
- // Go into split view mode by first going into overview, and then snapping
- // the open window on one side.
- EnterOverview();
- SplitViewController* split_view_controller =
- SplitViewController::Get(shelf_widget->GetNativeWindow());
- split_view_controller->SnapWindow(window.get(), SplitViewController::LEFT);
- EXPECT_TRUE(split_view_controller->InSplitViewMode());
- // The drag handle nudge should no longer be visible.
- EXPECT_FALSE(drag_handle->gesture_nudge_target_visibility());
- }
- TEST_P(DragHandleContextualNudgeTestA11yPrefs, HideNudgesForShelfControls) {
- SCOPED_TRACE(testing::Message() << "Pref=" << GetParam());
- // Creates a widget to put shelf into in-app state.
- views::Widget* widget = CreateTestWidget();
- widget->Maximize();
- TabletModeControllerTestApi().EnterTabletMode();
- EXPECT_EQ(ShelfBackgroundType::kInApp, GetShelfWidget()->GetBackgroundType());
- // The drag handle should be showing but the nudge should not. A timer to show
- // the nudge should be initialized.
- EXPECT_TRUE(GetShelfWidget()->GetDragHandle()->GetVisible());
- EXPECT_FALSE(
- GetShelfWidget()->GetDragHandle()->gesture_nudge_target_visibility());
- // Firing the timer should show the drag handle nudge.
- GetShelfWidget()->GetDragHandle()->fire_show_drag_handle_timer_for_testing();
- EXPECT_TRUE(GetShelfWidget()->GetDragHandle()->GetVisible());
- EXPECT_TRUE(
- GetShelfWidget()->GetDragHandle()->gesture_nudge_target_visibility());
- // Enabling accessibility auto click disables gestures and enables shelf
- // control buttons. In app to home nudge should be hidden.
- Shell::Get()
- ->session_controller()
- ->GetLastActiveUserPrefService()
- ->SetBoolean(GetParam(), true);
- EXPECT_TRUE(GetShelfWidget()->GetDragHandle()->GetVisible());
- EXPECT_FALSE(
- GetShelfWidget()->GetDragHandle()->gesture_nudge_target_visibility());
- }
- TEST_P(DragHandleContextualNudgeTestA11yPrefs, DisableNudgesForShelfControls) {
- SCOPED_TRACE(testing::Message() << "Pref=" << GetParam());
- // Turn on accessibility settings to enable shelf controls.
- Shell::Get()
- ->session_controller()
- ->GetLastActiveUserPrefService()
- ->SetBoolean(GetParam(), true);
- // Creates a widget to put shelf into in-app state.
- views::Widget* widget = CreateTestWidget();
- widget->Maximize();
- TabletModeControllerTestApi().EnterTabletMode();
- EXPECT_EQ(ShelfBackgroundType::kInApp, GetShelfWidget()->GetBackgroundType());
- // The drag handle should be showing but the nudge should not. A timer to show
- // the nudge should not be initialized because shelf controls are on.
- EXPECT_TRUE(GetShelfWidget()->GetDragHandle()->GetVisible());
- EXPECT_FALSE(
- GetShelfWidget()->GetDragHandle()->gesture_nudge_target_visibility());
- EXPECT_FALSE(GetShelfWidget()
- ->GetDragHandle()
- ->has_show_drag_handle_timer_for_testing());
- }
- } // namespace ash
|