From e2083d770bf0212102ffbbd9ec0e637f88eaef67 Mon Sep 17 00:00:00 2001 From: Toni Barzic Date: Wed, 6 Apr 2022 01:48:27 +0000 Subject: [PATCH] Haptic feedback when dragging apps in launcher and shelf Starting drag in the app list and shelf now fires haptics (tick). Adapts app list and shelf drag tests to also verify haptics are triggered when the drag starts (when dragging items using a mouse pointer). To ease test setup, moves input controller that tracks fired haptics from haptics_util_unittests to a designated file, so it can be reused in other tests. BUG=1312575 Change-Id: I947630cc47ff112699c0a95431e4cccd9b394ce9 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3566798 Reviewed-by: Sammie Quon Reviewed-by: Ahmed Fakhry Commit-Queue: Toni Barzic Cr-Commit-Position: refs/heads/main@{#989234} --- ash/BUILD.gn | 3 + ash/app_list/BUILD.gn | 1 + ash/app_list/views/apps_grid_view.cc | 11 +- ash/app_list/views/apps_grid_view_unittest.cc | 135 ++++++++++++- ash/shelf/shelf_view.cc | 8 + ash/shelf/shelf_view_unittest.cc | 72 ++++++- .../haptics_tracking_test_input_controller.cc | 186 ++++++++++++++++++ .../haptics_tracking_test_input_controller.h | 103 ++++++++++ ash/utility/haptics_util_unittest.cc | 155 +++------------ 9 files changed, 538 insertions(+), 136 deletions(-) create mode 100644 ash/utility/haptics_tracking_test_input_controller.cc create mode 100644 ash/utility/haptics_tracking_test_input_controller.h diff --git a/ash/BUILD.gn b/ash/BUILD.gn index b61ba7da458f11..d8ab807ce0c423 100644 --- a/ash/BUILD.gn +++ b/ash/BUILD.gn @@ -3166,6 +3166,8 @@ static_library("test_support") { "system/geolocation/test_geolocation_url_loader_factory.h", "test/layer_animation_stopped_waiter.cc", "test/layer_animation_stopped_waiter.h", + "utility/haptics_tracking_test_input_controller.cc", + "utility/haptics_tracking_test_input_controller.h", # These headers declare functions that are implemented inside of //ash, so # they cannot live in //ash/public/cpp/BUILD.gn. @@ -3351,6 +3353,7 @@ static_library("test_support") { "//ui/gl:test_support", "//ui/message_center", "//ui/message_center/public/cpp", + "//ui/ozone", "//ui/platform_window/common", "//ui/shell_dialogs", "//ui/views", diff --git a/ash/app_list/BUILD.gn b/ash/app_list/BUILD.gn index 76297aff0dc906..69256092ef368d 100644 --- a/ash/app_list/BUILD.gn +++ b/ash/app_list/BUILD.gn @@ -207,6 +207,7 @@ source_set("app_list") { "//ui/display", "//ui/display/manager", "//ui/events", + "//ui/events/devices", "//ui/gfx", "//ui/gfx/geometry", "//ui/native_theme", diff --git a/ash/app_list/views/apps_grid_view.cc b/ash/app_list/views/apps_grid_view.cc index 788bfb05a66931..f099755cb6d961 100644 --- a/ash/app_list/views/apps_grid_view.cc +++ b/ash/app_list/views/apps_grid_view.cc @@ -37,6 +37,7 @@ #include "ash/public/cpp/app_list/app_list_switches.h" #include "ash/public/cpp/metrics_util.h" #include "ash/strings/grit/ash_strings.h" +#include "ash/utility/haptics_util.h" #include "base/bind.h" #include "base/callback_helpers.h" #include "base/cxx17_backports.h" @@ -54,6 +55,7 @@ #include "ui/compositor/layer.h" #include "ui/display/display.h" #include "ui/display/screen.h" +#include "ui/events/devices/haptic_touchpad_effects.h" #include "ui/events/event.h" #include "ui/gfx/animation/animation.h" #include "ui/gfx/geometry/transform_util.h" @@ -590,9 +592,16 @@ void AppsGridView::TryStartDragAndDropHostDrag(Pointer pointer) { drag_pointer_ = pointer; - if (!dragging_for_reparent_item_) + if (!dragging_for_reparent_item_) { StartDragAndDropHostDrag(); + if (pointer == MOUSE) { + haptics_util::PlayHapticTouchpadEffect( + ui::HapticTouchpadEffect::kTick, + ui::HapticTouchpadEffectStrength::kMedium); + } + } + if (drag_start_callback_) std::move(drag_start_callback_).Run(); } diff --git a/ash/app_list/views/apps_grid_view_unittest.cc b/ash/app_list/views/apps_grid_view_unittest.cc index 67f9cc18116854..9a91b599e95da9 100644 --- a/ash/app_list/views/apps_grid_view_unittest.cc +++ b/ash/app_list/views/apps_grid_view_unittest.cc @@ -55,6 +55,7 @@ #include "ash/shell.h" #include "ash/test/ash_test_base.h" #include "ash/test/layer_animation_stopped_waiter.h" +#include "ash/utility/haptics_tracking_test_input_controller.h" #include "base/run_loop.h" #include "base/strings/string_number_conversions.h" #include "base/strings/utf_string_conversions.h" @@ -280,6 +281,8 @@ class AppsGridViewTest : public AshTestBase { // Make the display big enough to hold the app list. UpdateDisplay("1024x768"); + haptics_tracker_ = std::make_unique(); + // Populate some suggested apps. search_model_ = std::make_unique(); for (size_t i = 0; i < kNumOfSuggestedApps; ++i) { @@ -343,6 +346,7 @@ class AppsGridViewTest : public AshTestBase { page_flip_waiter_.reset(); ui::PresentationTimeRecorder::SetReportPresentationTimeImmediatelyForTest( false); + haptics_tracker_.reset(); AshTestBase::TearDown(); } @@ -596,7 +600,8 @@ class AppsGridViewTest : public AshTestBase { (root_to.y() - current_drag_location_->y()) * step / steps); ui::MouseEvent drag_event(ui::ET_MOUSE_DRAGGED, to, drag_increment_point, ui::EventTimeForNow(), 0, 0); - apps_grid_view->UpdateDragFromItem(pointer, drag_event); + apps_grid_view->UpdateDragFromItem( + /*is_touch=*/pointer == AppsGridView::TOUCH, drag_event); } current_drag_location_ = root_to; @@ -637,7 +642,7 @@ class AppsGridViewTest : public AshTestBase { GetPaginationModel(), base::BindLambdaForTesting([&]() { ui::MouseEvent drag_event(ui::ET_MOUSE_DRAGGED, to, root_to, ui::EventTimeForNow(), 0, 0); - paged_apps_grid_view_->UpdateDragFromItem(AppsGridView::MOUSE, + paged_apps_grid_view_->UpdateDragFromItem(/*is_touch=*/false, drag_event); })); page_flip_waiter_->Reset(); @@ -660,6 +665,12 @@ class AppsGridViewTest : public AshTestBase { : "Apps.AppListBubbleAppMovingType"; } + int GetHapticTickEventsCount() const { + return haptics_tracker_->GetSentHapticCount( + ui::HapticTouchpadEffect::kTick, + ui::HapticTouchpadEffectStrength::kMedium); + } + // May be a PagedAppsGridView or a ScrollableAppsGridView depending on the // ProductivityLauncher flag and tablet mode. AppsGridView* apps_grid_view_ = nullptr; @@ -698,6 +709,9 @@ class AppsGridViewTest : public AshTestBase { base::test::ScopedFeatureList feature_list_; absl::optional current_drag_location_; + + // Used to track haptics events sent during drag. + std::unique_ptr haptics_tracker_; }; // Tests that only run with ProductivityLauncher disabled, which disables the @@ -1436,12 +1450,14 @@ TEST_P(AppsGridViewDragTest, DismissWhileDraggingDoesNotCrash) { GetEventGenerator()->PressLeftButton(); item_view->FireMouseDragTimerForTest(); GetEventGenerator()->MoveMouseBy(20, 20); + EXPECT_EQ(1, GetHapticTickEventsCount()); ASSERT_TRUE(apps_grid_view_->drag_item()); ASSERT_TRUE(apps_grid_view_->IsDragging()); ASSERT_EQ(item_view->item(), apps_grid_view_->drag_item()); GetAppListTestHelper()->Dismiss(); + EXPECT_EQ(1, GetHapticTickEventsCount()); // No crash } @@ -1464,12 +1480,14 @@ TEST_P(AppsGridViewDragTest, DismissWhileDraggingInFolderDoesNotCrash) { GetEventGenerator()->PressLeftButton(); item_view->FireMouseDragTimerForTest(); GetEventGenerator()->MoveMouseBy(20, 20); + EXPECT_EQ(1, GetHapticTickEventsCount()); ASSERT_TRUE(folder_apps_grid_view()->drag_item()); ASSERT_TRUE(folder_apps_grid_view()->IsDragging()); ASSERT_EQ(item_view->item(), folder_apps_grid_view()->drag_item()); GetAppListTestHelper()->Dismiss(); + EXPECT_EQ(1, GetHapticTickEventsCount()); // No crash } @@ -1479,6 +1497,7 @@ TEST_P(AppsGridViewDragTest, ItemViewsHaveLayerDuringDrag) { UpdateLayout(); InitiateDragForItemAtCurrentPageAt(AppsGridView::MOUSE, 0, 1, apps_grid_view_); + EXPECT_EQ(1, GetHapticTickEventsCount()); // Dragging item_1 over item_0 creates a folder. gfx::Point to = GetItemRectOnCurrentPageAt(0, 0).CenterPoint(); @@ -1489,6 +1508,7 @@ TEST_P(AppsGridViewDragTest, ItemViewsHaveLayerDuringDrag) { EXPECT_TRUE(GetItemViewInTopLevelGrid(i)->layer()); EndDrag(apps_grid_view_, false /*cancel*/); + EXPECT_EQ(1, GetHapticTickEventsCount()); } TEST_P(AppsGridViewDragTest, ItemViewsDontHaveLayerAfterDrag) { @@ -1497,12 +1517,14 @@ TEST_P(AppsGridViewDragTest, ItemViewsDontHaveLayerAfterDrag) { UpdateLayout(); InitiateDragForItemAtCurrentPageAt(AppsGridView::MOUSE, 0, 1, apps_grid_view_); + EXPECT_EQ(1, GetHapticTickEventsCount()); // Dragging item_1 over item_0 creates a folder. gfx::Point to = GetItemRectOnCurrentPageAt(0, 0).CenterPoint(); UpdateDrag(AppsGridView::MOUSE, to, apps_grid_view_, 10 /*steps*/); EndDrag(apps_grid_view_, false /*cancel*/); test_api_->WaitForItemMoveAnimationDone(); + EXPECT_EQ(1, GetHapticTickEventsCount()); // The layer should be destroyed after the dragging. for (size_t i = 0; i < model_->top_level_item_list()->item_count(); ++i) @@ -1515,6 +1537,7 @@ TEST_P(AppsGridViewDragTest, MouseDragItemIntoFolder) { UpdateLayout(); InitiateDragForItemAtCurrentPageAt(AppsGridView::MOUSE, 0, 1, apps_grid_view_); + EXPECT_EQ(1, GetHapticTickEventsCount()); // Dragging item_1 over item_0 creates a folder. gfx::Point to = GetItemRectOnCurrentPageAt(0, 0).CenterPoint(); @@ -1546,6 +1569,7 @@ TEST_P(AppsGridViewDragTest, MouseDragItemIntoFolder) { ->GetFolderNameViewForTest() ->HasFocus()); } + EXPECT_EQ(1, GetHapticTickEventsCount()); } TEST_P(AppsGridViewDragTest, MouseDragSecondItemIntoFolder) { @@ -1554,6 +1578,7 @@ TEST_P(AppsGridViewDragTest, MouseDragSecondItemIntoFolder) { UpdateLayout(); InitiateDragForItemAtCurrentPageAt(AppsGridView::MOUSE, 0, 1, apps_grid_view_); + EXPECT_EQ(1, GetHapticTickEventsCount()); // Dragging item_2 to the folder adds Item_2 to the folder. gfx::Point to = GetItemRectOnCurrentPageAt(0, 0).CenterPoint(); @@ -1575,6 +1600,8 @@ TEST_P(AppsGridViewDragTest, MouseDragSecondItemIntoFolder) { EXPECT_TRUE(item_2->IsInFolder()); EXPECT_EQ(folder_item->id(), item_2->folder_id()); EXPECT_FALSE(GetAppListTestHelper()->IsInFolderView()); + + EXPECT_EQ(1, GetHapticTickEventsCount()); } TEST_P(AppsGridViewDragTest, DragIconAnimatesAfterDragToFolder) { @@ -1587,6 +1614,7 @@ TEST_P(AppsGridViewDragTest, DragIconAnimatesAfterDragToFolder) { InitiateDragForItemAtCurrentPageAt(AppsGridView::MOUSE, 0, 1, apps_grid_view_); + EXPECT_EQ(1, GetHapticTickEventsCount()); // Dragging item_2 to the folder adds Item_2 to the folder. gfx::Point to = GetItemRectOnCurrentPageAt(0, 0).CenterPoint(); @@ -1601,6 +1629,7 @@ TEST_P(AppsGridViewDragTest, DragIconAnimatesAfterDragToFolder) { LayerAnimationStoppedWaiter animation_waiter; animation_waiter.Wait(drag_icon_layer); EXPECT_FALSE(GetAppListTestHelper()->IsInFolderView()); + EXPECT_EQ(1, GetHapticTickEventsCount()); } TEST_P(AppsGridViewDragTest, DragIconHiddenImmediatelyWhenGridHides) { @@ -1613,6 +1642,7 @@ TEST_P(AppsGridViewDragTest, DragIconHiddenImmediatelyWhenGridHides) { InitiateDragForItemAtCurrentPageAt(AppsGridView::MOUSE, 0, 1, apps_grid_view_); + EXPECT_EQ(1, GetHapticTickEventsCount()); // Dragging item_2 to the folder adds Item_2 to the folder. gfx::Point to = GetItemRectOnCurrentPageAt(0, 0).CenterPoint(); @@ -1638,6 +1668,7 @@ TEST_P(AppsGridViewDragTest, DragIconHiddenImmediatelyWhenGridHides) { EXPECT_FALSE(test_api_->GetDragIconLayer()); EXPECT_FALSE(apps_grid_view_->drag_item()); EXPECT_FALSE(apps_grid_view_->IsDragging()); + EXPECT_EQ(1, GetHapticTickEventsCount()); } TEST_P(AppsGridViewDragTest, DragIconAnimatesAfterDragToCreateFolder) { @@ -1649,6 +1680,7 @@ TEST_P(AppsGridViewDragTest, DragIconAnimatesAfterDragToCreateFolder) { InitiateDragForItemAtCurrentPageAt(AppsGridView::MOUSE, 0, 1, apps_grid_view_); + EXPECT_EQ(1, GetHapticTickEventsCount()); // Dragging item_1 over item_0 creates a folder. gfx::Point to = GetItemRectOnCurrentPageAt(0, 0).CenterPoint(); @@ -1664,6 +1696,7 @@ TEST_P(AppsGridViewDragTest, DragIconAnimatesAfterDragToCreateFolder) { animation_waiter.Wait(drag_icon_layer); EXPECT_EQ(is_productivity_launcher_enabled_, GetAppListTestHelper()->IsInFolderView()); + EXPECT_EQ(1, GetHapticTickEventsCount()); } TEST_P(AppsGridViewDragTest, FolderNotOpenedIfGridHidesDuringIconDrop) { @@ -1675,6 +1708,7 @@ TEST_P(AppsGridViewDragTest, FolderNotOpenedIfGridHidesDuringIconDrop) { InitiateDragForItemAtCurrentPageAt(AppsGridView::MOUSE, 0, 1, apps_grid_view_); + EXPECT_EQ(1, GetHapticTickEventsCount()); // Dragging item_1 over Item_0 creates a folder. gfx::Point to = GetItemRectOnCurrentPageAt(0, 0).CenterPoint(); @@ -1705,6 +1739,7 @@ TEST_P(AppsGridViewDragTest, FolderNotOpenedIfGridHidesDuringIconDrop) { EXPECT_FALSE(test_api_->GetDragIconLayer()); EXPECT_FALSE(helper->IsInFolderView()); + EXPECT_EQ(1, GetHapticTickEventsCount()); } TEST_P(AppsGridViewClamshellTest, CheckFolderWithMultiplePagesContents) { @@ -1742,6 +1777,7 @@ TEST_P(AppsGridViewDragTest, MouseDragItemOutOfFolder) { // Drag the first folder child out of the folder. AppListItemView* drag_view = InitiateDragForItemAtCurrentPageAt( AppsGridView::MOUSE, 0, 0, folder_apps_grid_view()); + EXPECT_EQ(1, GetHapticTickEventsCount()); gfx::Point empty_space = app_list_folder_view()->GetLocalBounds().bottom_center() + gfx::Vector2d(0, drag_view->height() @@ -1760,6 +1796,7 @@ TEST_P(AppsGridViewDragTest, MouseDragItemOutOfFolder) { UpdateDrag(AppsGridView::MOUSE, drop_point, folder_apps_grid_view(), 5 /*steps*/); EndDrag(folder_apps_grid_view(), false /*cancel*/); + EXPECT_EQ(1, GetHapticTickEventsCount()); AppListItem* item_0 = model_->FindItem("Item 0"); AppListItem* item_1 = model_->FindItem("Item 1"); @@ -1783,6 +1820,7 @@ TEST_P(AppsGridViewDragTest, DragIconAnimatesAfterDragOutOfFolder) { // Drag the first folder child out of the folder. AppListItemView* drag_view = InitiateDragForItemAtCurrentPageAt( AppsGridView::MOUSE, 0, 0, folder_apps_grid_view()); + EXPECT_EQ(1, GetHapticTickEventsCount()); gfx::Point empty_space = app_list_folder_view()->GetLocalBounds().bottom_center() + gfx::Vector2d(0, drag_view->height() @@ -1801,6 +1839,7 @@ TEST_P(AppsGridViewDragTest, DragIconAnimatesAfterDragOutOfFolder) { UpdateDrag(AppsGridView::MOUSE, drop_point, folder_apps_grid_view(), 5 /*steps*/); EndDrag(folder_apps_grid_view(), false /*cancel*/); + EXPECT_EQ(1, GetHapticTickEventsCount()); ui::Layer* drag_icon_layer = test_api_->GetDragIconLayer(); ASSERT_TRUE(drag_icon_layer); @@ -1819,6 +1858,7 @@ TEST_P(AppsGridViewDragTest, DragIconAnimatesAfterDragToAnotherFolder) { // Drag the first folder child out of the folder. AppListItemView* drag_view = InitiateDragForItemAtCurrentPageAt( AppsGridView::MOUSE, 0, 0, folder_apps_grid_view()); + EXPECT_EQ(1, GetHapticTickEventsCount()); gfx::Point empty_space = app_list_folder_view()->GetLocalBounds().bottom_center() + gfx::Vector2d(0, drag_view->height() @@ -1836,6 +1876,7 @@ TEST_P(AppsGridViewDragTest, DragIconAnimatesAfterDragToAnotherFolder) { UpdateDrag(AppsGridView::MOUSE, drop_point, folder_apps_grid_view(), 5 /*steps*/); EndDrag(folder_apps_grid_view(), false /*cancel*/); + EXPECT_EQ(1, GetHapticTickEventsCount()); ui::Layer* drag_icon_layer = test_api_->GetDragIconLayer(); ASSERT_TRUE(drag_icon_layer); @@ -1860,6 +1901,7 @@ TEST_P(AppsGridViewDragTest, // Drag the only folder child out of the folder. AppListItemView* drag_view = InitiateDragForItemAtCurrentPageAt( AppsGridView::MOUSE, 0, 0, folder_apps_grid_view()); + EXPECT_EQ(1, GetHapticTickEventsCount()); gfx::Point empty_space = app_list_folder_view()->GetLocalBounds().bottom_center() + gfx::Vector2d(0, drag_view->height() @@ -1878,6 +1920,7 @@ TEST_P(AppsGridViewDragTest, UpdateDrag(AppsGridView::MOUSE, drop_point, folder_apps_grid_view(), 5 /*steps*/); EndDrag(folder_apps_grid_view(), false /*cancel*/); + EXPECT_EQ(1, GetHapticTickEventsCount()); ui::Layer* drag_icon_layer = test_api_->GetDragIconLayer(); ASSERT_TRUE(drag_icon_layer); @@ -1894,9 +1937,11 @@ TEST_P(AppsGridViewDragTest, DragIconAnimatesAfterReorderDrag) { // Drag the first item to an empty slot in the grid. InitiateDragForItemAtCurrentPageAt(AppsGridView::MOUSE, 0, 0, apps_grid_view_); + EXPECT_EQ(1, GetHapticTickEventsCount()); gfx::Point drop_point = GetItemRectOnCurrentPageAt(0, 3).CenterPoint(); UpdateDrag(AppsGridView::MOUSE, drop_point, apps_grid_view_, 5 /*steps*/); EndDrag(apps_grid_view_, false /*cancel*/); + EXPECT_EQ(1, GetHapticTickEventsCount()); ui::Layer* drag_icon_layer = test_api_->GetDragIconLayer(); ASSERT_TRUE(drag_icon_layer); @@ -1937,6 +1982,7 @@ TEST_P(AppsGridViewDragNonBubbleTest, MouseDragItemOutOfFolderSecondPage) { // Drag the first folder child on the second page out of the folder. AppListItemView* drag_view = InitiateDragForItemAtCurrentPageAt( AppsGridView::MOUSE, 0, 0, folder_apps_grid_view()); + EXPECT_EQ(1, GetHapticTickEventsCount()); // Calculate the target destination for our drag and update the drag to that // location. gfx::Point empty_space = @@ -1959,6 +2005,7 @@ TEST_P(AppsGridViewDragNonBubbleTest, MouseDragItemOutOfFolderSecondPage) { // End the drag and assert that the item has been dragged out of the folder // and the app list's grid view has been updated accordingly. EndDrag(folder_apps_grid_view(), false /*cancel*/); + EXPECT_EQ(1, GetHapticTickEventsCount()); AppListItem* item_0 = model_->FindItem("Item 0"); AppListItem* item_16 = model_->FindItem("Item 16"); @@ -1994,6 +2041,7 @@ TEST_P(AppsGridViewDragNonBubbleTest, MouseDropItemFromFolderSecondPage) { // Drag the first folder child on the second page out of the folder. AppListItemView* drag_view = InitiateDragForItemAtCurrentPageAt( AppsGridView::MOUSE, 0, 0, folder_apps_grid_view()); + EXPECT_EQ(1, GetHapticTickEventsCount()); // Calculate the target destination for our drag and update the drag to that // location. gfx::Point empty_space = @@ -2019,6 +2067,7 @@ TEST_P(AppsGridViewDragNonBubbleTest, MouseDropItemFromFolderSecondPage) { // End the drag and assert that the item has been dragged out of the folder // and the app list's grid view has been updated accordingly. EndDrag(folder_apps_grid_view(), false /*cancel*/); + EXPECT_EQ(1, GetHapticTickEventsCount()); AppListItem* item_0 = model_->FindItem("Item 0"); AppListItem* item_16 = model_->FindItem("Item 16"); @@ -2045,12 +2094,14 @@ TEST_P(AppsGridViewDragTest, MouseDragMaxItemsInFolder) { UpdateLayout(); InitiateDragForItemAtCurrentPageAt(AppsGridView::MOUSE, 0, 1, apps_grid_view_); + EXPECT_EQ(1, GetHapticTickEventsCount()); // Dragging one item into the folder, the folder should accept the item. gfx::Point to = GetItemRectOnCurrentPageAt(0, 0).CenterPoint(); UpdateDrag(AppsGridView::MOUSE, to, apps_grid_view_, 10 /*steps*/); EndDrag(apps_grid_view_, false /*cancel*/); test_api_->LayoutToIdealBounds(); + EXPECT_EQ(1, GetHapticTickEventsCount()); EXPECT_EQ(1u, model_->top_level_item_list()->item_count()); EXPECT_EQ(folder_item->id(), model_->top_level_item_list()->item_at(0)->id()); @@ -2069,6 +2120,7 @@ TEST_P(AppsGridViewDragTest, MouseDragExceedMaxItemsInFolder) { model_->PopulateAppWithId(kMaxItemsInFolder + 1); InitiateDragForItemAtCurrentPageAt(AppsGridView::MOUSE, 0, 1, apps_grid_view_); + EXPECT_EQ(1, GetHapticTickEventsCount()); // Dragging the last item over the folder, the folder won't accept the new // item. @@ -2076,6 +2128,7 @@ TEST_P(AppsGridViewDragTest, MouseDragExceedMaxItemsInFolder) { UpdateDrag(AppsGridView::MOUSE, to, apps_grid_view_, 10 /*steps*/); EndDrag(apps_grid_view_, false /*cancel*/); test_api_->LayoutToIdealBounds(); + EXPECT_EQ(1, GetHapticTickEventsCount()); EXPECT_EQ(2u, model_->top_level_item_list()->item_count()); EXPECT_EQ(kMaxItemsInFolder, folder_item->ChildItemCount()); @@ -2093,6 +2146,7 @@ TEST_P(AppsGridViewDragTest, MouseDragMovement) { // Drag the new item to the left so that the grid reorders. InitiateDragForItemAtCurrentPageAt(AppsGridView::MOUSE, 0, 1, apps_grid_view_); + EXPECT_EQ(1, GetHapticTickEventsCount()); gfx::Point to = GetItemRectOnCurrentPageAt(0, 0).bottom_left(); to.Offset(0, -1); // Get a point inside the rect. @@ -2106,6 +2160,7 @@ TEST_P(AppsGridViewDragTest, MouseDragMovement) { GetItemRectOnCurrentPageAt(0, 1).CenterPoint())); EndDrag(apps_grid_view_, false /*cancel*/); + EXPECT_EQ(1, GetHapticTickEventsCount()); } // Check that moving items around doesn't allow a drop to happen into a full @@ -2120,6 +2175,7 @@ TEST_P(AppsGridViewDragTest, MouseDragMaxItemsInFolderWithMovement) { // Drag the new item to the left so that the grid reorders. AppListItemView* dragged_view = InitiateDragForItemAtCurrentPageAt( AppsGridView::MOUSE, 0, 1, apps_grid_view_); + EXPECT_EQ(1, GetHapticTickEventsCount()); gfx::Point to = GetItemRectOnCurrentPageAt(0, 0).bottom_left(); to.Offset(0, -1); // Get a point inside the rect. @@ -2130,8 +2186,9 @@ TEST_P(AppsGridViewDragTest, MouseDragMaxItemsInFolderWithMovement) { folder_in_second_slot - dragged_view->origin()); ui::MouseEvent drag_event(ui::ET_MOUSE_DRAGGED, translated_destination, folder_in_second_slot, ui::EventTimeForNow(), 0, 0); - apps_grid_view_->UpdateDragFromItem(AppsGridView::MOUSE, drag_event); + apps_grid_view_->UpdateDragFromItem(/*is_touch=*/false, drag_event); EndDrag(apps_grid_view_, false /*cancel*/); + EXPECT_EQ(1, GetHapticTickEventsCount()); // The item should not have moved into the folder. EXPECT_EQ(2u, model_->top_level_item_list()->item_count()); @@ -2146,6 +2203,7 @@ TEST_P(AppsGridViewDragTest, MouseDragItemReorderBeforeFolderDropPoint) { UpdateLayout(); InitiateDragForItemAtCurrentPageAt(AppsGridView::MOUSE, 0, 1, apps_grid_view_); + EXPECT_EQ(1, GetHapticTickEventsCount()); gfx::Point to = GetItemRectOnCurrentPageAt(0, 1).CenterPoint(); int half_tile_width = std::abs(GetItemRectOnCurrentPageAt(0, 1).x() - @@ -2160,6 +2218,7 @@ TEST_P(AppsGridViewDragTest, MouseDragItemReorderBeforeFolderDropPoint) { UpdateDrag(AppsGridView::MOUSE, to + drag_vector, apps_grid_view_, 10 /*steps*/); EndDrag(apps_grid_view_, false /*cancel*/); + EXPECT_EQ(1, GetHapticTickEventsCount()); EXPECT_EQ(std::string("Item 0,Item 1"), model_->GetModelContent()); TestAppListItemViewIndice(); @@ -2170,6 +2229,7 @@ TEST_P(AppsGridViewDragTest, MouseDragItemReorderAfterFolderDropPoint) { UpdateLayout(); InitiateDragForItemAtCurrentPageAt(AppsGridView::MOUSE, 0, 1, apps_grid_view_); + EXPECT_EQ(1, GetHapticTickEventsCount()); gfx::Point to = GetItemRectOnCurrentPageAt(0, 1).CenterPoint(); int half_tile_width = std::abs(GetItemRectOnCurrentPageAt(0, 1).x() - @@ -2187,6 +2247,7 @@ TEST_P(AppsGridViewDragTest, MouseDragItemReorderAfterFolderDropPoint) { UpdateDrag(AppsGridView::MOUSE, to + drag_vector, apps_grid_view_, 10 /*steps*/); EndDrag(apps_grid_view_, false /*cancel*/); + EXPECT_EQ(1, GetHapticTickEventsCount()); EXPECT_EQ(std::string("Item 1,Item 0"), model_->GetModelContent()); TestAppListItemViewIndice(); @@ -2199,6 +2260,7 @@ TEST_P(AppsGridViewDragTest, MouseDragItemReorderDragDownOneRow) { UpdateLayout(); InitiateDragForItemAtCurrentPageAt(AppsGridView::MOUSE, 0, 1, apps_grid_view_); + EXPECT_EQ(1, GetHapticTickEventsCount()); gfx::Point to = GetItemRectOnCurrentPageAt(0, 1).CenterPoint(); int half_tile_width = std::abs(GetItemRectOnCurrentPageAt(0, 1).x() - @@ -2216,6 +2278,7 @@ TEST_P(AppsGridViewDragTest, MouseDragItemReorderDragDownOneRow) { UpdateDrag(AppsGridView::MOUSE, to + drag_vector, apps_grid_view_, 10 /*steps*/); EndDrag(apps_grid_view_, false /*cancel*/); + EXPECT_EQ(1, GetHapticTickEventsCount()); EXPECT_EQ(std::string("Item 0,Item 2,Item 3,Item 4,Item 5,Item 1,Item 6"), model_->GetModelContent()); @@ -2229,6 +2292,7 @@ TEST_P(AppsGridViewDragTest, MouseDragItemReorderDragUpOneRow) { UpdateLayout(); InitiateDragForItemAtCurrentPageAt(AppsGridView::MOUSE, 1, 0, apps_grid_view_); + EXPECT_EQ(1, GetHapticTickEventsCount()); gfx::Point to = GetItemRectOnCurrentPageAt(1, 0).CenterPoint(); int half_tile_width = std::abs(GetItemRectOnCurrentPageAt(0, 1).x() - @@ -2247,6 +2311,7 @@ TEST_P(AppsGridViewDragTest, MouseDragItemReorderDragUpOneRow) { 10 /*steps*/); EndDrag(apps_grid_view_, false /*cancel*/); test_api_->LayoutToIdealBounds(); + EXPECT_EQ(1, GetHapticTickEventsCount()); EXPECT_EQ(std::string("Item 0,Item 5,Item 1,Item 2,Item 3,Item 4,Item 6"), model_->GetModelContent()); @@ -2260,6 +2325,7 @@ TEST_P(AppsGridViewDragTest, MouseDragItemReorderDragPastLastApp) { UpdateLayout(); InitiateDragForItemAtCurrentPageAt(AppsGridView::MOUSE, 0, 1, apps_grid_view_); + EXPECT_EQ(1, GetHapticTickEventsCount()); gfx::Point to = GetItemRectOnCurrentPageAt(0, 1).CenterPoint(); int half_tile_width = std::abs(GetItemRectOnCurrentPageAt(0, 1).x() - @@ -2277,6 +2343,7 @@ TEST_P(AppsGridViewDragTest, MouseDragItemReorderDragPastLastApp) { UpdateDrag(AppsGridView::MOUSE, to + drag_vector, apps_grid_view_, 10 /*steps*/); EndDrag(apps_grid_view_, false /*cancel*/); + EXPECT_EQ(1, GetHapticTickEventsCount()); EXPECT_EQ(std::string("Item 0,Item 2,Item 3,Item 4,Item 5,Item 6,Item 1"), model_->GetModelContent()); @@ -2291,11 +2358,13 @@ TEST_P(AppsGridViewDragTest, MouseDragFolderOverItemReorder) { model_->PopulateAppWithId(kTotalItems); InitiateDragForItemAtCurrentPageAt(AppsGridView::MOUSE, 0, 0, apps_grid_view_); + EXPECT_EQ(1, GetHapticTickEventsCount()); gfx::Point to = GetItemRectOnCurrentPageAt(0, 1).CenterPoint(); UpdateDrag(AppsGridView::MOUSE, to, apps_grid_view_); EndDrag(apps_grid_view_, false /*cancel*/); test_api_->LayoutToIdealBounds(); + EXPECT_EQ(1, GetHapticTickEventsCount()); EXPECT_EQ(2u, model_->top_level_item_list()->item_count()); EXPECT_EQ("Item 2", model_->top_level_item_list()->item_at(0)->id()); @@ -2309,10 +2378,12 @@ TEST_P(AppsGridViewDragTest, MouseDragWithCancelKeepsOrder) { model_->PopulateApps(kTotalItems); InitiateDragForItemAtCurrentPageAt(AppsGridView::MOUSE, 0, 0, apps_grid_view_); + EXPECT_EQ(1, GetHapticTickEventsCount()); gfx::Point to = GetItemRectOnCurrentPageAt(0, 1).CenterPoint(); UpdateDrag(AppsGridView::MOUSE, to, apps_grid_view_, 10 /*steps*/); EndDrag(apps_grid_view_, true /*cancel*/); + EXPECT_EQ(1, GetHapticTickEventsCount()); EXPECT_EQ(std::string("Item 0,Item 1"), model_->GetModelContent()); test_api_->LayoutToIdealBounds(); @@ -2324,11 +2395,13 @@ TEST_P(AppsGridViewDragTest, MouseDragWithDeleteItemKeepsOrder) { model_->PopulateApps(kTotalItems); InitiateDragForItemAtCurrentPageAt(AppsGridView::MOUSE, 0, 0, apps_grid_view_); + EXPECT_EQ(1, GetHapticTickEventsCount()); gfx::Point to = GetItemRectOnCurrentPageAt(0, 1).CenterPoint(); UpdateDrag(AppsGridView::MOUSE, to, apps_grid_view_, 10 /*steps*/); model_->DeleteItem(model_->GetItemName(2)); EndDrag(apps_grid_view_, false /*cancel*/); + EXPECT_EQ(1, GetHapticTickEventsCount()); EXPECT_EQ(std::string("Item 0,Item 1"), model_->GetModelContent()); test_api_->LayoutToIdealBounds(); @@ -2340,11 +2413,13 @@ TEST_P(AppsGridViewDragTest, MouseDragWithAddItemKeepsOrder) { model_->PopulateApps(kTotalItems); InitiateDragForItemAtCurrentPageAt(AppsGridView::MOUSE, 0, 0, apps_grid_view_); + EXPECT_EQ(1, GetHapticTickEventsCount()); gfx::Point to = GetItemRectOnCurrentPageAt(0, 1).CenterPoint(); UpdateDrag(AppsGridView::MOUSE, to, apps_grid_view_, 10 /*steps*/); model_->CreateAndAddItem("Extra"); EndDrag(apps_grid_view_, false /*cancel*/); + EXPECT_EQ(1, GetHapticTickEventsCount()); EXPECT_EQ(std::string("Item 0,Item 1,Extra"), model_->GetModelContent()); test_api_->LayoutToIdealBounds(); @@ -3303,6 +3378,7 @@ TEST_P(AppsGridViewTabletTest, TouchDragFlipToNextPage) { page_flip_waiter_->Reset(); InitiateDragForItemAtCurrentPageAt(AppsGridView::TOUCH, 0, 0, paged_apps_grid_view_); + EXPECT_EQ(0, GetHapticTickEventsCount()); gfx::Point apps_grid_bottom_center = gfx::Point(apps_grid_bounds.width() / 2, apps_grid_bounds.bottom() - 1); UpdateDrag(AppsGridView::TOUCH, apps_grid_bottom_center, @@ -3329,6 +3405,7 @@ TEST_P(AppsGridViewTabletTest, TouchDragFlipToNextPage) { // End the drag to satisfy checks in AppsGridView destructor. EndDrag(apps_grid_view_, /*cancel=*/true); + EXPECT_EQ(0, GetHapticTickEventsCount()); } TEST_P(AppsGridViewTabletTest, DragAcrossPagesToTheLastSlot) { @@ -3354,6 +3431,7 @@ TEST_P(AppsGridViewTabletTest, DragAcrossPagesToTheLastSlot) { generator->PressLeftButton(); dragged_view->FireMouseDragTimerForTest(); generator->MoveMouseBy(10, 10); + EXPECT_EQ(1, GetHapticTickEventsCount()); // Drag the item to launcher page flip zone, and flip the launcher to the // second page. @@ -3413,6 +3491,7 @@ TEST_P(AppsGridViewTabletTest, DragAcrossPagesToTheLastSlot) { } EndDrag(paged_apps_grid_view_, false); + EXPECT_EQ(1, GetHapticTickEventsCount()); EXPECT_EQ(1, GetPaginationModel()->selected_page()); EXPECT_EQ(2, GetPaginationModel()->total_pages()); @@ -3458,6 +3537,7 @@ TEST_P(AppsGridViewTabletTest, DragAcrossPagesToSecondToLastSlot) { generator->PressLeftButton(); dragged_view->FireMouseDragTimerForTest(); generator->MoveMouseBy(10, 10); + EXPECT_EQ(1, GetHapticTickEventsCount()); // Drag the item to launcher page flip zone, and flip the launcher to the // second page. @@ -3540,6 +3620,7 @@ TEST_P(AppsGridViewTabletTest, DragAcrossPagesToSecondToLastSlot) { } generator->ReleaseLeftButton(); + EXPECT_EQ(1, GetHapticTickEventsCount()); EXPECT_EQ(1, GetPaginationModel()->selected_page()); EXPECT_EQ(2, GetPaginationModel()->total_pages()); @@ -3652,6 +3733,7 @@ TEST_P(AppsGridViewTabletTest, TouchDragFlipToPreviousPage) { page_flip_waiter_->Reset(); InitiateDragForItemAtCurrentPageAt(AppsGridView::TOUCH, 0, 0, paged_apps_grid_view_); + EXPECT_EQ(0, GetHapticTickEventsCount()); gfx::Point apps_grid_top_center( paged_apps_grid_view_->GetLocalBounds().width() / 2, 0); UpdateDrag(AppsGridView::TOUCH, apps_grid_top_center, paged_apps_grid_view_, @@ -3671,6 +3753,7 @@ TEST_P(AppsGridViewTabletTest, TouchDragFlipToPreviousPage) { // End the drag to satisfy checks in AppsGridView destructor. EndDrag(paged_apps_grid_view_, /*cancel=*/true); + EXPECT_EQ(0, GetHapticTickEventsCount()); } TEST_P(AppsGridViewDragTest, CancelDragDoesNotReorderItems) { @@ -3682,9 +3765,11 @@ TEST_P(AppsGridViewDragTest, CancelDragDoesNotReorderItems) { // Starts a mouse drag and then cancels it. InitiateDragForItemAtCurrentPageAt(AppsGridView::MOUSE, 0, 0, apps_grid_view_); + EXPECT_EQ(1, GetHapticTickEventsCount()); const gfx::Point to = GetItemRectOnCurrentPageAt(0, 2).CenterPoint(); UpdateDrag(AppsGridView::MOUSE, to, apps_grid_view_); EndDrag(apps_grid_view_, /*cancel=*/true); + EXPECT_EQ(1, GetHapticTickEventsCount()); // Model is not changed. EXPECT_EQ(std::string("Item 0,Item 1,Item 2,Item 3"), @@ -3863,6 +3948,7 @@ TEST_P(AppsGridViewDragTest, DragAndPinItemToShelf) { generator->PressLeftButton(); item_view->FireMouseDragTimerForTest(); generator->MoveMouseBy(10, 10); + EXPECT_EQ(1, GetHapticTickEventsCount()); // Verify that item drag has started. ASSERT_TRUE(apps_grid_view_->drag_item()); @@ -3880,6 +3966,7 @@ TEST_P(AppsGridViewDragTest, DragAndPinItemToShelf) { generator->ReleaseLeftButton(); EXPECT_TRUE(ShelfModel::Get()->IsAppPinned("Item 1")); EXPECT_EQ("Item 1", ShelfModel::Get()->items()[0].id.app_id); + EXPECT_EQ(1, GetHapticTickEventsCount()); } TEST_P(AppsGridViewDragTest, DragAndPinNotInitiallyVisibleItemToShelf) { @@ -3905,6 +3992,7 @@ TEST_P(AppsGridViewDragTest, DragAndPinNotInitiallyVisibleItemToShelf) { generator->PressLeftButton(); item_view->FireMouseDragTimerForTest(); generator->MoveMouseBy(10, 10); + EXPECT_EQ(1, GetHapticTickEventsCount()); // Verify app list item drag has started. ASSERT_TRUE(apps_grid_view_->drag_item()); @@ -3920,6 +4008,7 @@ TEST_P(AppsGridViewDragTest, DragAndPinNotInitiallyVisibleItemToShelf) { // Releasing drag over shelf should pin the dragged app. generator->ReleaseLeftButton(); + EXPECT_EQ(1, GetHapticTickEventsCount()); EXPECT_TRUE(ShelfModel::Get()->IsAppPinned("Item 40")); EXPECT_EQ("Item 40", ShelfModel::Get()->items()[0].id.app_id); } @@ -3935,6 +4024,7 @@ TEST_P(AppsGridViewDragTest, DragItemToAndFromShelf) { generator->PressLeftButton(); item_view->FireMouseDragTimerForTest(); generator->MoveMouseBy(10, 10); + EXPECT_EQ(1, GetHapticTickEventsCount()); // Verify app list item drag has started. ASSERT_TRUE(apps_grid_view_->drag_item()); @@ -3951,6 +4041,7 @@ TEST_P(AppsGridViewDragTest, DragItemToAndFromShelf) { // the drag ends. generator->MoveMouseTo(apps_grid_view_->GetBoundsInScreen().origin()); generator->ReleaseLeftButton(); + EXPECT_EQ(1, GetHapticTickEventsCount()); EXPECT_FALSE(ShelfModel::Get()->IsAppPinned("Item 1")); EXPECT_TRUE(ShelfModel::Get()->items().empty()); @@ -3974,6 +4065,7 @@ TEST_P(AppsGridViewDragTest, DragAndPinItemFromFolderToShelf) { generator->PressLeftButton(); item_view->FireMouseDragTimerForTest(); generator->MoveMouseBy(10, 10); + EXPECT_EQ(1, GetHapticTickEventsCount()); // Verify app list item drag has started. ASSERT_TRUE(folder_apps_grid_view()->drag_item()); @@ -3997,6 +4089,7 @@ TEST_P(AppsGridViewDragTest, DragAndPinItemFromFolderToShelf) { // Releasing drag over shelf should pin the dragged app. generator->ReleaseLeftButton(); + EXPECT_EQ(1, GetHapticTickEventsCount()); EXPECT_TRUE(ShelfModel::Get()->IsAppPinned("Item 1")); EXPECT_EQ("Item 1", ShelfModel::Get()->items()[0].id.app_id); } @@ -4028,6 +4121,7 @@ TEST_P(AppsGridViewDragTest, DragAndPinNotInitiallyVisibleFolderItemToShelf) { generator->PressLeftButton(); item_view->FireMouseDragTimerForTest(); generator->MoveMouseBy(10, 10); + EXPECT_EQ(1, GetHapticTickEventsCount()); // Verify app list item drag has started. ASSERT_TRUE(folder_apps_grid_view()->drag_item()); @@ -4051,6 +4145,7 @@ TEST_P(AppsGridViewDragTest, DragAndPinNotInitiallyVisibleFolderItemToShelf) { // Releasing drag over shelf should pin the dragged app. generator->ReleaseLeftButton(); + EXPECT_EQ(1, GetHapticTickEventsCount()); EXPECT_TRUE(ShelfModel::Get()->IsAppPinned("Item 30")); EXPECT_EQ("Item 30", ShelfModel::Get()->items()[0].id.app_id); @@ -4074,6 +4169,7 @@ TEST_P(AppsGridViewDragTest, DragAnItemFromFolderToAndFromShelf) { generator->PressLeftButton(); item_view->FireMouseDragTimerForTest(); generator->MoveMouseBy(10, 10); + EXPECT_EQ(1, GetHapticTickEventsCount()); // Verify app list item drag has started. ASSERT_TRUE(folder_apps_grid_view()->drag_item()); @@ -4099,6 +4195,7 @@ TEST_P(AppsGridViewDragTest, DragAnItemFromFolderToAndFromShelf) { // the drag ends. generator->MoveMouseTo(apps_grid_view_->GetBoundsInScreen().origin()); generator->ReleaseLeftButton(); + EXPECT_EQ(1, GetHapticTickEventsCount()); EXPECT_FALSE(ShelfModel::Get()->IsAppPinned("Item 1")); EXPECT_TRUE(ShelfModel::Get()->items().empty()); @@ -4262,6 +4359,7 @@ TEST_P(AppsGridViewDragNonBubbleTest, MoveAnItemToNewEmptyPage) { apps_grid_view_->view_model(); InitiateDragForItemAtCurrentPageAt(AppsGridView::MOUSE, 0, 0, apps_grid_view_); + EXPECT_EQ(1, GetHapticTickEventsCount()); gfx::Point to_in_next_page = test_api_->GetItemTileRectAtVisualIndex(1, 0).CenterPoint(); @@ -4282,6 +4380,7 @@ TEST_P(AppsGridViewDragNonBubbleTest, MoveAnItemToNewEmptyPage) { EXPECT_EQ("Item 0", view_model->view_at(1)->item()->id()); EXPECT_EQ(std::string("Item 1,PageBreakItem,Item 0"), model_->GetModelContent()); + EXPECT_EQ(1, GetHapticTickEventsCount()); } // This is a NonBubble test because new empty pages cannot be created with the @@ -4293,6 +4392,7 @@ TEST_P(AppsGridViewDragNonBubbleTest, MoveLastItemToCreateFolderInNextPage) { apps_grid_view_->view_model(); InitiateDragForItemAtCurrentPageAt(AppsGridView::MOUSE, 0, 0, apps_grid_view_); + EXPECT_EQ(1, GetHapticTickEventsCount()); gfx::Point to_in_next_page = test_api_->GetItemTileRectAtVisualIndex(1, 0).CenterPoint(); @@ -4302,6 +4402,7 @@ TEST_P(AppsGridViewDragNonBubbleTest, MoveLastItemToCreateFolderInNextPage) { GetPaginationModel()->SelectPage(0, false); InitiateDragForItemAtCurrentPageAt(AppsGridView::MOUSE, 0, 0, apps_grid_view_); + EXPECT_EQ(2, GetHapticTickEventsCount()); UpdateDragToNeighborPage(true /* next_page */, to_in_next_page); // A new folder is created on second page, but since the first page is @@ -4319,6 +4420,7 @@ TEST_P(AppsGridViewDragNonBubbleTest, MoveLastItemToCreateFolderInNextPage) { // AppListSyncableService. EXPECT_EQ(std::string("PageBreakItem," + folder_item->id()), model_->GetModelContent()); + EXPECT_EQ(2, GetHapticTickEventsCount()); } // This is a NonBubble test because new empty pages cannot be created with the @@ -4330,6 +4432,7 @@ TEST_P(AppsGridViewDragNonBubbleTest, MoveLastItemForReorderInNextPage) { apps_grid_view_->view_model(); InitiateDragForItemAtCurrentPageAt(AppsGridView::MOUSE, 0, 0, apps_grid_view_); + EXPECT_EQ(1, GetHapticTickEventsCount()); gfx::Rect tile_rect = test_api_->GetItemTileRectAtVisualIndex(1, 0); gfx::Point to_in_next_page = tile_rect.CenterPoint(); to_in_next_page.set_x(tile_rect.x()); @@ -4340,6 +4443,7 @@ TEST_P(AppsGridViewDragNonBubbleTest, MoveLastItemForReorderInNextPage) { GetPaginationModel()->SelectPage(0, false); InitiateDragForItemAtCurrentPageAt(AppsGridView::MOUSE, 0, 0, apps_grid_view_); + EXPECT_EQ(2, GetHapticTickEventsCount()); UpdateDragToNeighborPage(true /* next_page */, to_in_next_page); // The second item is put on the left of the first item, but since the first @@ -4358,6 +4462,7 @@ TEST_P(AppsGridViewDragNonBubbleTest, MoveLastItemForReorderInNextPage) { // AppListSyncableService. EXPECT_EQ(std::string("PageBreakItem,Item 1,Item 0"), model_->GetModelContent()); + EXPECT_EQ(2, GetHapticTickEventsCount()); } // This is a NonBubble test because new empty pages cannot be created with the @@ -4369,6 +4474,7 @@ TEST_P(AppsGridViewDragNonBubbleTest, MoveLastItemToNewEmptyPage) { apps_grid_view_->view_model(); InitiateDragForItemAtCurrentPageAt(AppsGridView::MOUSE, 0, 0, apps_grid_view_); + EXPECT_EQ(1, GetHapticTickEventsCount()); gfx::Point to_in_next_page = test_api_->GetItemTileRectAtVisualIndex(1, 0).CenterPoint(); @@ -4377,6 +4483,7 @@ TEST_P(AppsGridViewDragNonBubbleTest, MoveLastItemToNewEmptyPage) { GetPaginationModel()->SelectPage(0, false); InitiateDragForItemAtCurrentPageAt(AppsGridView::MOUSE, 0, 0, apps_grid_view_); + EXPECT_EQ(2, GetHapticTickEventsCount()); UpdateDragToNeighborPage(true /* next_page */, to_in_next_page); // The item is put on second page, but since the first page is empty, @@ -4389,6 +4496,7 @@ TEST_P(AppsGridViewDragNonBubbleTest, MoveLastItemToNewEmptyPage) { test_api_->GetViewAtVisualIndex(0 /* page */, 0 /* slot */)); EXPECT_EQ("Item 0", view_model->view_at(0)->item()->id()); EXPECT_EQ(std::string("Item 0"), model_->GetModelContent()); + EXPECT_EQ(2, GetHapticTickEventsCount()); } // There's no "page break" item at the end of first page with full grid. @@ -4621,6 +4729,7 @@ TEST_P(AppsGridViewTabletTest, MoveItemToPreviousFullPage) { GetPaginationModel()->SelectPage(1, false); InitiateDragForItemAtCurrentPageAt(AppsGridView::MOUSE, 0, 1, apps_grid_view_); + EXPECT_EQ(1, GetHapticTickEventsCount()); gfx::Rect tile_rect = test_api_->GetItemTileRectAtVisualIndex(0, 0); gfx::Point to_in_previous_page = @@ -4643,6 +4752,7 @@ TEST_P(AppsGridViewTabletTest, MoveItemToPreviousFullPage) { EXPECT_EQ("Item " + base::NumberToString((i + kApps - 1) % kApps), view_model->view_at(i)->item()->id()); } + EXPECT_EQ(1, GetHapticTickEventsCount()); } // This is a NonBubble test because page breaks are ignored with the @@ -4890,7 +5000,7 @@ TEST_P(AppsGridViewCardifiedStateTest, BackgroundCardBoundsOnSecondPage) { model_->PopulateApps(30); // Enter cardified state, and drag the item to the second apps grid page. - InitiateDragForItemAtCurrentPageAt(AppsGridView::TOUCH, 0, 0, + InitiateDragForItemAtCurrentPageAt(AppsGridView::MOUSE, 0, 0, paged_apps_grid_view_); const gfx::Point to_in_next_page = test_api_->GetItemTileRectAtVisualIndex(1, 0).left_center(); @@ -4898,7 +5008,7 @@ TEST_P(AppsGridViewCardifiedStateTest, BackgroundCardBoundsOnSecondPage) { UpdateDragToNeighborPage(true /* next_page */, to_in_next_page); // Trigger cardified state again. - InitiateDragForItemAtCurrentPageAt(AppsGridView::TOUCH, 0, 0, + InitiateDragForItemAtCurrentPageAt(AppsGridView::MOUSE, 0, 0, paged_apps_grid_view_); ASSERT_TRUE(paged_apps_grid_view_->cardified_state_for_testing()); @@ -4978,21 +5088,24 @@ TEST_P(AppsGridViewDragNonBubbleTest, // Create only one page with two apps. model_->PopulateApps(2); - InitiateDragForItemAtCurrentPageAt(AppsGridView::TOUCH, 0, 0, + InitiateDragForItemAtCurrentPageAt(AppsGridView::MOUSE, 0, 0, paged_apps_grid_view_); + EXPECT_EQ(1, GetHapticTickEventsCount()); const gfx::Point to_in_next_page = test_api_->GetItemTileRectAtVisualIndex(1, 0).CenterPoint(); // Drag the first item to the next page to create another page. UpdateDragToNeighborPage(true /* next_page */, to_in_next_page); // Trigger cardified state again. - InitiateDragForItemAtCurrentPageAt(AppsGridView::TOUCH, 0, 0, + InitiateDragForItemAtCurrentPageAt(AppsGridView::MOUSE, 0, 0, paged_apps_grid_view_); + EXPECT_EQ(2, GetHapticTickEventsCount()); EXPECT_TRUE(paged_apps_grid_view_->cardified_state_for_testing()); EXPECT_EQ(3, paged_apps_grid_view_->BackgroundCardCountForTesting()); EndDrag(paged_apps_grid_view_, false /*cancel*/); + EXPECT_EQ(2, GetHapticTickEventsCount()); } TEST_P(AppsGridViewCardifiedStateTest, AppsGridIsCardifiedDuringDrag) { @@ -5003,10 +5116,12 @@ TEST_P(AppsGridViewCardifiedStateTest, AppsGridIsCardifiedDuringDrag) { InitiateDragForItemAtCurrentPageAt(AppsGridView::TOUCH, 0, 0, paged_apps_grid_view_); + EXPECT_EQ(0, GetHapticTickEventsCount()); EXPECT_TRUE(paged_apps_grid_view_->cardified_state_for_testing()); EndDrag(paged_apps_grid_view_, false /*cancel*/); + EXPECT_EQ(0, GetHapticTickEventsCount()); EXPECT_FALSE(paged_apps_grid_view_->cardified_state_for_testing()); } @@ -5025,6 +5140,7 @@ TEST_P(AppsGridViewCardifiedStateTest, // Drag the first folder child within the folder. InitiateDragForItemAtCurrentPageAt(AppsGridView::TOUCH, 0, 0, folder_apps_grid_view()); + EXPECT_EQ(0, GetHapticTickEventsCount()); const gfx::Point to = folder_grid_test_api.GetItemTileRectOnCurrentPageAt(0, 1).CenterPoint(); UpdateDrag(AppsGridView::TOUCH, to, folder_apps_grid_view(), 10 /*steps*/); @@ -5034,6 +5150,7 @@ TEST_P(AppsGridViewCardifiedStateTest, EXPECT_FALSE(paged_apps_grid_view_->cardified_state_for_testing()); EndDrag(folder_apps_grid_view(), false /*cancel*/); + EXPECT_EQ(0, GetHapticTickEventsCount()); } TEST_P(AppsGridViewCardifiedStateTest, DragOutsideFolderEntersCardifiedState) { @@ -5048,6 +5165,7 @@ TEST_P(AppsGridViewCardifiedStateTest, DragOutsideFolderEntersCardifiedState) { // Drag the first folder child out of the folder. AppListItemView* drag_view = InitiateDragForItemAtCurrentPageAt( AppsGridView::TOUCH, 0, 0, folder_apps_grid_view()); + EXPECT_EQ(0, GetHapticTickEventsCount()); const gfx::Point to = app_list_folder_view()->GetLocalBounds().bottom_center() + gfx::Vector2d(0, drag_view->height() @@ -5060,6 +5178,7 @@ TEST_P(AppsGridViewCardifiedStateTest, DragOutsideFolderEntersCardifiedState) { EXPECT_TRUE(paged_apps_grid_view_->cardified_state_for_testing()); EndDrag(folder_apps_grid_view(), false /*cancel*/); + EXPECT_EQ(0, GetHapticTickEventsCount()); EXPECT_FALSE(paged_apps_grid_view_->cardified_state_for_testing()); } @@ -5072,6 +5191,7 @@ TEST_P(AppsGridViewCardifiedStateTest, model_->PopulateApps(1); InitiateDragForItemAtCurrentPageAt(AppsGridView::TOUCH, 0, 1, paged_apps_grid_view_); + EXPECT_EQ(0, GetHapticTickEventsCount()); // Dragging item_1 over folder to expand it. const gfx::Point to = GetItemRectOnCurrentPageAt(0, 0).CenterPoint(); @@ -5080,6 +5200,7 @@ TEST_P(AppsGridViewCardifiedStateTest, EXPECT_TRUE(paged_apps_grid_view_->cardified_state_for_testing()); EndDrag(paged_apps_grid_view_, false /*cancel*/); + EXPECT_EQ(0, GetHapticTickEventsCount()); EXPECT_FALSE(paged_apps_grid_view_->cardified_state_for_testing()); test_api_->WaitForItemMoveAnimationDone(); test_api_->LayoutToIdealBounds(); diff --git a/ash/shelf/shelf_view.cc b/ash/shelf/shelf_view.cc index 7b804434c03837..9d3825d5d72fc4 100644 --- a/ash/shelf/shelf_view.cc +++ b/ash/shelf/shelf_view.cc @@ -38,6 +38,7 @@ #include "ash/strings/grit/ash_strings.h" #include "ash/style/ash_color_provider.h" #include "ash/system/status_area_widget.h" +#include "ash/utility/haptics_util.h" #include "ash/wm/desks/desks_util.h" #include "ash/wm/mru_window_tracker.h" #include "ash/wm/tablet_mode/tablet_mode_controller.h" @@ -68,6 +69,7 @@ #include "ui/compositor/scoped_animation_duration_scale_mode.h" #include "ui/compositor/scoped_layer_animation_settings.h" #include "ui/display/scoped_display_for_new_windows.h" +#include "ui/events/devices/haptic_touchpad_effects.h" #include "ui/events/event_utils.h" #include "ui/gfx/canvas.h" #include "ui/gfx/geometry/point.h" @@ -1521,6 +1523,12 @@ void ShelfView::PrepareForDrag(Pointer pointer, const ui::LocatedEvent& event) { root_window, drag_view_->GetImage(), screen_location, gfx::Vector2d(), /*scale_factor=*/1.0f, /*use_blurred_background=*/false); + + if (pointer == MOUSE) { + haptics_util::PlayHapticTouchpadEffect( + ui::HapticTouchpadEffect::kTick, + ui::HapticTouchpadEffectStrength::kMedium); + } } } diff --git a/ash/shelf/shelf_view_unittest.cc b/ash/shelf/shelf_view_unittest.cc index f55f65537cced1..55760615ea6998 100644 --- a/ash/shelf/shelf_view_unittest.cc +++ b/ash/shelf/shelf_view_unittest.cc @@ -44,6 +44,7 @@ #include "ash/test/ash_test_base.h" #include "ash/test/ash_test_helper.h" #include "ash/test/ui_controls_factory_ash.h" +#include "ash/utility/haptics_tracking_test_input_controller.h" #include "ash/wallpaper/wallpaper_controller_impl.h" #include "ash/wallpaper/wallpaper_controller_test_api.h" #include "ash/wm/tablet_mode/tablet_mode_controller.h" @@ -350,6 +351,7 @@ class ShelfViewTest : public AshTestBase { void SetUp() override { AshTestBase::SetUp(); + haptics_tracker_ = std::make_unique(); model_ = ShelfModel::Get(); shelf_view_ = GetPrimaryShelf()->GetShelfViewForTesting(); navigation_view_ = GetPrimaryShelf() @@ -378,6 +380,7 @@ class ShelfViewTest : public AshTestBase { void TearDown() override { test_api_.reset(); + haptics_tracker_.reset(); AshTestBase::TearDown(); } @@ -606,6 +609,12 @@ class ShelfViewTest : public AshTestBase { return button->GetBoundsInScreen().CenterPoint(); } + int GetHapticTickEventsCount() const { + return haptics_tracker_->GetSentHapticCount( + ui::HapticTouchpadEffect::kTick, + ui::HapticTouchpadEffectStrength::kMedium); + } + ShelfModel* model_ = nullptr; ShelfView* shelf_view_ = nullptr; views::View* navigation_view_ = nullptr; @@ -613,6 +622,8 @@ class ShelfViewTest : public AshTestBase { int id_ = 0; + // Used to track haptics events sent during drag. + std::unique_ptr haptics_tracker_; std::unique_ptr test_api_; }; @@ -698,25 +709,37 @@ TEST_P(LtrRtlShelfViewTest, ModelChangesWhileDragging) { // Dragging browser shortcut at index 1. EXPECT_TRUE(model_->items()[0].type == TYPE_BROWSER_SHORTCUT); views::View* dragged_button = SimulateDrag(ShelfView::MOUSE, 0, 2, false); + EXPECT_EQ(1, GetHapticTickEventsCount()); std::rotate(id_map.begin(), id_map.begin() + 1, id_map.begin() + 3); ASSERT_NO_FATAL_FAILURE(CheckModelIDs(id_map)); shelf_view_->PointerReleasedOnButton(dragged_button, ShelfView::MOUSE, false); + EXPECT_EQ(1, GetHapticTickEventsCount()); EXPECT_TRUE(model_->items()[2].type == TYPE_BROWSER_SHORTCUT); + test_api_->RunMessageLoopUntilAnimationsDone(); // Dragging changes model order. dragged_button = SimulateDrag(ShelfView::MOUSE, 0, 2, false); + EXPECT_EQ(2, GetHapticTickEventsCount()); std::rotate(id_map.begin(), id_map.begin() + 1, id_map.begin() + 3); ASSERT_NO_FATAL_FAILURE(CheckModelIDs(id_map)); // Cancelling the drag operation restores previous order. shelf_view_->PointerReleasedOnButton(dragged_button, ShelfView::MOUSE, true); + test_api_->RunMessageLoopUntilAnimationsDone(); + EXPECT_EQ(2, GetHapticTickEventsCount()); std::rotate(id_map.begin(), id_map.begin() + 2, id_map.begin() + 3); ASSERT_NO_FATAL_FAILURE(CheckModelIDs(id_map)); // Deleting an item keeps the remaining intact. dragged_button = SimulateDrag(ShelfView::MOUSE, 0, 2, false); - model_->RemoveItemAt(0); - id_map.erase(id_map.begin()); + EXPECT_EQ(3, GetHapticTickEventsCount()); + + // The dragged view has been moved to index 2 during drag. + std::rotate(id_map.begin(), id_map.begin() + 1, id_map.begin() + 3); + ASSERT_NO_FATAL_FAILURE(CheckModelIDs(id_map)); + + model_->RemoveItemAt(2); + id_map.erase(id_map.begin() + 2); ASSERT_NO_FATAL_FAILURE(CheckModelIDs(id_map)); shelf_view_->PointerReleasedOnButton(dragged_button, ShelfView::MOUSE, false); @@ -725,11 +748,13 @@ TEST_P(LtrRtlShelfViewTest, ModelChangesWhileDragging) { // Adding a shelf item cancels the drag and respects the order. dragged_button = SimulateDrag(ShelfView::MOUSE, 0, 2, false); + EXPECT_EQ(4, GetHapticTickEventsCount()); ShelfID new_id = AddAppShortcut(); id_map.insert(id_map.begin() + 5, std::make_pair(new_id, GetButtonByID(new_id))); ASSERT_NO_FATAL_FAILURE(CheckModelIDs(id_map)); shelf_view_->PointerReleasedOnButton(dragged_button, ShelfView::MOUSE, false); + EXPECT_EQ(4, GetHapticTickEventsCount()); } // Check that 2nd drag from the other pointer would be ignored. @@ -740,11 +765,13 @@ TEST_P(LtrRtlShelfViewTest, SimultaneousDrag) { // Start a mouse drag. views::View* dragged_button_mouse = SimulateDrag(ShelfView::MOUSE, 2, 4, false); + EXPECT_EQ(1, GetHapticTickEventsCount()); std::rotate(id_map.begin() + 2, id_map.begin() + 3, id_map.begin() + 5); ASSERT_NO_FATAL_FAILURE(CheckModelIDs(id_map)); // Attempt a touch drag before the mouse drag finishes. views::View* dragged_button_touch = SimulateDrag(ShelfView::TOUCH, 5, 3, false); + EXPECT_EQ(1, GetHapticTickEventsCount()); // Nothing changes since 2nd drag is ignored. ASSERT_NO_FATAL_FAILURE(CheckModelIDs(id_map)); @@ -768,6 +795,7 @@ TEST_P(LtrRtlShelfViewTest, SimultaneousDrag) { shelf_view_->PointerReleasedOnButton(dragged_button_touch, ShelfView::TOUCH, false); ASSERT_NO_FATAL_FAILURE(CheckModelIDs(id_map)); + EXPECT_EQ(1, GetHapticTickEventsCount()); } // Ensure that the behavior of pinning and unpinning by dragging works as @@ -799,9 +827,12 @@ TEST_F(ShelfViewDragToPinTest, DragAppsToPinAndUnpin) { // app should be unpinned and moved to the released position. views::View* dragged_button = SimulateDrag(ShelfView::MOUSE, 1, id_map.size() - 1, false); + EXPECT_EQ(1, GetHapticTickEventsCount()); std::rotate(id_map.begin() + 1, id_map.begin() + 2, id_map.end()); ASSERT_NO_FATAL_FAILURE(CheckModelIDs(id_map)); shelf_view_->PointerReleasedOnButton(dragged_button, ShelfView::MOUSE, false); + test_api_->RunMessageLoopUntilAnimationsDone(); + EXPECT_EQ(1, GetHapticTickEventsCount()); EXPECT_FALSE(IsAppPinned(id_map.back().first)); --pinned_apps_size; @@ -809,19 +840,24 @@ TEST_F(ShelfViewDragToPinTest, DragAppsToPinAndUnpin) { // available and the app is dragged to the unpinned app side, the dragged app // with no running instance should be unpinned and removed from shelf. dragged_button = SimulateDrag(ShelfView::MOUSE, 2, id_map.size() - 1, false); + EXPECT_EQ(2, GetHapticTickEventsCount()); shelf_view_->PointerReleasedOnButton(dragged_button, ShelfView::MOUSE, false); id_map.erase(id_map.begin() + 2); EXPECT_EQ(id_map.size(), model_->items().size()); ASSERT_NO_FATAL_FAILURE(CheckModelIDs(id_map)); --pinned_apps_size; + EXPECT_EQ(2, GetHapticTickEventsCount()); // Drag an app in unpinned app side and move it to the beginning of the shelf. // With separator available and the app is dragged to the pinned app side, the // dragged app should be pinned and moved to the released position. dragged_button = SimulateDrag(ShelfView::MOUSE, id_map.size() - 2, 0, false); + EXPECT_EQ(3, GetHapticTickEventsCount()); std::rotate(id_map.rbegin() + 1, id_map.rbegin() + 2, id_map.rend()); ASSERT_NO_FATAL_FAILURE(CheckModelIDs(id_map)); shelf_view_->PointerReleasedOnButton(dragged_button, ShelfView::MOUSE, false); + test_api_->RunMessageLoopUntilAnimationsDone(); + EXPECT_EQ(3, GetHapticTickEventsCount()); EXPECT_TRUE(IsAppPinned(id_map[0].first)); ++pinned_apps_size; @@ -845,6 +881,7 @@ TEST_F(ShelfViewDragToPinTest, BlockBrowserShortcutFromUnpinningByDragging) { // unpinned. views::View* dragged_button = SimulateDrag(ShelfView::MOUSE, 0, id_map.size() - 1, false); + EXPECT_EQ(1, GetHapticTickEventsCount()); std::rotate(id_map.begin(), id_map.begin() + 1, id_map.begin() + pinned_apps_size); ASSERT_NO_FATAL_FAILURE(CheckModelIDs(id_map)); @@ -853,6 +890,7 @@ TEST_F(ShelfViewDragToPinTest, BlockBrowserShortcutFromUnpinningByDragging) { // the pinned app side. shelf_view_->PointerReleasedOnButton(dragged_button, ShelfView::MOUSE, false); EXPECT_EQ(model_->items()[pinned_apps_size - 1].type, TYPE_BROWSER_SHORTCUT); + EXPECT_EQ(1, GetHapticTickEventsCount()); } // Check that separator index updates as expected when a drag view is dragged @@ -884,6 +922,7 @@ TEST_F(ShelfViewDragToPinTest, DragAppAroundSeparator) { // Drag the mouse slightly to the left. The dragged app will stay at the same // index but the separator will move to the right. generator->MoveMouseBy(-button_width / 4, 0); + EXPECT_EQ(1, GetHapticTickEventsCount()); // In this case, the separator is moved to the end of the shelf so it is set // invisible and the |separator_index_| will be updated to -1. EXPECT_FALSE(test_api_->IsSeparatorVisible()); @@ -895,6 +934,7 @@ TEST_F(ShelfViewDragToPinTest, DragAppAroundSeparator) { // dragging it back to its original place will show the separator again. EXPECT_EQ(test_api_->GetSeparatorIndex(), pinned_apps_size - 1); generator->ReleaseLeftButton(); + EXPECT_EQ(1, GetHapticTickEventsCount()); // Drag an pinned app that is beside the separator around and check that the // separator is correctly placed. Check that the dragged app is not a browser @@ -909,12 +949,14 @@ TEST_F(ShelfViewDragToPinTest, DragAppAroundSeparator) { // Drag the mouse slightly to the right. The dragged app will stay at the same // index but the separator will move to the left. generator->MoveMouseBy(button_width / 4, 0); + EXPECT_EQ(2, GetHapticTickEventsCount()); EXPECT_EQ(test_api_->GetSeparatorIndex(), pinned_apps_size - 2); // Drag the mouse slightly to the left. The dragged app will stay at the same // index but the separator will move to the right. generator->MoveMouseBy(-button_width / 2, 0); EXPECT_EQ(test_api_->GetSeparatorIndex(), pinned_apps_size - 1); generator->ReleaseLeftButton(); + EXPECT_EQ(2, GetHapticTickEventsCount()); } // Ensure that clicking on one item and then dragging another works as expected. @@ -928,10 +970,12 @@ TEST_P(LtrRtlShelfViewTest, ClickOneDragAnother) { // Dragging the browser item at index 0 should change the model order. EXPECT_TRUE(model_->items()[0].type == TYPE_BROWSER_SHORTCUT); views::View* dragged_button = SimulateDrag(ShelfView::MOUSE, 0, 2, false); + EXPECT_EQ(1, GetHapticTickEventsCount()); std::rotate(id_map.begin(), id_map.begin() + 1, id_map.begin() + 3); ASSERT_NO_FATAL_FAILURE(CheckModelIDs(id_map)); shelf_view_->PointerReleasedOnButton(dragged_button, ShelfView::MOUSE, false); EXPECT_TRUE(model_->items()[2].type == TYPE_BROWSER_SHORTCUT); + EXPECT_EQ(1, GetHapticTickEventsCount()); } // Tests that double-clicking an item does not activate it twice. @@ -947,6 +991,7 @@ TEST_P(LtrRtlShelfViewTest, ClickingTwiceActivatesOnce) { EXPECT_EQ(1u, selection_tracker->item_selected_count()); SimulateDoubleClick(0); EXPECT_EQ(1u, selection_tracker->item_selected_count()); + EXPECT_EQ(0, GetHapticTickEventsCount()); } // Check that very small mouse drags do not prevent shelf item selection. @@ -991,6 +1036,7 @@ TEST_P(LtrRtlShelfViewTest, ClickAndMoveSlightly) { ui::EF_LEFT_MOUSE_BUTTON, 0); button->OnMouseReleased(release_event); EXPECT_EQ(1u, selection_tracker->item_selected_count()); + EXPECT_EQ(0, GetHapticTickEventsCount()); } // Confirm that item status changes are reflected in the buttons. @@ -1030,6 +1076,7 @@ TEST_P(LtrRtlShelfViewTest, ShelfRipOff) { generator->PressLeftButton(); // Drag the mouse to just off the shelf. generator->MoveMouseBy(0, -ShelfConfig::Get()->shelf_size() / 2 - 1); + EXPECT_EQ(1, GetHapticTickEventsCount()); EXPECT_FALSE(test_api_->IsRippedOffFromShelf()); // Drag the mouse past the rip off threshold. generator->MoveMouseBy(0, -kRipOffDistance); @@ -1038,6 +1085,7 @@ TEST_P(LtrRtlShelfViewTest, ShelfRipOff) { // deleted. generator->MoveMouseTo(first_app_location); generator->ReleaseLeftButton(); + EXPECT_EQ(1, GetHapticTickEventsCount()); EXPECT_FALSE(test_api_->IsRippedOffFromShelf()); } @@ -1072,6 +1120,7 @@ TEST_P(LtrRtlShelfViewTest, ShelfRipOffCancel) { // Drag the mouse to just off the shelf. generator->MoveMouseBy(0, -ShelfConfig::Get()->shelf_size() / 2 - 1); + EXPECT_EQ(1, GetHapticTickEventsCount()); EXPECT_FALSE(test_api_->IsRippedOffFromShelf()); // Drag the mouse past the rip off threshold. @@ -1080,6 +1129,7 @@ TEST_P(LtrRtlShelfViewTest, ShelfRipOffCancel) { shelf_view_->PointerReleasedOnButton(dragged_button, ShelfView::MOUSE, true); generator->ReleaseLeftButton(); + EXPECT_EQ(1, GetHapticTickEventsCount()); EXPECT_FALSE(test_api_->IsRippedOffFromShelf()); ASSERT_NO_FATAL_FAILURE(CheckModelIDs(id_map)); @@ -1108,11 +1158,13 @@ TEST_P(LtrRtlShelfViewTest, DragAndDropPinnedRunningApp) { generator->set_current_screen_location(app_location); generator->PressLeftButton(); generator->MoveMouseBy(0, -ShelfConfig::Get()->shelf_size() / 2 - 1); + EXPECT_EQ(1, GetHapticTickEventsCount()); EXPECT_FALSE(test_api_->IsRippedOffFromShelf()); generator->MoveMouseBy(0, -kRipOffDistance); EXPECT_TRUE(test_api_->IsRippedOffFromShelf()); generator->ReleaseLeftButton(); EXPECT_FALSE(IsAppPinned(GetItemId(index))); + EXPECT_EQ(1, GetHapticTickEventsCount()); } // Double click an app while animating drag icon drop. @@ -1140,12 +1192,15 @@ TEST_P(LtrRtlShelfViewTest, ActivateAppButtonDuringDropAnimation) { GetButtonCenter(GetButtonByID(drag_item_id))); generator->PressLeftButton(); generator->MoveMouseBy(0, -ShelfConfig::Get()->shelf_size() / 2 - 1); + EXPECT_EQ(1, GetHapticTickEventsCount()); generator->ReleaseLeftButton(); + EXPECT_EQ(1, GetHapticTickEventsCount()); generator->set_current_screen_location( GetButtonCenter(GetButtonByID(activated_item_id))); generator->DoubleClickLeftButton(); + EXPECT_EQ(1, GetHapticTickEventsCount()); EXPECT_EQ(1u, selection_tracker->item_selected_count()); VerifyShelfItemBoundsAreValid(); } @@ -1677,6 +1732,8 @@ TEST_P(LtrRtlShelfViewTest, ShelfDragViewAndContextMenu) { EXPECT_EQ(shelf_view_->drag_view(), button); generator->ReleaseLeftButton(); EXPECT_FALSE(shelf_view_->drag_view()); + + EXPECT_EQ(0, GetHapticTickEventsCount()); } // Tests that context menu show is cancelled if item drag starts during context @@ -1870,6 +1927,7 @@ TEST_P(LtrRtlShelfViewTest, DragAppAfterContextMenuIsShownInAlwaysShownShelf) { generator->GestureScrollSequence(start, end, base::Milliseconds(100), 3); generator->ReleaseTouch(); + EXPECT_EQ(0, GetHapticTickEventsCount()); // |first_add_id| has been moved to the end of the items in the shelf. EXPECT_EQ(first_app_id, model_->items()[last_index].id); @@ -1942,6 +2000,7 @@ TEST_P(LtrRtlShelfViewTest, DragAppAfterContextMenuIsShownInAutoHideShelf) { generator->GestureScrollSequence(start, end, base::Milliseconds(100), 3); generator->ReleaseTouch(); + EXPECT_EQ(0, GetHapticTickEventsCount()); // |first_add_id| has been moved to the end of the items in the shelf. EXPECT_EQ(first_app_id, model_->items()[last_index].id); @@ -2014,6 +2073,7 @@ TEST_P(LtrRtlShelfViewTest, // Releasing the original touch should not show another menu. generator->ReleaseTouch(); + EXPECT_EQ(0, GetHapticTickEventsCount()); EXPECT_FALSE(shelf_view_->IsShowingMenu()); EXPECT_FALSE(shelf_view_->GetShelfItemViewWithContextMenu()); @@ -2227,6 +2287,7 @@ TEST_P(LtrRtlShelfViewTest, ClickItemInFullscreen) { // Shelf gets hidden when the app list is dismissed. GetAppListTestHelper()->DismissAndRunLoop(); EXPECT_EQ(SHELF_HIDDEN, shelf->GetVisibilityState()); + EXPECT_EQ(0, GetHapticTickEventsCount()); } // Verifies that shelf is shown with the app list in fullscreen mode, and that @@ -2263,6 +2324,7 @@ TEST_P(LtrRtlShelfViewTest, TapInFullscreen) { // Shelf gets hidden when the app list is dismissed. GetAppListTestHelper()->DismissAndRunLoop(); EXPECT_EQ(SHELF_HIDDEN, shelf->GetVisibilityState()); + EXPECT_EQ(0, GetHapticTickEventsCount()); } // Verifies that partying items are hidden from the shelf. @@ -2388,6 +2450,7 @@ TEST_F(GhostImageShelfViewTest, ShowGhostImageOnDrag) { ShelfAppButton* first_app = GetButtonByID(id_map[0].first); StartDrag(first_app); + EXPECT_EQ(0, GetHapticTickEventsCount()); EXPECT_TRUE(first_app->state() & ShelfAppButton::STATE_DRAGGING); EXPECT_FALSE(shelf_view_->drag_view()); @@ -2401,6 +2464,7 @@ TEST_F(GhostImageShelfViewTest, ShowGhostImageOnDrag) { EXPECT_EQ(1, shelf_view_->current_ghost_view_index()); GetEventGenerator()->ReleaseTouch(); + EXPECT_EQ(0, GetHapticTickEventsCount()); EXPECT_FALSE(first_app->state() & ShelfAppButton::STATE_DRAGGING); EXPECT_FALSE(shelf_view_->drag_view()); @@ -2415,6 +2479,7 @@ TEST_F(GhostImageShelfViewTest, RemoveGhostImageForRipOffDrag) { ShelfAppButton* first_app = GetButtonByID(id_map[0].first); StartDrag(first_app); + EXPECT_EQ(0, GetHapticTickEventsCount()); EXPECT_TRUE(first_app->state() & ShelfAppButton::STATE_DRAGGING); EXPECT_FALSE(shelf_view_->drag_view()); @@ -2438,6 +2503,7 @@ TEST_F(GhostImageShelfViewTest, RemoveGhostImageForRipOffDrag) { EXPECT_EQ(-1, shelf_view_->current_ghost_view_index()); GetEventGenerator()->ReleaseTouch(); + EXPECT_EQ(0, GetHapticTickEventsCount()); EXPECT_FALSE(first_app->state() & ShelfAppButton::STATE_DRAGGING); EXPECT_FALSE(shelf_view_->drag_view()); @@ -2452,6 +2518,7 @@ TEST_F(GhostImageShelfViewTest, ReinsertGhostImageAfterRipOffDrag) { ShelfAppButton* first_app = GetButtonByID(id_map[0].first); StartDrag(first_app); + EXPECT_EQ(0, GetHapticTickEventsCount()); EXPECT_TRUE(first_app->state() & ShelfAppButton::STATE_DRAGGING); EXPECT_FALSE(shelf_view_->drag_view()); @@ -2481,6 +2548,7 @@ TEST_F(GhostImageShelfViewTest, ReinsertGhostImageAfterRipOffDrag) { EXPECT_EQ(1, shelf_view_->current_ghost_view_index()); GetEventGenerator()->ReleaseTouch(); + EXPECT_EQ(0, GetHapticTickEventsCount()); EXPECT_FALSE(first_app->state() & ShelfAppButton::STATE_DRAGGING); EXPECT_FALSE(shelf_view_->drag_view()); diff --git a/ash/utility/haptics_tracking_test_input_controller.cc b/ash/utility/haptics_tracking_test_input_controller.cc new file mode 100644 index 00000000000000..73e11a0f0a9f0b --- /dev/null +++ b/ash/utility/haptics_tracking_test_input_controller.cc @@ -0,0 +1,186 @@ +// Copyright 2022 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/utility/haptics_tracking_test_input_controller.h" + +#include "ash/utility/haptics_util.h" +#include "base/notreached.h" +#include "ui/events/devices/stylus_state.h" +#include "ui/ozone/public/ozone_platform.h" + +namespace ash { + +HapticsTrackingTestInputController::HapticsTrackingTestInputController() { + haptics_util::SetInputControllerForTesting(this); +} + +HapticsTrackingTestInputController::~HapticsTrackingTestInputController() { + haptics_util::SetInputControllerForTesting(nullptr); +} + +bool HapticsTrackingTestInputController::HasMouse() { + return false; +} + +bool HapticsTrackingTestInputController::HasPointingStick() { + return false; +} + +bool HapticsTrackingTestInputController::HasTouchpad() { + return false; +} + +bool HapticsTrackingTestInputController::HasHapticTouchpad() { + return true; +} + +bool HapticsTrackingTestInputController::IsCapsLockEnabled() { + return false; +} + +void HapticsTrackingTestInputController::SetCapsLockEnabled(bool enabled) {} + +void HapticsTrackingTestInputController::SetNumLockEnabled(bool enabled) {} + +bool HapticsTrackingTestInputController::IsAutoRepeatEnabled() { + return true; +} + +void HapticsTrackingTestInputController::SetAutoRepeatEnabled(bool enabled) {} + +void HapticsTrackingTestInputController::SetAutoRepeatRate( + const base::TimeDelta& delay, + const base::TimeDelta& interval) {} + +void HapticsTrackingTestInputController::GetAutoRepeatRate( + base::TimeDelta* delay, + base::TimeDelta* interval) {} + +void HapticsTrackingTestInputController::SetCurrentLayoutByName( + const std::string& layout_name) {} + +void HapticsTrackingTestInputController::SetTouchpadSensitivity(int value) {} + +void HapticsTrackingTestInputController::SetTouchpadScrollSensitivity( + int value) {} + +void HapticsTrackingTestInputController::SetTapToClick(bool enabled) {} + +void HapticsTrackingTestInputController::SetThreeFingerClick(bool enabled) {} + +void HapticsTrackingTestInputController::SetTapDragging(bool enabled) {} + +void HapticsTrackingTestInputController::SetNaturalScroll(bool enabled) {} + +void HapticsTrackingTestInputController::SetTouchpadAcceleration(bool enabled) { +} + +void HapticsTrackingTestInputController::SetTouchpadScrollAcceleration( + bool enabled) {} + +void HapticsTrackingTestInputController::SetTouchpadHapticFeedback( + bool enabled) {} + +void HapticsTrackingTestInputController::SetTouchpadHapticClickSensitivity( + int value) {} + +void HapticsTrackingTestInputController::SetMouseSensitivity(int value) {} + +void HapticsTrackingTestInputController::SetMouseScrollSensitivity(int value) {} + +void HapticsTrackingTestInputController::SetPrimaryButtonRight(bool right) {} + +void HapticsTrackingTestInputController::SetMouseReverseScroll(bool enabled) {} + +void HapticsTrackingTestInputController::SetMouseAcceleration(bool enabled) {} + +void HapticsTrackingTestInputController::SuspendMouseAcceleration() {} + +void HapticsTrackingTestInputController::EndMouseAccelerationSuspension() {} + +void HapticsTrackingTestInputController::SetMouseScrollAcceleration( + bool enabled) {} + +void HapticsTrackingTestInputController::SetPointingStickSensitivity( + int value) {} + +void HapticsTrackingTestInputController::SetPointingStickPrimaryButtonRight( + bool right) {} + +void HapticsTrackingTestInputController::SetPointingStickAcceleration( + bool enabled) {} + +void HapticsTrackingTestInputController::GetTouchDeviceStatus( + GetTouchDeviceStatusReply reply) { + std::move(reply).Run(std::string()); +} + +void HapticsTrackingTestInputController::GetTouchEventLog( + const base::FilePath& out_dir, + GetTouchEventLogReply reply) { + std::move(reply).Run(std::vector()); +} + +void HapticsTrackingTestInputController::SetTouchEventLoggingEnabled( + bool enabled) { + NOTIMPLEMENTED_LOG_ONCE(); +} + +void HapticsTrackingTestInputController::SetTapToClickPaused(bool state) {} + +void HapticsTrackingTestInputController::SetInternalTouchpadEnabled( + bool enabled) {} + +bool HapticsTrackingTestInputController::IsInternalTouchpadEnabled() const { + return false; +} + +void HapticsTrackingTestInputController::SetTouchscreensEnabled(bool enabled) {} + +void HapticsTrackingTestInputController::GetStylusSwitchState( + GetStylusSwitchStateReply reply) { + // Return that there is no stylus in the garage; this test class + // does not need to trigger stylus charging behaviours. + std::move(reply).Run(ui::StylusState::REMOVED); +} + +void HapticsTrackingTestInputController::PlayVibrationEffect( + int id, + uint8_t amplitude, + uint16_t duration_millis) {} + +void HapticsTrackingTestInputController::StopVibration(int id) {} + +void HapticsTrackingTestInputController::PlayHapticTouchpadEffect( + ui::HapticTouchpadEffect effect, + ui::HapticTouchpadEffectStrength strength) { + sent_haptic_count_[effect][strength]++; +} + +void HapticsTrackingTestInputController:: + SetHapticTouchpadEffectForNextButtonRelease( + ui::HapticTouchpadEffect effect, + ui::HapticTouchpadEffectStrength strength) {} + +void HapticsTrackingTestInputController::SetInternalKeyboardFilter( + bool enable_filter, + std::vector allowed_keys) {} + +void HapticsTrackingTestInputController::GetGesturePropertiesService( + mojo::PendingReceiver + receiver) {} + +int HapticsTrackingTestInputController::GetSentHapticCount( + ui::HapticTouchpadEffect effect, + ui::HapticTouchpadEffectStrength strength) const { + const auto& effect_it = sent_haptic_count_.find(effect); + if (effect_it == sent_haptic_count_.cend()) + return 0; + const auto& strength_it = effect_it->second.find(strength); + if (strength_it == effect_it->second.cend()) + return 0; + return strength_it->second; +} + +} // namespace ash diff --git a/ash/utility/haptics_tracking_test_input_controller.h b/ash/utility/haptics_tracking_test_input_controller.h new file mode 100644 index 00000000000000..6b1c7f9ca6afc3 --- /dev/null +++ b/ash/utility/haptics_tracking_test_input_controller.h @@ -0,0 +1,103 @@ +// Copyright 2022 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. + +#ifndef ASH_UTILITY_HAPTICS_TRACKING_TEST_INPUT_CONTROLLER_H_ +#define ASH_UTILITY_HAPTICS_TRACKING_TEST_INPUT_CONTROLLER_H_ + +#include "base/containers/flat_map.h" +#include "ui/events/devices/haptic_touchpad_effects.h" +#include "ui/ozone/public/input_controller.h" + +namespace ash { + +// Test input controller that can be used to track haptics events sent out in +// tests. The input controller will be set as the input controller that should +// be used by haptics util using `haptics_util::SetInputControllerForTesting()`. +// Only one should be initialized at a time. +class HapticsTrackingTestInputController : public ui::InputController { + public: + HapticsTrackingTestInputController(); + HapticsTrackingTestInputController( + const HapticsTrackingTestInputController&) = delete; + HapticsTrackingTestInputController& operator=( + const HapticsTrackingTestInputController&) = delete; + ~HapticsTrackingTestInputController() override; + + // ui::InputController: + bool HasMouse() override; + bool HasPointingStick() override; + bool HasTouchpad() override; + bool HasHapticTouchpad() override; + bool IsCapsLockEnabled() override; + void SetCapsLockEnabled(bool enabled) override; + void SetNumLockEnabled(bool enabled) override; + bool IsAutoRepeatEnabled() override; + void SetAutoRepeatEnabled(bool enabled) override; + void SetAutoRepeatRate(const base::TimeDelta& delay, + const base::TimeDelta& interval) override; + void GetAutoRepeatRate(base::TimeDelta* delay, + base::TimeDelta* interval) override; + void SetCurrentLayoutByName(const std::string& layout_name) override; + void SetTouchpadSensitivity(int value) override; + void SetTouchpadScrollSensitivity(int value) override; + void SetTapToClick(bool enabled) override; + void SetThreeFingerClick(bool enabled) override; + void SetTapDragging(bool enabled) override; + void SetNaturalScroll(bool enabled) override; + void SetTouchpadAcceleration(bool enabled) override; + void SetTouchpadScrollAcceleration(bool enabled) override; + void SetTouchpadHapticFeedback(bool enabled) override; + void SetTouchpadHapticClickSensitivity(int value) override; + void SetMouseSensitivity(int value) override; + void SetMouseScrollSensitivity(int value) override; + void SetPrimaryButtonRight(bool right) override; + void SetMouseReverseScroll(bool enabled) override; + void SetMouseAcceleration(bool enabled) override; + void SuspendMouseAcceleration() override; + void EndMouseAccelerationSuspension() override; + void SetMouseScrollAcceleration(bool enabled) override; + void SetPointingStickSensitivity(int value) override; + void SetPointingStickPrimaryButtonRight(bool right) override; + void SetPointingStickAcceleration(bool enabled) override; + void GetTouchDeviceStatus(GetTouchDeviceStatusReply reply) override; + void GetTouchEventLog(const base::FilePath& out_dir, + GetTouchEventLogReply reply) override; + void SetTouchEventLoggingEnabled(bool enabled) override; + void SetTapToClickPaused(bool state) override; + void SetInternalTouchpadEnabled(bool enabled) override; + bool IsInternalTouchpadEnabled() const override; + void SetTouchscreensEnabled(bool enabled) override; + void GetStylusSwitchState(GetStylusSwitchStateReply reply) override; + void PlayVibrationEffect(int id, + uint8_t amplitude, + uint16_t duration_millis) override; + void StopVibration(int id) override; + void PlayHapticTouchpadEffect( + ui::HapticTouchpadEffect effect, + ui::HapticTouchpadEffectStrength strength) override; + void SetHapticTouchpadEffectForNextButtonRelease( + ui::HapticTouchpadEffect effect, + ui::HapticTouchpadEffectStrength strength) override; + void SetInternalKeyboardFilter( + bool enable_filter, + std::vector allowed_keys) override; + void GetGesturePropertiesService( + mojo::PendingReceiver + receiver) override; + + // Returns haptic count for effect/strength combination for testing. + int GetSentHapticCount(ui::HapticTouchpadEffect effect, + ui::HapticTouchpadEffectStrength strength) const; + + private: + // A map of map that stores counts for given haptic effect/strength. + // This is used for testing only. + base::flat_map> + sent_haptic_count_; +}; + +} // namespace ash + +#endif // ASH_UTILITY_HAPTICS_TRACKING_TEST_INPUT_CONTROLLER_H_ diff --git a/ash/utility/haptics_util_unittest.cc b/ash/utility/haptics_util_unittest.cc index 61a198eb35c9c1..644fcf6e8ab98c 100644 --- a/ash/utility/haptics_util_unittest.cc +++ b/ash/utility/haptics_util_unittest.cc @@ -8,6 +8,7 @@ #include "ash/shell.h" #include "ash/test/ash_test_base.h" +#include "ash/utility/haptics_tracking_test_input_controller.h" #include "ash/wm/desks/desk_animation_impl.h" #include "ash/wm/desks/desk_mini_view.h" #include "ash/wm/desks/desks_bar_view.h" @@ -22,125 +23,22 @@ #include "ash/wm/overview/overview_item.h" #include "ash/wm/overview/overview_session.h" #include "ash/wm/workspace/workspace_window_resizer.h" -#include "base/containers/flat_map.h" #include "ui/aura/window.h" #include "ui/events/devices/haptic_touchpad_effects.h" -#include "ui/events/devices/stylus_state.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/rect_f.h" -#include "ui/ozone/public/input_controller.h" -#include "ui/ozone/public/ozone_platform.h" namespace ash { using ui::HapticTouchpadEffect; using ui::HapticTouchpadEffectStrength; -class InputControllerForTesting : public ui::InputController { - public: - InputControllerForTesting() { - haptics_util::SetInputControllerForTesting(this); - } - ~InputControllerForTesting() override { - haptics_util::SetInputControllerForTesting(nullptr); - } - InputControllerForTesting(const InputControllerForTesting&) = delete; - InputControllerForTesting& operator=(const InputControllerForTesting&) = - delete; - - // ui::InputController: - bool HasMouse() override { return false; } - bool HasPointingStick() override { return false; } - bool HasTouchpad() override { return false; } - bool HasHapticTouchpad() override { return true; } - bool IsCapsLockEnabled() override { return false; } - void SetCapsLockEnabled(bool enabled) override {} - void SetNumLockEnabled(bool enabled) override {} - bool IsAutoRepeatEnabled() override { return true; } - void SetAutoRepeatEnabled(bool enabled) override {} - void SetAutoRepeatRate(const base::TimeDelta& delay, - const base::TimeDelta& interval) override {} - void GetAutoRepeatRate(base::TimeDelta* delay, - base::TimeDelta* interval) override {} - void SetCurrentLayoutByName(const std::string& layout_name) override {} - void SetTouchpadSensitivity(int value) override {} - void SetTouchpadScrollSensitivity(int value) override {} - void SetTapToClick(bool enabled) override {} - void SetThreeFingerClick(bool enabled) override {} - void SetTapDragging(bool enabled) override {} - void SetNaturalScroll(bool enabled) override {} - void SetTouchpadAcceleration(bool enabled) override {} - void SetTouchpadScrollAcceleration(bool enabled) override {} - void SetTouchpadHapticFeedback(bool enabled) override {} - void SetTouchpadHapticClickSensitivity(int value) override {} - void SetMouseSensitivity(int value) override {} - void SetMouseScrollSensitivity(int value) override {} - void SetPrimaryButtonRight(bool right) override {} - void SetMouseReverseScroll(bool enabled) override {} - void SetMouseAcceleration(bool enabled) override {} - void SuspendMouseAcceleration() override {} - void EndMouseAccelerationSuspension() override {} - void SetMouseScrollAcceleration(bool enabled) override {} - void SetPointingStickSensitivity(int value) override {} - void SetPointingStickPrimaryButtonRight(bool right) override {} - void SetPointingStickAcceleration(bool enabled) override {} - void GetTouchDeviceStatus(GetTouchDeviceStatusReply reply) override { - std::move(reply).Run(std::string()); - } - void GetTouchEventLog(const base::FilePath& out_dir, - GetTouchEventLogReply reply) override { - std::move(reply).Run(std::vector()); - } - void SetTouchEventLoggingEnabled(bool enabled) override { - NOTIMPLEMENTED_LOG_ONCE(); - } - void SetTapToClickPaused(bool state) override {} - void SetInternalTouchpadEnabled(bool enabled) override {} - bool IsInternalTouchpadEnabled() const override { return false; } - void SetTouchscreensEnabled(bool enabled) override {} - void GetStylusSwitchState(GetStylusSwitchStateReply reply) override { - // Return that there is no stylus in the garage; this test class - // does not need to trigger stylus charging behaviours. - std::move(reply).Run(ui::StylusState::REMOVED); - } - void PlayVibrationEffect(int id, - uint8_t amplitude, - uint16_t duration_millis) override {} - void StopVibration(int id) override {} - void PlayHapticTouchpadEffect( - HapticTouchpadEffect effect, - HapticTouchpadEffectStrength strength) override { - send_haptic_count_[effect][strength]++; - } - void SetHapticTouchpadEffectForNextButtonRelease( - HapticTouchpadEffect effect, - HapticTouchpadEffectStrength strength) override {} - void SetInternalKeyboardFilter( - bool enable_filter, - std::vector allowed_keys) override {} - void GetGesturePropertiesService( - mojo::PendingReceiver - receiver) override {} - - // Return haptic count for effect/strength combination for testing. - int GetSendHapticCount(HapticTouchpadEffect effect, - HapticTouchpadEffectStrength strength) { - return send_haptic_count_[effect][strength]; - } - - private: - // A map of map that stores counts for given haptic effect/strength. - // This is used for testing only. - base::flat_map> - send_haptic_count_; -}; - using HapticsUtilTest = AshTestBase; // Test haptic feedback with all effect/strength combinations. TEST_F(HapticsUtilTest, HapticFeedbackBasic) { - auto input_controller = std::make_unique(); + auto input_controller = + std::make_unique(); std::vector effects = { HapticTouchpadEffect::kSnap, HapticTouchpadEffect::kKnock, @@ -158,7 +56,7 @@ TEST_F(HapticsUtilTest, HapticFeedbackBasic) { for (int count = 0; count < 16; count++) { haptics_util::PlayHapticTouchpadEffect(effect, strength); EXPECT_EQ(count + 1, - input_controller->GetSendHapticCount(effect, strength)); + input_controller->GetSentHapticCount(effect, strength)); } } } @@ -167,7 +65,8 @@ TEST_F(HapticsUtilTest, HapticFeedbackBasic) { // Test haptic feedback for normal window snapping. This covers drag to snap // primary/secondary/maximize. TEST_F(HapticsUtilTest, HapticFeedbackForNormalWindowSnap) { - auto input_controller = std::make_unique(); + auto input_controller = + std::make_unique(); UpdateDisplay("800x600"); gfx::Rect bounds(200, 200, 300, 300); @@ -192,7 +91,7 @@ TEST_F(HapticsUtilTest, HapticFeedbackForNormalWindowSnap) { event_generator->set_current_screen_location(start); event_generator->PressTouch(); event_generator->MoveTouch(test_case.first); - EXPECT_EQ(0, input_controller->GetSendHapticCount( + EXPECT_EQ(0, input_controller->GetSentHapticCount( HapticTouchpadEffect::kSnap, HapticTouchpadEffectStrength::kMedium)); event_generator->ReleaseTouch(); @@ -212,7 +111,7 @@ TEST_F(HapticsUtilTest, HapticFeedbackForNormalWindowSnap) { WorkspaceWindowResizer::GetInstanceForTest(); if (workspace_resizer->dwell_countdown_timer_.IsRunning()) workspace_resizer->dwell_countdown_timer_.FireNow(); - EXPECT_EQ((int)i + 1, input_controller->GetSendHapticCount( + EXPECT_EQ((int)i + 1, input_controller->GetSentHapticCount( HapticTouchpadEffect::kSnap, HapticTouchpadEffectStrength::kMedium)); event_generator->ReleaseLeftButton(); @@ -223,7 +122,8 @@ TEST_F(HapticsUtilTest, HapticFeedbackForNormalWindowSnap) { // Test haptic feedback for overview window snapping. This covers drag to split // in overview. TEST_F(HapticsUtilTest, HapticFeedbackForOverviewWindowSnap) { - auto input_controller = std::make_unique(); + auto input_controller = + std::make_unique(); OverviewController* overview_controller = Shell::Get()->overview_controller(); UpdateDisplay("800x600"); @@ -252,7 +152,7 @@ TEST_F(HapticsUtilTest, HapticFeedbackForOverviewWindowSnap) { event_generator->PressTouch(); event_generator->MoveTouch(test_case.first); EXPECT_TRUE(overview_controller->InOverviewSession()); - EXPECT_EQ(0, input_controller->GetSendHapticCount( + EXPECT_EQ(0, input_controller->GetSentHapticCount( HapticTouchpadEffect::kSnap, HapticTouchpadEffectStrength::kMedium)); event_generator->ReleaseTouch(); @@ -273,7 +173,7 @@ TEST_F(HapticsUtilTest, HapticFeedbackForOverviewWindowSnap) { event_generator->PressLeftButton(); event_generator->MoveMouseTo(test_case.first); EXPECT_TRUE(overview_controller->InOverviewSession()); - EXPECT_EQ((int)i + 1, input_controller->GetSendHapticCount( + EXPECT_EQ((int)i + 1, input_controller->GetSentHapticCount( HapticTouchpadEffect::kSnap, HapticTouchpadEffectStrength::kMedium)); event_generator->ReleaseLeftButton(); @@ -285,7 +185,8 @@ TEST_F(HapticsUtilTest, HapticFeedbackForOverviewWindowSnap) { // Test haptic feedback for off limits desk switching, e.g. swiping left from // the first desk and swiping right from the last desk. TEST_F(HapticsUtilTest, HapticFeedbackForDeskSwitchingOffLimits) { - auto input_controller = std::make_unique(); + auto input_controller = + std::make_unique(); auto* desk_controller = DesksController::Get(); // Make sure to start with two desks. @@ -293,14 +194,14 @@ TEST_F(HapticsUtilTest, HapticFeedbackForDeskSwitchingOffLimits) { EXPECT_EQ(2u, desk_controller->desks().size()); EXPECT_EQ(0, desk_controller->GetActiveDeskIndex()); EXPECT_EQ( - input_controller->GetSendHapticCount( + input_controller->GetSentHapticCount( HapticTouchpadEffect::kKnock, HapticTouchpadEffectStrength::kMedium), 0); // Swipe from `desk 0` to `desk 1` should not trigger `kKnock` effect. ScrollToSwitchDesks(/*scroll_left=*/false, GetEventGenerator()); EXPECT_EQ(1, desk_controller->GetActiveDeskIndex()); - EXPECT_EQ(0, input_controller->GetSendHapticCount( + EXPECT_EQ(0, input_controller->GetSentHapticCount( HapticTouchpadEffect::kKnock, HapticTouchpadEffectStrength::kMedium)); @@ -308,7 +209,7 @@ TEST_F(HapticsUtilTest, HapticFeedbackForDeskSwitchingOffLimits) { ScrollToSwitchDesks(/*scroll_left=*/false, /*event_generator=*/GetEventGenerator()); EXPECT_EQ(1, desk_controller->GetActiveDeskIndex()); - EXPECT_EQ(1, input_controller->GetSendHapticCount( + EXPECT_EQ(1, input_controller->GetSentHapticCount( HapticTouchpadEffect::kKnock, HapticTouchpadEffectStrength::kMedium)); } @@ -317,7 +218,8 @@ TEST_F(HapticsUtilTest, HapticFeedbackForDeskSwitchingOffLimits) { // switch desks. They are expected to be sent if we hit the edge, or when the // visible desk changes. TEST_F(HapticsUtilTest, HapticFeedbackForContinuousDesksSwitching) { - auto input_controller = std::make_unique(); + auto input_controller = + std::make_unique(); // Add three desks for a total of four. auto* desks_controller = DesksController::Get(); @@ -338,10 +240,10 @@ TEST_F(HapticsUtilTest, HapticFeedbackForContinuousDesksSwitching) { // Wait for the ending screenshot to be taken. WaitUntilEndingScreenshotTaken(&animation); - EXPECT_EQ(0, input_controller->GetSendHapticCount( + EXPECT_EQ(0, input_controller->GetSentHapticCount( HapticTouchpadEffect::kKnock, HapticTouchpadEffectStrength::kMedium)); - EXPECT_EQ(0, input_controller->GetSendHapticCount( + EXPECT_EQ(0, input_controller->GetSentHapticCount( HapticTouchpadEffect::kTick, HapticTouchpadEffectStrength::kMedium)); @@ -355,14 +257,14 @@ TEST_F(HapticsUtilTest, HapticFeedbackForContinuousDesksSwitching) { WaitUntilEndingScreenshotTaken(&animation); animation.UpdateSwipeAnimation(-kTouchpadSwipeLengthForDeskChange); - EXPECT_EQ(3, input_controller->GetSendHapticCount( + EXPECT_EQ(3, input_controller->GetSentHapticCount( HapticTouchpadEffect::kTick, HapticTouchpadEffectStrength::kMedium)); // Try doing a full swipe to the right. Test that a knock haptic event is sent // because we are at the edge. animation.UpdateSwipeAnimation(-kTouchpadSwipeLengthForDeskChange); - EXPECT_EQ(1, input_controller->GetSendHapticCount( + EXPECT_EQ(1, input_controller->GetSentHapticCount( HapticTouchpadEffect::kKnock, HapticTouchpadEffectStrength::kMedium)); @@ -371,21 +273,22 @@ TEST_F(HapticsUtilTest, HapticFeedbackForContinuousDesksSwitching) { animation.UpdateSwipeAnimation(kTouchpadSwipeLengthForDeskChange); animation.UpdateSwipeAnimation(kTouchpadSwipeLengthForDeskChange); animation.UpdateSwipeAnimation(kTouchpadSwipeLengthForDeskChange); - EXPECT_EQ(6, input_controller->GetSendHapticCount( + EXPECT_EQ(6, input_controller->GetSentHapticCount( HapticTouchpadEffect::kTick, HapticTouchpadEffectStrength::kMedium)); // Swipe to the left while at the first desk. Tests that another haptic event // is sent because we are at the edge. animation.UpdateSwipeAnimation(kTouchpadSwipeLengthForDeskChange); - EXPECT_EQ(2, input_controller->GetSendHapticCount( + EXPECT_EQ(2, input_controller->GetSentHapticCount( HapticTouchpadEffect::kKnock, HapticTouchpadEffectStrength::kMedium)); } // Tests that haptics are sent when dragging a window/desk in overview. TEST_F(HapticsUtilTest, HapticFeedbackForDragAndDrop) { - auto input_controller = std::make_unique(); + auto input_controller = + std::make_unique(); OverviewController* overview_controller = Shell::Get()->overview_controller(); std::unique_ptr window = CreateTestWindow(); @@ -405,7 +308,7 @@ TEST_F(HapticsUtilTest, HapticFeedbackForDragAndDrop) { gfx::ToRoundedPoint(bounds_f.CenterPoint())); event_generator->PressLeftButton(); event_generator->MoveMouseTo(gfx::ToRoundedPoint(bounds_f.right_center())); - EXPECT_EQ(1, input_controller->GetSendHapticCount( + EXPECT_EQ(1, input_controller->GetSentHapticCount( HapticTouchpadEffect::kTick, HapticTouchpadEffectStrength::kMedium)); event_generator->ReleaseLeftButton(); @@ -422,7 +325,7 @@ TEST_F(HapticsUtilTest, HapticFeedbackForDragAndDrop) { event_generator->set_current_screen_location(bounds.CenterPoint()); event_generator->PressLeftButton(); event_generator->MoveMouseTo(bounds.right_center()); - EXPECT_EQ(2, input_controller->GetSendHapticCount( + EXPECT_EQ(2, input_controller->GetSentHapticCount( HapticTouchpadEffect::kTick, HapticTouchpadEffectStrength::kMedium)); event_generator->ReleaseLeftButton();