File: platform_notification_service_impl.h

package info (click to toggle)
chromium 138.0.7204.157-1
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 6,071,864 kB
  • sloc: cpp: 34,936,859; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,953; asm: 946,768; xml: 739,967; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,806; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (222 lines) | stat: -rw-r--r-- 9,550 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
// Copyright 2014 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_PLATFORM_NOTIFICATION_SERVICE_IMPL_H_
#define CHROME_BROWSER_NOTIFICATIONS_PLATFORM_NOTIFICATION_SERVICE_IMPL_H_

#include <stdint.h>

#include <memory>
#include <optional>
#include <string>
#include <unordered_set>

#include "base/gtest_prod_util.h"
#include "base/memory/raw_ptr.h"
#include "base/task/cancelable_task_tracker.h"
#include "chrome/browser/notifications/notification_common.h"
#include "chrome/browser/notifications/notification_trigger_scheduler.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/buildflags.h"
#include "components/content_settings/core/browser/content_settings_observer.h"
#include "components/keyed_service/core/keyed_service.h"
#include "components/webapps/common/web_app_id.h"
#include "content/public/browser/platform_notification_service.h"
#include "services/metrics/public/cpp/ukm_source_id.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/message_center/public/cpp/notification.h"

class GURL;
class Profile;

namespace blink {
struct NotificationResources;
}  // namespace blink

