File: persistent_notification_handler.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 (138 lines) | stat: -rw-r--r-- 5,958 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
// Copyright 2016 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_PERSISTENT_NOTIFICATION_HANDLER_H_
#define CHROME_BROWSER_NOTIFICATIONS_PERSISTENT_NOTIFICATION_HANDLER_H_

#include <map>
#include <memory>

#include "base/callback_list.h"
#include "base/containers/id_map.h"
#include "base/memory/weak_ptr.h"
#include "chrome/browser/notifications/notification_handler.h"
#include "chrome/common/buildflags.h"

#if BUILDFLAG(ENABLE_BACKGROUND_MODE)
#include "chrome/browser/profiles/keep_alive/profile_keep_alive_types.h"
#include "components/keep_alive_registry/keep_alive_types.h"
#endif  // BUILDFLAG(ENABLE_BACKGROUND_MODE)

class ScopedKeepAlive;
class ScopedProfileKeepAlive;

namespace content {
enum class PersistentNotificationStatus;
}  // namespace content

// NotificationHandler implementation for persistent Web Notifications, that is,
// notifications associated with a Service Worker. Lives on the UI thread.
class PersistentNotificationHandler : public NotificationHandler {
 public:
  PersistentNotificationHandler();
  PersistentNotificationHandler(const PersistentNotificationHandler&) = delete;
  PersistentNotificationHandler& operator=(
      const PersistentNotificationHandler&) = delete;
  ~PersistentNotificationHandler() override;

  // NotificationHandler implementation.
  void OnClose(Profile* profile,
               const GURL& origin,
               const std::string& notification_id,
               bool by_user,
               base::OnceClosure completed_closure) override;
  void OnClick(Profile* profile,
               const GURL& origin,
               const std::string& notification_id,
               const std::optional<int>& action_index,
               const std::optional<std::u16string>& reply,
               base::OnceClosure completed_closure) override;
  void DisableNotifications(Profile* profile, const GURL& origin) override;
  void OpenSettings(Profile* profile, const GURL& origin) override;
  void ReportNotificationAsSafe(const std::string& notification_id,
                                const GURL& url,
                                Profile* profile) override;
  void ReportWarnedNotificationAsSpam(const std::string& notification_id,
                                      const GURL& url,
                                      Profile* profile) override;
  void ReportUnwarnedNotificationAsSpam(const std::string& notification_id,
                                        const GURL& url,
                                        Profile* profile) override;

 private:
  void OnCloseCompleted(Profile* profile,
                        uint64_t close_completed_callback_id,
                        content::PersistentNotificationStatus status);
  void OnClickCompleted(Profile* profile,
                        const std::string& notification_id,
                        base::OnceClosure completed_closure,
                        content::PersistentNotificationStatus status);
  void OnMaybeReport(const std::string& notification_id,
                     const GURL& url,
                     Profile* profile,
                     bool did_show_warning,
                     bool did_user_unsubscribe);
  void OnAppTerminating();

#if BUILDFLAG(ENABLE_BACKGROUND_MODE)
  class NotificationKeepAliveState {
   public:
    NotificationKeepAliveState(
        KeepAliveOrigin keep_alive_origin,
        ProfileKeepAliveOrigin profile_keep_alive_origin);
    ~NotificationKeepAliveState();

    void AddKeepAlive(Profile* profile);
    void RemoveKeepAlive(Profile* profile);

    void RemoveAllKeepAlives();

   private:
    const KeepAliveOrigin keep_alive_origin_;
    const ProfileKeepAliveOrigin profile_keep_alive_origin_;

    // Makes sure we keep the browser alive while the event in being processed.
    // As we have no control on the click handling, the notification could be
    // closed before a browser is brought up, thus terminating Chrome if it was
    // the last KeepAlive (see crbug.com/612815). We also need to wait until
    // close events got handled as we need to access the profile when removing
    // notifications from the NotificationDatabase (see crbug.com/1221601).
    std::unique_ptr<ScopedKeepAlive> event_dispatch_keep_alive_;

    // Same as |event_dispatch_keep_alive_|, but prevent Profile* deletion
    // instead of BrowserProcess teardown.
    std::map<Profile*, std::unique_ptr<ScopedProfileKeepAlive>>
        event_dispatch_profile_keep_alives_;

    // Number of in-flight notification events.
    int pending_dispatch_events_ = 0;

    // Number of in-flight notification events per Profile, for
    // |event_dispatch_profile_keep_alives_|.
    std::map<Profile*, int> profile_pending_dispatch_events_;
  };

  NotificationKeepAliveState click_event_keep_alive_state_{
      KeepAliveOrigin::PENDING_NOTIFICATION_CLICK_EVENT,
      ProfileKeepAliveOrigin::kPendingNotificationClickEvent};
  NotificationKeepAliveState close_event_keep_alive_state_{
      KeepAliveOrigin::PENDING_NOTIFICATION_CLOSE_EVENT,
      ProfileKeepAliveOrigin::kPendingNotificationCloseEvent};
#endif

  // App termination must release all `PENDING_NOTIFICATION_CLOSE_EVENT` keep
  // alives to avoid delaying shutdown.  After app termination begins, a new
  // browser launch cannot create a new window until shutdown completes.
  base::CallbackListSubscription on_app_terminating_subscription_;

  // Store pending 'notificationclose' event callbacks.  App termination may
  // run these callbacks before the 'notificationclose' event completes.
  using CloseCompletedCallbackMap =
      base::IDMap<std::unique_ptr<base::OnceClosure>>;
  CloseCompletedCallbackMap close_completed_callbacks_;

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

#endif  // CHROME_BROWSER_NOTIFICATIONS_PERSISTENT_NOTIFICATION_HANDLER_H_