1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef CHROME_BROWSER_NOTIFICATIONS_PLATFORM_NOTIFICATION_SERVICE_IMPL_H_
6 #define CHROME_BROWSER_NOTIFICATIONS_PLATFORM_NOTIFICATION_SERVICE_IMPL_H_
7 
8 #include <stdint.h>
9 
10 #include <memory>
11 #include <string>
12 #include <unordered_set>
13 
14 #include "base/gtest_prod_util.h"
15 #include "base/strings/string16.h"
16 #include "base/task/cancelable_task_tracker.h"
17 #include "chrome/browser/notifications/notification_common.h"
18 #include "chrome/browser/notifications/notification_trigger_scheduler.h"
19 #include "chrome/browser/profiles/profile.h"
20 #include "chrome/common/buildflags.h"
21 #include "components/content_settings/core/browser/content_settings_observer.h"
22 #include "components/keyed_service/core/keyed_service.h"
23 #include "content/public/browser/platform_notification_service.h"
24 #include "services/metrics/public/cpp/ukm_source_id.h"
25 #include "ui/message_center/public/cpp/notification.h"
26 
27 class GURL;
28 class Profile;
29 
30 namespace content {
31 struct NotificationResources;
32 }  // namespace content
33 
34 // The platform notification service is the profile-specific entry point through
35 // which Web Notifications can be controlled.
36 class PlatformNotificationServiceImpl
37     : public content::PlatformNotificationService,
38       public content_settings::Observer,
39       public KeyedService {
40  public:
41   explicit PlatformNotificationServiceImpl(Profile* profile);
42   PlatformNotificationServiceImpl(const PlatformNotificationServiceImpl&) =
43       delete;
44   PlatformNotificationServiceImpl& operator=(
45       const PlatformNotificationServiceImpl&) = delete;
46   ~PlatformNotificationServiceImpl() override;
47 
48   // Register profile-specific prefs.
49   static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
50 
51   // Returns whether the notification identified by |notification_id| was
52   // closed programmatically through ClosePersistentNotification().
53   bool WasClosedProgrammatically(const std::string& notification_id);
54 
55   // content::PlatformNotificationService implementation.
56   void DisplayNotification(
57       const std::string& notification_id,
58       const GURL& origin,
59       const blink::PlatformNotificationData& notification_data,
60       const blink::NotificationResources& notification_resources) override;
61   void DisplayPersistentNotification(
62       const std::string& notification_id,
63       const GURL& service_worker_scope,
64       const GURL& origin,
65       const blink::PlatformNotificationData& notification_data,
66       const blink::NotificationResources& notification_resources) override;
67   void CloseNotification(const std::string& notification_id) override;
68   void ClosePersistentNotification(const std::string& notification_id) override;
69   void GetDisplayedNotifications(
70       DisplayedNotificationsCallback callback) override;
71   void ScheduleTrigger(base::Time timestamp) override;
72   base::Time ReadNextTriggerTimestamp() override;
73   int64_t ReadNextPersistentNotificationId() override;
74   void RecordNotificationUkmEvent(
75       const content::NotificationDatabaseData& data) override;
76 
set_ukm_recorded_closure_for_testing(base::OnceClosure closure)77   void set_ukm_recorded_closure_for_testing(base::OnceClosure closure) {
78     ukm_recorded_closure_for_testing_ = std::move(closure);
79   }
80 
81   NotificationTriggerScheduler* GetNotificationTriggerScheduler();
82 
83  private:
84   friend class NotificationTriggerSchedulerTest;
85   friend class PersistentNotificationHandlerTest;
86   friend class PlatformNotificationServiceBrowserTest;
87   friend class PlatformNotificationServiceTest;
88   friend class PushMessagingBrowserTest;
89   FRIEND_TEST_ALL_PREFIXES(PlatformNotificationServiceTest,
90                            CreateNotificationFromData);
91   FRIEND_TEST_ALL_PREFIXES(PlatformNotificationServiceTest,
92                            DisplayNameForContextMessage);
93   FRIEND_TEST_ALL_PREFIXES(PlatformNotificationServiceTest,
94                            RecordNotificationUkmEvent);
95 
96   // KeyedService implementation.
97   void Shutdown() override;
98 
99   // content_settings::Observer implementation.
100   void OnContentSettingChanged(const ContentSettingsPattern& primary_pattern,
101                                const ContentSettingsPattern& secondary_pattern,
102                                ContentSettingsType content_type) override;
103 
104   static void DidGetBackgroundSourceId(
105       base::OnceClosure recorded_closure,
106       const content::NotificationDatabaseData& data,
107       base::Optional<ukm::SourceId> source_id);
108 
109   // Creates a new Web Notification-based Notification object. Should only be
110   // called when the notification is first shown.
111   message_center::Notification CreateNotificationFromData(
112       const GURL& origin,
113       const std::string& notification_id,
114       const blink::PlatformNotificationData& notification_data,
115       const blink::NotificationResources& notification_resources) const;
116 
117   // Returns a display name for an origin, to be used in the context message
118   base::string16 DisplayNameForContextMessage(const GURL& origin) const;
119 
120   // Clears |closed_notifications_|. Should only be used for testing purposes.
ClearClosedNotificationsForTesting()121   void ClearClosedNotificationsForTesting() { closed_notifications_.clear(); }
122 
123   // The profile for this instance or NULL if the initial profile has been
124   // shutdown already.
125   Profile* profile_;
126 
127   // Tracks the id of persistent notifications that have been closed
128   // programmatically to avoid dispatching close events for them.
129   std::unordered_set<std::string> closed_notifications_;
130 
131   // Scheduler for notifications with a trigger.
132   std::unique_ptr<NotificationTriggerScheduler> trigger_scheduler_;
133 
134   // Testing-only closure to observe when a UKM event has been recorded.
135   base::OnceClosure ukm_recorded_closure_for_testing_;
136 };
137 
138 #endif  // CHROME_BROWSER_NOTIFICATIONS_PLATFORM_NOTIFICATION_SERVICE_IMPL_H_
139