1// Copyright 2013 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
5#include "ash/metrics/user_metrics_recorder.h"
6
7#include "ash/shelf/shelf_layout_manager.h"
8#include "ash/shelf/shelf_view.h"
9#include "ash/shelf/shelf_widget.h"
10#include "ash/shell.h"
11#include "ash/wm/window_state.h"
12#include "base/metrics/histogram.h"
13#include "base/metrics/user_metrics.h"
14
15namespace ash {
16
17// Time in seconds between calls to "RecordPeriodicMetrics".
18const int kAshPeriodicMetricsTimeInSeconds = 30 * 60;
19
20UserMetricsRecorder::UserMetricsRecorder() {
21  timer_.Start(FROM_HERE,
22               base::TimeDelta::FromSeconds(kAshPeriodicMetricsTimeInSeconds),
23               this,
24               &UserMetricsRecorder::RecordPeriodicMetrics);
25}
26
27UserMetricsRecorder::~UserMetricsRecorder() {
28  timer_.Stop();
29}
30
31void UserMetricsRecorder::RecordUserMetricsAction(UserMetricsAction action) {
32  switch (action) {
33    case ash::UMA_ACCEL_KEYBOARD_BRIGHTNESS_DOWN_F6:
34      base::RecordAction(
35          base::UserMetricsAction("Accel_KeyboardBrightnessDown_F6"));
36      break;
37    case ash::UMA_ACCEL_KEYBOARD_BRIGHTNESS_UP_F7:
38      base::RecordAction(
39          base::UserMetricsAction("Accel_KeyboardBrightnessUp_F7"));
40      break;
41    case ash::UMA_ACCEL_LOCK_SCREEN_LOCK_BUTTON:
42      base::RecordAction(
43          base::UserMetricsAction("Accel_LockScreen_LockButton"));
44      break;
45    case ash::UMA_ACCEL_LOCK_SCREEN_POWER_BUTTON:
46      base::RecordAction(
47          base::UserMetricsAction("Accel_LockScreen_PowerButton"));
48      break;
49    case ash::UMA_ACCEL_MAXIMIZE_RESTORE_F4:
50      base::RecordAction(
51          base::UserMetricsAction("Accel_Maximize_Restore_F4"));
52      break;
53    case ash::UMA_ACCEL_PREVWINDOW_F5:
54      base::RecordAction(base::UserMetricsAction("Accel_PrevWindow_F5"));
55      break;
56    case ash::UMA_ACCEL_EXIT_FIRST_Q:
57      base::RecordAction(base::UserMetricsAction("Accel_Exit_First_Q"));
58      break;
59    case ash::UMA_ACCEL_EXIT_SECOND_Q:
60      base::RecordAction(base::UserMetricsAction("Accel_Exit_Second_Q"));
61      break;
62    case ash::UMA_ACCEL_SHUT_DOWN_POWER_BUTTON:
63      base::RecordAction(
64          base::UserMetricsAction("Accel_ShutDown_PowerButton"));
65      break;
66    case ash::UMA_CLOSE_THROUGH_CONTEXT_MENU:
67      base::RecordAction(base::UserMetricsAction("CloseFromContextMenu"));
68      break;
69    case ash::UMA_DRAG_MAXIMIZE_LEFT:
70      base::RecordAction(base::UserMetricsAction("WindowDrag_MaximizeLeft"));
71      break;
72    case ash::UMA_DRAG_MAXIMIZE_RIGHT:
73      base::RecordAction(base::UserMetricsAction("WindowDrag_MaximizeRight"));
74      break;
75    case ash::UMA_GESTURE_OVERVIEW:
76      base::RecordAction(base::UserMetricsAction("Gesture_Overview"));
77      break;
78    case ash::UMA_LAUNCHER_CLICK_ON_APP:
79      base::RecordAction(base::UserMetricsAction("Launcher_ClickOnApp"));
80      break;
81    case ash::UMA_LAUNCHER_CLICK_ON_APPLIST_BUTTON:
82      base::RecordAction(
83          base::UserMetricsAction("Launcher_ClickOnApplistButton"));
84      break;
85    case ash::UMA_MOUSE_DOWN:
86      base::RecordAction(base::UserMetricsAction("Mouse_Down"));
87      break;
88    case ash::UMA_PANEL_MINIMIZE_CAPTION_CLICK:
89      base::RecordAction(
90         base::UserMetricsAction("Panel_Minimize_Caption_Click"));
91      break;
92    case ash::UMA_PANEL_MINIMIZE_CAPTION_GESTURE:
93      base::RecordAction(
94          base::UserMetricsAction("Panel_Minimize_Caption_Gesture"));
95      break;
96    case ash::UMA_SHELF_ALIGNMENT_SET_BOTTOM:
97      base::RecordAction(
98          base::UserMetricsAction("Shelf_AlignmentSetBottom"));
99      break;
100    case ash::UMA_SHELF_ALIGNMENT_SET_LEFT:
101      base::RecordAction(
102          base::UserMetricsAction("Shelf_AlignmentSetLeft"));
103      break;
104    case ash::UMA_SHELF_ALIGNMENT_SET_RIGHT:
105      base::RecordAction(
106          base::UserMetricsAction("Shelf_AlignmentSetRight"));
107      break;
108    case ash::UMA_STATUS_AREA_AUDIO_CURRENT_INPUT_DEVICE:
109      base::RecordAction(
110          base::UserMetricsAction("StatusArea_Audio_CurrentInputDevice"));
111      break;
112    case ash::UMA_STATUS_AREA_AUDIO_CURRENT_OUTPUT_DEVICE:
113      base::RecordAction(
114          base::UserMetricsAction("StatusArea_Audio_CurrentOutputDevice"));
115      break;
116    case ash::UMA_STATUS_AREA_AUDIO_SWITCH_INPUT_DEVICE:
117      base::RecordAction(
118          base::UserMetricsAction("StatusArea_Audio_SwitchInputDevice"));
119      break;
120    case ash::UMA_STATUS_AREA_AUDIO_SWITCH_OUTPUT_DEVICE:
121      base::RecordAction(
122          base::UserMetricsAction("StatusArea_Audio_SwitchOutputDevice"));
123      break;
124    case ash::UMA_STATUS_AREA_BRIGHTNESS_CHANGED:
125      base::RecordAction(
126          base::UserMetricsAction("StatusArea_BrightnessChanged"));
127      break;
128    case ash::UMA_STATUS_AREA_BLUETOOTH_CONNECT_KNOWN_DEVICE:
129      base::RecordAction(
130          base::UserMetricsAction("StatusArea_Bluetooth_Connect_Known"));
131      break;
132    case ash::UMA_STATUS_AREA_BLUETOOTH_CONNECT_UNKNOWN_DEVICE:
133      base::RecordAction(
134          base::UserMetricsAction("StatusArea_Bluetooth_Connect_Unknown"));
135      break;
136    case ash::UMA_STATUS_AREA_BLUETOOTH_DISABLED:
137      base::RecordAction(
138          base::UserMetricsAction("StatusArea_Bluetooth_Disabled"));
139      break;
140    case ash::UMA_STATUS_AREA_BLUETOOTH_ENABLED:
141      base::RecordAction(
142          base::UserMetricsAction("StatusArea_Bluetooth_Enabled"));
143      break;
144    case ash::UMA_STATUS_AREA_CAPS_LOCK_DETAILED:
145      base::RecordAction(
146          base::UserMetricsAction("StatusArea_CapsLock_Detailed"));
147      break;
148    case ash::UMA_STATUS_AREA_CAPS_LOCK_DISABLED_BY_CLICK:
149      base::RecordAction(
150          base::UserMetricsAction("StatusArea_CapsLock_DisabledByClick"));
151      break;
152    case ash::UMA_STATUS_AREA_CAPS_LOCK_ENABLED_BY_CLICK:
153      base::RecordAction(
154          base::UserMetricsAction("StatusArea_CapsLock_EnabledByClick"));
155      break;
156    case ash::UMA_STATUS_AREA_CAPS_LOCK_POPUP:
157      base::RecordAction(
158          base::UserMetricsAction("StatusArea_CapsLock_Popup"));
159      break;
160    case ash::UMA_STATUS_AREA_CONNECT_TO_CONFIGURED_NETWORK:
161      base::RecordAction(
162          base::UserMetricsAction("StatusArea_Network_ConnectConfigured"));
163      break;
164    case ash::UMA_STATUS_AREA_CONNECT_TO_UNCONFIGURED_NETWORK:
165      base::RecordAction(
166          base::UserMetricsAction("StatusArea_Network_ConnectUnconfigured"));
167      break;
168    case ash::UMA_STATUS_AREA_CONNECT_TO_VPN:
169      base::RecordAction(
170          base::UserMetricsAction("StatusArea_VPN_ConnectToNetwork"));
171      break;
172    case ash::UMA_STATUS_AREA_CHANGED_VOLUME_MENU:
173      base::RecordAction(
174          base::UserMetricsAction("StatusArea_Volume_ChangedMenu"));
175      break;
176    case ash::UMA_STATUS_AREA_CHANGED_VOLUME_POPUP:
177      base::RecordAction(
178          base::UserMetricsAction("StatusArea_Volume_ChangedPopup"));
179      break;
180    case ash::UMA_STATUS_AREA_DETAILED_ACCESSABILITY:
181      base::RecordAction(
182          base::UserMetricsAction("StatusArea_Accessability_DetailedView"));
183      break;
184    case ash::UMA_STATUS_AREA_DETAILED_AUDIO_VIEW:
185      base::RecordAction(
186          base::UserMetricsAction("StatusArea_Audio_Detailed"));
187      break;
188    case ash::UMA_STATUS_AREA_DETAILED_BLUETOOTH_VIEW:
189      base::RecordAction(
190          base::UserMetricsAction("StatusArea_Bluetooth_Detailed"));
191      break;
192    case ash::UMA_STATUS_AREA_DETAILED_BRIGHTNESS_VIEW:
193      base::RecordAction(
194          base::UserMetricsAction("StatusArea_Brightness_Detailed"));
195      break;
196    case ash::UMA_STATUS_AREA_DETAILED_DRIVE_VIEW:
197      base::RecordAction(
198          base::UserMetricsAction("StatusArea_Drive_Detailed"));
199      break;
200    case ash::UMA_STATUS_AREA_DETAILED_NETWORK_VIEW:
201      base::RecordAction(
202          base::UserMetricsAction("StatusArea_Network_Detailed"));
203      break;
204    case ash::UMA_STATUS_AREA_DETAILED_VPN_VIEW:
205      base::RecordAction(
206          base::UserMetricsAction("StatusArea_VPN_Detailed"));
207      break;
208    case ash::UMA_STATUS_AREA_DISABLE_AUTO_CLICK:
209      base::RecordAction(
210          base::UserMetricsAction("StatusArea_AutoClickDisabled"));
211      break;
212    case ash::UMA_STATUS_AREA_DISABLE_HIGH_CONTRAST:
213      base::RecordAction(
214          base::UserMetricsAction("StatusArea_HighContrastDisabled"));
215      break;
216    case ash::UMA_STATUS_AREA_DISABLE_LARGE_CURSOR:
217      base::RecordAction(
218          base::UserMetricsAction("StatusArea_LargeCursorDisabled"));
219      break;
220    case ash::UMA_STATUS_AREA_DISABLE_MAGNIFIER:
221      base::RecordAction(
222          base::UserMetricsAction("StatusArea_MagnifierDisabled"));
223      break;
224    case ash::UMA_STATUS_AREA_DISABLE_SPOKEN_FEEDBACK:
225      base::RecordAction(
226          base::UserMetricsAction("StatusArea_SpokenFeedbackDisabled"));
227      break;
228    case ash::UMA_STATUS_AREA_DISABLE_VIRTUAL_KEYBOARD:
229      base::RecordAction(
230          base::UserMetricsAction("StatusArea_VirtualKeyboardDisabled"));
231      break;
232    case ash::UMA_STATUS_AREA_DISABLE_WIFI:
233      base::RecordAction(
234          base::UserMetricsAction("StatusArea_Network_WifiDisabled"));
235      break;
236    case ash::UMA_STATUS_AREA_DRIVE_CANCEL_OPERATION:
237      base::RecordAction(
238          base::UserMetricsAction("StatusArea_Drive_CancelOperation"));
239      break;
240    case ash::UMA_STATUS_AREA_DRIVE_SETTINGS:
241      base::RecordAction(
242          base::UserMetricsAction("StatusArea_Drive_Settings"));
243      break;
244    case ash::UMA_STATUS_AREA_ENABLE_AUTO_CLICK:
245      base::RecordAction(
246          base::UserMetricsAction("StatusArea_AutoClickEnabled"));
247      break;
248    case ash::UMA_STATUS_AREA_ENABLE_HIGH_CONTRAST:
249      base::RecordAction(
250          base::UserMetricsAction("StatusArea_HighContrastEnabled"));
251      break;
252    case ash::UMA_STATUS_AREA_ENABLE_LARGE_CURSOR:
253      base::RecordAction(
254          base::UserMetricsAction("StatusArea_LargeCursorEnabled"));
255      break;
256    case ash::UMA_STATUS_AREA_ENABLE_MAGNIFIER:
257      base::RecordAction(
258          base::UserMetricsAction("StatusArea_MagnifierEnabled"));
259      break;
260    case ash::UMA_STATUS_AREA_ENABLE_SPOKEN_FEEDBACK:
261      base::RecordAction(
262          base::UserMetricsAction("StatusArea_SpokenFeedbackEnabled"));
263      break;
264    case ash::UMA_STATUS_AREA_ENABLE_VIRTUAL_KEYBOARD:
265      base::RecordAction(
266          base::UserMetricsAction("StatusArea_VirtualKeyboardEnabled"));
267      break;
268    case ash::UMA_STATUS_AREA_ENABLE_WIFI:
269      base::RecordAction(
270          base::UserMetricsAction("StatusArea_Network_WifiEnabled"));
271      break;
272    case ash::UMA_STATUS_AREA_IME_SHOW_DETAILED:
273      base::RecordAction(
274          base::UserMetricsAction("StatusArea_IME_Detailed"));
275      break;
276    case ash::UMA_STATUS_AREA_IME_SWITCH_MODE:
277      base::RecordAction(
278          base::UserMetricsAction("StatusArea_IME_SwitchMode"));
279      break;
280    case ash::UMA_STATUS_AREA_MENU_OPENED:
281      base::RecordAction(
282          base::UserMetricsAction("StatusArea_MenuOpened"));
283      break;
284    case ash::UMA_STATUS_AREA_NETWORK_JOIN_OTHER_CLICKED:
285      base::RecordAction(
286          base::UserMetricsAction("StatusArea_Network_JoinOther"));
287      break;
288    case ash::UMA_STATUS_AREA_NETWORK_SETTINGS_CLICKED:
289      base::RecordAction(
290          base::UserMetricsAction("StatusArea_Network_Settings"));
291      break;
292    case ash::UMA_STATUS_AREA_SHOW_NETWORK_CONNECTION_DETAILS:
293      base::RecordAction(
294          base::UserMetricsAction("StatusArea_Network_ConnectionDetails"));
295      break;
296    case ash::UMA_STATUS_AREA_SHOW_VPN_CONNECTION_DETAILS:
297      base::RecordAction(
298          base::UserMetricsAction("StatusArea_VPN_ConnectionDetails"));
299      break;
300    case ash::UMA_STATUS_AREA_SIGN_OUT:
301      base::RecordAction(
302          base::UserMetricsAction("StatusArea_SignOut"));
303      break;
304    case ash::UMA_STATUS_AREA_VPN_JOIN_OTHER_CLICKED:
305      base::RecordAction(
306          base::UserMetricsAction("StatusArea_VPN_JoinOther"));
307      break;
308    case ash::UMA_STATUS_AREA_VPN_SETTINGS_CLICKED:
309      base::RecordAction(
310          base::UserMetricsAction("StatusArea_VPN_Settings"));
311      break;
312    case ash::UMA_TOGGLE_MAXIMIZE_CAPTION_CLICK:
313      base::RecordAction(
314          base::UserMetricsAction("Caption_ClickTogglesMaximize"));
315      break;
316    case ash::UMA_TOGGLE_MAXIMIZE_CAPTION_GESTURE:
317      base::RecordAction(
318          base::UserMetricsAction("Caption_GestureTogglesMaximize"));
319      break;
320    case ash::UMA_TOGGLE_SINGLE_AXIS_MAXIMIZE_BORDER_CLICK:
321      base::RecordAction(
322          base::UserMetricsAction(
323              "WindowBorder_ClickTogglesSingleAxisMaximize"));
324      break;
325    case ash::UMA_TOUCHPAD_GESTURE_OVERVIEW:
326      base::RecordAction(
327          base::UserMetricsAction("Touchpad_Gesture_Overview"));
328      break;
329    case ash::UMA_TOUCHSCREEN_TAP_DOWN:
330      base::RecordAction(base::UserMetricsAction("Touchscreen_Down"));
331      break;
332    case ash::UMA_TRAY_HELP:
333      base::RecordAction(base::UserMetricsAction("Tray_Help"));
334      break;
335    case ash::UMA_TRAY_LOCK_SCREEN:
336      base::RecordAction(base::UserMetricsAction("Tray_LockScreen"));
337      break;
338    case ash::UMA_TRAY_SHUT_DOWN:
339      base::RecordAction(base::UserMetricsAction("Tray_ShutDown"));
340      break;
341    case ash::UMA_WINDOW_APP_CLOSE_BUTTON_CLICK:
342      base::RecordAction(base::UserMetricsAction("AppCloseButton_Clk"));
343      break;
344    case ash::UMA_WINDOW_CLOSE_BUTTON_CLICK:
345      base::RecordAction(base::UserMetricsAction("CloseButton_Clk"));
346      break;
347    case ash::UMA_WINDOW_MAXIMIZE_BUTTON_CLICK_EXIT_FULLSCREEN:
348      base::RecordAction(base::UserMetricsAction("MaxButton_Clk_ExitFS"));
349      break;
350    case ash::UMA_WINDOW_MAXIMIZE_BUTTON_CLICK_RESTORE:
351      base::RecordAction(
352          base::UserMetricsAction("MaxButton_Clk_Restore"));
353      break;
354    case ash::UMA_WINDOW_MAXIMIZE_BUTTON_CLICK_MAXIMIZE:
355      base::RecordAction(
356          base::UserMetricsAction("MaxButton_Clk_Maximize"));
357      break;
358    case ash::UMA_WINDOW_MAXIMIZE_BUTTON_CLICK_MINIMIZE:
359      base::RecordAction(base::UserMetricsAction("MinButton_Clk"));
360      break;
361    case ash::UMA_WINDOW_MAXIMIZE_BUTTON_MAXIMIZE_LEFT:
362      base::RecordAction(base::UserMetricsAction("MaxButton_MaxLeft"));
363      break;
364    case ash::UMA_WINDOW_MAXIMIZE_BUTTON_MAXIMIZE_RIGHT:
365      base::RecordAction(base::UserMetricsAction("MaxButton_MaxRight"));
366      break;
367    case ash::UMA_WINDOW_OVERVIEW:
368      base::RecordAction(
369          base::UserMetricsAction("WindowSelector_Overview"));
370      break;
371    case ash::UMA_WINDOW_OVERVIEW_ENTER_KEY:
372      base::RecordAction(
373          base::UserMetricsAction("WindowSelector_OverviewEnterKey"));
374      break;
375    case ash::UMA_WINDOW_CYCLE:
376      base::RecordAction(
377          base::UserMetricsAction("WindowCycleController_Cycle"));
378      break;
379  }
380}
381
382void UserMetricsRecorder::RecordPeriodicMetrics() {
383  ShelfLayoutManager* manager =
384      ShelfLayoutManager::ForShelf(Shell::GetPrimaryRootWindow());
385  if (manager) {
386    UMA_HISTOGRAM_ENUMERATION("Ash.ShelfAlignmentOverTime",
387                              manager->SelectValueForShelfAlignment(
388                                  SHELF_ALIGNMENT_UMA_ENUM_VALUE_BOTTOM,
389                                  SHELF_ALIGNMENT_UMA_ENUM_VALUE_LEFT,
390                                  SHELF_ALIGNMENT_UMA_ENUM_VALUE_RIGHT,
391                                  -1),
392                              SHELF_ALIGNMENT_UMA_ENUM_VALUE_COUNT);
393  }
394
395  enum ActiveWindowStateType {
396    ACTIVE_WINDOW_STATE_TYPE_NO_ACTIVE_WINDOW,
397    ACTIVE_WINDOW_STATE_TYPE_OTHER,
398    ACTIVE_WINDOW_STATE_TYPE_MAXIMIZED,
399    ACTIVE_WINDOW_STATE_TYPE_FULLSCREEN,
400    ACTIVE_WINDOW_STATE_TYPE_SNAPPED,
401    ACTIVE_WINDOW_STATE_TYPE_COUNT
402  };
403
404  ActiveWindowStateType active_window_state_type =
405      ACTIVE_WINDOW_STATE_TYPE_NO_ACTIVE_WINDOW;
406  wm::WindowState* active_window_state = ash::wm::GetActiveWindowState();
407  if (active_window_state) {
408    switch (active_window_state->GetStateType()) {
409      case wm::WINDOW_STATE_TYPE_MAXIMIZED:
410        active_window_state_type = ACTIVE_WINDOW_STATE_TYPE_MAXIMIZED;
411        break;
412      case wm::WINDOW_STATE_TYPE_FULLSCREEN:
413        active_window_state_type = ACTIVE_WINDOW_STATE_TYPE_FULLSCREEN;
414        break;
415      case wm::WINDOW_STATE_TYPE_LEFT_SNAPPED:
416      case wm::WINDOW_STATE_TYPE_RIGHT_SNAPPED:
417        active_window_state_type = ACTIVE_WINDOW_STATE_TYPE_SNAPPED;
418        break;
419      case wm::WINDOW_STATE_TYPE_DEFAULT:
420      case wm::WINDOW_STATE_TYPE_NORMAL:
421      case wm::WINDOW_STATE_TYPE_MINIMIZED:
422      case wm::WINDOW_STATE_TYPE_INACTIVE:
423      case wm::WINDOW_STATE_TYPE_END:
424      case wm::WINDOW_STATE_TYPE_AUTO_POSITIONED:
425        active_window_state_type = ACTIVE_WINDOW_STATE_TYPE_OTHER;
426        break;
427    }
428  }
429  UMA_HISTOGRAM_ENUMERATION("Ash.ActiveWindowShowTypeOverTime",
430                            active_window_state_type,
431                            ACTIVE_WINDOW_STATE_TYPE_COUNT);
432}
433
434}  // namespace ash
435