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 <memory>
8 #include <vector>
9
10 #include "ash/login/ui/lock_screen.h"
11 #include "ash/metrics/demo_session_metrics_recorder.h"
12 #include "ash/metrics/desktop_task_switch_metric_recorder.h"
13 #include "ash/metrics/pointer_metrics_recorder.h"
14 #include "ash/public/cpp/accessibility_controller_enums.h"
15 #include "ash/public/cpp/shelf_item.h"
16 #include "ash/public/cpp/shelf_model.h"
17 #include "ash/public/cpp/shell_window_ids.h"
18 #include "ash/session/session_controller_impl.h"
19 #include "ash/shelf/shelf.h"
20 #include "ash/shelf/shelf_view.h"
21 #include "ash/shell.h"
22 #include "ash/wm/desks/desks_util.h"
23 #include "ash/wm/window_state.h"
24 #include "base/metrics/histogram_macros.h"
25 #include "base/metrics/user_metrics.h"
26 #include "ui/aura/window.h"
27
28 namespace ash {
29
30 namespace {
31
32 using ::chromeos::WindowStateType;
33
34 // Time in seconds between calls to "RecordPeriodicMetrics".
35 const int kAshPeriodicMetricsTimeInSeconds = 30 * 60;
36
37 enum ActiveWindowStateType {
38 ACTIVE_WINDOW_STATE_TYPE_NO_ACTIVE_WINDOW,
39 ACTIVE_WINDOW_STATE_TYPE_OTHER,
40 ACTIVE_WINDOW_STATE_TYPE_MAXIMIZED,
41 ACTIVE_WINDOW_STATE_TYPE_FULLSCREEN,
42 ACTIVE_WINDOW_STATE_TYPE_SNAPPED,
43 ACTIVE_WINDOW_STATE_TYPE_PINNED,
44 ACTIVE_WINDOW_STATE_TYPE_TRUSTED_PINNED,
45 ACTIVE_WINDOW_STATE_TYPE_PIP,
46 ACTIVE_WINDOW_STATE_TYPE_COUNT,
47 };
48
GetActiveWindowState()49 ActiveWindowStateType GetActiveWindowState() {
50 ActiveWindowStateType active_window_state_type =
51 ACTIVE_WINDOW_STATE_TYPE_NO_ACTIVE_WINDOW;
52 WindowState* active_window_state = WindowState::ForActiveWindow();
53 if (active_window_state) {
54 switch (active_window_state->GetStateType()) {
55 case WindowStateType::kMaximized:
56 active_window_state_type = ACTIVE_WINDOW_STATE_TYPE_MAXIMIZED;
57 break;
58 case WindowStateType::kFullscreen:
59 active_window_state_type = ACTIVE_WINDOW_STATE_TYPE_FULLSCREEN;
60 break;
61 case WindowStateType::kLeftSnapped:
62 case WindowStateType::kRightSnapped:
63 active_window_state_type = ACTIVE_WINDOW_STATE_TYPE_SNAPPED;
64 break;
65 case WindowStateType::kPinned:
66 active_window_state_type = ACTIVE_WINDOW_STATE_TYPE_PINNED;
67 break;
68 case WindowStateType::kTrustedPinned:
69 active_window_state_type = ACTIVE_WINDOW_STATE_TYPE_TRUSTED_PINNED;
70 break;
71 case WindowStateType::kPip:
72 active_window_state_type = ACTIVE_WINDOW_STATE_TYPE_PIP;
73 break;
74 case WindowStateType::kDefault:
75 case WindowStateType::kNormal:
76 case WindowStateType::kMinimized:
77 case WindowStateType::kInactive:
78 case WindowStateType::kAutoPositioned:
79 active_window_state_type = ACTIVE_WINDOW_STATE_TYPE_OTHER;
80 break;
81 }
82 }
83 return active_window_state_type;
84 }
85
86 // Returns true if kiosk mode is active.
IsKioskModeActive()87 bool IsKioskModeActive() {
88 return Shell::Get()->session_controller()->login_status() ==
89 LoginStatus::KIOSK_APP;
90 }
91
92 // Returns true if there is an active user and their session isn't currently
93 // locked.
IsUserActive()94 bool IsUserActive() {
95 SessionControllerImpl* session = Shell::Get()->session_controller();
96 return session->IsActiveUserSessionStarted() && !session->IsScreenLocked();
97 }
98
99 // Returns a list of window container ids that contain visible windows to be
100 // counted for UMA statistics. Note the containers are ordered from top most
101 // visible container to the lowest to allow the |GetNumVisibleWindows| method to
102 // short circuit when processing a maximized or fullscreen window.
GetVisibleWindowContainerIds()103 std::vector<int> GetVisibleWindowContainerIds() {
104 std::vector<int> ids{kShellWindowId_PipContainer,
105 kShellWindowId_AlwaysOnTopContainer};
106 // TODO(afakhry): Add metrics for the inactive desks.
107 ids.emplace_back(desks_util::GetActiveDeskContainerId());
108 return ids;
109 }
110
111 // Returns an approximate count of how many windows are currently visible in the
112 // primary root window.
GetNumVisibleWindowsInPrimaryDisplay()113 int GetNumVisibleWindowsInPrimaryDisplay() {
114 int visible_window_count = 0;
115 bool maximized_or_fullscreen_window_present = false;
116
117 for (const int& current_container_id : GetVisibleWindowContainerIds()) {
118 if (maximized_or_fullscreen_window_present)
119 break;
120
121 const aura::Window::Windows& children =
122 Shell::GetContainer(Shell::Get()->GetPrimaryRootWindow(),
123 current_container_id)
124 ->children();
125 // Reverse iterate over the child windows so that they are processed in
126 // visible stacking order.
127 for (aura::Window::Windows::const_reverse_iterator it = children.rbegin(),
128 rend = children.rend();
129 it != rend; ++it) {
130 const aura::Window* child_window = *it;
131 const WindowState* child_window_state = WindowState::Get(child_window);
132
133 if (!child_window->IsVisible() || child_window_state->IsMinimized())
134 continue;
135
136 // Only count activatable windows for 1 reason:
137 // - Ensures that a browser window and its transient, modal child will
138 // only count as 1 visible window.
139 if (child_window_state->CanActivate())
140 ++visible_window_count;
141
142 // Stop counting windows that will be hidden by maximized or fullscreen
143 // windows. Only windows in the active desk container and
144 // kShellWindowId_AlwaysOnTopContainer can be maximized or fullscreened
145 // and completely obscure windows beneath them.
146 if (child_window_state->IsMaximizedOrFullscreenOrPinned()) {
147 maximized_or_fullscreen_window_present = true;
148 break;
149 }
150 }
151 }
152 return visible_window_count;
153 }
154
155 // Records the number of items in the shelf as an UMA statistic.
RecordShelfItemCounts()156 void RecordShelfItemCounts() {
157 int pinned_item_count = 0;
158 int unpinned_item_count = 0;
159 for (const ShelfItem& item : ShelfModel::Get()->items()) {
160 if (item.type == TYPE_PINNED_APP || item.type == TYPE_BROWSER_SHORTCUT)
161 ++pinned_item_count;
162 else
163 ++unpinned_item_count;
164 }
165
166 UMA_HISTOGRAM_COUNTS_100("Ash.Shelf.NumberOfItems",
167 pinned_item_count + unpinned_item_count);
168 UMA_HISTOGRAM_COUNTS_100("Ash.Shelf.NumberOfPinnedItems", pinned_item_count);
169 UMA_HISTOGRAM_COUNTS_100("Ash.Shelf.NumberOfUnpinnedItems",
170 unpinned_item_count);
171 }
172
173 } // namespace
174
UserMetricsRecorder()175 UserMetricsRecorder::UserMetricsRecorder() {
176 StartTimer();
177 login_metrics_recorder_ = std::make_unique<LoginMetricsRecorder>();
178 }
179
UserMetricsRecorder(bool record_periodic_metrics)180 UserMetricsRecorder::UserMetricsRecorder(bool record_periodic_metrics) {
181 if (record_periodic_metrics)
182 StartTimer();
183 }
184
~UserMetricsRecorder()185 UserMetricsRecorder::~UserMetricsRecorder() {
186 timer_.Stop();
187 }
188
189 // static
RecordUserClickOnTray(LoginMetricsRecorder::TrayClickTarget target)190 void UserMetricsRecorder::RecordUserClickOnTray(
191 LoginMetricsRecorder::TrayClickTarget target) {
192 LoginMetricsRecorder* recorder =
193 Shell::Get()->metrics()->login_metrics_recorder();
194 recorder->RecordUserTrayClick(target);
195 }
196
197 // static
RecordUserClickOnShelfButton(LoginMetricsRecorder::ShelfButtonClickTarget target)198 void UserMetricsRecorder::RecordUserClickOnShelfButton(
199 LoginMetricsRecorder::ShelfButtonClickTarget target) {
200 LoginMetricsRecorder* recorder =
201 Shell::Get()->metrics()->login_metrics_recorder();
202 recorder->RecordUserShelfButtonClick(target);
203 }
204
205 // static
RecordUserToggleDictation(DictationToggleSource source)206 void UserMetricsRecorder::RecordUserToggleDictation(
207 DictationToggleSource source) {
208 UMA_HISTOGRAM_ENUMERATION("Accessibility.CrosDictation.ToggleDictationMethod",
209 source);
210 }
211
RecordUserMetricsAction(UserMetricsAction action)212 void UserMetricsRecorder::RecordUserMetricsAction(UserMetricsAction action) {
213 using base::RecordAction;
214 using base::UserMetricsAction;
215
216 switch (action) {
217 case UMA_DESKTOP_SWITCH_TASK:
218 RecordAction(UserMetricsAction("Desktop_SwitchTask"));
219 task_switch_metrics_recorder_.OnTaskSwitch(TaskSwitchSource::DESKTOP);
220 break;
221 case UMA_LAUNCHER_BUTTON_PRESSED_WITH_MOUSE:
222 RecordAction(UserMetricsAction("Launcher_ButtonPressed_Mouse"));
223 break;
224 case UMA_LAUNCHER_BUTTON_PRESSED_WITH_TOUCH:
225 RecordAction(UserMetricsAction("Launcher_ButtonPressed_Touch"));
226 break;
227 case UMA_LAUNCHER_CLICK_ON_APP:
228 RecordAction(UserMetricsAction("Launcher_ClickOnApp"));
229 break;
230 case UMA_LAUNCHER_CLICK_ON_APPLIST_BUTTON:
231 RecordAction(UserMetricsAction("Launcher_ClickOnApplistButton"));
232 break;
233 case UMA_LAUNCHER_LAUNCH_TASK:
234 RecordAction(UserMetricsAction("Launcher_LaunchTask"));
235 task_switch_metrics_recorder_.OnTaskSwitch(TaskSwitchSource::SHELF);
236 break;
237 case UMA_LAUNCHER_MINIMIZE_TASK:
238 RecordAction(UserMetricsAction("Launcher_MinimizeTask"));
239 break;
240 case UMA_LAUNCHER_SWITCH_TASK:
241 RecordAction(UserMetricsAction("Launcher_SwitchTask"));
242 task_switch_metrics_recorder_.OnTaskSwitch(TaskSwitchSource::SHELF);
243 break;
244 case UMA_SHELF_ALIGNMENT_SET_BOTTOM:
245 RecordAction(UserMetricsAction("Shelf_AlignmentSetBottom"));
246 break;
247 case UMA_SHELF_ALIGNMENT_SET_LEFT:
248 RecordAction(UserMetricsAction("Shelf_AlignmentSetLeft"));
249 break;
250 case UMA_SHELF_ALIGNMENT_SET_RIGHT:
251 RecordAction(UserMetricsAction("Shelf_AlignmentSetRight"));
252 break;
253 case UMA_STATUS_AREA_AUDIO_CURRENT_INPUT_DEVICE:
254 RecordAction(UserMetricsAction("StatusArea_Audio_CurrentInputDevice"));
255 break;
256 case UMA_STATUS_AREA_AUDIO_CURRENT_OUTPUT_DEVICE:
257 RecordAction(UserMetricsAction("StatusArea_Audio_CurrentOutputDevice"));
258 break;
259 case UMA_STATUS_AREA_AUDIO_SWITCH_INPUT_DEVICE:
260 RecordAction(UserMetricsAction("StatusArea_Audio_SwitchInputDevice"));
261 break;
262 case UMA_STATUS_AREA_AUDIO_SWITCH_OUTPUT_DEVICE:
263 RecordAction(UserMetricsAction("StatusArea_Audio_SwitchOutputDevice"));
264 break;
265 case UMA_STATUS_AREA_BRIGHTNESS_CHANGED:
266 RecordAction(UserMetricsAction("StatusArea_BrightnessChanged"));
267 break;
268 case UMA_STATUS_AREA_BLUETOOTH_DISABLED:
269 RecordAction(UserMetricsAction("StatusArea_Bluetooth_Disabled"));
270 break;
271 case UMA_STATUS_AREA_BLUETOOTH_ENABLED:
272 RecordAction(UserMetricsAction("StatusArea_Bluetooth_Enabled"));
273 break;
274 case UMA_STATUS_AREA_CAPS_LOCK_DETAILED:
275 RecordAction(UserMetricsAction("StatusArea_CapsLock_Detailed"));
276 break;
277 case UMA_STATUS_AREA_CAPS_LOCK_DISABLED_BY_CLICK:
278 RecordAction(UserMetricsAction("StatusArea_CapsLock_DisabledByClick"));
279 break;
280 case UMA_STATUS_AREA_CAPS_LOCK_ENABLED_BY_CLICK:
281 RecordAction(UserMetricsAction("StatusArea_CapsLock_EnabledByClick"));
282 break;
283 case UMA_STATUS_AREA_CAPS_LOCK_POPUP:
284 RecordAction(UserMetricsAction("StatusArea_CapsLock_Popup"));
285 break;
286 case UMA_STATUS_AREA_CAST_STOP_CAST:
287 RecordAction(UserMetricsAction("StatusArea_Cast_StopCast"));
288 break;
289 case UMA_STATUS_AREA_CONNECT_TO_CONFIGURED_NETWORK:
290 RecordAction(UserMetricsAction("StatusArea_Network_ConnectConfigured"));
291 break;
292 case UMA_STATUS_AREA_CONNECT_TO_UNCONFIGURED_NETWORK:
293 RecordAction(UserMetricsAction("StatusArea_Network_ConnectUnconfigured"));
294 break;
295 case UMA_STATUS_AREA_CONNECT_TO_VPN:
296 RecordAction(UserMetricsAction("StatusArea_VPN_ConnectToNetwork"));
297 break;
298 case UMA_STATUS_AREA_CHANGED_VOLUME_MENU:
299 RecordAction(UserMetricsAction("StatusArea_Volume_ChangedMenu"));
300 break;
301 case UMA_STATUS_AREA_CHANGED_VOLUME_POPUP:
302 RecordAction(UserMetricsAction("StatusArea_Volume_ChangedPopup"));
303 break;
304 case UMA_STATUS_AREA_DETAILED_ACCESSIBILITY:
305 RecordAction(UserMetricsAction("StatusArea_Accessability_DetailedView"));
306 break;
307 case UMA_STATUS_AREA_DETAILED_AUDIO_VIEW:
308 RecordAction(UserMetricsAction("StatusArea_Audio_Detailed"));
309 break;
310 case UMA_STATUS_AREA_DETAILED_BLUETOOTH_VIEW:
311 RecordAction(UserMetricsAction("StatusArea_Bluetooth_Detailed"));
312 break;
313 case UMA_STATUS_AREA_DETAILED_BRIGHTNESS_VIEW:
314 RecordAction(UserMetricsAction("StatusArea_Brightness_Detailed"));
315 break;
316 case UMA_STATUS_AREA_DETAILED_CAST_VIEW:
317 RecordAction(UserMetricsAction("StatusArea_Cast_Detailed"));
318 break;
319 case UMA_STATUS_AREA_DETAILED_CAST_VIEW_LAUNCH_CAST:
320 RecordAction(UserMetricsAction("StatusArea_Cast_Detailed_Launch_Cast"));
321 break;
322 case UMA_STATUS_AREA_DETAILED_DRIVE_VIEW:
323 RecordAction(UserMetricsAction("StatusArea_Drive_Detailed"));
324 break;
325 case UMA_STATUS_AREA_DETAILED_NETWORK_VIEW:
326 RecordAction(UserMetricsAction("StatusArea_Network_Detailed"));
327 break;
328 case UMA_STATUS_AREA_DETAILED_SMS_VIEW:
329 RecordAction(UserMetricsAction("StatusArea_SMS_Detailed"));
330 break;
331 case UMA_STATUS_AREA_DETAILED_VPN_VIEW:
332 RecordAction(UserMetricsAction("StatusArea_VPN_Detailed"));
333 break;
334 case UMA_STATUS_AREA_DISPLAY_DEFAULT_SELECTED:
335 RecordAction(UserMetricsAction("StatusArea_Display_Default_Selected"));
336 break;
337 case UMA_STATUS_AREA_DISPLAY_DEFAULT_SHOW_SETTINGS:
338 RecordAction(
339 UserMetricsAction("StatusArea_Display_Default_ShowSettings"));
340 break;
341 case UMA_STATUS_AREA_DISPLAY_NOTIFICATION_CREATED:
342 RecordAction(
343 UserMetricsAction("StatusArea_Display_Notification_Created"));
344 break;
345 case UMA_STATUS_AREA_DISPLAY_NOTIFICATION_SELECTED:
346 RecordAction(
347 UserMetricsAction("StatusArea_Display_Notification_Selected"));
348 break;
349 case UMA_STATUS_AREA_DISPLAY_NOTIFICATION_SHOW_SETTINGS:
350 RecordAction(
351 UserMetricsAction("StatusArea_Display_Notification_Show_Settings"));
352 break;
353 case UMA_STATUS_AREA_DISABLE_WIFI:
354 RecordAction(UserMetricsAction("StatusArea_Network_WifiDisabled"));
355 break;
356 case UMA_STATUS_AREA_DRIVE_CANCEL_OPERATION:
357 RecordAction(UserMetricsAction("StatusArea_Drive_CancelOperation"));
358 break;
359 case UMA_STATUS_AREA_DRIVE_SETTINGS:
360 RecordAction(UserMetricsAction("StatusArea_Drive_Settings"));
361 break;
362 case UMA_STATUS_AREA_ENABLE_WIFI:
363 RecordAction(UserMetricsAction("StatusArea_Network_WifiEnabled"));
364 break;
365 case UMA_STATUS_AREA_MENU_OPENED:
366 RecordAction(UserMetricsAction("StatusArea_MenuOpened"));
367 break;
368 case UMA_STATUS_AREA_NETWORK_JOIN_OTHER_CLICKED:
369 RecordAction(UserMetricsAction("StatusArea_Network_JoinOther"));
370 break;
371 case UMA_STATUS_AREA_NETWORK_SETTINGS_OPENED:
372 RecordAction(UserMetricsAction("StatusArea_Network_Settings"));
373 break;
374 case UMA_STATUS_AREA_OS_UPDATE_DEFAULT_SELECTED:
375 RecordAction(UserMetricsAction("StatusArea_OS_Update_Default_Selected"));
376 break;
377 case UMA_STATUS_AREA_SCREEN_CAPTURE_CHANGE_SOURCE:
378 RecordAction(UserMetricsAction("StatusArea_ScreenCapture_Change_Source"));
379 break;
380 case UMA_STATUS_AREA_SCREEN_CAPTURE_DEFAULT_STOP:
381 RecordAction(UserMetricsAction("StatusArea_ScreenCapture_Default_Stop"));
382 break;
383 case UMA_STATUS_AREA_SCREEN_CAPTURE_NOTIFICATION_STOP:
384 RecordAction(
385 UserMetricsAction("StatusArea_ScreenCapture_Notification_Stop"));
386 break;
387 case UMA_STATUS_AREA_SHOW_NETWORK_CONNECTION_DETAILS:
388 RecordAction(UserMetricsAction("StatusArea_Network_ConnectionDetails"));
389 break;
390 case UMA_STATUS_AREA_SHOW_VPN_CONNECTION_DETAILS:
391 RecordAction(UserMetricsAction("StatusArea_VPN_ConnectionDetails"));
392 break;
393 case UMA_STATUS_AREA_SIGN_OUT:
394 RecordAction(UserMetricsAction("StatusArea_SignOut"));
395 break;
396 case UMA_STATUS_AREA_SMS_DETAILED_DISMISS_MSG:
397 RecordAction(UserMetricsAction("StatusArea_SMS_Detailed_DismissMsg"));
398 break;
399 case UMA_STATUS_AREA_SMS_NOTIFICATION_DISMISS_MSG:
400 RecordAction(UserMetricsAction("StatusArea_SMS_Notification_DismissMsg"));
401 break;
402 case UMA_STATUS_AREA_TRACING_DEFAULT_SELECTED:
403 RecordAction(UserMetricsAction("StatusArea_Tracing_Default_Selected"));
404 break;
405 case UMA_STATUS_AREA_VPN_ADD_BUILT_IN_CLICKED:
406 RecordAction(UserMetricsAction("StatusArea_VPN_AddBuiltIn"));
407 break;
408 case UMA_STATUS_AREA_VPN_ADD_THIRD_PARTY_CLICKED:
409 RecordAction(UserMetricsAction("StatusArea_VPN_AddThirdParty"));
410 break;
411 case UMA_STATUS_AREA_VPN_DISCONNECT_CLICKED:
412 RecordAction(UserMetricsAction("StatusArea_VPN_Disconnect"));
413 break;
414 case UMA_STATUS_AREA_VPN_SETTINGS_OPENED:
415 RecordAction(UserMetricsAction("StatusArea_VPN_Settings"));
416 break;
417 case UMA_TRAY_HELP:
418 RecordAction(UserMetricsAction("Tray_Help"));
419 break;
420 case UMA_TRAY_LOCK_SCREEN:
421 RecordAction(UserMetricsAction("Tray_LockScreen"));
422 break;
423 case UMA_TRAY_NIGHT_LIGHT:
424 RecordAction(UserMetricsAction("Tray_NightLight"));
425 break;
426 case UMA_TRAY_OVERVIEW:
427 RecordAction(UserMetricsAction("Tray_Overview"));
428 break;
429 case UMA_TRAY_SETTINGS:
430 RecordAction(UserMetricsAction("Tray_Settings"));
431 break;
432 case UMA_TRAY_SHUT_DOWN:
433 RecordAction(UserMetricsAction("Tray_ShutDown"));
434 break;
435 }
436 }
437
StartDemoSessionMetricsRecording()438 void UserMetricsRecorder::StartDemoSessionMetricsRecording() {
439 demo_session_metrics_recorder_ =
440 std::make_unique<DemoSessionMetricsRecorder>();
441 }
442
OnShellInitialized()443 void UserMetricsRecorder::OnShellInitialized() {
444 // Lazy creation of the DesktopTaskSwitchMetricRecorder because it accesses
445 // Shell::Get() which is not available when |this| is instantiated.
446 if (!desktop_task_switch_metric_recorder_) {
447 desktop_task_switch_metric_recorder_.reset(
448 new DesktopTaskSwitchMetricRecorder());
449 }
450 pointer_metrics_recorder_ = std::make_unique<PointerMetricsRecorder>();
451 }
452
OnShellShuttingDown()453 void UserMetricsRecorder::OnShellShuttingDown() {
454 demo_session_metrics_recorder_.reset();
455 desktop_task_switch_metric_recorder_.reset();
456
457 // To clean up pointer_metrics_recorder_ properly, a valid shell instance is
458 // required, so explicitly delete it before the shell instance becomes
459 // invalid.
460 pointer_metrics_recorder_.reset();
461 }
462
RecordPeriodicMetrics()463 void UserMetricsRecorder::RecordPeriodicMetrics() {
464 Shelf* shelf = Shelf::ForWindow(Shell::GetPrimaryRootWindow());
465 // TODO(bruthig): Investigating whether the check for |manager| is necessary
466 // and add tests if it is.
467 if (shelf) {
468 // TODO(bruthig): Consider tracking the time spent in each alignment.
469 UMA_HISTOGRAM_ENUMERATION("Ash.ShelfAlignmentOverTime",
470 static_cast<ShelfAlignmentUmaEnumValue>(
471 shelf->SelectValueForShelfAlignment(
472 SHELF_ALIGNMENT_UMA_ENUM_VALUE_BOTTOM,
473 SHELF_ALIGNMENT_UMA_ENUM_VALUE_LEFT,
474 SHELF_ALIGNMENT_UMA_ENUM_VALUE_RIGHT)),
475 SHELF_ALIGNMENT_UMA_ENUM_VALUE_COUNT);
476 }
477
478 if (IsUserInActiveDesktopEnvironment()) {
479 RecordShelfItemCounts();
480 UMA_HISTOGRAM_COUNTS_100("Ash.NumberOfVisibleWindowsInPrimaryDisplay",
481 GetNumVisibleWindowsInPrimaryDisplay());
482 }
483
484 // TODO(bruthig): Find out if this should only be logged when the user is
485 // active.
486 // TODO(bruthig): Consider tracking how long a particular type of window is
487 // active at a time.
488 UMA_HISTOGRAM_ENUMERATION("Ash.ActiveWindowShowTypeOverTime",
489 GetActiveWindowState(),
490 ACTIVE_WINDOW_STATE_TYPE_COUNT);
491 }
492
IsUserInActiveDesktopEnvironment() const493 bool UserMetricsRecorder::IsUserInActiveDesktopEnvironment() const {
494 return IsUserActive() && !IsKioskModeActive();
495 }
496
StartTimer()497 void UserMetricsRecorder::StartTimer() {
498 timer_.Start(FROM_HERE,
499 base::TimeDelta::FromSeconds(kAshPeriodicMetricsTimeInSeconds),
500 this, &UserMetricsRecorder::RecordPeriodicMetrics);
501 }
502
503 } // namespace ash
504