app_list_metrics_unittest.cc 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927
  1. // Copyright 2019 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include <memory>
  5. #include <string>
  6. #include <utility>
  7. #include <vector>
  8. #include "ash/accessibility/accessibility_controller_impl.h"
  9. #include "ash/app_list/app_list_bubble_presenter.h"
  10. #include "ash/app_list/app_list_controller_impl.h"
  11. #include "ash/app_list/app_list_metrics.h"
  12. #include "ash/app_list/app_list_model_provider.h"
  13. #include "ash/app_list/app_list_presenter_impl.h"
  14. #include "ash/app_list/model/app_list_test_model.h"
  15. #include "ash/app_list/model/search/search_model.h"
  16. #include "ash/app_list/test/app_list_test_helper.h"
  17. #include "ash/app_list/views/app_list_item_view.h"
  18. #include "ash/app_list/views/app_list_main_view.h"
  19. #include "ash/app_list/views/app_list_view.h"
  20. #include "ash/app_list/views/apps_container_view.h"
  21. #include "ash/app_list/views/contents_view.h"
  22. #include "ash/app_list/views/paged_apps_grid_view.h"
  23. #include "ash/app_list/views/privacy_container_view.h"
  24. #include "ash/app_list/views/recent_apps_view.h"
  25. #include "ash/app_list/views/search_result_container_view.h"
  26. #include "ash/app_list/views/search_result_page_view.h"
  27. #include "ash/app_list/views/search_result_tile_item_list_view.h"
  28. #include "ash/app_list/views/search_result_tile_item_view.h"
  29. #include "ash/app_list/views/suggestion_chip_container_view.h"
  30. #include "ash/constants/ash_features.h"
  31. #include "ash/public/cpp/app_list/app_list_types.h"
  32. #include "ash/public/cpp/shelf_item_delegate.h"
  33. #include "ash/public/cpp/shelf_model.h"
  34. #include "ash/shelf/home_button.h"
  35. #include "ash/shelf/shelf.h"
  36. #include "ash/shelf/shelf_navigation_widget.h"
  37. #include "ash/shelf/shelf_view.h"
  38. #include "ash/shelf/shelf_view_test_api.h"
  39. #include "ash/shelf/shelf_widget.h"
  40. #include "ash/shell.h"
  41. #include "ash/test/ash_test_base.h"
  42. #include "ash/wm/tablet_mode/tablet_mode_controller.h"
  43. #include "base/test/metrics/histogram_tester.h"
  44. #include "base/test/scoped_feature_list.h"
  45. #include "ui/display/screen.h"
  46. namespace ash {
  47. namespace {
  48. constexpr int kBrowserAppIndexOnShelf = 0;
  49. // A test shelf item delegate that simulates an activated window when a shelf
  50. // item is selected.
  51. class TestShelfItemDelegate : public ShelfItemDelegate {
  52. public:
  53. explicit TestShelfItemDelegate(const ShelfID& shelf_id)
  54. : ShelfItemDelegate(shelf_id) {}
  55. void ItemSelected(std::unique_ptr<ui::Event> event,
  56. int64_t display_id,
  57. ash::ShelfLaunchSource source,
  58. ItemSelectedCallback callback,
  59. const ItemFilterPredicate& filter_predicate) override {
  60. std::move(callback).Run(SHELF_ACTION_WINDOW_ACTIVATED, {});
  61. }
  62. void ExecuteCommand(bool from_context_menu,
  63. int64_t command_id,
  64. int32_t event_flags,
  65. int64_t display_id) override {}
  66. void Close() override {}
  67. };
  68. } // namespace
  69. int64_t GetPrimaryDisplayId() {
  70. return display::Screen::GetScreen()->GetPrimaryDisplay().id();
  71. }
  72. // Used to test that app launched metrics are properly recorded.
  73. class AppListMetricsTest : public AshTestBase {
  74. public:
  75. AppListMetricsTest() = default;
  76. AppListMetricsTest(const AppListMetricsTest&) = delete;
  77. AppListMetricsTest& operator=(const AppListMetricsTest&) = delete;
  78. ~AppListMetricsTest() override = default;
  79. void SetUp() override {
  80. AshTestBase::SetUp();
  81. search_model_ = AppListModelProvider::Get()->search_model();
  82. shelf_test_api_ = std::make_unique<ShelfViewTestAPI>(
  83. GetPrimaryShelf()->GetShelfViewForTesting());
  84. }
  85. protected:
  86. void CreateAndClickShelfItem() {
  87. // Add shelf item to be launched. Waits for the shelf view's bounds
  88. // animations to end.
  89. ShelfItem shelf_item;
  90. shelf_item.id = ShelfID("app_id");
  91. shelf_item.type = TYPE_BROWSER_SHORTCUT;
  92. ShelfModel::Get()->Add(
  93. shelf_item, std::make_unique<TestShelfItemDelegate>(shelf_item.id));
  94. shelf_test_api_->RunMessageLoopUntilAnimationsDone();
  95. ClickShelfItem();
  96. }
  97. void ClickShelfItem() {
  98. // Get location of the shelf item.
  99. const views::ViewModel* view_model =
  100. GetPrimaryShelf()->GetShelfViewForTesting()->view_model_for_test();
  101. LeftClickOn(view_model->view_at(kBrowserAppIndexOnShelf));
  102. }
  103. void PopulateAndLaunchSearchBoxTileItem() {
  104. // Populate 4 tile items.
  105. for (size_t i = 0; i < 4; i++) {
  106. auto search_result = std::make_unique<SearchResult>();
  107. search_result->set_display_type(SearchResultDisplayType::kTile);
  108. search_model_->results()->Add(std::move(search_result));
  109. }
  110. GetAppListTestHelper()->WaitUntilIdle();
  111. // Mark the privacy notices as dismissed so that the tile items will be the
  112. // first search container.
  113. ContentsView* contents_view = Shell::Get()
  114. ->app_list_controller()
  115. ->fullscreen_presenter()
  116. ->GetView()
  117. ->app_list_main_view()
  118. ->contents_view();
  119. Shell::Get()->app_list_controller()->MarkSuggestedContentInfoDismissed();
  120. contents_view->search_result_page_view()
  121. ->GetPrivacyContainerViewForTest()
  122. ->Update();
  123. SearchResultContainerView* search_result_container_view =
  124. contents_view->search_result_page_view()
  125. ->GetSearchResultTileItemListViewForTest();
  126. // Request focus on the first tile item view.
  127. search_result_container_view->GetFirstResultView()->RequestFocus();
  128. // Press return to simulate an app launch from the tile item.
  129. PressAndReleaseKey(ui::KeyboardCode::VKEY_RETURN);
  130. }
  131. void PopulateAndLaunchSuggestionChip() {
  132. // Populate 4 suggestion chips.
  133. for (size_t i = 0; i < 4; i++) {
  134. auto search_result_chip = std::make_unique<SearchResult>();
  135. search_result_chip->set_display_type(SearchResultDisplayType::kChip);
  136. search_result_chip->set_is_recommendation(true);
  137. search_model_->results()->Add(std::move(search_result_chip));
  138. }
  139. GetAppListTestHelper()->WaitUntilIdle();
  140. SearchResultContainerView* suggestions_container_ =
  141. Shell::Get()
  142. ->app_list_controller()
  143. ->fullscreen_presenter()
  144. ->GetView()
  145. ->app_list_main_view()
  146. ->contents_view()
  147. ->apps_container_view()
  148. ->suggestion_chip_container_view_for_test();
  149. // Get focus on the first chip.
  150. suggestions_container_->children().front()->RequestFocus();
  151. GetAppListTestHelper()->WaitUntilIdle();
  152. // Press return to simulate an app launch from the suggestion chip.
  153. PressAndReleaseKey(ui::KeyboardCode::VKEY_RETURN);
  154. }
  155. void PopulateAndLaunchAppInGrid() {
  156. // Populate apps in the root app grid.
  157. AppListModel* model = AppListModelProvider::Get()->model();
  158. model->AddItem(std::make_unique<AppListItem>("item 0"));
  159. model->AddItem(std::make_unique<AppListItem>("item 1"));
  160. model->AddItem(std::make_unique<AppListItem>("item 2"));
  161. model->AddItem(std::make_unique<AppListItem>("item 3"));
  162. AppListView::TestApi test_api(
  163. Shell::Get()->app_list_controller()->fullscreen_presenter()->GetView());
  164. // Focus the first item in the root app grid.
  165. test_api.GetRootAppsGridView()->GetItemViewAt(0)->RequestFocus();
  166. // Press return to simulate an app launch from a grid item.
  167. PressAndReleaseKey(ui::KeyboardCode::VKEY_RETURN);
  168. }
  169. private:
  170. SearchModel* search_model_ = nullptr;
  171. std::unique_ptr<ShelfViewTestAPI> shelf_test_api_;
  172. };
  173. // Suite for tests that only apply to peeking launcher (and can be deleted when
  174. // ProductivityLauncher is the default).
  175. class AppListMetricsPeekingLauncherTest : public AppListMetricsTest {
  176. public:
  177. AppListMetricsPeekingLauncherTest() {
  178. scoped_feature_list_.InitAndDisableFeature(features::kProductivityLauncher);
  179. }
  180. ~AppListMetricsPeekingLauncherTest() override = default;
  181. base::test::ScopedFeatureList scoped_feature_list_;
  182. };
  183. // Test that the histogram records an app launch from the shelf while the half
  184. // launcher is showing.
  185. TEST_F(AppListMetricsPeekingLauncherTest, HalfLaunchFromShelf) {
  186. base::HistogramTester histogram_tester;
  187. GetAppListTestHelper()->ShowAndRunLoop(GetPrimaryDisplayId());
  188. GetAppListTestHelper()->CheckState(AppListViewState::kPeeking);
  189. // Press a letter key, the AppListView should transition to kHalf.
  190. PressAndReleaseKey(ui::KeyboardCode::VKEY_H);
  191. GetAppListTestHelper()->CheckState(AppListViewState::kHalf);
  192. CreateAndClickShelfItem();
  193. GetAppListTestHelper()->WaitUntilIdle();
  194. histogram_tester.ExpectBucketCount(
  195. "Apps.AppListAppLaunchedV2.Half", AppListLaunchedFrom::kLaunchedFromShelf,
  196. 1 /* Number of times launched from shelf */);
  197. }
  198. // Test that the histogram records an app launch from the search box while the
  199. // half launcher is showing.
  200. TEST_F(AppListMetricsPeekingLauncherTest, HalfLaunchFromSearchBox) {
  201. base::HistogramTester histogram_tester;
  202. GetAppListTestHelper()->ShowAndRunLoop(GetPrimaryDisplayId());
  203. GetAppListTestHelper()->CheckState(AppListViewState::kPeeking);
  204. // Press a letter key, the AppListView should transition to kHalf.
  205. PressAndReleaseKey(ui::KeyboardCode::VKEY_H);
  206. GetAppListTestHelper()->CheckState(AppListViewState::kHalf);
  207. PopulateAndLaunchSearchBoxTileItem();
  208. histogram_tester.ExpectBucketCount(
  209. "Apps.AppListAppLaunchedV2.Half",
  210. AppListLaunchedFrom::kLaunchedFromSearchBox,
  211. 1 /* Number of times launched from search box */);
  212. }
  213. // Test that the histogram records an app launch from the search box while the
  214. // fullscreen search launcher is showing.
  215. TEST_F(AppListMetricsPeekingLauncherTest, FullscreenSearchLaunchFromSearchBox) {
  216. base::HistogramTester histogram_tester;
  217. // Press search + shift to transition to kFullscreenAllApps.
  218. PressAndReleaseKey(ui::KeyboardCode::VKEY_BROWSER_SEARCH, ui::EF_SHIFT_DOWN);
  219. GetAppListTestHelper()->CheckState(AppListViewState::kFullscreenAllApps);
  220. // Press a letter key, the AppListView should transition to kFullscreenSearch.
  221. PressAndReleaseKey(ui::KeyboardCode::VKEY_H);
  222. GetAppListTestHelper()->CheckState(AppListViewState::kFullscreenSearch);
  223. PopulateAndLaunchSearchBoxTileItem();
  224. GetAppListTestHelper()->WaitUntilIdle();
  225. histogram_tester.ExpectBucketCount(
  226. "Apps.AppListAppLaunchedV2.FullscreenSearch",
  227. AppListLaunchedFrom::kLaunchedFromSearchBox,
  228. 1 /* Number of times launched from search box */);
  229. }
  230. // Test that the histogram records an app launch from the shelf while the
  231. // fullscreen search launcher is showing.
  232. TEST_F(AppListMetricsPeekingLauncherTest, FullscreenSearchLaunchFromShelf) {
  233. base::HistogramTester histogram_tester;
  234. // Press search + shift to transition to kFullscreenAllApps.
  235. PressAndReleaseKey(ui::KeyboardCode::VKEY_BROWSER_SEARCH, ui::EF_SHIFT_DOWN);
  236. GetAppListTestHelper()->CheckState(AppListViewState::kFullscreenAllApps);
  237. // Press a letter key, the AppListView should transition to kFullscreenSearch.
  238. PressAndReleaseKey(ui::KeyboardCode::VKEY_H);
  239. GetAppListTestHelper()->CheckState(AppListViewState::kFullscreenSearch);
  240. CreateAndClickShelfItem();
  241. histogram_tester.ExpectBucketCount(
  242. "Apps.AppListAppLaunchedV2.FullscreenSearch",
  243. AppListLaunchedFrom::kLaunchedFromShelf,
  244. 1 /* Number of times launched from shelf */);
  245. }
  246. // Test that the histogram records an app launch from a suggestion chip while
  247. // the fullscreen all apps launcher is showing.
  248. TEST_F(AppListMetricsPeekingLauncherTest, FullscreenAllAppsLaunchFromChip) {
  249. base::HistogramTester histogram_tester;
  250. // Press search + shift to transition to kFullscreenAllApps.
  251. PressAndReleaseKey(ui::KeyboardCode::VKEY_BROWSER_SEARCH, ui::EF_SHIFT_DOWN);
  252. GetAppListTestHelper()->CheckState(AppListViewState::kFullscreenAllApps);
  253. PopulateAndLaunchSuggestionChip();
  254. histogram_tester.ExpectBucketCount(
  255. "Apps.AppListAppLaunchedV2.FullscreenAllApps",
  256. AppListLaunchedFrom::kLaunchedFromSuggestionChip,
  257. 1 /* Number of times launched from chip */);
  258. }
  259. // Test that the histogram records an app launch from the app grid while the
  260. // fullscreen all apps launcher is showing.
  261. TEST_F(AppListMetricsPeekingLauncherTest, FullscreenAllAppsLaunchFromGrid) {
  262. base::HistogramTester histogram_tester;
  263. // Press search + shift to transition to kFullscreenAllApps.
  264. PressAndReleaseKey(ui::KeyboardCode::VKEY_BROWSER_SEARCH, ui::EF_SHIFT_DOWN);
  265. GetAppListTestHelper()->CheckState(AppListViewState::kFullscreenAllApps);
  266. PopulateAndLaunchAppInGrid();
  267. histogram_tester.ExpectBucketCount(
  268. "Apps.AppListAppLaunchedV2.FullscreenAllApps",
  269. AppListLaunchedFrom::kLaunchedFromGrid,
  270. 1 /* Number of times launched from grid */);
  271. }
  272. // Test that the histogram records an app launch from the shelf while the
  273. // fullscreen all apps launcher is showing.
  274. TEST_F(AppListMetricsPeekingLauncherTest, FullscreenAllAppsLaunchFromShelf) {
  275. base::HistogramTester histogram_tester;
  276. // Press search + shift to transition to kFullscreenAllApps.
  277. PressAndReleaseKey(ui::KeyboardCode::VKEY_BROWSER_SEARCH, ui::EF_SHIFT_DOWN);
  278. GetAppListTestHelper()->CheckState(AppListViewState::kFullscreenAllApps);
  279. CreateAndClickShelfItem();
  280. histogram_tester.ExpectBucketCount(
  281. "Apps.AppListAppLaunchedV2.FullscreenAllApps",
  282. AppListLaunchedFrom::kLaunchedFromShelf,
  283. 1 /* Number of times launched from shelf */);
  284. }
  285. // Test that the histogram records an app launch from the shelf while the
  286. // peeking launcher is showing.
  287. TEST_F(AppListMetricsPeekingLauncherTest, PeekingLaunchFromShelf) {
  288. base::HistogramTester histogram_tester;
  289. GetAppListTestHelper()->ShowAndRunLoop(GetPrimaryDisplayId());
  290. GetAppListTestHelper()->CheckState(AppListViewState::kPeeking);
  291. CreateAndClickShelfItem();
  292. histogram_tester.ExpectBucketCount(
  293. "Apps.AppListAppLaunchedV2.Peeking",
  294. AppListLaunchedFrom::kLaunchedFromShelf,
  295. 1 /* Number of times launched from shelf */);
  296. }
  297. // Test that the histogram records an app launch from a suggestion chip while
  298. // the peeking launcher is showing.
  299. TEST_F(AppListMetricsPeekingLauncherTest, PeekingLaunchFromChip) {
  300. base::HistogramTester histogram_tester;
  301. GetAppListTestHelper()->ShowAndRunLoop(GetPrimaryDisplayId());
  302. GetAppListTestHelper()->CheckState(AppListViewState::kPeeking);
  303. PopulateAndLaunchSuggestionChip();
  304. histogram_tester.ExpectBucketCount(
  305. "Apps.AppListAppLaunchedV2.Peeking",
  306. AppListLaunchedFrom::kLaunchedFromSuggestionChip,
  307. 1 /* Number of times launched from chip */);
  308. }
  309. // Test that the histogram records an app launch from the shelf while the
  310. // launcher is closed.
  311. TEST_F(AppListMetricsPeekingLauncherTest, ClosedLaunchFromShelf) {
  312. base::HistogramTester histogram_tester;
  313. GetAppListTestHelper()->CheckState(AppListViewState::kClosed);
  314. CreateAndClickShelfItem();
  315. histogram_tester.ExpectBucketCount(
  316. "Apps.AppListAppLaunchedV2.Closed",
  317. AppListLaunchedFrom::kLaunchedFromShelf,
  318. 1 /* Number of times launched from shelf */);
  319. // Open the launcher to peeking.
  320. PressAndReleaseKey(ui::KeyboardCode::VKEY_BROWSER_SEARCH);
  321. GetAppListTestHelper()->CheckState(AppListViewState::kPeeking);
  322. // Close launcher back to closed.
  323. PressAndReleaseKey(ui::KeyboardCode::VKEY_BROWSER_SEARCH);
  324. GetAppListTestHelper()->CheckState(AppListViewState::kClosed);
  325. ClickShelfItem();
  326. histogram_tester.ExpectBucketCount(
  327. "Apps.AppListAppLaunchedV2.Closed",
  328. AppListLaunchedFrom::kLaunchedFromShelf,
  329. 2 /* Number of times launched from shelf */);
  330. }
  331. // Suite for tests that run in tablet mode, parameterized by feature
  332. // ProductivityLauncher.
  333. class AppListMetricsTabletTest : public AppListMetricsTest,
  334. public testing::WithParamInterface<bool> {
  335. public:
  336. AppListMetricsTabletTest() {
  337. const bool enable = GetParam();
  338. feature_list_.InitWithFeatureState(features::kProductivityLauncher, enable);
  339. }
  340. ~AppListMetricsTabletTest() override = default;
  341. base::test::ScopedFeatureList feature_list_;
  342. };
  343. INSTANTIATE_TEST_SUITE_P(ProductivityLauncher,
  344. AppListMetricsTabletTest,
  345. testing::Bool());
  346. // Test that the histogram records an app launch from the shelf while the
  347. // homecher all apps state is showing.
  348. TEST_P(AppListMetricsTabletTest, HomecherAllAppsLaunchFromShelf) {
  349. Shell::Get()->tablet_mode_controller()->SetEnabledForTest(true);
  350. base::HistogramTester histogram_tester;
  351. GetAppListTestHelper()->CheckState(AppListViewState::kFullscreenAllApps);
  352. CreateAndClickShelfItem();
  353. histogram_tester.ExpectBucketCount(
  354. "Apps.AppListAppLaunchedV2.HomecherAllApps",
  355. AppListLaunchedFrom::kLaunchedFromShelf,
  356. 1 /* Number of times launched from shelf */);
  357. }
  358. // Test that the histogram records an app launch from the app grid while the
  359. // homecher all apps state is showing.
  360. TEST_P(AppListMetricsTabletTest, HomecherAllAppsLaunchFromGrid) {
  361. base::HistogramTester histogram_tester;
  362. // Enable tablet mode.
  363. Shell::Get()->tablet_mode_controller()->SetEnabledForTest(true);
  364. GetAppListTestHelper()->CheckState(AppListViewState::kFullscreenAllApps);
  365. PopulateAndLaunchAppInGrid();
  366. histogram_tester.ExpectBucketCount(
  367. "Apps.AppListAppLaunchedV2.HomecherAllApps",
  368. AppListLaunchedFrom::kLaunchedFromGrid,
  369. 1 /* Number of times launched from grid */);
  370. }
  371. // Test that the histogram records an app launch from a suggestion chip while
  372. // the homecher all apps state is showing.
  373. TEST_P(AppListMetricsTabletTest, HomecherAllAppsLaunchFromChip) {
  374. // ProductivityLauncher does not use suggestion chips.
  375. if (features::IsProductivityLauncherEnabled())
  376. return;
  377. base::HistogramTester histogram_tester;
  378. GetAppListTestHelper()->WaitUntilIdle();
  379. // Enable tablet mode.
  380. Shell::Get()->tablet_mode_controller()->SetEnabledForTest(true);
  381. GetAppListTestHelper()->CheckState(AppListViewState::kFullscreenAllApps);
  382. PopulateAndLaunchSuggestionChip();
  383. histogram_tester.ExpectBucketCount(
  384. "Apps.AppListAppLaunchedV2.HomecherAllApps",
  385. AppListLaunchedFrom::kLaunchedFromSuggestionChip,
  386. 1 /* Number of times launched from chip */);
  387. }
  388. // Test that the histogram records an app launch from the shelf while the
  389. // homecher search state is showing.
  390. TEST_P(AppListMetricsTabletTest, HomecherSearchLaunchFromShelf) {
  391. base::HistogramTester histogram_tester;
  392. // Enable tablet mode.
  393. GetAppListTestHelper()->WaitUntilIdle();
  394. Shell::Get()->tablet_mode_controller()->SetEnabledForTest(true);
  395. // Press a letter key, the AppListView should transition to kFullscreenSearch.
  396. PressAndReleaseKey(ui::KeyboardCode::VKEY_H);
  397. GetAppListTestHelper()->WaitUntilIdle();
  398. GetAppListTestHelper()->CheckState(AppListViewState::kFullscreenSearch);
  399. CreateAndClickShelfItem();
  400. histogram_tester.ExpectBucketCount(
  401. "Apps.AppListAppLaunchedV2.HomecherSearch",
  402. AppListLaunchedFrom::kLaunchedFromShelf,
  403. 1 /* Number of times launched from shelf */);
  404. }
  405. // Test that the histogram records an app launch from the search box while the
  406. // homercher search state is showing.
  407. TEST_P(AppListMetricsTabletTest, HomecherSearchLaunchFromSearchBox) {
  408. // ProductivityLauncher does not tile search results.
  409. if (features::IsProductivityLauncherEnabled())
  410. return;
  411. base::HistogramTester histogram_tester;
  412. // Enable tablet mode.
  413. GetAppListTestHelper()->WaitUntilIdle();
  414. Shell::Get()->tablet_mode_controller()->SetEnabledForTest(true);
  415. // Press a letter key, the AppListView should transition to kFullscreenSearch.
  416. PressAndReleaseKey(ui::KeyboardCode::VKEY_H);
  417. GetAppListTestHelper()->WaitUntilIdle();
  418. GetAppListTestHelper()->CheckState(AppListViewState::kFullscreenSearch);
  419. // Populate search box with tile items and launch a tile item.
  420. PopulateAndLaunchSearchBoxTileItem();
  421. histogram_tester.ExpectBucketCount(
  422. "Apps.AppListAppLaunchedV2.HomecherSearch",
  423. AppListLaunchedFrom::kLaunchedFromSearchBox,
  424. 1 /* Number of times launched from search box */);
  425. }
  426. // Tests with feature ProductivityLauncher enabled.
  427. class AppListMetricsProductivityLauncherTest : public AppListMetricsTest {
  428. public:
  429. AppListMetricsProductivityLauncherTest() {
  430. scoped_feature_list_.InitWithFeatures({features::kProductivityLauncher},
  431. {});
  432. }
  433. ~AppListMetricsProductivityLauncherTest() override = default;
  434. base::test::ScopedFeatureList scoped_feature_list_;
  435. };
  436. // Test that the histogram records an app launch from a recent app suggestion
  437. // while the bubble launcher all apps is showing.
  438. TEST_F(AppListMetricsProductivityLauncherTest,
  439. BubbleAllAppsLaunchFromRecentApps) {
  440. base::HistogramTester histogram_tester;
  441. auto* helper = GetAppListTestHelper();
  442. helper->WaitUntilIdle();
  443. helper->AddRecentApps(5);
  444. helper->AddAppItems(5);
  445. helper->ShowAppList();
  446. helper->WaitUntilIdle();
  447. views::View* recent_apps = helper->GetBubbleRecentAppsView();
  448. // Get focus on the first chip.
  449. recent_apps->children().front()->RequestFocus();
  450. helper->WaitUntilIdle();
  451. // Press return to simulate an app launch from the recent apps.
  452. PressAndReleaseKey(ui::KeyboardCode::VKEY_RETURN);
  453. helper->WaitUntilIdle();
  454. histogram_tester.ExpectBucketCount(
  455. "Apps.AppListAppLaunchedV2.BubbleAllApps",
  456. AppListLaunchedFrom::kLaunchedFromRecentApps,
  457. 1 /* Number of times launched from chip */);
  458. }
  459. TEST_F(AppListMetricsProductivityLauncherTest,
  460. HideContinueSectionMetricInClamshellMode) {
  461. base::test::ScopedFeatureList feature_list(
  462. features::kLauncherHideContinueSection);
  463. base::HistogramTester histograms;
  464. // Show the app list with a full continue section.
  465. auto* helper = GetAppListTestHelper();
  466. helper->AddContinueSuggestionResults(4);
  467. helper->AddRecentApps(5);
  468. helper->AddAppItems(5);
  469. helper->ShowAppList();
  470. // Metric is recorded in false bucket.
  471. const int false_bucket = 0;
  472. histograms.ExpectBucketCount(
  473. "Apps.AppList.ContinueSectionHiddenByUser.ClamshellMode", false_bucket,
  474. 1);
  475. helper->Dismiss();
  476. // Hide the continue section, then show the app list.
  477. Shell::Get()->app_list_controller()->SetHideContinueSection(true);
  478. helper->ShowAppList();
  479. // Metric is recorded in true bucket.
  480. const int true_bucket = 1;
  481. histograms.ExpectBucketCount(
  482. "Apps.AppList.ContinueSectionHiddenByUser.ClamshellMode", true_bucket, 1);
  483. helper->Dismiss();
  484. }
  485. TEST_F(AppListMetricsProductivityLauncherTest,
  486. HideContinueSectionMetricInTabletMode) {
  487. base::test::ScopedFeatureList feature_list(
  488. features::kLauncherHideContinueSection);
  489. base::HistogramTester histograms;
  490. // Show the tablet mode app list with a full continue section.
  491. auto* helper = GetAppListTestHelper();
  492. helper->AddContinueSuggestionResults(4);
  493. helper->AddRecentApps(5);
  494. helper->AddAppItems(5);
  495. Shell::Get()->tablet_mode_controller()->SetEnabledForTest(true);
  496. // Metric is recorded in false bucket.
  497. const int false_bucket = 0;
  498. histograms.ExpectBucketCount(
  499. "Apps.AppList.ContinueSectionHiddenByUser.TabletMode", false_bucket, 1);
  500. Shell::Get()->tablet_mode_controller()->SetEnabledForTest(false);
  501. // Hide the continue section, then show the tablet mode app list.
  502. Shell::Get()->app_list_controller()->SetHideContinueSection(true);
  503. Shell::Get()->tablet_mode_controller()->SetEnabledForTest(true);
  504. // Metric is recorded in true bucket.
  505. const int true_bucket = 1;
  506. histograms.ExpectBucketCount(
  507. "Apps.AppList.ContinueSectionHiddenByUser.TabletMode", true_bucket, 1);
  508. }
  509. // Test that the histogram records an app launch from a recent app suggestion
  510. // while the homecher all apps is showing.
  511. TEST_F(AppListMetricsProductivityLauncherTest, HomecherLaunchFromRecentApps) {
  512. base::HistogramTester histogram_tester;
  513. auto* helper = GetAppListTestHelper();
  514. helper->WaitUntilIdle();
  515. helper->AddRecentApps(5);
  516. helper->AddAppItems(5);
  517. Shell::Get()->tablet_mode_controller()->SetEnabledForTest(true);
  518. helper->WaitUntilIdle();
  519. views::View* recent_apps = helper->GetFullscreenRecentAppsView();
  520. // Get focus on the first chip.
  521. recent_apps->children().front()->RequestFocus();
  522. helper->WaitUntilIdle();
  523. // Press return to simulate an app launch from the recent apps.
  524. PressAndReleaseKey(ui::KeyboardCode::VKEY_RETURN);
  525. helper->WaitUntilIdle();
  526. histogram_tester.ExpectBucketCount(
  527. "Apps.AppListAppLaunchedV2.HomecherAllApps",
  528. AppListLaunchedFrom::kLaunchedFromRecentApps,
  529. 1 /* Number of times launched from chip */);
  530. }
  531. class AppListShowSourceMetricTest : public AshTestBase {
  532. public:
  533. AppListShowSourceMetricTest() = default;
  534. AppListShowSourceMetricTest(const AppListShowSourceMetricTest&) = delete;
  535. AppListShowSourceMetricTest& operator=(const AppListShowSourceMetricTest&) =
  536. delete;
  537. ~AppListShowSourceMetricTest() override = default;
  538. protected:
  539. void ClickHomeButton() {
  540. LeftClickOn(GetPrimaryShelf()->navigation_widget()->GetHomeButton());
  541. }
  542. };
  543. // In tablet mode, test that AppListShowSource metric is only recorded when
  544. // pressing home button when not already home. Any presses on the home button
  545. // when already home should do nothing.
  546. TEST_F(AppListShowSourceMetricTest, TabletInAppToHome) {
  547. base::HistogramTester histogram_tester;
  548. // Enable accessibility feature that forces home button to be shown in tablet
  549. // mode.
  550. Shell::Get()
  551. ->accessibility_controller()
  552. ->SetTabletModeShelfNavigationButtonsEnabled(true);
  553. std::unique_ptr<views::Widget> widget = CreateTestWidget();
  554. Shell::Get()->tablet_mode_controller()->SetEnabledForTest(true);
  555. ClickHomeButton();
  556. histogram_tester.ExpectBucketCount(
  557. "Apps.AppListShowSource", kShelfButton,
  558. 1 /* Number of times app list is shown with a shelf button */);
  559. histogram_tester.ExpectBucketCount(
  560. "Apps.AppListShowSource", kTabletMode,
  561. 0 /* Number of times app list is shown by tablet mode transition */);
  562. GetAppListTestHelper()->CheckVisibility(true);
  563. // Ensure that any subsequent clicks while already at home do not count as
  564. // showing the app list.
  565. ClickHomeButton();
  566. histogram_tester.ExpectBucketCount(
  567. "Apps.AppListShowSource", kShelfButton,
  568. 1 /* Number of times app list shown with a shelf button */);
  569. histogram_tester.ExpectTotalCount("Apps.AppListShowSource", 1);
  570. }
  571. // Ensure that app list is not recorded as shown when going to tablet mode with
  572. // a window open.
  573. TEST_F(AppListShowSourceMetricTest, TabletModeWithWindowOpen) {
  574. base::HistogramTester histogram_tester;
  575. std::unique_ptr<views::Widget> widget = CreateTestWidget();
  576. Shell::Get()->tablet_mode_controller()->SetEnabledForTest(true);
  577. GetAppListTestHelper()->CheckVisibility(false);
  578. // Ensure that no AppListShowSource metric was recorded.
  579. histogram_tester.ExpectTotalCount("Apps.AppListShowSource", 0);
  580. }
  581. // Ensure that app list is recorded as shown when going to tablet mode with no
  582. // other windows open.
  583. TEST_F(AppListShowSourceMetricTest, TabletModeWithNoWindowOpen) {
  584. base::HistogramTester histogram_tester;
  585. Shell::Get()->tablet_mode_controller()->SetEnabledForTest(true);
  586. GetAppListTestHelper()->CheckVisibility(true);
  587. histogram_tester.ExpectBucketCount(
  588. "Apps.AppListShowSource", kTabletMode,
  589. 1 /* Number of times app list shown after entering tablet mode */);
  590. }
  591. class AppListBubbleShowSourceMetricTest : public AppListShowSourceMetricTest {
  592. public:
  593. AppListBubbleShowSourceMetricTest() {
  594. scoped_feature_list_.InitWithFeatures({features::kProductivityLauncher},
  595. {});
  596. }
  597. ~AppListBubbleShowSourceMetricTest() override = default;
  598. base::test::ScopedFeatureList scoped_feature_list_;
  599. };
  600. // Tests that showing the bubble launcher in clamshell mode records the proper
  601. // metrics for Apps.AppListBubbleShowSource.
  602. TEST_F(AppListBubbleShowSourceMetricTest, ClamshellModeHomeButton) {
  603. base::HistogramTester histogram_tester;
  604. auto* app_list_bubble_presenter =
  605. Shell::Get()->app_list_controller()->bubble_presenter_for_test();
  606. // Show the Bubble AppList.
  607. GetAppListTestHelper()->ShowAndRunLoop(GetPrimaryDisplayId());
  608. EXPECT_TRUE(app_list_bubble_presenter->IsShowing());
  609. // Test that the proper histogram is logged.
  610. histogram_tester.ExpectTotalCount("Apps.AppListBubbleShowSource", 1);
  611. // Hide the Bubble AppList.
  612. GetAppListTestHelper()->Dismiss();
  613. EXPECT_FALSE(app_list_bubble_presenter->IsShowing());
  614. // Test that no histograms were logged.
  615. histogram_tester.ExpectTotalCount("Apps.AppListBubbleShowSource", 1);
  616. // Show the Bubble AppList one more time.
  617. GetAppListTestHelper()->ShowAndRunLoop(GetPrimaryDisplayId());
  618. EXPECT_TRUE(app_list_bubble_presenter->IsShowing());
  619. // Test that the histogram records 2 total shows.
  620. histogram_tester.ExpectTotalCount("Apps.AppListBubbleShowSource", 2);
  621. // Test that no fullscreen app list metrics were recorded.
  622. histogram_tester.ExpectTotalCount("Apps.AppListShowSource", 0);
  623. }
  624. // Test that tablet mode launcher operations do not record AppListBubble
  625. // metrics.
  626. TEST_F(AppListBubbleShowSourceMetricTest,
  627. TabletModeDoesNotRecordAppListBubbleShow) {
  628. base::HistogramTester histogram_tester;
  629. // Enable accessibility feature that forces home button to be shown in tablet
  630. // mode.
  631. Shell::Get()
  632. ->accessibility_controller()
  633. ->SetTabletModeShelfNavigationButtonsEnabled(true);
  634. // Go to tablet mode, the tablet mode (non bubble) launcher will show. Create
  635. // a test widget so the launcher will show in the background.
  636. std::unique_ptr<views::Widget> widget = CreateTestWidget();
  637. Shell::Get()->tablet_mode_controller()->SetEnabledForTest(true);
  638. auto* app_list_bubble_presenter =
  639. Shell::Get()->app_list_controller()->bubble_presenter_for_test();
  640. EXPECT_FALSE(app_list_bubble_presenter->IsShowing());
  641. // Ensure that no AppListBubbleShowSource metric was recorded.
  642. histogram_tester.ExpectTotalCount("Apps.AppListBubbleShowSource", 0);
  643. // Press the Home Button, which hides `widget` and shows the tablet mode
  644. // launcher.
  645. ClickHomeButton();
  646. EXPECT_FALSE(app_list_bubble_presenter->IsShowing());
  647. // Test that no bubble launcher metrics were recorded.
  648. histogram_tester.ExpectTotalCount("Apps.AppListBubbleShowSource", 0);
  649. }
  650. // Tests that toggling the bubble launcher does not record metrics when the
  651. // result of the toggle is that the launcher is hidden.
  652. TEST_F(AppListBubbleShowSourceMetricTest, ToggleDoesNotRecordOnHide) {
  653. base::HistogramTester histogram_tester;
  654. auto* app_list_controller = Shell::Get()->app_list_controller();
  655. // Toggle the app list to show it.
  656. app_list_controller->ToggleAppList(GetPrimaryDisplayId(),
  657. AppListShowSource::kSearchKey,
  658. base::TimeTicks::Now());
  659. auto* app_list_bubble_presenter =
  660. Shell::Get()->app_list_controller()->bubble_presenter_for_test();
  661. ASSERT_TRUE(app_list_bubble_presenter->IsShowing());
  662. // Toggle the app list once more, to hide it.
  663. app_list_controller->ToggleAppList(GetPrimaryDisplayId(),
  664. AppListShowSource::kSearchKey,
  665. base::TimeTicks::Now());
  666. ASSERT_FALSE(app_list_bubble_presenter->IsShowing());
  667. // Test that only one show was recorded.
  668. histogram_tester.ExpectTotalCount("Apps.AppListBubbleShowSource", 1);
  669. }
  670. using AppListPeriodicMetricsTest = AshTestBase;
  671. // Verify that the number of items in the app list are recorded correctly.
  672. TEST_F(AppListPeriodicMetricsTest, PeriodicAppListMetrics_NumberOfApps) {
  673. base::HistogramTester histogram;
  674. histogram.ExpectTotalCount("Apps.AppList.NumberOfApps", 0);
  675. histogram.ExpectTotalCount("Apps.AppList.NumberOfRootLevelItems", 0);
  676. AppListModel* model = AppListModelProvider::Get()->model();
  677. // Add 5 items to the app list.
  678. for (int i = 0; i < 5; i++) {
  679. model->AddItem(
  680. std::make_unique<AppListItem>(base::StringPrintf("app_id_%d", i)));
  681. }
  682. // Check that 5 items are recorded as being in the app list.
  683. RecordPeriodicAppListMetrics();
  684. histogram.ExpectBucketCount("Apps.AppList.NumberOfApps", 5, 1);
  685. histogram.ExpectBucketCount("Apps.AppList.NumberOfRootLevelItems", 5, 1);
  686. histogram.ExpectTotalCount("Apps.AppList.NumberOfApps", 1);
  687. histogram.ExpectTotalCount("Apps.AppList.NumberOfRootLevelItems", 1);
  688. // Create a folder and add 3 items to it.
  689. const std::string folder_id = "folder_id";
  690. model->CreateFolderItem(folder_id);
  691. for (int i = 0; i < 3; i++) {
  692. auto item =
  693. std::make_unique<AppListItem>(base::StringPrintf("id_in_folder_%d", i));
  694. model->AddItemToFolder(std::move(item), folder_id);
  695. }
  696. // Check that the folder and its items are recorded in the metrics.
  697. RecordPeriodicAppListMetrics();
  698. histogram.ExpectBucketCount("Apps.AppList.NumberOfApps", 8, 1);
  699. histogram.ExpectBucketCount("Apps.AppList.NumberOfRootLevelItems", 6, 1);
  700. }
  701. TEST_F(AppListPeriodicMetricsTest, RecordFolderMetrics_ZeroFolders) {
  702. base::HistogramTester histogram;
  703. GetAppListTestHelper()->model()->PopulateApps(2);
  704. RecordPeriodicAppListMetrics();
  705. // 1 sample in the 0 folders bucket.
  706. EXPECT_EQ(1, histogram.GetBucketCount("Apps.AppList.NumberOfFolders", 0));
  707. // 1 sample in the 0 folders bucket.
  708. EXPECT_EQ(
  709. 1, histogram.GetBucketCount("Apps.AppList.NumberOfNonSystemFolders", 0));
  710. // 1 sample in the 0 apps bucket.
  711. EXPECT_EQ(1, histogram.GetBucketCount(
  712. "Apps.AppList.NumberOfAppsInNonSystemFolders", 0));
  713. }
  714. TEST_F(AppListPeriodicMetricsTest, RecordFolderMetrics_OneRegularFolder) {
  715. base::HistogramTester histogram;
  716. GetAppListTestHelper()->model()->CreateAndPopulateFolderWithApps(2);
  717. RecordPeriodicAppListMetrics();
  718. // 1 sample in the 1 folder bucket.
  719. EXPECT_EQ(1, histogram.GetBucketCount("Apps.AppList.NumberOfFolders", 1));
  720. // 1 sample in the 1 folder bucket.
  721. EXPECT_EQ(
  722. 1, histogram.GetBucketCount("Apps.AppList.NumberOfNonSystemFolders", 1));
  723. // 1 sample in the 2 apps bucket.
  724. EXPECT_EQ(1, histogram.GetBucketCount(
  725. "Apps.AppList.NumberOfAppsInNonSystemFolders", 2));
  726. }
  727. TEST_F(AppListPeriodicMetricsTest, RecordFolderMetrics_SystemFolder) {
  728. base::HistogramTester histogram;
  729. AppListFolderItem* folder =
  730. GetAppListTestHelper()->model()->CreateSingleItemFolder("folder_id",
  731. "item_id");
  732. folder->SetIsSystemFolder(true);
  733. RecordPeriodicAppListMetrics();
  734. // 1 sample in the 1 folder bucket.
  735. EXPECT_EQ(1, histogram.GetBucketCount("Apps.AppList.NumberOfFolders", 1));
  736. // 1 sample in the 0 folders bucket, because the folder is a system folder.
  737. EXPECT_EQ(
  738. 1, histogram.GetBucketCount("Apps.AppList.NumberOfNonSystemFolders", 0));
  739. // 1 sample in the 0 apps bucket, because items in system folders don't count.
  740. EXPECT_EQ(1, histogram.GetBucketCount(
  741. "Apps.AppList.NumberOfAppsInNonSystemFolders", 0));
  742. }
  743. } // namespace ash