// The platform notification service is the profile-specific entry point through
// which Web Notifications can be controlled.
class PlatformNotificationServiceImpl
    : public content::PlatformNotificationService,
      public content_settings::Observer,
      public KeyedService {
 public:
  explicit PlatformNotificationServiceImpl(Profile* profile);
  PlatformNotificationServiceImpl(const PlatformNotificationServiceImpl&) =
      delete;
  PlatformNotificationServiceImpl& operator=(
      const PlatformNotificationServiceImpl&) = delete;
  ~PlatformNotificationServiceImpl() override;

  // Register profile-specific prefs.
  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);

  // Returns whether the notification identified by |notification_id| was
  // closed programmatically through ClosePersistentNotification().
  bool WasClosedProgrammatically(const std::string& notification_id);

  // content::PlatformNotificationService implementation.
  void DisplayNotification(
      const std::string& notification_id,
      const GURL& origin,
      const GURL& document_url,
      const blink::PlatformNotificationData& notification_data,
      const blink::NotificationResources& notification_resources) override;
  void DisplayPersistentNotification(
      const std::string& notification_id,
      const GURL& service_worker_scope,
      const GURL& origin,
      const blink::PlatformNotificationData& notification_data,
      const blink::NotificationResources& notification_resources) override;
  void CloseNotification(const std::string& notification_id) override;
  void ClosePersistentNotification(const std::string& notification_id) override;
  void GetDisplayedNotifications(
      DisplayedNotificationsCallback callback) override;
  void GetDisplayedNotificationsForOrigin(
      const GURL& origin,
      DisplayedNotificationsCallback callback) override;
  void ScheduleTrigger(base::Time timestamp) override;
  base::Time ReadNextTriggerTimestamp() override;
  int64_t ReadNextPersistentNotificationId() override;
  void RecordNotificationUkmEvent(
      const content::NotificationDatabaseData& data) override;

  void set_ukm_recorded_closure_for_testing(base::OnceClosure closure) {
    ukm_recorded_closure_for_testing_ = std::move(closure);
  }

  NotificationTriggerScheduler* GetNotificationTriggerScheduler();

 private:
  friend class NotificationTriggerSchedulerTest;
  friend class PersistentNotificationHandlerTest;
  friend class PlatformNotificationServiceBrowserTest;
  friend class PlatformNotificationServiceTest;
  friend class PushMessagingBrowserTest;
  FRIEND_TEST_ALL_PREFIXES(PlatformNotificationServiceTest,
                           CreateNotificationFromData);
  FRIEND_TEST_ALL_PREFIXES(PlatformNotificationServiceTest_WebApps,
                           CreateNotificationFromData);
  FRIEND_TEST_ALL_PREFIXES(PlatformNotificationServiceTest,
                           DisplayNameForContextMessage);
  FRIEND_TEST_ALL_PREFIXES(PlatformNotificationServiceTest,
                           RecordNotificationUkmEvent);
  FRIEND_TEST_ALL_PREFIXES(PlatformNotificationServiceTest_WebApps,
                           IncomingCallWebApp);
  FRIEND_TEST_ALL_PREFIXES(
      PlatformNotificationServiceTest_WebAppNotificationIconAndTitle,
      FindWebAppIconAndTitle_NoApp);
  FRIEND_TEST_ALL_PREFIXES(
      PlatformNotificationServiceTest_WebAppNotificationIconAndTitle,
      FindWebAppIconAndTitle);
  FRIEND_TEST_ALL_PREFIXES(
      PlatformNotificationServiceTest_ReportNotificationContentDetectionData,
      UpdateNotificationDatabaseMetadata);

  struct WebAppIconAndTitle {
    gfx::ImageSkia icon;
    std::u16string title;
  };

  // KeyedService implementation.
  void Shutdown() override;

  // content_settings::Observer implementation.
  void OnContentSettingChanged(
      const ContentSettingsPattern& primary_pattern,
      const ContentSettingsPattern& secondary_pattern,
      ContentSettingsTypeSet content_type_set) override;

  static void RecordNotificationUkmEventWithSourceId(
      base::OnceClosure recorded_closure,
      const content::NotificationDatabaseData& data,
      ukm::SourceId source_id);

  // Creates a new Web Notification-based Notification object. Should only be
  // called when the notification is first shown. |web_app_hint_url| is used to
  // find a corresponding web app, it can be a service worker scope or document
  // url.
  message_center::Notification CreateNotificationFromData(
      const GURL& origin,
      const std::string& notification_id,
      const blink::PlatformNotificationData& notification_data,
      const blink::NotificationResources& notification_resources,
      const GURL& web_app_hint_url) const;

  // Returns a display name for an origin, to be used in the context message
  std::u16string DisplayNameForContextMessage(const GURL& origin) const;

  // Finds the AppId associated with |web_app_hint_url| when this is part of
  // an installed experience, and the notification can be attributed as such.
  std::optional<webapps::AppId> FindWebAppId(
      const GURL& web_app_hint_url) const;

  // Finds the icon and title associated with |web_app_id| when this
  // is part of an installed experience, and the notification can be attributed
  // as such.
  std::optional<WebAppIconAndTitle> FindWebAppIconAndTitle(
      const GURL& web_app_hint_url) const;

  // Identifies whether the notification was sent from an installed web app or
  // not.
  bool IsActivelyInstalledWebAppScope(const GURL& web_app_url) const;

  // Clears |closed_notifications_|. Should only be used for testing purposes.
  void ClearClosedNotificationsForTesting() { closed_notifications_.clear(); }

  // Update the notification entry in the `NotificationDatabase` with
  // `serialized_content_detection_metadata` for possible MQLS logging later.
  // Update `persistent_metadata`, given the value of `should_show_warning`, to
  // tell the front end whether to display the notification or the warning.
  void UpdatePersistentMetadataThenDisplay(
      const message_center::Notification& notification,
      std::unique_ptr<PersistentNotificationMetadata> persistent_metadata,
      bool should_show_warning,
      std::optional<std::string> serialized_content_detection_metadata);

  // Logs metrics when displaying a persistent notification.
  void LogPersistentNotificationShownMetrics(
      const blink::PlatformNotificationData& notification_data,
      const GURL& origin,
      const GURL& notification_origin);

  // Returns true if the user tapped "Always allow" on a notification warning
  // for `origin`.
  bool AreSuspiciousNotificationsAllowlistedByUser(const GURL& origin);

  // `WriteResourcesResultCallback` callback that updates the
  // `persistent_metadata` and displays the notification with a call to
  // `DoUpdatePersistentMetadataThenDisplay`, after updating the notification
  // database with serialized metadata. Note the `success` value is currently
  // unused.
  void DidUpdatePersistentMetadata(
      std::unique_ptr<PersistentNotificationMetadata> persistent_metadata,
      message_center::Notification notification,
      bool should_show_warning,
      bool success);

  // Helper method for updating `persistent_metadata`, given the value of
  // `should_show_warning` then displaying the notification.
  void DoUpdatePersistentMetadataThenDisplay(
      std::unique_ptr<PersistentNotificationMetadata> persistent_metadata,
      message_center::Notification notification,
      bool should_show_warning);

  // The profile for this instance or NULL if the initial profile has been
  // shutdown already.
  raw_ptr<Profile> profile_;

  // Tracks the id of persistent notifications that have been closed
  // programmatically to avoid dispatching close events for them.
  std::unordered_set<std::string> closed_notifications_;

  // Scheduler for notifications with a trigger.
  std::unique_ptr<NotificationTriggerScheduler> trigger_scheduler_;

  // Testing-only closure to observe when a UKM event has been recorded.
  base::OnceClosure ukm_recorded_closure_for_testing_;

  base::WeakPtrFactory<PlatformNotificationServiceImpl> weak_ptr_factory_{this};
};

#endif  // CHROME_BROWSER_NOTIFICATIONS_PLATFORM_NOTIFICATION_SERVICE_IMPL_H_