| // Copyright 2020 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_NOTIFICATIONS_NOTIFICATION_DISPLAY_QUEUE_H_ |
| #define CHROME_BROWSER_NOTIFICATIONS_NOTIFICATION_DISPLAY_QUEUE_H_ |
| |
| #include <memory> |
| #include <set> |
| #include <string> |
| #include <vector> |
| |
| #include "base/functional/callback.h" |
| #include "base/memory/raw_ptr.h" |
| #include "base/scoped_multi_source_observation.h" |
| #include "chrome/browser/notifications/notification_blocker.h" |
| #include "chrome/browser/notifications/notification_common.h" |
| #include "chrome/browser/notifications/notification_handler.h" |
| #include "ui/message_center/public/cpp/notification.h" |
| |
| class NotificationDisplayService; |
| |
| // The NotificationDisplayQueue holds on to a list of NotificationBlockers that |
| // determine if we should block new notifications from being displayed. During |
| // that time this class will hold on to new incoming notifications and display |
| // them once all blockers stop being active. |
| class NotificationDisplayQueue : public NotificationBlocker::Observer { |
| public: |
| using NotificationBlockers = |
| std::vector<std::unique_ptr<NotificationBlocker>>; |
| |
| explicit NotificationDisplayQueue( |
| NotificationDisplayService* notification_display_service); |
| NotificationDisplayQueue(const NotificationDisplayQueue&) = delete; |
| NotificationDisplayQueue& operator=(const NotificationDisplayQueue&) = delete; |
| ~NotificationDisplayQueue() override; |
| |
| // NotificationBlocker::Observer: |
| void OnBlockingStateChanged() override; |
| |
| // Returns if we should currently queue up |notification|. This is the case if |
| // at least one NotificationBlocker is active and |notification_type| is a Web |
| // Notification. |
| bool ShouldEnqueueNotification( |
| NotificationHandler::Type notification_type, |
| const message_center::Notification& notification) const; |
| |
| // Enqueue the passed |notification| to be shown once no blocker is active |
| // anymore. If there is already a notification with the same id queued, it |
| // will be removed before adding this new one. |
| void EnqueueNotification( |
| NotificationHandler::Type notification_type, |
| const message_center::Notification& notification, |
| std::unique_ptr<NotificationCommon::Metadata> metadata); |
| |
| // Removes a queued notification by its |notification_id|. This is a no-op if |
| // there was no notification queued with that id. |
| void RemoveQueuedNotification(const std::string& notification_id); |
| |
| // Returns a set of the currently queued notification ids. |
| std::set<std::string> GetQueuedNotificationIds() const; |
| |
| // Returns a set of the currently queued notification ids associated with |
| // `origin`. |
| std::set<std::string> GetQueuedNotificationIdsForOrigin( |
| const GURL& origin) const; |
| |
| // Sets the list of |blockers| to be used and observes their state. |
| void SetNotificationBlockers(NotificationBlockers blockers); |
| |
| // Adds |blocker| to the list of blockers to be used and observes its state. |
| void AddNotificationBlocker(std::unique_ptr<NotificationBlocker> blocker); |
| |
| private: |
| // Removes a queued notification by its |notification_id| and returns if there |
| // was a queued notification with that id. If |notify| is true this will |
| // notify all relevant blockers about the removal. |
| bool DoRemoveQueuedNotification(const std::string& notification_id, |
| bool notify); |
| |
| // Called when the state of a notification blocker changes. Will display and |
| // free all queued notifications if no blocker is active anymore. |
| void MaybeDisplayQueuedNotifications(); |
| |
| // Checks if any notification blocker is currently active for |notification|. |
| bool IsAnyNotificationBlockerActive( |
| const message_center::Notification& notification) const; |
| |
| // Represents a queued notification. |
| struct QueuedNotification { |
| QueuedNotification(NotificationHandler::Type notification_type, |
| const message_center::Notification& notification, |
| std::unique_ptr<NotificationCommon::Metadata> metadata); |
| QueuedNotification(QueuedNotification&&); |
| QueuedNotification& operator=(QueuedNotification&&); |
| ~QueuedNotification(); |
| |
| NotificationHandler::Type notification_type; |
| message_center::Notification notification; |
| std::unique_ptr<NotificationCommon::Metadata> metadata; |
| }; |
| |
| // The |notification_display_service_| owns |this|. |
| raw_ptr<NotificationDisplayService> notification_display_service_; |
| |
| // A list of notification blockers that indicate when notifications should be |
| // blocked and notify when their state changes. |
| NotificationBlockers blockers_; |
| |
| // A list of queued notifications in order of last update. Each notification |
| // has a unique id in this list as adding a duplication will remove the |
| // existing one before inserting at the end. |
| std::vector<QueuedNotification> queued_notifications_; |
| |
| // Observer for the list of |blockers_|. |
| base::ScopedMultiSourceObservation<NotificationBlocker, |
| NotificationBlocker::Observer> |
| notification_blocker_observations_{this}; |
| }; |
| |
| #endif // CHROME_BROWSER_NOTIFICATIONS_NOTIFICATION_DISPLAY_QUEUE_H_ |