app_list_metrics.cc 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573
  1. // Copyright 2018 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 "ash/app_list/app_list_metrics.h"
  5. #include <algorithm>
  6. #include <string>
  7. #include "ash/app_list/app_list_controller_impl.h"
  8. #include "ash/app_list/app_list_model_provider.h"
  9. #include "ash/app_list/model/app_list_folder_item.h"
  10. #include "ash/app_list/model/app_list_item.h"
  11. #include "ash/app_list/model/app_list_item_list.h"
  12. #include "ash/app_list/model/search/search_result.h"
  13. #include "ash/app_list/views/continue_section_view.h"
  14. #include "ash/constants/ash_features.h"
  15. #include "ash/public/cpp/app_menu_constants.h"
  16. #include "ash/shell.h"
  17. #include "base/logging.h"
  18. #include "base/metrics/histogram_functions.h"
  19. #include "base/metrics/histogram_macros.h"
  20. #include "ui/compositor/compositor.h"
  21. namespace ash {
  22. // The number of files removed from the continue section during this session.
  23. int g_continue_file_removals_in_session = 0;
  24. const char kAppListPeekingToFullscreenHistogram[] =
  25. "Apps.AppListPeekingToFullscreenSource";
  26. // The UMA histogram that logs smoothness of pagination animation.
  27. constexpr char kPaginationTransitionAnimationSmoothness[] =
  28. "Apps.PaginationTransition.AnimationSmoothness";
  29. constexpr char kPaginationTransitionAnimationSmoothnessInTablet[] =
  30. "Apps.PaginationTransition.AnimationSmoothness.TabletMode";
  31. constexpr char kPaginationTransitionAnimationSmoothnessInClamshell[] =
  32. "Apps.PaginationTransition.AnimationSmoothness.ClamshellMode";
  33. // The UMA histogram that logs which state search results are opened from.
  34. constexpr char kAppListSearchResultOpenSourceHistogram[] =
  35. "Apps.AppListSearchResultOpenedSource";
  36. // The UMA histogram that logs smoothness of cardified animation.
  37. constexpr char kCardifiedStateAnimationSmoothnessEnter[] =
  38. "Apps.AppList.CardifiedStateAnimation.AnimationSmoothness."
  39. "EnterCardifiedState";
  40. constexpr char kCardifiedStateAnimationSmoothnessExit[] =
  41. "Apps.AppList.CardifiedStateAnimation.AnimationSmoothness."
  42. "ExitCardifiedState";
  43. // The UMA hisotogram that logs the action user performs on zero state
  44. // search result.
  45. constexpr char kAppListZeroStateSearchResultUserActionHistogram[] =
  46. "Apps.AppList.ZeroStateSearchResultUserActionType";
  47. // The UMA histogram that logs user's decision (remove or cancel) for zero state
  48. // search result removal confirmation.
  49. constexpr char kAppListZeroStateSearchResultRemovalHistogram[] =
  50. "Apps.AppList.ZeroStateSearchResultRemovalDecision";
  51. // The UMA histogram that logs user's decision (remove or cancel) for search
  52. // result removal confirmation. Recorded if productivity launcher is enabled, in
  53. // which case search result removal is enabled outside zero state search.
  54. // Otherwise, the dialog result is reported using
  55. // `kAppListZeroStateSearchResultRemovalHistogram`.
  56. constexpr char kSearchResultRemovalDialogDecisionHistogram[] =
  57. "Apps.AppList.SearchResultRemovalDecision";
  58. // The base UMA histogram that logs app launches within the HomeLauncher (tablet
  59. // mode AppList), and the fullscreen AppList (when ProductivityLauncher is
  60. // disabled in clamshell mode) and the Shelf.
  61. constexpr char kAppListAppLaunched[] = "Apps.AppListAppLaunchedV2";
  62. // UMA histograms that log app launches within the app list, and the shelf.
  63. // Split depending on whether tablet mode is active or not.
  64. constexpr char kAppLaunchInTablet[] = "Apps.AppList.AppLaunched.TabletMode";
  65. constexpr char kAppLaunchInClamshell[] =
  66. "Apps.AppList.AppLaunched.ClamshellMode";
  67. // UMA histograms that log launcher workflow actions (launching an app, search
  68. // result, or a continue section task) in the app list UI. Split depending on
  69. // whether tablet mode is active or not. Note that unlike `kAppListAppLaunched`
  70. // histograms, these do not include actions from shelf, but do include non-app
  71. // launch actions.
  72. constexpr char kLauncherUserActionInTablet[] =
  73. "Apps.AppList.UserAction.TabletMode";
  74. constexpr char kLauncherUserActionInClamshell[] =
  75. "Apps.AppList.UserAction.ClamshellMode";
  76. // UMA histograms that log time elapsed from launcher getting shown at the time
  77. // of an user taking a launcher workflow action (launching an app, search
  78. // result, or a continue section task) in the app list UI. Split depending on
  79. // whether tablet mode is active or not.
  80. constexpr char kTimeToLauncherUserActionInTablet[] =
  81. "Apps.AppList.TimeToUserAction.TabletMode";
  82. constexpr char kTimeToLauncherUserActionInClamshell[] =
  83. "Apps.AppList.TimeToUserAction.ClamshellMode";
  84. // The UMA histograms that log app launches within the AppList, AppListBubble
  85. // and Shelf. The app launches are divided by histogram for each of the the
  86. // different AppList states.
  87. constexpr char kAppListAppLaunchedBubbleAllApps[] =
  88. "Apps.AppListAppLaunchedV2.BubbleAllApps";
  89. constexpr char kAppListAppLaunchedClosed[] = "Apps.AppListAppLaunchedV2.Closed";
  90. constexpr char kAppListAppLaunchedPeeking[] =
  91. "Apps.AppListAppLaunchedV2.Peeking";
  92. constexpr char kAppListAppLaunchedHalf[] = "Apps.AppListAppLaunchedV2.Half";
  93. constexpr char kAppListAppLaunchedFullscreenAllApps[] =
  94. "Apps.AppListAppLaunchedV2.FullscreenAllApps";
  95. constexpr char kAppListAppLaunchedFullscreenSearch[] =
  96. "Apps.AppListAppLaunchedV2.FullscreenSearch";
  97. constexpr char kAppListAppLaunchedHomecherClosed[] =
  98. "Apps.AppListAppLaunchedV2.HomecherClosed";
  99. constexpr char kAppListAppLaunchedHomecherAllApps[] =
  100. "Apps.AppListAppLaunchedV2.HomecherAllApps";
  101. constexpr char kAppListAppLaunchedHomecherSearch[] =
  102. "Apps.AppListAppLaunchedV2.HomecherSearch";
  103. constexpr char kClamshellReorderAnimationSmoothnessHistogram[] =
  104. "Apps.Launcher.ProductivityReorderAnimationSmoothness.ClamshellMode";
  105. constexpr char kTabletReorderAnimationSmoothnessHistogram[] =
  106. "Apps.Launcher.ProductivityReorderAnimationSmoothness.TabletMode";
  107. constexpr char kClamshellReorderActionHistogram[] =
  108. "Apps.Launcher.ProductivityReorderAction.ClamshellMode";
  109. constexpr char kTabletReorderActionHistogram[] =
  110. "Apps.Launcher.ProductivityReorderAction.TabletMode";
  111. // The prefix for all the variants that track how long the app list is kept
  112. // open by open method. Suffix is decided in `GetAppListOpenMethod`
  113. constexpr char kAppListOpenTimePrefix[] = "Apps.AppListOpenTime.";
  114. constexpr char kContinueSectionFilesRemovedInSessionHistogram[] =
  115. "Apps.AppList.Search.ContinueSectionFilesRemovedPerSession";
  116. // The different sources from which a search result is displayed. These values
  117. // are written to logs. New enum values can be added, but existing enums must
  118. // never be renumbered or deleted and reused.
  119. enum class ApplistSearchResultOpenedSource {
  120. kHalfClamshell = 0,
  121. kFullscreenClamshell = 1,
  122. kFullscreenTablet = 2,
  123. kMaxApplistSearchResultOpenedSource = 3,
  124. };
  125. AppLaunchedMetricParams::AppLaunchedMetricParams() = default;
  126. AppLaunchedMetricParams::AppLaunchedMetricParams(
  127. const AppLaunchedMetricParams&) = default;
  128. AppLaunchedMetricParams& AppLaunchedMetricParams::operator=(
  129. const AppLaunchedMetricParams&) = default;
  130. AppLaunchedMetricParams::AppLaunchedMetricParams(
  131. AppListLaunchedFrom launched_from,
  132. AppListLaunchType launch_type)
  133. : launched_from(launched_from), launch_type(launch_type) {}
  134. AppLaunchedMetricParams::~AppLaunchedMetricParams() = default;
  135. void AppListRecordPageSwitcherSourceByEventType(ui::EventType type,
  136. bool is_tablet_mode) {
  137. AppListPageSwitcherSource source;
  138. switch (type) {
  139. case ui::ET_MOUSEWHEEL:
  140. source = kMouseWheelScroll;
  141. break;
  142. case ui::ET_SCROLL:
  143. source = kMousePadScroll;
  144. break;
  145. case ui::ET_GESTURE_SCROLL_END:
  146. source = kSwipeAppGrid;
  147. break;
  148. case ui::ET_SCROLL_FLING_START:
  149. source = kFlingAppGrid;
  150. break;
  151. case ui::ET_MOUSE_RELEASED:
  152. source = kMouseDrag;
  153. break;
  154. default:
  155. NOTREACHED();
  156. return;
  157. }
  158. RecordPageSwitcherSource(source, is_tablet_mode);
  159. }
  160. void RecordPageSwitcherSource(AppListPageSwitcherSource source,
  161. bool is_tablet_mode) {
  162. UMA_HISTOGRAM_ENUMERATION("Apps.AppListPageSwitcherSource", source,
  163. kMaxAppListPageSwitcherSource);
  164. if (is_tablet_mode) {
  165. UMA_HISTOGRAM_ENUMERATION("Apps.AppListPageSwitcherSource.TabletMode",
  166. source, kMaxAppListPageSwitcherSource);
  167. } else {
  168. UMA_HISTOGRAM_ENUMERATION("Apps.AppListPageSwitcherSource.ClamshellMode",
  169. source, kMaxAppListPageSwitcherSource);
  170. }
  171. }
  172. void RecordSearchResultOpenSource(const SearchResult* result,
  173. AppListViewState state,
  174. bool is_tablet_mode) {
  175. // Record the search metric if the SearchResult is not a suggested app.
  176. if (result->is_recommendation())
  177. return;
  178. ApplistSearchResultOpenedSource source;
  179. if (is_tablet_mode) {
  180. source = ApplistSearchResultOpenedSource::kFullscreenTablet;
  181. } else {
  182. source = state == AppListViewState::kHalf
  183. ? ApplistSearchResultOpenedSource::kHalfClamshell
  184. : ApplistSearchResultOpenedSource::kFullscreenClamshell;
  185. }
  186. UMA_HISTOGRAM_ENUMERATION(
  187. kAppListSearchResultOpenSourceHistogram, source,
  188. ApplistSearchResultOpenedSource::kMaxApplistSearchResultOpenedSource);
  189. }
  190. void RecordZeroStateSearchResultUserActionHistogram(
  191. ZeroStateSearchResultUserActionType action) {
  192. UMA_HISTOGRAM_ENUMERATION(kAppListZeroStateSearchResultUserActionHistogram,
  193. action);
  194. }
  195. void RecordZeroStateSearchResultRemovalHistogram(
  196. SearchResultRemovalConfirmation removal_decision) {
  197. UMA_HISTOGRAM_ENUMERATION(kAppListZeroStateSearchResultRemovalHistogram,
  198. removal_decision);
  199. }
  200. void RecordSearchResultRemovalDialogDecision(
  201. SearchResultRemovalConfirmation removal_decision) {
  202. base::UmaHistogramEnumeration(kSearchResultRemovalDialogDecisionHistogram,
  203. removal_decision);
  204. }
  205. std::string GetAppListOpenMethod(AppListShowSource source) {
  206. // This switch determines which metric we submit for the Apps.AppListOpenTime
  207. // metric. Adding a string requires you update the apps histogram.xml as well.
  208. switch (source) {
  209. case kSearchKey:
  210. case kSearchKeyFullscreen:
  211. return "SearchKey";
  212. case kShelfButton:
  213. case kShelfButtonFullscreen:
  214. return "HomeButton";
  215. case kSwipeFromShelf:
  216. return "Swipe";
  217. case kScrollFromShelf:
  218. return "Scroll";
  219. case kTabletMode:
  220. case kAssistantEntryPoint:
  221. return "Others";
  222. }
  223. NOTREACHED();
  224. }
  225. void RecordAppListUserJourneyTime(AppListShowSource source,
  226. base::TimeDelta time) {
  227. base::UmaHistogramMediumTimes(
  228. kAppListOpenTimePrefix + GetAppListOpenMethod(source), time);
  229. }
  230. void RecordPeriodicAppListMetrics() {
  231. int number_of_apps_in_launcher = 0;
  232. int number_of_root_level_items = 0;
  233. int number_of_folders = 0;
  234. int number_of_non_system_folders = 0;
  235. int number_of_apps_in_non_system_folders = 0;
  236. AppListModel* const model = AppListModelProvider::Get()->model();
  237. AppListItemList* const item_list = model->top_level_item_list();
  238. for (size_t i = 0; i < item_list->item_count(); ++i) {
  239. AppListItem* item = item_list->item_at(i);
  240. if (item->is_page_break())
  241. continue;
  242. number_of_root_level_items++;
  243. // Item is a folder.
  244. if (item->GetItemType() == AppListFolderItem::kItemType) {
  245. AppListFolderItem* folder = static_cast<AppListFolderItem*>(item);
  246. number_of_apps_in_launcher += folder->item_list()->item_count();
  247. number_of_folders++;
  248. // Ignore the OEM folder and the "Linux apps" folder because those folders
  249. // are automatically created. The following metrics are trying to measure
  250. // how often users engage with folders that they created themselves.
  251. if (folder->IsSystemFolder())
  252. continue;
  253. number_of_apps_in_non_system_folders += folder->item_list()->item_count();
  254. number_of_non_system_folders++;
  255. continue;
  256. }
  257. // Item is an app that isn't in a folder.
  258. number_of_apps_in_launcher++;
  259. }
  260. UMA_HISTOGRAM_COUNTS_100("Apps.AppList.NumberOfApps",
  261. number_of_apps_in_launcher);
  262. UMA_HISTOGRAM_COUNTS_100("Apps.AppList.NumberOfRootLevelItems",
  263. number_of_root_level_items);
  264. UMA_HISTOGRAM_COUNTS_100("Apps.AppList.NumberOfFolders", number_of_folders);
  265. UMA_HISTOGRAM_COUNTS_100("Apps.AppList.NumberOfNonSystemFolders",
  266. number_of_non_system_folders);
  267. UMA_HISTOGRAM_COUNTS_100("Apps.AppList.NumberOfAppsInNonSystemFolders",
  268. number_of_apps_in_non_system_folders);
  269. }
  270. void RecordAppListAppLaunched(AppListLaunchedFrom launched_from,
  271. AppListViewState app_list_state,
  272. bool is_tablet_mode,
  273. bool app_list_shown) {
  274. UMA_HISTOGRAM_ENUMERATION(kAppListAppLaunched, launched_from);
  275. if (is_tablet_mode) {
  276. base::UmaHistogramEnumeration(kAppLaunchInTablet, launched_from);
  277. } else {
  278. base::UmaHistogramEnumeration(kAppLaunchInClamshell, launched_from);
  279. }
  280. if (features::IsProductivityLauncherEnabled() && !is_tablet_mode) {
  281. if (!app_list_shown) {
  282. UMA_HISTOGRAM_ENUMERATION(kAppListAppLaunchedClosed, launched_from);
  283. } else {
  284. // TODO(newcomer): Handle the case where search is open.
  285. UMA_HISTOGRAM_ENUMERATION(kAppListAppLaunchedBubbleAllApps,
  286. launched_from);
  287. }
  288. return;
  289. }
  290. switch (app_list_state) {
  291. case AppListViewState::kClosed:
  292. DCHECK(!features::IsProductivityLauncherEnabled());
  293. // Only exists in clamshell mode with ProductivityLauncher disabled.
  294. UMA_HISTOGRAM_ENUMERATION(kAppListAppLaunchedClosed, launched_from);
  295. break;
  296. case AppListViewState::kPeeking:
  297. DCHECK(!features::IsProductivityLauncherEnabled());
  298. // Only exists in clamshell mode with ProductivityLauncher disabled.
  299. UMA_HISTOGRAM_ENUMERATION(kAppListAppLaunchedPeeking, launched_from);
  300. break;
  301. case AppListViewState::kHalf:
  302. DCHECK(!features::IsProductivityLauncherEnabled());
  303. // Only exists in clamshell mode with ProductivityLauncher disabled.
  304. UMA_HISTOGRAM_ENUMERATION(kAppListAppLaunchedHalf, launched_from);
  305. break;
  306. case AppListViewState::kFullscreenAllApps:
  307. if (is_tablet_mode) {
  308. if (app_list_shown) {
  309. UMA_HISTOGRAM_ENUMERATION(kAppListAppLaunchedHomecherAllApps,
  310. launched_from);
  311. } else {
  312. UMA_HISTOGRAM_ENUMERATION(kAppListAppLaunchedHomecherClosed,
  313. launched_from);
  314. }
  315. } else {
  316. UMA_HISTOGRAM_ENUMERATION(kAppListAppLaunchedFullscreenAllApps,
  317. launched_from);
  318. }
  319. break;
  320. case AppListViewState::kFullscreenSearch:
  321. if (is_tablet_mode) {
  322. if (app_list_shown) {
  323. UMA_HISTOGRAM_ENUMERATION(kAppListAppLaunchedHomecherSearch,
  324. launched_from);
  325. } else {
  326. // (http://crbug.com/947729) Search box still expanded when opening
  327. // launcher in tablet mode
  328. UMA_HISTOGRAM_ENUMERATION(kAppListAppLaunchedHomecherClosed,
  329. launched_from);
  330. }
  331. } else {
  332. UMA_HISTOGRAM_ENUMERATION(kAppListAppLaunchedFullscreenSearch,
  333. launched_from);
  334. }
  335. break;
  336. }
  337. }
  338. ASH_EXPORT void RecordLauncherWorkflowMetrics(
  339. AppListUserAction action,
  340. bool is_tablet_mode,
  341. absl::optional<base::TimeTicks> launcher_show_time) {
  342. if (is_tablet_mode) {
  343. base::UmaHistogramEnumeration(kLauncherUserActionInTablet, action);
  344. if (launcher_show_time) {
  345. base::UmaHistogramMediumTimes(
  346. kTimeToLauncherUserActionInTablet,
  347. base::TimeTicks::Now() - *launcher_show_time);
  348. }
  349. } else {
  350. base::UmaHistogramEnumeration(kLauncherUserActionInClamshell, action);
  351. if (launcher_show_time) {
  352. base::UmaHistogramMediumTimes(
  353. kTimeToLauncherUserActionInClamshell,
  354. base::TimeTicks::Now() - *launcher_show_time);
  355. }
  356. }
  357. }
  358. bool IsCommandIdAnAppLaunch(int command_id_number) {
  359. CommandId command_id = static_cast<CommandId>(command_id_number);
  360. // Consider all platform app menu options as launches.
  361. if (command_id >= CommandId::EXTENSIONS_CONTEXT_CUSTOM_FIRST &&
  362. command_id < CommandId::EXTENSIONS_CONTEXT_CUSTOM_LAST) {
  363. return true;
  364. }
  365. // Consider all arc app shortcut options as launches.
  366. if (command_id >= CommandId::LAUNCH_APP_SHORTCUT_FIRST &&
  367. command_id < CommandId::LAUNCH_APP_SHORTCUT_LAST) {
  368. return true;
  369. }
  370. // All app menu items in a ShelfApplicationMenuModel are not launches.
  371. if (command_id >= CommandId::APP_MENU_ITEM_ID_FIRST &&
  372. command_id < CommandId::APP_MENU_ITEM_ID_LAST) {
  373. return false;
  374. }
  375. switch (command_id) {
  376. // Used by AppContextMenu and/or ShelfContextMenu.
  377. case CommandId::LAUNCH_NEW:
  378. case CommandId::SHOW_APP_INFO:
  379. case CommandId::OPTIONS:
  380. case CommandId::APP_CONTEXT_MENU_NEW_WINDOW:
  381. case CommandId::APP_CONTEXT_MENU_NEW_INCOGNITO_WINDOW:
  382. case CommandId::SETTINGS:
  383. // Used by both AppContextMenu and ShelfContextMenu for app shortcuts.
  384. case CommandId::LAUNCH_APP_SHORTCUT_FIRST:
  385. case CommandId::LAUNCH_APP_SHORTCUT_LAST:
  386. return true;
  387. // Used by ShelfContextMenu (shelf).
  388. case CommandId::MENU_CLOSE:
  389. case CommandId::SWAP_WITH_NEXT:
  390. case CommandId::SWAP_WITH_PREVIOUS:
  391. // Used by AppMenuModelAdapter
  392. case CommandId::NOTIFICATION_CONTAINER:
  393. // Used by CrostiniShelfContextMenu.
  394. case CommandId::CROSTINI_USE_LOW_DENSITY:
  395. case CommandId::CROSTINI_USE_HIGH_DENSITY:
  396. // Used by AppContextMenu.
  397. case CommandId::TOGGLE_PIN:
  398. case CommandId::UNINSTALL:
  399. case CommandId::REMOVE_FROM_FOLDER:
  400. case CommandId::INSTALL:
  401. case CommandId::USE_LAUNCH_TYPE_PINNED:
  402. case CommandId::USE_LAUNCH_TYPE_REGULAR:
  403. case CommandId::USE_LAUNCH_TYPE_FULLSCREEN:
  404. case CommandId::USE_LAUNCH_TYPE_WINDOW:
  405. case CommandId::USE_LAUNCH_TYPE_TABBED_WINDOW:
  406. case CommandId::USE_LAUNCH_TYPE_COMMAND_END:
  407. case CommandId::REORDER_SUBMENU:
  408. case CommandId::REORDER_BY_NAME_ALPHABETICAL:
  409. case CommandId::REORDER_BY_NAME_REVERSE_ALPHABETICAL:
  410. case CommandId::REORDER_BY_COLOR:
  411. case CommandId::SHUTDOWN_GUEST_OS:
  412. case CommandId::EXTENSIONS_CONTEXT_CUSTOM_FIRST:
  413. case CommandId::EXTENSIONS_CONTEXT_CUSTOM_LAST:
  414. case CommandId::COMMAND_ID_COUNT:
  415. // Used by ShelfApplicationMenuModel.
  416. case CommandId::APP_MENU_ITEM_ID_FIRST:
  417. case CommandId::APP_MENU_ITEM_ID_LAST:
  418. return false;
  419. case CommandId::DEPRECATED_MENU_OPEN_NEW:
  420. case CommandId::DEPRECATED_MENU_PIN:
  421. case CommandId::DEPRECATED_MENU_NEW_WINDOW:
  422. case CommandId::DEPRECATED_MENU_NEW_INCOGNITO_WINDOW:
  423. case CommandId::DEPRECATED_LAUNCH_TYPE_PINNED_TAB:
  424. case CommandId::DEPRECATED_LAUNCH_TYPE_REGULAR_TAB:
  425. case CommandId::DEPRECATED_LAUNCH_TYPE_WINDOW:
  426. case CommandId::DEPRECATED_LAUNCH_TYPE_TABBED_WINDOW:
  427. case CommandId::DEPRECATED_LAUNCH_TYPE_FULLSCREEN:
  428. NOTREACHED();
  429. return false;
  430. }
  431. NOTREACHED();
  432. return false;
  433. }
  434. void ReportPaginationSmoothness(bool is_tablet_mode, int smoothness) {
  435. UMA_HISTOGRAM_PERCENTAGE(kPaginationTransitionAnimationSmoothness,
  436. smoothness);
  437. if (is_tablet_mode) {
  438. UMA_HISTOGRAM_PERCENTAGE(kPaginationTransitionAnimationSmoothnessInTablet,
  439. smoothness);
  440. } else {
  441. UMA_HISTOGRAM_PERCENTAGE(
  442. kPaginationTransitionAnimationSmoothnessInClamshell, smoothness);
  443. }
  444. }
  445. void ReportCardifiedSmoothness(bool is_entering_cardified, int smoothness) {
  446. if (is_entering_cardified) {
  447. UMA_HISTOGRAM_PERCENTAGE(kCardifiedStateAnimationSmoothnessEnter,
  448. smoothness);
  449. } else {
  450. UMA_HISTOGRAM_PERCENTAGE(kCardifiedStateAnimationSmoothnessExit,
  451. smoothness);
  452. }
  453. }
  454. // Reports reorder animation smoothness.
  455. void ReportReorderAnimationSmoothness(bool in_tablet, int smoothness) {
  456. if (in_tablet) {
  457. base::UmaHistogramPercentage(kTabletReorderAnimationSmoothnessHistogram,
  458. smoothness);
  459. } else {
  460. base::UmaHistogramPercentage(kClamshellReorderAnimationSmoothnessHistogram,
  461. smoothness);
  462. }
  463. }
  464. void RecordAppListSortAction(AppListSortOrder new_order, bool in_tablet) {
  465. // NOTE: (1) kNameReverseAlphabetical is not used for now; (2) Resetting the
  466. // sort order is not recorded here.
  467. DCHECK(new_order != AppListSortOrder::kNameReverseAlphabetical &&
  468. new_order != AppListSortOrder::kCustom);
  469. if (in_tablet)
  470. base::UmaHistogramEnumeration(kTabletReorderActionHistogram, new_order);
  471. else
  472. base::UmaHistogramEnumeration(kClamshellReorderActionHistogram, new_order);
  473. }
  474. void RecordMetricsOnSessionEnd() {
  475. if (ContinueSectionView::EnableContinueSectionFileRemovalMetrics() &&
  476. g_continue_file_removals_in_session == 0) {
  477. base::UmaHistogramCounts100(kContinueSectionFilesRemovedInSessionHistogram,
  478. 0);
  479. }
  480. }
  481. void RecordCumulativeContinueSectionResultRemovedNumber() {
  482. base::UmaHistogramCounts100(kContinueSectionFilesRemovedInSessionHistogram,
  483. ++g_continue_file_removals_in_session);
  484. }
  485. void ResetContinueSectionFileRemovedCountForTest() {
  486. g_continue_file_removals_in_session = 0;
  487. }
  488. void RecordHideContinueSectionMetric() {
  489. // The continue section is a productivity launcher feature.
  490. if (!features::IsProductivityLauncherEnabled())
  491. return;
  492. const bool hide_continue_section =
  493. Shell::Get()->app_list_controller()->ShouldHideContinueSection();
  494. if (Shell::Get()->IsInTabletMode()) {
  495. base::UmaHistogramBoolean(
  496. "Apps.AppList.ContinueSectionHiddenByUser.TabletMode",
  497. hide_continue_section);
  498. } else {
  499. base::UmaHistogramBoolean(
  500. "Apps.AppList.ContinueSectionHiddenByUser.ClamshellMode",
  501. hide_continue_section);
  502. }
  503. }
  504. } // namespace ash