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
ash / user_education / welcome_tour / welcome_tour_controller.h [blame]
// Copyright 2023 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_USER_EDUCATION_WELCOME_TOUR_WELCOME_TOUR_CONTROLLER_H_
#define ASH_USER_EDUCATION_WELCOME_TOUR_WELCOME_TOUR_CONTROLLER_H_
#include <memory>
#include "ash/accessibility/accessibility_observer.h"
#include "ash/ash_export.h"
#include "ash/public/cpp/session/session_observer.h"
#include "ash/shell_observer.h"
#include "ash/user_education/user_education_feature_controller.h"
#include "ash/user_education/welcome_tour/welcome_tour_metrics.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "base/scoped_observation.h"
#include "base/timer/elapsed_timer.h"
#include "ui/base/interaction/element_identifier.h"
#include "ui/display/display_observer.h"
namespace display {
class Screen;
enum class TabletState;
} // namespace display
namespace user_education {
struct TutorialDescription;
} // namespace user_education
namespace ash {
class AccessibilityController;
class ScopedNudgePause;
class ScopedToastPause;
class SessionController;
class Shell;
class WelcomeTourAcceleratorHandler;
class WelcomeTourControllerObserver;
class WelcomeTourNotificationBlocker;
class WelcomeTourScrim;
class WelcomeTourWindowMinimizer;
// Controller responsible for the Welcome Tour feature tutorial. Note that the
// `WelcomeTourController` is owned by the `UserEducationController` and exists
// if and only if the Welcome Tour feature is enabled.
class ASH_EXPORT WelcomeTourController : public UserEducationFeatureController,
public AccessibilityObserver,
public SessionObserver,
public ShellObserver,
public display::DisplayObserver {
public:
WelcomeTourController();
WelcomeTourController(const WelcomeTourController&) = delete;
WelcomeTourController& operator=(const WelcomeTourController&) = delete;
~WelcomeTourController() override;
// Returns the singleton instance owned by the `UserEducationController`.
// NOTE: Exists if and only if the Welcome Tour feature is enabled.
static WelcomeTourController* Get();
// Adds/removes the specified `observer` from being notified of events.
void AddObserver(WelcomeTourControllerObserver* observer);
void RemoveObserver(WelcomeTourControllerObserver* observer);
// Returns the initial element context to be used to start the Welcome Tour.
ui::ElementContext GetInitialElementContext() const;
// Returns the tutorial description for the Welcome Tour.
user_education::TutorialDescription GetTutorialDescription() const;
private:
// AccessibilityObserver:
void OnAccessibilityControllerShutdown() override;
void OnAccessibilityStatusChanged() override;
// SessionObserver:
void OnActiveUserPrefServiceChanged(PrefService* pref_service) override;
void OnActiveUserSessionChanged(const AccountId& account_id) override;
void OnChromeTerminating() override;
void OnSessionStateChanged(session_manager::SessionState) override;
// ShellObserver:
void OnShellDestroying() override;
// display::DisplayObserver:
void OnDisplayTabletStateChanged(display::TabletState state) override;
// Starts the Welcome Tour if and only if the primary user session is active.
void MaybeStartWelcomeTour();
// Aborts the Welcome Tour if and only if the tour is in progress.
void MaybeAbortWelcomeTour(welcome_tour_metrics::AbortedReason reason);
// Invoked when the Welcome Tour is started/ended. The latter is called
// regardless of whether the tour was `completed` or aborted.
void OnWelcomeTourStarted();
void OnWelcomeTourEnded(bool completed, base::ElapsedTimer time_since_start);
// Sets the current step of the tutorial, since that information is not
// directly available.
void SetCurrentStep(std::optional<welcome_tour_metrics::Step> step);
// The reason the tour was aborted.
welcome_tour_metrics::AbortedReason aborted_reason_ =
welcome_tour_metrics::AbortedReason::kUnknown;
// The current step of the Welcome Tour, if it is active. Tracked here because
// it is not directly available from the tutorial.
std::optional<welcome_tour_metrics::Step> current_step_;
// The elapsed time since the beginning of the `current_step_`.
base::ElapsedTimer current_step_timer_;
// Handles accelerator actions during the Welcome Tour. Exists only while the
// Welcome Tour is in progress.
std::unique_ptr<WelcomeTourAcceleratorHandler> accelerator_handler_;
// Blocks all notifications while the Welcome Tour is in progress. Any
// notifications received during the tour will appear in the Notification
// Center after the tour is over.
std::unique_ptr<WelcomeTourNotificationBlocker> notification_blocker_;
// Suppresses all nudges during the Welcome Tour. Exists only while the
// Welcome Tour is in progress.
std::unique_ptr<ScopedNudgePause> nudge_pause_;
// Used to apply a scrim to the help bubble container on all root windows
// while the Welcome Tour is in progress. Exists only while the Welcome Tour
// is in progress.
std::unique_ptr<WelcomeTourScrim> scrim_;
// Suppresses all toasts during the Welcome Tour. Exists only while the
// Welcome Tour is in progress.
std::unique_ptr<ScopedToastPause> toast_pause_;
// Minimizes any app windows that are visible at the start of the Welcome
// Tour, and any that attempt to become visible during the tour. Exists only
// while the Welcome Tour is in progress.
std::unique_ptr<WelcomeTourWindowMinimizer> window_minimizer_;
// The collection of observers to be notified of events.
base::ObserverList<WelcomeTourControllerObserver> observer_list_;
// The accessibility controller is observed only while the Welcome Tour is in
// progress, and will trigger an abort of the tour if ChromeVox is enabled.
base::ScopedObservation<AccessibilityController, AccessibilityObserver>
accessibility_observation_{this};
// Sessions are observed only until the primary user session is activated for
// the first time at which point the Welcome Tour is started.
base::ScopedObservation<SessionController, SessionObserver>
session_observation_{this};
// Shell is observed only while the Welcome Tour is in progress. The Welcome
// Tour is aborted when Shell is destroying to ensure the Welcome Tour does
// not outlive its dependencies.
base::ScopedObservation<Shell, ShellObserver> shell_observation_{this};
// Display is observed only while the Welcome Tour is in progress, and will
// trigger an abort of the tour if the device switches to tablet mode.
base::ScopedObservation<display::Screen, display::DisplayObserver>
display_observation_{this};
// It is theoretically possible for the Welcome Tour tutorial to outlive
// `this` controller during the destruction sequence.
base::WeakPtrFactory<WelcomeTourController> weak_ptr_factory_{this};
};
} // namespace ash
#endif // ASH_USER_EDUCATION_WELCOME_TOUR_WELCOME_TOUR_CONTROLLER_H_