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 15 namespace ash { 16 17 // Time in seconds between calls to "RecordPeriodicMetrics". 18 const int kAshPeriodicMetricsTimeInSeconds = 30 * 60; 19 20 UserMetricsRecorder::UserMetricsRecorder() { 21 timer_.Start(FROM_HERE, 22 base::TimeDelta::FromSeconds(kAshPeriodicMetricsTimeInSeconds), 23 this, 24 &UserMetricsRecorder::RecordPeriodicMetrics); 25 } 26 27 UserMetricsRecorder::~UserMetricsRecorder() { 28 timer_.Stop(); 29 } 30 31 void 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 382 void 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