1 // Copyright 2018 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef ASH_MULTI_DEVICE_SETUP_MULTI_DEVICE_NOTIFICATION_PRESENTER_H_
6 #define ASH_MULTI_DEVICE_SETUP_MULTI_DEVICE_NOTIFICATION_PRESENTER_H_
11 #include "ash/ash_export.h"
12 #include "ash/public/cpp/session/session_observer.h"
13 #include "base/auto_reset.h"
14 #include "base/functional/callback.h"
15 #include "base/memory/raw_ptr.h"
16 #include "base/memory/weak_ptr.h"
17 #include "chromeos/ash/services/multidevice_setup/public/mojom/multidevice_setup.mojom.h"
18 #include "mojo/public/cpp/bindings/receiver.h"
19 #include "mojo/public/cpp/bindings/remote.h"
20 #include "ui/message_center/message_center_observer.h"
22 namespace message_center {
25 class RichNotificationData;
26 } // namespace message_center
30 // Presents notifications necessary for MultiDevice setup flow. It observes the
31 // MultiDeviceSetup mojo service to show a notification when
32 // (1) a potential host is found for someone who has not gone through the setup
34 // (2) the host has switched for someone who has, or
35 // (3) a new Chromebook has been added to an account for someone who has.
37 // The behavior caused by clicking a notification depends its content as
39 // (1) triggers the setup UI to appear to prompt setup flow and
40 // (2) & (3) open the Connected Devices subpage in Settings.
42 // Note that if one notification is showing and another one is triggered, the
43 // old text is replaced (if it's different) and the notification pops up again.
44 class ASH_EXPORT MultiDeviceNotificationPresenter
45 : public multidevice_setup::mojom::AccountStatusChangeDelegate,
46 public SessionObserver,
47 public message_center::MessageCenterObserver {
49 explicit MultiDeviceNotificationPresenter(
50 message_center::MessageCenter* message_center);
52 MultiDeviceNotificationPresenter(const MultiDeviceNotificationPresenter&) =
54 MultiDeviceNotificationPresenter& operator=(
55 const MultiDeviceNotificationPresenter&) = delete;
57 ~MultiDeviceNotificationPresenter() override;
59 // Disables notifications for tests.
60 static std::unique_ptr<base::AutoReset<bool>>
61 DisableNotificationsForTesting();
63 // Removes the notification created by NotifyPotentialHostExists() or does
64 // nothing if that notification is not currently displayed.
65 void RemoveMultiDeviceSetupNotification();
67 void UpdateIsSetupNotificationInteracted(
68 bool is_setup_notificaton_interacted);
70 // MultiDevice setup notification ID. Public so it can be accessed from
72 static const char kSetupNotificationId[];
75 // multidevice_setup::mojom::AccountStatusChangeDelegate:
76 void OnPotentialHostExistsForNewUser() override;
77 void OnNoLongerNewUser() override;
78 void OnConnectedHostSwitchedForExistingUser(
79 const std::string& new_host_device_name) override;
80 void OnNewChromebookAddedForExistingUser(
81 const std::string& new_host_device_name) override;
82 void OnBecameEligibleForWifiSync() override;
85 void OnUserSessionAdded(const AccountId& account_id) override;
86 void OnSessionStateChanged(session_manager::SessionState state) override;
88 // message_center::MessageCenterObserver
89 void OnNotificationRemoved(const std::string& notification_id,
90 bool by_user) override;
92 void OnNotificationClicked(
93 const std::string& notification_id,
94 const absl::optional<int>& button_index,
95 const absl::optional<std::u16string>& reply) override;
98 friend class MultiDeviceNotificationPresenterTest;
100 // MultiDevice setup notification ID.
101 static const char kWifiSyncNotificationId[];
103 // Represents each possible MultiDevice setup notification that the setup flow
104 // can show with a "none" option for the general state with no notification
107 kNoNotificationVisible,
108 kNewUserNotificationVisible,
109 kExistingUserHostSwitchedNotificationVisible,
110 kExistingUserNewChromebookNotificationVisible
113 // Reflects MultiDeviceSetupNotification enum in enums.xml. Do not
115 enum class NotificationType {
116 kNewUserPotentialHostExists = 0,
117 kExistingUserHostSwitched = 1,
118 kExistingUserNewChromebookAdded = 2,
119 // This is a legacy error case that is not expected to occur.
121 kWifiSyncAnnouncement = 4,
122 kMaxValue = kWifiSyncAnnouncement
125 static NotificationType GetMetricValueForNotification(
126 Status notification_status);
128 static std::string GetNotificationDescriptionForLogging(
129 Status notification_status);
131 void ObserveMultiDeviceSetupIfPossible();
132 void ShowSetupNotification(const Status notification_status,
133 const std::u16string& title,
134 const std::u16string& message);
135 void ShowNotification(const std::string& id,
136 const std::u16string& title,
137 const std::u16string& message,
138 message_center::RichNotificationData optional_fields);
140 void FlushForTesting();
142 // Indicates if Phone Hub icon is clicked when the setup notification is
143 // visible. If the value is true, we do not log event to
144 // MultiDevice.Setup.NotificationInteracted histogram.
145 bool is_setup_notification_interacted_ = false;
147 raw_ptr<message_center::MessageCenter, ExperimentalAsh> message_center_;
149 // Notification currently showing or
150 // Status::kNoNotificationVisible if there isn't one.
151 Status notification_status_ = Status::kNoNotificationVisible;
153 mojo::Remote<multidevice_setup::mojom::MultiDeviceSetup>
154 multidevice_setup_remote_;
155 mojo::Receiver<multidevice_setup::mojom::AccountStatusChangeDelegate>
158 base::WeakPtrFactory<MultiDeviceNotificationPresenter> weak_ptr_factory_{
164 #endif // ASH_MULTI_DEVICE_SETUP_MULTI_DEVICE_NOTIFICATION_PRESENTER_H_