|  | // 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_MULTI_DEVICE_SETUP_MULTI_DEVICE_NOTIFICATION_PRESENTER_H_ | 
|  | #define ASH_MULTI_DEVICE_SETUP_MULTI_DEVICE_NOTIFICATION_PRESENTER_H_ | 
|  |  | 
|  | #include <memory> | 
|  | #include <string> | 
|  |  | 
|  | #include "ash/ash_export.h" | 
|  | #include "ash/public/cpp/session/session_observer.h" | 
|  | #include "base/auto_reset.h" | 
|  | #include "base/functional/callback.h" | 
|  | #include "base/memory/raw_ptr.h" | 
|  | #include "base/memory/weak_ptr.h" | 
|  | #include "chromeos/ash/services/multidevice_setup/public/mojom/multidevice_setup.mojom.h" | 
|  | #include "mojo/public/cpp/bindings/receiver.h" | 
|  | #include "mojo/public/cpp/bindings/remote.h" | 
|  | #include "ui/message_center/message_center_observer.h" | 
|  |  | 
|  | namespace message_center { | 
|  | class MessageCenter; | 
|  | class Notification; | 
|  | class RichNotificationData; | 
|  | }  // namespace message_center | 
|  |  | 
|  | namespace ash { | 
|  |  | 
|  | // Presents notifications necessary for MultiDevice setup flow. It observes the | 
|  | // MultiDeviceSetup mojo service to show a notification when | 
|  | // (1) a potential host is found for someone who has not gone through the setup | 
|  | //     flow before, | 
|  | // (2) the host has switched for someone who has, or | 
|  | // (3) a new Chromebook has been added to an account for someone who has. | 
|  | // | 
|  | // The behavior caused by clicking a notification depends its content as | 
|  | // described above: | 
|  | // (1) triggers the setup UI to appear to prompt setup flow and | 
|  | // (2) & (3) open the Connected Devices subpage in Settings. | 
|  | // | 
|  | // Note that if one notification is showing and another one is triggered, the | 
|  | // old text is replaced (if it's different) and the notification pops up again. | 
|  | class ASH_EXPORT MultiDeviceNotificationPresenter | 
|  | : public multidevice_setup::mojom::AccountStatusChangeDelegate, | 
|  | public SessionObserver, | 
|  | public message_center::MessageCenterObserver { | 
|  | public: | 
|  | explicit MultiDeviceNotificationPresenter( | 
|  | message_center::MessageCenter* message_center); | 
|  |  | 
|  | MultiDeviceNotificationPresenter(const MultiDeviceNotificationPresenter&) = | 
|  | delete; | 
|  | MultiDeviceNotificationPresenter& operator=( | 
|  | const MultiDeviceNotificationPresenter&) = delete; | 
|  |  | 
|  | ~MultiDeviceNotificationPresenter() override; | 
|  |  | 
|  | // Disables notifications for tests. | 
|  | static std::unique_ptr<base::AutoReset<bool>> | 
|  | DisableNotificationsForTesting(); | 
|  |  | 
|  | // Removes the notification created by NotifyPotentialHostExists() or does | 
|  | // nothing if that notification is not currently displayed. | 
|  | void RemoveMultiDeviceSetupNotification(); | 
|  |  | 
|  | void UpdateIsSetupNotificationInteracted( | 
|  | bool is_setup_notificaton_interacted); | 
|  |  | 
|  | // MultiDevice setup notification ID. Public so it can be accessed from | 
|  | // phone_hub_tray.cc | 
|  | static const char kSetupNotificationId[]; | 
|  |  | 
|  | protected: | 
|  | // multidevice_setup::mojom::AccountStatusChangeDelegate: | 
|  | void OnPotentialHostExistsForNewUser() override; | 
|  | void OnNoLongerNewUser() override; | 
|  | void OnConnectedHostSwitchedForExistingUser( | 
|  | const std::string& new_host_device_name) override; | 
|  | void OnNewChromebookAddedForExistingUser( | 
|  | const std::string& new_host_device_name) override; | 
|  | void OnBecameEligibleForWifiSync() override; | 
|  |  | 
|  | // SessionObserver: | 
|  | void OnUserSessionAdded(const AccountId& account_id) override; | 
|  | void OnSessionStateChanged(session_manager::SessionState state) override; | 
|  |  | 
|  | // message_center::MessageCenterObserver | 
|  | void OnNotificationRemoved(const std::string& notification_id, | 
|  | bool by_user) override; | 
|  |  | 
|  | void OnNotificationClicked( | 
|  | const std::string& notification_id, | 
|  | const std::optional<int>& button_index, | 
|  | const std::optional<std::u16string>& reply) override; | 
|  |  | 
|  | private: | 
|  | friend class MultiDeviceNotificationPresenterTest; | 
|  |  | 
|  | // MultiDevice setup notification ID. | 
|  | static const char kWifiSyncNotificationId[]; | 
|  |  | 
|  | // Represents each possible MultiDevice setup notification that the setup flow | 
|  | // can show with a "none" option for the general state with no notification | 
|  | // present. | 
|  | enum class Status { | 
|  | kNoNotificationVisible, | 
|  | kNewUserNotificationVisible, | 
|  | kExistingUserHostSwitchedNotificationVisible, | 
|  | kExistingUserNewChromebookNotificationVisible | 
|  | }; | 
|  |  | 
|  | // Reflects MultiDeviceSetupNotification enum in enums.xml. Do not | 
|  | // rearrange. | 
|  | enum class NotificationType { | 
|  | kNewUserPotentialHostExists = 0, | 
|  | kExistingUserHostSwitched = 1, | 
|  | kExistingUserNewChromebookAdded = 2, | 
|  | // This is a legacy error case that is not expected to occur. | 
|  | kErrorUnknown = 3, | 
|  | kWifiSyncAnnouncement = 4, | 
|  | kMaxValue = kWifiSyncAnnouncement | 
|  | }; | 
|  |  | 
|  | static NotificationType GetMetricValueForNotification( | 
|  | Status notification_status); | 
|  |  | 
|  | static std::string GetNotificationDescriptionForLogging( | 
|  | Status notification_status); | 
|  |  | 
|  | void ObserveMultiDeviceSetupIfPossible(); | 
|  | void ShowSetupNotification(const Status notification_status, | 
|  | const std::u16string& title, | 
|  | const std::u16string& message); | 
|  | void ShowNotification(const std::string& id, | 
|  | const std::u16string& title, | 
|  | const std::u16string& message, | 
|  | message_center::RichNotificationData optional_fields); | 
|  |  | 
|  | void FlushForTesting(); | 
|  |  | 
|  | // Indicates if Phone Hub icon is clicked when the setup notification is | 
|  | // visible. If the value is true, we do not log event to | 
|  | // MultiDevice.Setup.NotificationInteracted histogram. | 
|  | bool is_setup_notification_interacted_ = false; | 
|  |  | 
|  | raw_ptr<message_center::MessageCenter> message_center_; | 
|  |  | 
|  | // Notification currently showing or | 
|  | // Status::kNoNotificationVisible if there isn't one. | 
|  | Status notification_status_ = Status::kNoNotificationVisible; | 
|  |  | 
|  | mojo::Remote<multidevice_setup::mojom::MultiDeviceSetup> | 
|  | multidevice_setup_remote_; | 
|  | mojo::Receiver<multidevice_setup::mojom::AccountStatusChangeDelegate> | 
|  | receiver_{this}; | 
|  |  | 
|  | base::WeakPtrFactory<MultiDeviceNotificationPresenter> weak_ptr_factory_{ | 
|  | this}; | 
|  | }; | 
|  |  | 
|  | }  // namespace ash | 
|  |  | 
|  | #endif  // ASH_MULTI_DEVICE_SETUP_MULTI_DEVICE_NOTIFICATION_PRESENTER_H_ |