blob: e87b6cc85c11205c53762ab1bac163e455ab69aa [file] [log] [blame]
Avi Drissman4a8573c2022-09-09 19:35:541// Copyright 2015 The Chromium Authors
peter679ad3482015-05-07 12:06:472// 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_PUSH_MESSAGING_PUSH_MESSAGING_NOTIFICATION_MANAGER_H_
6#define CHROME_BROWSER_PUSH_MESSAGING_PUSH_MESSAGING_NOTIFICATION_MANAGER_H_
7
8#include <stdint.h>
9#include <vector>
10
Avi Drissman9269d4ed2023-01-07 01:38:0611#include "base/functional/callback_forward.h"
mvanouwerkerk0035b7a2015-11-23 15:07:3812#include "base/gtest_prod_util.h"
Keishi Hattori0e45c022021-11-27 09:25:5213#include "base/memory/raw_ptr.h"
peter679ad3482015-05-07 12:06:4714#include "base/memory/weak_ptr.h"
Yuta Hijikata235fc62b2020-12-08 03:48:3215#include "build/chromeos_buildflags.h"
Peter Beverlooafb1ab42018-08-20 13:03:4516#include "chrome/browser/push_messaging/budget_database.h"
Justin Lulejianf6a88002023-10-31 22:09:1017#include "extensions/buildflags/buildflags.h"
peter679ad3482015-05-07 12:06:4718
19class GURL;
20class Profile;
21
Nicola Tommasiad487082024-02-15 16:33:4422// These values are persisted to logs. Entries should not be renumbered and
23// numeric values should never be reused.
24enum class SilentPushEvent {
25 kSilentRequest = 0,
26 kNotificationEnforcementSkipped = 1,
27 kAllowedWithoutNotification = 2,
28 kAllowedWithGenericNotification = 3,
29 kMaxValue = kAllowedWithGenericNotification,
30};
31
peter679ad3482015-05-07 12:06:4732namespace content {
mvanouwerkerk0035b7a2015-11-23 15:07:3833class WebContents;
Richard Knollca55419a2019-03-22 15:41:2734} // namespace content
Han Leon96d6b6e8c22018-09-06 06:21:0635
peter679ad3482015-05-07 12:06:4736// Developers may be required to display a Web Notification in response to an
37// incoming push message in order to clarify to the user that something has
38// happened in the background. When they forget to do so, a default notification
39// has to be displayed on their behalf.
40//
41// This class implements the heuristics for determining whether the default
42// notification is necessary, as well as the functionality of displaying the
43// default notification when it is.
44//
45// See the following document and bug for more context:
46// https://docs.google.com/document/d/13VxFdLJbMwxHrvnpDm8RXnU41W2ZlcP0mdWWe9zXQT8/edit
47// https://crbug.com/437277
48class PushMessagingNotificationManager {
49 public:
Rayan Kansob2c21aa2019-05-08 21:49:4950 using EnforceRequirementsCallback =
51 base::OnceCallback<void(bool did_show_generic_notification)>;
52
peter679ad3482015-05-07 12:06:4753 explicit PushMessagingNotificationManager(Profile* profile);
Peter Boström53c6c5952021-09-17 09:41:2654
55 PushMessagingNotificationManager(const PushMessagingNotificationManager&) =
56 delete;
57 PushMessagingNotificationManager& operator=(
58 const PushMessagingNotificationManager&) = delete;
59
peter679ad3482015-05-07 12:06:4760 ~PushMessagingNotificationManager();
61
62 // Enforces the requirements implied for push subscriptions which must display
63 // a Web Notification in response to an incoming message.
Justin Lulejianf6a88002023-10-31 22:09:1064 // `requested_user_visible_only` is the userVisibleOnly value a worker based
65 // extension sets on push subscription.
peter679ad3482015-05-07 12:06:4766 void EnforceUserVisibleOnlyRequirements(
mvanouwerkerk90698562015-11-19 20:20:2567 const GURL& origin,
peter679ad3482015-05-07 12:06:4768 int64_t service_worker_registration_id,
Justin Lulejianf6a88002023-10-31 22:09:1069 EnforceRequirementsCallback message_handled_callback,
70 bool requested_user_visible_only);
71
Justin Lulejianed68ac782024-11-04 12:13:5972 // Checks if the userVisibleOnly: true requirement or the notifications
73 // permission requirement can be bypassed in certain scenarios.
74 //
75 // Currently that is only allowed for extensions with workers that set
76 // userVisibleOnly: false on subscription.
77 bool ShouldBypassUserVisibleOnlyRequirement(const GURL& origin,
78 bool requested_user_visible_only);
79 bool ShouldBypassNotificationPermissionRequirement(
80 const GURL& origin,
81 bool requested_user_visible_only) {
82 return ShouldBypassUserVisibleOnlyRequirement(origin,
83 requested_user_visible_only);
84 }
peter679ad3482015-05-07 12:06:4785
86 private:
mvanouwerkerk0035b7a2015-11-23 15:07:3887 FRIEND_TEST_ALL_PREFIXES(PushMessagingNotificationManagerTest, IsTabVisible);
peter2d356322016-02-03 13:09:2388 FRIEND_TEST_ALL_PREFIXES(PushMessagingNotificationManagerTest,
89 IsTabVisibleViewSource);
mvanouwerkerk0035b7a2015-11-23 15:07:3890
Richard Knoll25d3a8d2020-07-26 03:26:4391 void DidCountVisibleNotifications(
mvanouwerkerk90698562015-11-19 20:20:2592 const GURL& origin,
peter679ad3482015-05-07 12:06:4793 int64_t service_worker_registration_id,
Rayan Kansob2c21aa2019-05-08 21:49:4994 EnforceRequirementsCallback message_handled_callback,
peter679ad3482015-05-07 12:06:4795 bool success,
Richard Knoll25d3a8d2020-07-26 03:26:4396 int notification_count);
peter679ad3482015-05-07 12:06:4797
mvanouwerkerk0035b7a2015-11-23 15:07:3898 // Checks whether |profile| is the one owning this instance,
99 // |active_web_contents| exists and its main frame is visible, and the URL
100 // currently visible to the user is for |origin|.
101 bool IsTabVisible(Profile* profile,
102 content::WebContents* active_web_contents,
103 const GURL& origin);
104
harkness6f6b41432016-09-08 09:17:28105 void ProcessSilentPush(const GURL& origin,
106 int64_t service_worker_registration_id,
Rayan Kansob2c21aa2019-05-08 21:49:49107 EnforceRequirementsCallback message_handled_callback,
harkness6f6b41432016-09-08 09:17:28108 bool silent_push_allowed);
peter679ad3482015-05-07 12:06:47109
Rayan Kansob2c21aa2019-05-08 21:49:49110 void DidWriteNotificationData(
111 EnforceRequirementsCallback message_handled_callback,
112 bool success,
113 const std::string& notification_id);
peter679ad3482015-05-07 12:06:47114
Nicola Tommasiad487082024-02-15 16:33:44115 void LogSilentPushEvent(SilentPushEvent event);
116
Justin Lulejianf6a88002023-10-31 22:09:10117#if BUILDFLAG(ENABLE_EXTENSIONS)
118 // For extensions builds, skip userVisibleOnly requirement for worker-based
119 // extensions that set it to false.
Justin Lulejianed68ac782024-11-04 12:13:59120 bool ShouldExtensionsBypassUserVisibleOnlyRequirement(
Justin Lulejianf6a88002023-10-31 22:09:10121 const GURL& origin,
122 bool requested_user_visible_only);
123#endif // BUILDFLAG(ENABLE_EXTENSIONS)
124
peter679ad3482015-05-07 12:06:47125 // Weak. This manager is owned by a keyed service on this profile.
Keishi Hattori0e45c022021-11-27 09:25:52126 raw_ptr<Profile> profile_;
peter679ad3482015-05-07 12:06:47127
Peter Beverlooafb1ab42018-08-20 13:03:45128 BudgetDatabase budget_database_;
129
Jeremy Roman495db682019-07-12 16:03:24130 base::WeakPtrFactory<PushMessagingNotificationManager> weak_factory_{this};
peter679ad3482015-05-07 12:06:47131};
132
133#endif // CHROME_BROWSER_PUSH_MESSAGING_PUSH_MESSAGING_NOTIFICATION_MANAGER_H_