| // Copyright 2021 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef CHROME_BROWSER_ASH_EXTENSIONS_FILE_MANAGER_SYSTEM_NOTIFICATION_MANAGER_H_ |
| #define CHROME_BROWSER_ASH_EXTENSIONS_FILE_MANAGER_SYSTEM_NOTIFICATION_MANAGER_H_ |
| |
| #include "ash/public/cpp/notification_utils.h" |
| #include "base/functional/callback_forward.h" |
| #include "base/gtest_prod_util.h" |
| #include "base/memory/raw_ptr.h" |
| #include "base/memory/weak_ptr.h" |
| #include "chrome/browser/ash/file_manager/io_task.h" |
| #include "chrome/browser/ash/file_manager/io_task_controller.h" |
| #include "chrome/browser/ash/file_manager/volume_manager.h" |
| #include "chrome/browser/ash/policy/dlp/dialogs/files_policy_dialog.h" |
| #include "chrome/browser/notifications/notification_display_service.h" |
| #include "chrome/browser/notifications/notification_display_service_factory.h" |
| #include "chrome/browser/notifications/system_notification_helper.h" |
| #include "chrome/browser/profiles/profile.h" |
| #include "chrome/common/extensions/api/file_manager_private.h" |
| #include "extensions/browser/event_router.h" |
| #include "storage/browser/file_system/file_system_url.h" |
| #include "ui/message_center/public/cpp/notification.h" |
| #include "ui/message_center/public/cpp/notification_delegate.h" |
| |
| namespace file_manager { |
| |
| namespace file_manager_private = extensions::api::file_manager_private; |
| |
| class DriveFsEventRouter; |
| |
| // Status of mounted removable devices. |
| enum SystemNotificationManagerMountStatus { |
| // Initial state. |
| MOUNT_STATUS_NO_RESULT, |
| // No errors on the device. |
| MOUNT_STATUS_SUCCESS, |
| // Parent errors exist that may be overridden by child partitions. |
| MOUNT_STATUS_ONLY_PARENT_ERROR, |
| // A single child partition error. |
| MOUNT_STATUS_CHILD_ERROR, |
| // Multiple child partitions with at least one in error. |
| MOUNT_STATUS_MULTIPART_ERROR, |
| }; |
| |
| // Enum of possible UMA values for histogram Notification.Show. |
| // Keep the order of this in sync with FileManagerNotificationType in |
| // tools/metrics/histograms/enums.xml. |
| enum class DeviceNotificationUmaType { |
| DEVICE_NAVIGATION_ALLOW_APP_ACCESS = 0, |
| DEVICE_NAVIGATION_APPS_HAVE_ACCESS = 1, |
| DEVICE_NAVIGATION = 2, |
| DEVICE_NAVIGATION_READONLY_POLICY = 3, |
| DEVICE_IMPORT = 4, |
| DEVICE_FAIL = 5, |
| DEVICE_FAIL_UNKNOWN = 6, |
| DEVICE_FAIL_UNKNOWN_READONLY = 7, |
| DEVICE_EXTERNAL_STORAGE_DISABLED = 8, |
| DEVICE_HARD_UNPLUGGED = 9, |
| FORMAT_START = 10, |
| FORMAT_SUCCESS = 11, |
| FORMAT_FAIL = 12, |
| RENAME_FAIL = 13, |
| PARTITION_START = 14, |
| PARTITION_SUCCESS = 15, |
| PARTITION_FAIL = 16, |
| kMaxValue = PARTITION_FAIL, |
| }; |
| |
| // Enum of possible UMA values for histogram Notification.UserAction. |
| // Keep the order of this in sync with FileManagerNotificationUserAction in |
| // tools/metrics/histograms/enums.xml. |
| enum class DeviceNotificationUserActionUmaType { |
| OPEN_SETTINGS_FOR_ARC_STORAGE = 0, // OPEN_EXTERNAL_STORAGE_PREFERENCES. |
| OPEN_MEDIA_DEVICE_NAVIGATION = 1, |
| OPEN_MEDIA_DEVICE_NAVIGATION_ARC = 2, |
| OPEN_MEDIA_DEVICE_FAIL = 3, |
| OPEN_MEDIA_DEVICE_IMPORT = 4, |
| kMaxValue = OPEN_MEDIA_DEVICE_IMPORT, |
| }; |
| |
| // Histogram name for Notification.Show. |
| inline constexpr char kNotificationShowHistogramName[] = |
| "FileBrowser.Notification.Show"; |
| |
| // Histogram name for Notification.UserAction. |
| inline constexpr char kNotificationUserActionHistogramName[] = |
| "FileBrowser.Notification.UserAction"; |
| |
| // Generates a notification id based on `task_id`. |
| std::string GetNotificationId(io_task::IOTaskId task_id); |
| |
| // Returns an instance of an 'ash' Notification with a bound click delegate. |
| // The notification will have Files app system notification theme. |
| std::unique_ptr<message_center::Notification> CreateSystemNotification( |
| const std::string& notification_id, |
| const std::u16string& title, |
| const std::u16string& message, |
| scoped_refptr<message_center::NotificationDelegate> delegate, |
| message_center::RichNotificationData optional_fields = |
| message_center::RichNotificationData()); |
| |
| // Returns an instance of an 'ash' Notification with title and message specified |
| // by string ID values (for 110n) with a bound click delegate. |
| // The notification will have Files app system notification theme. |
| std::unique_ptr<message_center::Notification> CreateSystemNotification( |
| const std::string& notification_id, |
| int title_id, |
| int message_id, |
| scoped_refptr<message_center::NotificationDelegate> delegate); |
| |
| // Returns an instance of an 'ash' Notification with a bound click callback. |
| // The notification will have Files app system notification theme. |
| std::unique_ptr<message_center::Notification> CreateSystemNotification( |
| const std::string& notification_id, |
| const std::u16string& title, |
| const std::u16string& message, |
| const base::RepeatingClosure& click_callback); |
| |
| // Manages creation/deletion and update of system notifications on behalf |
| // of the File Manager application. |
| class SystemNotificationManager { |
| public: |
| explicit SystemNotificationManager(Profile* profile); |
| ~SystemNotificationManager(); |
| |
| // Returns whether or not ANY SWA windows are opened. Does this by checking |
| // the URL of all opened windows. |
| bool DoFilesSwaWindowsExist(); |
| |
| // Processes a device event to generate a system notification if needed. |
| void HandleDeviceEvent(const file_manager_private::DeviceEvent& event); |
| |
| using NotificationPtr = std::unique_ptr<message_center::Notification>; |
| |
| // Returns an instance of an 'ash' Notification. |
| NotificationPtr CreateNotification(const std::string& notification_id, |
| const std::u16string& title, |
| const std::u16string& message); |
| |
| // Returns an instance of an 'ash' Notification with progress value. |
| NotificationPtr CreateProgressNotification(const std::string& notification_id, |
| const std::u16string& title, |
| const std::u16string& message, |
| int progress); |
| |
| // Returns an instance of an 'ash' Notification with IOTask progress value. |
| NotificationPtr CreateIOTaskProgressNotification( |
| file_manager::io_task::IOTaskId task_id, |
| const std::string& notification_id, |
| const std::u16string& title, |
| const std::u16string& message, |
| const bool paused, |
| int progress); |
| |
| // Click handler for the IOTask progress notification. |
| void HandleIOTaskProgressNotificationClick( |
| file_manager::io_task::IOTaskId task_id, |
| const std::string& notification_id, |
| const bool paused, |
| std::optional<int> button_index); |
| |
| // Returns an instance of an 'ash' Notification with title and message |
| // specified by string ID values (for 110n). |
| NotificationPtr CreateNotification(const std::string& notification_id, |
| int title_id, |
| int message_id); |
| |
| using Event = extensions::Event; |
| |
| // Processes general extension events and can create a system notification. |
| void HandleEvent(const Event& event); |
| |
| // Processes progress event from IOTaskController. |
| void HandleIOTaskProgress( |
| const file_manager::io_task::ProgressStatus& status); |
| |
| // Stores and updates the state of a device based on mount events for the top |
| // level or any child partitions. |
| SystemNotificationManagerMountStatus UpdateDeviceMountStatus( |
| file_manager_private::MountCompletedEvent& event, |
| const Volume& volume); |
| |
| // Processes volume mount completed events. |
| void HandleMountCompletedEvent( |
| file_manager_private::MountCompletedEvent& event, |
| const Volume& volume); |
| |
| // Returns the message center display service that manages notifications. |
| NotificationDisplayService* GetNotificationDisplayService(); |
| |
| // Stores a reference to the DriveFS event router instance. |
| void SetDriveFSEventRouter(DriveFsEventRouter* drivefs_event_router); |
| |
| // Stores a pointer to the IOTaskController instance to be able to cancel |
| // tasks. |
| void SetIOTaskController( |
| file_manager::io_task::IOTaskController* io_task_controller); |
| |
| private: |
| // Handles clicks on the DriveFS bulk-pinning error notification. |
| void HandleBulkPinningNotificationClick(); |
| |
| // Make notification for DriveFS bulk-pinning error. |
| NotificationPtr MakeBulkPinningErrorNotification(const Event& event); |
| |
| // Make notifications for DriveFS sync errors. |
| NotificationPtr MakeDriveSyncErrorNotification(const Event& event); |
| |
| // Click handler for the Drive offline confirmation dialog notification. |
| void HandleDriveDialogClick(std::optional<int> button_index); |
| |
| // Make notification from the DriveFS offline settings event. |
| NotificationPtr MakeDriveConfirmDialogNotification(const Event& event); |
| |
| // Click handler for the removable device notification. |
| void HandleRemovableNotificationClick( |
| const std::string& path, |
| const std::vector<DeviceNotificationUserActionUmaType>& |
| uma_types_for_buttons, |
| std::optional<int> button_index); |
| |
| // Click handler for Data Leak Prevention or Enterprise Connectors policy |
| // notifications. |
| void HandleDataProtectionPolicyNotificationClick( |
| base::RepeatingClosure proceed_callback, |
| base::RepeatingClosure cancel_callback, |
| std::optional<int> button_index); |
| |
| // Click handler for the progress notification. |
| void HandleProgressClick(const std::string& notification_id, |
| std::optional<int> button_index); |
| |
| // Makes a notification instance for mount errors. |
| NotificationPtr MakeMountErrorNotification( |
| file_manager_private::MountCompletedEvent& event, |
| const Volume& volume); |
| |
| // Makes a notification instance for removable devices. |
| NotificationPtr MakeRemovableNotification( |
| file_manager_private::MountCompletedEvent& event, |
| const Volume& volume); |
| |
| // Makes a notification instance for Data Protection progress notifications. |
| NotificationPtr MakeDataProtectionPolicyProgressNotification( |
| const std::string& notification_id, |
| const file_manager::io_task::ProgressStatus& status); |
| |
| // Helper function to show a data protection policy dialog. |
| void ShowDataProtectionPolicyDialog(file_manager::io_task::IOTaskId task_id, |
| policy::FilesDialogType type); |
| |
| // Helper function bound to notification instances that hides notifications. |
| void Dismiss(const std::string& notification_id); |
| |
| // Helper function to cancel a task. |
| void CancelTask(file_manager::io_task::IOTaskId task_id); |
| |
| // Helper function to resume a task. |
| void ResumeTask(file_manager::io_task::IOTaskId task_id, |
| policy::Policy policy); |
| |
| // Maps device paths to their mount status. |
| // This is used for removable devices with single/multiple partitions. |
| // e.g. the same device path could have 2 partitions that each generate a |
| // mount event. One partition could have a known file system and the other an |
| // unknown file system. Different combinations of known/unknown file |
| // systems on a multi-partition devices require this map to generate |
| // the correct system notification when errors occur. |
| std::map<std::string, SystemNotificationManagerMountStatus> mount_status_; |
| |
| // User profile. |
| const raw_ptr<Profile, DanglingUntriaged> profile_; |
| |
| // Application name (used for notification display source). |
| std::u16string const app_name_; |
| |
| // DriveFS event router: not owned. |
| raw_ptr<DriveFsEventRouter, DanglingUntriaged> drivefs_event_router_ = |
| nullptr; |
| |
| // IOTaskController is owned by VolumeManager. |
| raw_ptr<file_manager::io_task::IOTaskController, DanglingUntriaged> |
| io_task_controller_ = nullptr; |
| |
| // Keep track of the bulk-pinning stage. |
| using BulkPinStage = file_manager_private::BulkPinStage; |
| BulkPinStage bulk_pin_stage_ = BulkPinStage::kNone; |
| |
| // base::WeakPtr{this} factory. |
| base::WeakPtrFactory<SystemNotificationManager> weak_ptr_factory_{this}; |
| }; |
| |
| } // namespace file_manager |
| |
| #endif // CHROME_BROWSER_ASH_EXTENSIONS_FILE_MANAGER_SYSTEM_NOTIFICATION_MANAGER_H_ |