123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229 |
- // Copyright 2013 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "ash/metrics/user_metrics_recorder.h"
- #include <memory>
- #include <vector>
- #include "ash/app_list/app_list_metrics.h"
- #include "ash/constants/ash_pref_names.h"
- #include "ash/login/ui/lock_screen.h"
- #include "ash/metrics/demo_session_metrics_recorder.h"
- #include "ash/metrics/desktop_task_switch_metric_recorder.h"
- #include "ash/metrics/pointer_metrics_recorder.h"
- #include "ash/metrics/stylus_metrics_recorder.h"
- #include "ash/public/cpp/accessibility_controller_enums.h"
- #include "ash/public/cpp/shelf_item.h"
- #include "ash/public/cpp/shelf_model.h"
- #include "ash/session/session_controller_impl.h"
- #include "ash/shelf/shelf.h"
- #include "ash/shelf/shelf_view.h"
- #include "ash/shell.h"
- #include "ash/wm/window_state.h"
- #include "base/metrics/histogram_macros.h"
- #include "base/metrics/user_metrics.h"
- #include "components/prefs/pref_service.h"
- namespace ash {
- namespace {
- using ::chromeos::WindowStateType;
- // Time between calls to "RecordPeriodicMetrics".
- constexpr base::TimeDelta kRecordPeriodicMetricsInterval = base::Minutes(30);
- enum ActiveWindowStateType {
- ACTIVE_WINDOW_STATE_TYPE_NO_ACTIVE_WINDOW,
- ACTIVE_WINDOW_STATE_TYPE_OTHER,
- ACTIVE_WINDOW_STATE_TYPE_MAXIMIZED,
- ACTIVE_WINDOW_STATE_TYPE_FULLSCREEN,
- ACTIVE_WINDOW_STATE_TYPE_SNAPPED,
- ACTIVE_WINDOW_STATE_TYPE_PINNED,
- ACTIVE_WINDOW_STATE_TYPE_TRUSTED_PINNED,
- ACTIVE_WINDOW_STATE_TYPE_PIP,
- ACTIVE_WINDOW_STATE_TYPE_FLOATED,
- ACTIVE_WINDOW_STATE_TYPE_COUNT,
- };
- ActiveWindowStateType GetActiveWindowState() {
- ActiveWindowStateType active_window_state_type =
- ACTIVE_WINDOW_STATE_TYPE_NO_ACTIVE_WINDOW;
- WindowState* active_window_state = WindowState::ForActiveWindow();
- if (active_window_state) {
- switch (active_window_state->GetStateType()) {
- case WindowStateType::kMaximized:
- active_window_state_type = ACTIVE_WINDOW_STATE_TYPE_MAXIMIZED;
- break;
- case WindowStateType::kFullscreen:
- active_window_state_type = ACTIVE_WINDOW_STATE_TYPE_FULLSCREEN;
- break;
- case WindowStateType::kPrimarySnapped:
- case WindowStateType::kSecondarySnapped:
- active_window_state_type = ACTIVE_WINDOW_STATE_TYPE_SNAPPED;
- break;
- case WindowStateType::kPinned:
- active_window_state_type = ACTIVE_WINDOW_STATE_TYPE_PINNED;
- break;
- case WindowStateType::kTrustedPinned:
- active_window_state_type = ACTIVE_WINDOW_STATE_TYPE_TRUSTED_PINNED;
- break;
- case WindowStateType::kPip:
- active_window_state_type = ACTIVE_WINDOW_STATE_TYPE_PIP;
- break;
- case WindowStateType::kFloated:
- active_window_state_type = ACTIVE_WINDOW_STATE_TYPE_FLOATED;
- break;
- case WindowStateType::kDefault:
- case WindowStateType::kNormal:
- case WindowStateType::kMinimized:
- case WindowStateType::kInactive:
- active_window_state_type = ACTIVE_WINDOW_STATE_TYPE_OTHER;
- break;
- }
- }
- return active_window_state_type;
- }
- // Returns true if kiosk mode is active.
- bool IsKioskModeActive() {
- return Shell::Get()->session_controller()->login_status() ==
- LoginStatus::KIOSK_APP;
- }
- // Returns true if there is an active user and their session isn't currently
- // locked.
- bool IsUserActive() {
- SessionControllerImpl* session = Shell::Get()->session_controller();
- return session->IsActiveUserSessionStarted() && !session->IsScreenLocked();
- }
- // Records the number of items in the shelf as an UMA statistic.
- void RecordShelfItemCounts() {
- int pinned_item_count = 0;
- int unpinned_item_count = 0;
- for (const ShelfItem& item : ShelfModel::Get()->items()) {
- if (item.type == TYPE_PINNED_APP || item.type == TYPE_BROWSER_SHORTCUT)
- ++pinned_item_count;
- else
- ++unpinned_item_count;
- }
- UMA_HISTOGRAM_COUNTS_100("Ash.Shelf.NumberOfItems",
- pinned_item_count + unpinned_item_count);
- UMA_HISTOGRAM_COUNTS_100("Ash.Shelf.NumberOfPinnedItems", pinned_item_count);
- UMA_HISTOGRAM_COUNTS_100("Ash.Shelf.NumberOfUnpinnedItems",
- unpinned_item_count);
- }
- } // namespace
- UserMetricsRecorder::UserMetricsRecorder() {
- StartTimer();
- login_metrics_recorder_ = std::make_unique<LoginMetricsRecorder>();
- }
- UserMetricsRecorder::UserMetricsRecorder(bool record_periodic_metrics) {
- if (record_periodic_metrics)
- StartTimer();
- }
- UserMetricsRecorder::~UserMetricsRecorder() {
- timer_.Stop();
- }
- // static
- void UserMetricsRecorder::RecordUserClickOnTray(
- LoginMetricsRecorder::TrayClickTarget target) {
- LoginMetricsRecorder* recorder =
- Shell::Get()->metrics()->login_metrics_recorder();
- recorder->RecordUserTrayClick(target);
- }
- // static
- void UserMetricsRecorder::RecordUserClickOnShelfButton(
- LoginMetricsRecorder::ShelfButtonClickTarget target) {
- LoginMetricsRecorder* recorder =
- Shell::Get()->metrics()->login_metrics_recorder();
- recorder->RecordUserShelfButtonClick(target);
- }
- void UserMetricsRecorder::StartDemoSessionMetricsRecording() {
- demo_session_metrics_recorder_ =
- std::make_unique<DemoSessionMetricsRecorder>();
- Shell::Get()->AddPreTargetHandler(demo_session_metrics_recorder_.get());
- }
- void UserMetricsRecorder::OnShellInitialized() {
- // Lazy creation of the DesktopTaskSwitchMetricRecorder because it accesses
- // Shell::Get() which is not available when |this| is instantiated.
- if (!desktop_task_switch_metric_recorder_) {
- desktop_task_switch_metric_recorder_ =
- std::make_unique<DesktopTaskSwitchMetricRecorder>();
- }
- pointer_metrics_recorder_ = std::make_unique<PointerMetricsRecorder>();
- stylus_metrics_recorder_ = std::make_unique<StylusMetricsRecorder>();
- }
- void UserMetricsRecorder::OnShellShuttingDown() {
- // Doing the nullptr check as the recorder is not initialized outside demo
- // session. It was initialized during StartDemoSessionMetricsRecording().
- if (demo_session_metrics_recorder_ != nullptr) {
- Shell::Get()->RemovePreTargetHandler(demo_session_metrics_recorder_.get());
- demo_session_metrics_recorder_.reset();
- }
- desktop_task_switch_metric_recorder_.reset();
- // To clean up pointer_metrics_recorder_ and stylus_metrics_recorder_
- // properly, a valid shell instance is required, so explicitly delete them
- // before the shell instance becomes invalid.
- pointer_metrics_recorder_.reset();
- stylus_metrics_recorder_.reset();
- }
- void UserMetricsRecorder::RecordPeriodicMetrics() {
- Shelf* shelf = Shelf::ForWindow(Shell::GetPrimaryRootWindow());
- // TODO(bruthig): Investigating whether the check for |manager| is necessary
- // and add tests if it is.
- if (shelf) {
- // TODO(bruthig): Consider tracking the time spent in each alignment.
- UMA_HISTOGRAM_ENUMERATION("Ash.ShelfAlignmentOverTime",
- static_cast<ShelfAlignmentUmaEnumValue>(
- shelf->SelectValueForShelfAlignment(
- SHELF_ALIGNMENT_UMA_ENUM_VALUE_BOTTOM,
- SHELF_ALIGNMENT_UMA_ENUM_VALUE_LEFT,
- SHELF_ALIGNMENT_UMA_ENUM_VALUE_RIGHT)),
- SHELF_ALIGNMENT_UMA_ENUM_VALUE_COUNT);
- }
- if (IsUserInActiveDesktopEnvironment()) {
- RecordShelfItemCounts();
- RecordPeriodicAppListMetrics();
- base::UmaHistogramBoolean(
- "Ash.AppNotificationBadgingPref",
- Shell::Get()->session_controller()->GetActivePrefService()->GetBoolean(
- prefs::kAppNotificationBadgingEnabled));
- }
- // TODO(bruthig): Find out if this should only be logged when the user is
- // active.
- // TODO(bruthig): Consider tracking how long a particular type of window is
- // active at a time.
- UMA_HISTOGRAM_ENUMERATION("Ash.ActiveWindowShowTypeOverTime",
- GetActiveWindowState(),
- ACTIVE_WINDOW_STATE_TYPE_COUNT);
- }
- bool UserMetricsRecorder::IsUserInActiveDesktopEnvironment() const {
- return IsUserActive() && !IsKioskModeActive();
- }
- void UserMetricsRecorder::StartTimer() {
- timer_.Start(FROM_HERE, kRecordPeriodicMetricsInterval, this,
- &UserMetricsRecorder::RecordPeriodicMetrics);
- }
- } // namespace ash
|