1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
ash / metrics / demo_session_metrics_recorder.h [blame]
// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef ASH_METRICS_DEMO_SESSION_METRICS_RECORDER_H_
#define ASH_METRICS_DEMO_SESSION_METRICS_RECORDER_H_
#include <memory>
#include <string>
#include <vector>
#include "ash/ash_export.h"
#include "base/containers/flat_set.h"
#include "base/memory/raw_ptr.h"
#include "base/scoped_observation.h"
#include "base/time/time.h"
#include "chromeos/ui/base/app_types.h"
#include "ui/aura/window_observer.h"
#include "ui/base/user_activity/user_activity_detector.h"
#include "ui/base/user_activity/user_activity_observer.h"
#include "ui/events/event_handler.h"
#include "ui/wm/public/activation_change_observer.h"
#include "ui/wm/public/activation_client.h"
namespace base {
class RepeatingTimer;
} // namespace base
namespace ash {
// A metrics recorder for demo sessions that samples the active window's app or
// window type. Only used when the device is in Demo Mode.
class ASH_EXPORT DemoSessionMetricsRecorder
: public ui::UserActivityObserver,
public wm::ActivationChangeObserver,
public ui::EventHandler {
public:
// These apps are preinstalled in Demo Mode. This list is not exhaustive, and
// includes first- and third-party Chrome and ARC apps.
//
// These values are persisted to logs. Entries should not be renumbered and
// numeric values should never be reused.
enum class DemoModeApp {
kBrowser = 0,
kOtherChromeApp = 1,
kOtherArcApp = 2,
kOtherWindow = 3,
kHighlights = 4, // Auto-launched Demo Mode app highlighting CrOS features.
kAsphalt8 = 5, // Android racing game demo app.
kCamera = 6,
kFiles = 7,
kGetHelp = 8,
kGoogleKeepChromeApp = 9,
kGooglePhotos = 10,
kGoogleSheetsAndroidApp = 11,
kGoogleSlidesAndroidApp = 12,
kInfinitePainter = 13, // Android painting app.
kMyScriptNebo = 14, // Android note-taking app.
kPlayStore = 15,
kSquid = 16, // Android note-taking app.
kWebStore = 17,
kYouTube = 18,
kScreensaver = 19, // Demo Mode screensaver app.
kAsphalt9 = 20, // Android racing game demo app.
kStardewValley = 21, // Android farming game demo app.
kKinemaster = 22, // Android video editing software demo app. nocheck
kGoogleKeepAndroidApp = 23,
kAutoCAD = 24, // Android 2D/3D drawing software demo app.
kPixlr = 25, // Android photo editing software demo app.
kCalculator = 26, // Essential apps calculator.
kCalendar = 27,
kGoogleDocsChromeApp = 28,
kGoogleSheetsChromeApp = 29,
kGoogleSlidesChromeApp = 30,
kYoutubePwa = 31,
kGoogleDocsPwa = 32,
kGoogleMeetPwa = 33,
kGoogleSheetsPwa = 34,
kSpotify = 35,
kBeFunky = 36,
kClipchamp = 37,
kGeForceNow = 38,
kZoom = 39,
kSumo = 40,
kAdobeSpark = 41,
// Add future entries above this comment, in sync with enums.xml.
// Update kMaxValue to the last value.
kMaxValue = kAdobeSpark,
};
static constexpr char kUserClicksAndPressesMetric[] =
"DemoMode.UserClicksAndPresses";
// The recorder will create a normal timer by default. Tests should provide a
// mock timer to control sampling periods.
explicit DemoSessionMetricsRecorder(
std::unique_ptr<base::RepeatingTimer> timer = nullptr);
DemoSessionMetricsRecorder(const DemoSessionMetricsRecorder&) = delete;
DemoSessionMetricsRecorder& operator=(const DemoSessionMetricsRecorder&) =
delete;
~DemoSessionMetricsRecorder() override;
// ui::UserActivityObserver:
void OnUserActivity(const ui::Event* event) override;
// wm::ActivationChangeObserver:
void OnWindowActivated(wm::ActivationChangeObserver::ActivationReason reason,
aura::Window* gained_active,
aura::Window* lost_active) override;
// ui::EventHandler:
void OnMouseEvent(ui::MouseEvent* event) override;
void OnTouchEvent(ui::TouchEvent* event) override;
private:
// Starts the timer for periodic sampling.
void StartRecording();
// Records the active window's app type or, if the user has been inactive for
// too long, pauses sampling and wipes samples from the inactive period.
void TakeSampleOrPause();
// Emits histograms for recorded samples.
void ReportSamples();
// Records |app| as being seen while sampling all active apps.
void RecordActiveAppSample(DemoModeApp app);
// Indicates whether the specified app_id should be recorded for
// the unique-apps-launched stat.
bool ShouldRecordAppLaunch(const std::string& app_id);
// Records the specified app's launch, subject to the
// restrictions of ShouldRecordAppLaunch().
void RecordAppLaunch(const std::string& id, chromeos::AppType app_type);
// Emits various histograms for unique apps launched.
void ReportUniqueAppsLaunched();
// Records the duration of time the user spent interacting with the current
// demo session, measured from first user activity to last user activity.
void ReportDwellTime();
// Records the number of times the user clicks mouse/trackpad and presses
// screen in the demo session.
void ReportUserClickesAndPresses();
// Stores samples as they are collected. Report to UMA if we see user
// activity soon after. Guaranteed not to grow too large.
std::vector<DemoModeApp> unreported_samples_;
// Indicates whether the unique-app-launch stats recording has been enabled.
bool unique_apps_launched_recording_enabled_ = false;
// Tracks the ids of apps that have been launched in Demo Mode.
base::flat_set<std::string> unique_apps_launched_;
// Used for subscribing to window activation events.
raw_ptr<wm::ActivationClient> activation_client_ = nullptr;
// How many periods have elapsed since the last user activity.
int periods_since_activity_ = 0;
// Indicates number of user clicks mouse/trackpad and presses screen with
// demo mode in the current session.
int user_clicks_and_presses_ = 0;
base::TimeTicks first_user_activity_;
base::TimeTicks last_user_activity_;
std::unique_ptr<base::RepeatingTimer> timer_;
base::ScopedObservation<ui::UserActivityDetector, ui::UserActivityObserver>
observation_{this};
class ActiveAppArcPackageNameObserver;
class UniqueAppsLaunchedArcPackageNameObserver;
std::unique_ptr<UniqueAppsLaunchedArcPackageNameObserver>
unique_apps_arc_package_name_observer_;
std::unique_ptr<ActiveAppArcPackageNameObserver>
active_app_arc_package_name_observer_;
};
} // namespace ash
#endif // ASH_METRICS_DEMO_SESSION_METRICS_RECORDER_H_