Apply BFCache logic to notifications dispatched to dedicated workers
In the previous CL from the chain (https://crrev.com/c/3861889), we implemented the logic to check if the current document is BFCache when dispatching the notification events. However, this only works for notification service that is created from the document directly since the weak document pointer will be null if the notification service is created from a worker. In this CL, the notification service creation functions are changed to also accept a enum flag indicating whether it's created from a document, shared worker, dedicated worker, or service worker. This flag will be stored in the notification service so we don't have to rely on the `document_url` to check if it's associated with a worker. Additionally, for dedicated workers, we store the weak document pointer of its ancestor frame so we can determined if the host document is in BFCache when dispatching the notification events. Bug: 1350944 Change-Id: I8475b1e243998e599ebb3208a48f1cfa9df30b95 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3876770 Reviewed-by: Takashi Toyoshima <toyoshim@chromium.org> Reviewed-by: Alexander Timin <altimin@chromium.org> Reviewed-by: Daniel Cheng <dcheng@chromium.org> Reviewed-by: Rakina Zata Amni <rakina@chromium.org> Commit-Queue: Mingyu Lei <leimy@chromium.org> Reviewed-by: Peter Beverloo <peter@chromium.org> Cr-Commit-Position: refs/heads/main@{#1064794}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
99f2486cec
commit
0ece2ab04a
content
browser
browser_interface_binders.cc
notifications
blink_notification_service_impl.ccblink_notification_service_impl.hblink_notification_service_impl_unittest.ccnotification_event_dispatcher_impl.ccnotification_event_dispatcher_impl.hnotification_event_dispatcher_impl_unittest.ccplatform_notification_context_impl.ccplatform_notification_context_impl.h
renderer_host
public
@ -6,6 +6,7 @@
|
||||
|
||||
#include "base/callback.h"
|
||||
#include "base/callback_helpers.h"
|
||||
#include "base/check_op.h"
|
||||
#include "base/command_line.h"
|
||||
#include "base/feature_list.h"
|
||||
#include "base/no_destructor.h"
|
||||
@ -67,6 +68,9 @@
|
||||
#include "content/common/input/input_injector.mojom.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/browser/device_service.h"
|
||||
#include "content/public/browser/notification_service.h"
|
||||
#include "content/public/browser/render_frame_host.h"
|
||||
#include "content/public/browser/render_process_host.h"
|
||||
#include "content/public/browser/service_worker_context.h"
|
||||
#include "content/public/browser/service_worker_version_base_info.h"
|
||||
#include "content/public/browser/shared_worker_instance.h"
|
||||
@ -339,6 +343,54 @@ void BindFileUtilitiesHost(
|
||||
std::move(receiver)));
|
||||
}
|
||||
|
||||
// Binds the `RenderFrameHost` pointer and the notification service creator type
|
||||
// to the notification service creator.
|
||||
template <typename WorkerHost>
|
||||
base::RepeatingCallback<
|
||||
void(const url::Origin&,
|
||||
mojo::PendingReceiver<blink::mojom::NotificationService>)>
|
||||
BindNotificationService(
|
||||
RenderFrameHost* rfh,
|
||||
RenderProcessHost::NotificationServiceCreatorType creator_type,
|
||||
WorkerHost* host) {
|
||||
DCHECK_NE(creator_type,
|
||||
RenderProcessHost::NotificationServiceCreatorType::kServiceWorker);
|
||||
return base::BindRepeating(
|
||||
[](WorkerHost* host, RenderFrameHost* rfh,
|
||||
RenderProcessHost::NotificationServiceCreatorType creator_type,
|
||||
const url::Origin& origin,
|
||||
mojo::PendingReceiver<blink::mojom::NotificationService> receiver) {
|
||||
auto* process_host =
|
||||
static_cast<RenderProcessHostImpl*>(host->GetProcessHost());
|
||||
CHECK(process_host);
|
||||
process_host->CreateNotificationService(rfh, creator_type, origin,
|
||||
std::move(receiver));
|
||||
},
|
||||
base::Unretained(host), rfh, creator_type);
|
||||
}
|
||||
|
||||
// Binds the `RenderFrameHost` pointer and the `kServiceWorker` creator type
|
||||
// to the notification service creator.
|
||||
base::RepeatingCallback<
|
||||
void(const ServiceWorkerVersionBaseInfo&,
|
||||
mojo::PendingReceiver<blink::mojom::NotificationService>)>
|
||||
BindNotificationService(ServiceWorkerHost* host) {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
||||
return base::BindRepeating(
|
||||
[](ServiceWorkerHost* host, const ServiceWorkerVersionBaseInfo& info,
|
||||
mojo::PendingReceiver<blink::mojom::NotificationService> receiver) {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
||||
auto origin = info.storage_key.origin();
|
||||
auto* process_host = static_cast<RenderProcessHostImpl*>(
|
||||
RenderProcessHost::FromID(host->worker_process_id()));
|
||||
process_host->CreateNotificationService(
|
||||
/*rfh=*/nullptr,
|
||||
RenderProcessHost::NotificationServiceCreatorType::kServiceWorker,
|
||||
origin, std::move(receiver));
|
||||
},
|
||||
base::Unretained(host));
|
||||
}
|
||||
|
||||
template <typename WorkerHost, typename Interface>
|
||||
base::RepeatingCallback<void(mojo::PendingReceiver<Interface>)>
|
||||
BindWorkerReceiver(
|
||||
@ -377,28 +429,6 @@ BindWorkerReceiverForOrigin(
|
||||
base::Unretained(host), method);
|
||||
}
|
||||
|
||||
template <typename WorkerHost, typename Interface>
|
||||
base::RepeatingCallback<void(const url::Origin&,
|
||||
mojo::PendingReceiver<Interface>)>
|
||||
BindWorkerReceiverForOriginAndFrameId(
|
||||
void (RenderProcessHostImpl::*method)(int,
|
||||
const url::Origin&,
|
||||
mojo::PendingReceiver<Interface>),
|
||||
WorkerHost* host) {
|
||||
return base::BindRepeating(
|
||||
[](WorkerHost* host,
|
||||
void (RenderProcessHostImpl::*method)(
|
||||
int, const url::Origin&, mojo::PendingReceiver<Interface>),
|
||||
const url::Origin& origin, mojo::PendingReceiver<Interface> receiver) {
|
||||
auto* process_host =
|
||||
static_cast<RenderProcessHostImpl*>(host->GetProcessHost());
|
||||
if (process_host)
|
||||
(process_host->*method)(MSG_ROUTING_NONE, origin,
|
||||
std::move(receiver));
|
||||
},
|
||||
base::Unretained(host), method);
|
||||
}
|
||||
|
||||
template <typename WorkerHost, typename Interface>
|
||||
base::RepeatingCallback<void(mojo::PendingReceiver<Interface>)>
|
||||
BindWorkerReceiverForStorageKey(
|
||||
@ -464,32 +494,6 @@ BindServiceWorkerReceiverForOrigin(
|
||||
base::Unretained(host), method);
|
||||
}
|
||||
|
||||
template <typename Interface>
|
||||
base::RepeatingCallback<void(const ServiceWorkerVersionBaseInfo&,
|
||||
mojo::PendingReceiver<Interface>)>
|
||||
BindServiceWorkerReceiverForOriginAndFrameId(
|
||||
void (RenderProcessHostImpl::*method)(int,
|
||||
const url::Origin&,
|
||||
mojo::PendingReceiver<Interface>),
|
||||
ServiceWorkerHost* host) {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
||||
return base::BindRepeating(
|
||||
[](ServiceWorkerHost* host,
|
||||
void (RenderProcessHostImpl::*method)(
|
||||
int, const url::Origin&, mojo::PendingReceiver<Interface>),
|
||||
const ServiceWorkerVersionBaseInfo& info,
|
||||
mojo::PendingReceiver<Interface> receiver) {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
||||
auto origin = info.storage_key.origin();
|
||||
auto* process_host = static_cast<RenderProcessHostImpl*>(
|
||||
RenderProcessHost::FromID(host->worker_process_id()));
|
||||
if (!process_host)
|
||||
return;
|
||||
(process_host->*method)(MSG_ROUTING_NONE, origin, std::move(receiver));
|
||||
},
|
||||
base::Unretained(host), method);
|
||||
}
|
||||
|
||||
template <typename Interface>
|
||||
base::RepeatingCallback<void(const ServiceWorkerVersionBaseInfo&,
|
||||
mojo::PendingReceiver<Interface>)>
|
||||
@ -1210,10 +1214,12 @@ void PopulateBinderMapWithContext(
|
||||
map->Add<blink::mojom::PermissionService>(BindWorkerReceiverForOrigin(
|
||||
&RenderProcessHostImpl::CreatePermissionService, host));
|
||||
|
||||
// RenderProcessHost binders taking a frame id and an origin
|
||||
map->Add<blink::mojom::NotificationService>(
|
||||
BindWorkerReceiverForOriginAndFrameId(
|
||||
&RenderProcessHostImpl::CreateNotificationService, host));
|
||||
RenderFrameHost* rfh =
|
||||
RenderFrameHost::FromID(host->GetAncestorRenderFrameHostId());
|
||||
CHECK(rfh);
|
||||
map->Add<blink::mojom::NotificationService>(BindNotificationService(
|
||||
rfh, RenderProcessHost::NotificationServiceCreatorType::kDedicatedWorker,
|
||||
host));
|
||||
}
|
||||
|
||||
void PopulateBinderMap(DedicatedWorkerHost* host, mojo::BinderMap* map) {
|
||||
@ -1306,10 +1312,9 @@ void PopulateBinderMapWithContext(
|
||||
map->Add<blink::mojom::PermissionService>(BindWorkerReceiverForOrigin(
|
||||
&RenderProcessHostImpl::CreatePermissionService, host));
|
||||
|
||||
// RenderProcessHost binders taking a frame id and an origin
|
||||
map->Add<blink::mojom::NotificationService>(
|
||||
BindWorkerReceiverForOriginAndFrameId(
|
||||
&RenderProcessHostImpl::CreateNotificationService, host));
|
||||
map->Add<blink::mojom::NotificationService>(BindNotificationService(
|
||||
/*rfh=*/nullptr,
|
||||
RenderProcessHost::NotificationServiceCreatorType::kSharedWorker, host));
|
||||
}
|
||||
|
||||
void PopulateBinderMap(SharedWorkerHost* host, mojo::BinderMap* map) {
|
||||
@ -1432,10 +1437,7 @@ void PopulateBinderMapWithContext(
|
||||
BindServiceWorkerReceiverForStorageKey(
|
||||
&RenderProcessHostImpl::BindQuotaManagerHost, host));
|
||||
|
||||
// RenderProcessHost binders taking a frame id and an origin
|
||||
map->Add<blink::mojom::NotificationService>(
|
||||
BindServiceWorkerReceiverForOriginAndFrameId(
|
||||
&RenderProcessHostImpl::CreateNotificationService, host));
|
||||
map->Add<blink::mojom::NotificationService>(BindNotificationService(host));
|
||||
|
||||
// This is called when `host` is constructed. ServiceWorkerVersion, which
|
||||
// constructs `host`, checks that context() is not null and also uses
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "base/feature_list.h"
|
||||
#include "content/browser/notifications/notification_event_dispatcher_impl.h"
|
||||
#include "content/browser/notifications/platform_notification_context_impl.h"
|
||||
#include "content/browser/renderer_host/render_process_host_impl.h"
|
||||
#include "content/public/browser/browser_task_traits.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/browser/notification_database_data.h"
|
||||
@ -40,6 +41,8 @@ const char kBadMessageInvalidNotificationTriggerTimestamp[] =
|
||||
const char kBadMessageInvalidNotificationActionButtons[] =
|
||||
"Received a notification with a number of action images that does not "
|
||||
"match the number of actions.";
|
||||
const char kBadMessageNonPersistentNotificationFromServiceWorker[] =
|
||||
"Received a non-persistent notification from a service worker.";
|
||||
|
||||
bool FilterByTag(const std::string& filter_tag,
|
||||
const NotificationDatabaseData& database_data) {
|
||||
@ -86,6 +89,7 @@ BlinkNotificationServiceImpl::BlinkNotificationServiceImpl(
|
||||
const url::Origin& origin,
|
||||
const GURL& document_url,
|
||||
const WeakDocumentPtr& weak_document_ptr,
|
||||
RenderProcessHost::NotificationServiceCreatorType creator_type,
|
||||
mojo::PendingReceiver<blink::mojom::NotificationService> receiver)
|
||||
: notification_context_(notification_context),
|
||||
browser_context_(browser_context),
|
||||
@ -94,6 +98,7 @@ BlinkNotificationServiceImpl::BlinkNotificationServiceImpl(
|
||||
origin_(origin),
|
||||
document_url_(document_url),
|
||||
weak_document_ptr_(weak_document_ptr),
|
||||
creator_type_(creator_type),
|
||||
receiver_(this, std::move(receiver)) {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
||||
DCHECK(notification_context_);
|
||||
@ -125,6 +130,22 @@ void BlinkNotificationServiceImpl::OnConnectionError() {
|
||||
// |this| has now been deleted.
|
||||
}
|
||||
|
||||
// Since a non-persistent notification cannot be created by service workers, we
|
||||
// report the bad message here and raise a connection error.
|
||||
bool BlinkNotificationServiceImpl::IsValidForNonPersistentNotification() {
|
||||
switch (creator_type_) {
|
||||
case RenderProcessHost::NotificationServiceCreatorType::kDocument:
|
||||
case RenderProcessHost::NotificationServiceCreatorType::kDedicatedWorker:
|
||||
case RenderProcessHost::NotificationServiceCreatorType::kSharedWorker:
|
||||
return true;
|
||||
case RenderProcessHost::NotificationServiceCreatorType::kServiceWorker:
|
||||
receiver_.ReportBadMessage(
|
||||
kBadMessageNonPersistentNotificationFromServiceWorker);
|
||||
OnConnectionError();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void BlinkNotificationServiceImpl::DisplayNonPersistentNotification(
|
||||
const std::string& token,
|
||||
const blink::PlatformNotificationData& platform_notification_data,
|
||||
@ -142,6 +163,9 @@ void BlinkNotificationServiceImpl::DisplayNonPersistentNotification(
|
||||
if (CheckPermissionStatus() != blink::mojom::PermissionStatus::GRANTED)
|
||||
return;
|
||||
|
||||
if (!IsValidForNonPersistentNotification())
|
||||
return;
|
||||
|
||||
std::string notification_id =
|
||||
notification_context_->notification_id_generator()
|
||||
->GenerateForNonPersistentNotification(origin_, token);
|
||||
@ -149,7 +173,8 @@ void BlinkNotificationServiceImpl::DisplayNonPersistentNotification(
|
||||
NotificationEventDispatcherImpl* event_dispatcher =
|
||||
NotificationEventDispatcherImpl::GetInstance();
|
||||
event_dispatcher->RegisterNonPersistentNotificationListener(
|
||||
notification_id, std::move(event_listener_remote), weak_document_ptr_);
|
||||
notification_id, std::move(event_listener_remote), weak_document_ptr_,
|
||||
creator_type_);
|
||||
|
||||
browser_context_->GetPlatformNotificationService()->DisplayNotification(
|
||||
notification_id, origin_.GetURL(), document_url_,
|
||||
@ -165,6 +190,9 @@ void BlinkNotificationServiceImpl::CloseNonPersistentNotification(
|
||||
if (CheckPermissionStatus() != blink::mojom::PermissionStatus::GRANTED)
|
||||
return;
|
||||
|
||||
if (!IsValidForNonPersistentNotification())
|
||||
return;
|
||||
|
||||
std::string notification_id =
|
||||
notification_context_->notification_id_generator()
|
||||
->GenerateForNonPersistentNotification(origin_, token);
|
||||
@ -185,11 +213,8 @@ BlinkNotificationServiceImpl::CheckPermissionStatus() {
|
||||
// TODO(crbug.com/987654): It is odd that a service instance can be created
|
||||
// for cross-origin subframes, yet the instance is completely oblivious of
|
||||
// whether it is serving a top-level browsing context or an embedded one.
|
||||
|
||||
// An empty |document_url_| should mean this is initiated by a worker.
|
||||
// See: `RenderProcessHostImpl::CreateNotificationService` description in
|
||||
// content/browser/renderer_host/render_process_host_impl.h
|
||||
if (!document_url_.is_empty()) {
|
||||
if (creator_type_ ==
|
||||
RenderProcessHost::NotificationServiceCreatorType::kDocument) {
|
||||
RenderFrameHost* rfh = weak_document_ptr_.AsRenderFrameHostIfValid();
|
||||
if (!rfh) {
|
||||
return blink::mojom::PermissionStatus::DENIED;
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "content/browser/service_worker/service_worker_context_wrapper.h"
|
||||
#include "content/common/content_export.h"
|
||||
#include "content/public/browser/browser_context.h"
|
||||
#include "content/public/browser/render_process_host.h"
|
||||
#include "content/public/browser/weak_document_ptr.h"
|
||||
#include "mojo/public/cpp/bindings/pending_receiver.h"
|
||||
#include "mojo/public/cpp/bindings/pending_remote.h"
|
||||
@ -46,6 +47,7 @@ class CONTENT_EXPORT BlinkNotificationServiceImpl
|
||||
const url::Origin& origin,
|
||||
const GURL& document_url,
|
||||
const WeakDocumentPtr& weak_document_ptr,
|
||||
RenderProcessHost::NotificationServiceCreatorType creator_type,
|
||||
mojo::PendingReceiver<blink::mojom::NotificationService> receiver);
|
||||
|
||||
BlinkNotificationServiceImpl(const BlinkNotificationServiceImpl&) = delete;
|
||||
@ -101,6 +103,12 @@ class CONTENT_EXPORT BlinkNotificationServiceImpl
|
||||
bool success,
|
||||
const std::vector<NotificationDatabaseData>& notifications);
|
||||
|
||||
// Returns if the current notification service is valid for displaying and
|
||||
// handling non persistent notifications.
|
||||
// This may report bad message to the receiver and raise connection error if
|
||||
// the checks fail.
|
||||
bool IsValidForNonPersistentNotification();
|
||||
|
||||
// The notification context that owns this service instance.
|
||||
raw_ptr<PlatformNotificationContextImpl> notification_context_;
|
||||
|
||||
@ -113,11 +121,17 @@ class CONTENT_EXPORT BlinkNotificationServiceImpl
|
||||
// The origin that this notification service is communicating with.
|
||||
url::Origin origin_;
|
||||
// The document url that this notification service is communicating with.
|
||||
// This is empty when used for a worker.
|
||||
// This is empty when the notification service is created by a worker
|
||||
// (including dedicated workers, thus the URL might not be the same as
|
||||
// document that `weak_document_ptr_` is pointing at).
|
||||
const GURL document_url_;
|
||||
// The weak document pointer that this notification service is communicating
|
||||
// with. This is valid only for a document.
|
||||
// with. This is either the document that created the notification or the
|
||||
// ancestor document of the dedicated worker that created the notification.
|
||||
const WeakDocumentPtr weak_document_ptr_;
|
||||
// The type of the notification service's creator.
|
||||
// See RenderProcessHost::NotificationServiceCreatorType.
|
||||
const RenderProcessHost::NotificationServiceCreatorType creator_type_;
|
||||
|
||||
mojo::Receiver<blink::mojom::NotificationService> receiver_;
|
||||
|
||||
|
@ -20,13 +20,16 @@
|
||||
#include "content/browser/notifications/platform_notification_context_impl.h"
|
||||
#include "content/browser/service_worker/embedded_worker_test_helper.h"
|
||||
#include "content/browser/service_worker/service_worker_context_wrapper.h"
|
||||
#include "content/public/browser/browser_context.h"
|
||||
#include "content/public/common/content_client.h"
|
||||
#include "content/public/common/content_features.h"
|
||||
#include "content/public/test/browser_task_environment.h"
|
||||
#include "content/public/test/mock_permission_manager.h"
|
||||
#include "content/public/test/mock_render_process_host.h"
|
||||
#include "content/public/test/test_browser_context.h"
|
||||
#include "content/public/test/test_renderer_host.h"
|
||||
#include "content/public/test/test_utils.h"
|
||||
#include "content/public/test/web_contents_tester.h"
|
||||
#include "content/test/mock_platform_notification_service.h"
|
||||
#include "mojo/public/cpp/bindings/pending_remote.h"
|
||||
#include "mojo/public/cpp/bindings/remote.h"
|
||||
@ -43,8 +46,8 @@
|
||||
#include "third_party/blink/public/mojom/service_worker/service_worker_registration_options.mojom.h"
|
||||
#include "third_party/skia/include/core/SkBitmap.h"
|
||||
|
||||
using ::testing::Return;
|
||||
using ::testing::_;
|
||||
using ::testing::Return;
|
||||
|
||||
namespace content {
|
||||
|
||||
@ -126,12 +129,15 @@ class BlinkNotificationServiceImplTest : public ::testing::Test {
|
||||
// will be initialized long before it is read from so this is fine.
|
||||
RunAllTasksUntilIdle();
|
||||
|
||||
contents_ = CreateTestWebContents();
|
||||
|
||||
notification_service_ = std::make_unique<BlinkNotificationServiceImpl>(
|
||||
notification_context_.get(), &browser_context_,
|
||||
embedded_worker_helper_->context_wrapper(), &render_process_host_,
|
||||
url::Origin::Create(GURL(kTestOrigin)),
|
||||
/*document_url=*/GURL(),
|
||||
/*weak_document_ptr=*/WeakDocumentPtr(),
|
||||
contents_.get()->GetPrimaryMainFrame()->GetWeakDocumentPtr(),
|
||||
RenderProcessHost::NotificationServiceCreatorType::kDocument,
|
||||
notification_service_remote_.BindNewPipeAndPassReceiver());
|
||||
|
||||
// Provide a mock permission manager to the |browser_context_|.
|
||||
@ -440,6 +446,12 @@ class BlinkNotificationServiceImplTest : public ::testing::Test {
|
||||
std::vector<std::string> bad_messages_;
|
||||
|
||||
private:
|
||||
std::unique_ptr<content::WebContents> CreateTestWebContents() {
|
||||
auto site_instance = content::SiteInstance::Create(&browser_context_);
|
||||
return content::WebContentsTester::CreateTestWebContents(
|
||||
&browser_context_, std::move(site_instance));
|
||||
}
|
||||
|
||||
blink::mojom::PermissionStatus permission_callback_result_ =
|
||||
blink::mojom::PermissionStatus::ASK;
|
||||
|
||||
@ -452,6 +464,10 @@ class BlinkNotificationServiceImplTest : public ::testing::Test {
|
||||
absl::optional<blink::NotificationResources> get_notification_resources_;
|
||||
|
||||
bool read_notification_data_callback_result_ = false;
|
||||
|
||||
RenderViewHostTestEnabler rvh_enabler_;
|
||||
|
||||
std::unique_ptr<WebContents> contents_;
|
||||
};
|
||||
|
||||
TEST_F(BlinkNotificationServiceImplTest, GetPermissionStatus) {
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "base/callback.h"
|
||||
#include "base/callback_helpers.h"
|
||||
#include "base/metrics/histogram_functions.h"
|
||||
#include "base/notreached.h"
|
||||
#include "build/build_config.h"
|
||||
#include "content/browser/notifications/devtools_event_logging.h"
|
||||
#include "content/browser/notifications/platform_notification_context_impl.h"
|
||||
@ -417,8 +418,11 @@ NotificationEventDispatcherImpl::~NotificationEventDispatcherImpl() = default;
|
||||
NotificationEventDispatcherImpl::NonPersistentNotificationListenerInfo::
|
||||
NonPersistentNotificationListenerInfo(
|
||||
mojo::Remote<blink::mojom::NonPersistentNotificationListener> remote,
|
||||
WeakDocumentPtr document)
|
||||
: remote(std::move(remote)), document(document) {}
|
||||
WeakDocumentPtr document,
|
||||
RenderProcessHost::NotificationServiceCreatorType creator_type)
|
||||
: remote(std::move(remote)),
|
||||
document(document),
|
||||
creator_type(creator_type) {}
|
||||
|
||||
NotificationEventDispatcherImpl::NonPersistentNotificationListenerInfo::
|
||||
NonPersistentNotificationListenerInfo(
|
||||
@ -439,25 +443,39 @@ bool NotificationEventDispatcherImpl::
|
||||
return false;
|
||||
}
|
||||
|
||||
if (RenderFrameHost* rfh =
|
||||
listener->second.document.AsRenderFrameHostIfValid()) {
|
||||
// If the associated document is currently in back/forward cache, the
|
||||
// function
|
||||
// returns false to prevent the listener from being triggered.
|
||||
// TODO: in the future, this could be improved to cover more lifecycle
|
||||
// state. see: https://crrev.com/c/3861889/comment/e1759c1e_4dd15e4e/
|
||||
return !rfh->IsInLifecycleState(
|
||||
RenderFrameHost::LifecycleState::kInBackForwardCache);
|
||||
// The non-persistent notification should not be created by service workers.
|
||||
DCHECK(listener->second.creator_type !=
|
||||
RenderProcessHost::NotificationServiceCreatorType::kServiceWorker);
|
||||
|
||||
RenderFrameHost* rfh = listener->second.document.AsRenderFrameHostIfValid();
|
||||
if (!rfh) {
|
||||
switch (listener->second.creator_type) {
|
||||
case RenderProcessHost::NotificationServiceCreatorType::kDedicatedWorker:
|
||||
case RenderProcessHost::NotificationServiceCreatorType::kDocument: {
|
||||
// The weak document pointer should be pointing to the document that the
|
||||
// notification service is communicating with, if it's empty, it's
|
||||
// possible that the document is already destroyed. In this case, the
|
||||
// notification event shouldn't be dispatched.
|
||||
return false;
|
||||
}
|
||||
case RenderProcessHost::NotificationServiceCreatorType::kSharedWorker: {
|
||||
// In this case, the weak document pointer is always null and we
|
||||
// shouldn't block the notification.
|
||||
return true;
|
||||
}
|
||||
case RenderProcessHost::NotificationServiceCreatorType::kServiceWorker: {
|
||||
NOTREACHED();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(https://crbug.com/1350944): if the rfh is not set, there are two
|
||||
// possible cases: it's possible that the notification service is registered
|
||||
// from a shared/service worker, or the original page is gone and the
|
||||
// disconnect handler does not complete yet. We can't set this to false
|
||||
// since it will break the notification that's created from a shared/service
|
||||
// worker. A better support will be added in another CL
|
||||
// (https://crrev.com/c/3876770).
|
||||
return true;
|
||||
// If the associated document is currently in back/forward cache, the
|
||||
// function returns false to prevent the listener from being triggered.
|
||||
// TODO: in the future, this could be improved to cover more lifecycle
|
||||
// state. see: https://crrev.com/c/3861889/comment/e1759c1e_4dd15e4e/
|
||||
return !rfh->IsInLifecycleState(
|
||||
RenderFrameHost::LifecycleState::kInBackForwardCache);
|
||||
}
|
||||
|
||||
void NotificationEventDispatcherImpl::DispatchNotificationClickEvent(
|
||||
@ -502,7 +520,8 @@ void NotificationEventDispatcherImpl::RegisterNonPersistentNotificationListener(
|
||||
const std::string& notification_id,
|
||||
mojo::PendingRemote<blink::mojom::NonPersistentNotificationListener>
|
||||
event_listener_remote,
|
||||
const WeakDocumentPtr& event_document_ptr) {
|
||||
const WeakDocumentPtr& event_document_ptr,
|
||||
const RenderProcessHost::NotificationServiceCreatorType creator_type) {
|
||||
mojo::Remote<blink::mojom::NonPersistentNotificationListener> bound_remote(
|
||||
std::move(event_listener_remote));
|
||||
|
||||
@ -527,7 +546,8 @@ void NotificationEventDispatcherImpl::RegisterNonPersistentNotificationListener(
|
||||
}
|
||||
non_persistent_notification_listeners_.emplace(
|
||||
std::piecewise_construct, std::forward_as_tuple(notification_id),
|
||||
std::forward_as_tuple(std::move(bound_remote), event_document_ptr));
|
||||
std::forward_as_tuple(std::move(bound_remote), event_document_ptr,
|
||||
creator_type));
|
||||
}
|
||||
|
||||
// Only fire the notification listeners (including show, click and
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "content/common/content_export.h"
|
||||
#include "content/public/browser/notification_database_data.h"
|
||||
#include "content/public/browser/notification_event_dispatcher.h"
|
||||
#include "content/public/browser/render_process_host.h"
|
||||
#include "content/public/browser/weak_document_ptr.h"
|
||||
#include "mojo/public/cpp/bindings/pending_remote.h"
|
||||
#include "mojo/public/cpp/bindings/remote.h"
|
||||
@ -65,13 +66,15 @@ class CONTENT_EXPORT NotificationEventDispatcherImpl
|
||||
const std::string& notification_id,
|
||||
mojo::PendingRemote<blink::mojom::NonPersistentNotificationListener>
|
||||
event_listener_remote,
|
||||
const WeakDocumentPtr& event_document_ptr);
|
||||
const WeakDocumentPtr& event_document_ptr,
|
||||
RenderProcessHost::NotificationServiceCreatorType creator_type);
|
||||
|
||||
private:
|
||||
struct NonPersistentNotificationListenerInfo {
|
||||
NonPersistentNotificationListenerInfo(
|
||||
mojo::Remote<blink::mojom::NonPersistentNotificationListener> remote,
|
||||
WeakDocumentPtr document);
|
||||
WeakDocumentPtr document,
|
||||
RenderProcessHost::NotificationServiceCreatorType creator_type);
|
||||
NonPersistentNotificationListenerInfo(
|
||||
NonPersistentNotificationListenerInfo&&);
|
||||
NonPersistentNotificationListenerInfo(
|
||||
@ -83,7 +86,11 @@ class CONTENT_EXPORT NotificationEventDispatcherImpl
|
||||
mojo::Remote<blink::mojom::NonPersistentNotificationListener> remote;
|
||||
// This is used to determine if the associated document that registers the
|
||||
// listeners is in back/forward cache when the event is dispatched.
|
||||
// See weak_document_ptr_ in BlinkNotificationServiceImpl.
|
||||
WeakDocumentPtr document;
|
||||
// This is used to determine if the notification service is created by
|
||||
// document, shared worker, dedicated worker or service worker.
|
||||
RenderProcessHost::NotificationServiceCreatorType creator_type;
|
||||
};
|
||||
|
||||
friend class NotificationEventDispatcherImplTest;
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "base/test/test_simple_task_runner.h"
|
||||
#include "base/threading/thread_task_runner_handle.h"
|
||||
#include "content/browser/renderer_host/render_frame_host_impl.h"
|
||||
#include "content/public/browser/render_process_host.h"
|
||||
#include "content/public/test/test_renderer_host.h"
|
||||
#include "mojo/public/cpp/bindings/pending_remote.h"
|
||||
#include "mojo/public/cpp/bindings/receiver.h"
|
||||
@ -95,6 +96,13 @@ class NotificationEventDispatcherImplTest : public RenderViewHostTestHarness {
|
||||
void WaitForMojoTasksToComplete() { task_environment()->RunUntilIdle(); }
|
||||
|
||||
protected:
|
||||
struct CreatorTypeTestData {
|
||||
RenderProcessHost::NotificationServiceCreatorType creator_type;
|
||||
bool is_document_pointer_empty;
|
||||
bool is_show_event_dispatched;
|
||||
bool is_click_event_dispatched;
|
||||
bool is_close_event_dispatched;
|
||||
};
|
||||
// Using a raw pointer because NotificationEventDispatcherImpl is a singleton
|
||||
// with private constructor and destructor, so unique_ptr is not an option.
|
||||
raw_ptr<NotificationEventDispatcherImpl> dispatcher_;
|
||||
@ -104,12 +112,13 @@ TEST_F(NotificationEventDispatcherImplTest,
|
||||
DispatchNonPersistentShowEvent_NotifiesCorrectRegisteredListener) {
|
||||
auto listener = std::make_unique<TestNotificationListener>();
|
||||
dispatcher_->RegisterNonPersistentNotificationListener(
|
||||
kPrimaryUniqueId, listener->GetRemote(),
|
||||
main_rfh()->GetWeakDocumentPtr());
|
||||
kPrimaryUniqueId, listener->GetRemote(), main_rfh()->GetWeakDocumentPtr(),
|
||||
RenderProcessHost::NotificationServiceCreatorType::kDocument);
|
||||
auto other_listener = std::make_unique<TestNotificationListener>();
|
||||
dispatcher_->RegisterNonPersistentNotificationListener(
|
||||
kSomeOtherUniqueId, other_listener->GetRemote(),
|
||||
main_rfh()->GetWeakDocumentPtr());
|
||||
main_rfh()->GetWeakDocumentPtr(),
|
||||
RenderProcessHost::NotificationServiceCreatorType::kDocument);
|
||||
|
||||
dispatcher_->DispatchNonPersistentShowEvent(kPrimaryUniqueId);
|
||||
|
||||
@ -126,6 +135,88 @@ TEST_F(NotificationEventDispatcherImplTest,
|
||||
EXPECT_EQ(other_listener->on_show_count(), 1);
|
||||
}
|
||||
|
||||
TEST_F(NotificationEventDispatcherImplTest,
|
||||
DispatchNonPersistentEvent_RegisterListenerWithDifferentCreatorTypes) {
|
||||
// For `kDocument` and `kDedicatedWorker`, if the document pointer is empty,
|
||||
// then all the non persistent notification event should not be dispatched.
|
||||
// For `kSharedWorker`, the document pointer should always be empty and the
|
||||
// event will always be dispatched.
|
||||
// Since it's not possible for `kServiceWorker` to create non persistent
|
||||
// notification events, the test cases for those two creator types are not
|
||||
// added.
|
||||
std::vector<CreatorTypeTestData> creator_type_tests{
|
||||
{.creator_type =
|
||||
RenderProcessHost::NotificationServiceCreatorType::kDocument,
|
||||
.is_document_pointer_empty = true,
|
||||
.is_show_event_dispatched = false,
|
||||
.is_click_event_dispatched = false,
|
||||
.is_close_event_dispatched = false},
|
||||
{.creator_type =
|
||||
RenderProcessHost::NotificationServiceCreatorType::kDocument,
|
||||
.is_document_pointer_empty = false,
|
||||
.is_show_event_dispatched = true,
|
||||
.is_click_event_dispatched = true,
|
||||
.is_close_event_dispatched = true},
|
||||
{.creator_type =
|
||||
RenderProcessHost::NotificationServiceCreatorType::kDedicatedWorker,
|
||||
.is_document_pointer_empty = true,
|
||||
.is_show_event_dispatched = false,
|
||||
.is_click_event_dispatched = false,
|
||||
.is_close_event_dispatched = false},
|
||||
{.creator_type =
|
||||
RenderProcessHost::NotificationServiceCreatorType::kDedicatedWorker,
|
||||
.is_document_pointer_empty = false,
|
||||
.is_show_event_dispatched = true,
|
||||
.is_click_event_dispatched = true,
|
||||
.is_close_event_dispatched = true},
|
||||
{.creator_type =
|
||||
RenderProcessHost::NotificationServiceCreatorType::kSharedWorker,
|
||||
.is_document_pointer_empty = true,
|
||||
.is_show_event_dispatched = true,
|
||||
.is_click_event_dispatched = true,
|
||||
.is_close_event_dispatched = true},
|
||||
};
|
||||
|
||||
for (auto t : creator_type_tests) {
|
||||
int expected_show_count = t.is_show_event_dispatched ? 1 : 0;
|
||||
int expected_click_count = t.is_click_event_dispatched ? 1 : 0;
|
||||
int expected_close_count = t.is_close_event_dispatched ? 1 : 0;
|
||||
|
||||
auto listener = std::make_unique<TestNotificationListener>();
|
||||
dispatcher_->RegisterNonPersistentNotificationListener(
|
||||
kPrimaryUniqueId, listener->GetRemote(),
|
||||
t.is_document_pointer_empty ? WeakDocumentPtr()
|
||||
: main_rfh()->GetWeakDocumentPtr(),
|
||||
t.creator_type);
|
||||
|
||||
dispatcher_->DispatchNonPersistentShowEvent(kPrimaryUniqueId);
|
||||
|
||||
WaitForMojoTasksToComplete();
|
||||
|
||||
EXPECT_EQ(listener->on_show_count(), expected_show_count);
|
||||
EXPECT_EQ(listener->on_click_count(), 0);
|
||||
EXPECT_EQ(listener->on_close_count(), 0);
|
||||
|
||||
dispatcher_->DispatchNonPersistentClickEvent(kPrimaryUniqueId,
|
||||
base::DoNothing());
|
||||
|
||||
WaitForMojoTasksToComplete();
|
||||
|
||||
EXPECT_EQ(listener->on_show_count(), expected_show_count);
|
||||
EXPECT_EQ(listener->on_click_count(), expected_click_count);
|
||||
EXPECT_EQ(listener->on_close_count(), 0);
|
||||
|
||||
dispatcher_->DispatchNonPersistentCloseEvent(kPrimaryUniqueId,
|
||||
base::DoNothing());
|
||||
|
||||
WaitForMojoTasksToComplete();
|
||||
|
||||
EXPECT_EQ(listener->on_show_count(), expected_show_count);
|
||||
EXPECT_EQ(listener->on_click_count(), expected_click_count);
|
||||
EXPECT_EQ(listener->on_close_count(), expected_close_count);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(NotificationEventDispatcherImplTest,
|
||||
DispatchNonPersistentEvent_DocumentInBFCache) {
|
||||
auto listener = std::make_unique<TestNotificationListener>();
|
||||
@ -137,7 +228,8 @@ TEST_F(NotificationEventDispatcherImplTest,
|
||||
EXPECT_TRUE(
|
||||
rfh->IsInLifecycleState(RenderFrameHost::LifecycleState::kActive));
|
||||
dispatcher_->RegisterNonPersistentNotificationListener(
|
||||
kPrimaryUniqueId, listener->GetRemote(), document);
|
||||
kPrimaryUniqueId, listener->GetRemote(), document,
|
||||
RenderProcessHost::NotificationServiceCreatorType::kDocument);
|
||||
|
||||
dispatcher_->DispatchNonPersistentShowEvent(kPrimaryUniqueId);
|
||||
|
||||
@ -211,7 +303,8 @@ TEST_F(NotificationEventDispatcherImplTest,
|
||||
auto original_listener = std::make_unique<TestNotificationListener>();
|
||||
dispatcher_->RegisterNonPersistentNotificationListener(
|
||||
kPrimaryUniqueId, original_listener->GetRemote(),
|
||||
main_rfh()->GetWeakDocumentPtr());
|
||||
main_rfh()->GetWeakDocumentPtr(),
|
||||
RenderProcessHost::NotificationServiceCreatorType::kDocument);
|
||||
|
||||
dispatcher_->DispatchNonPersistentShowEvent(kPrimaryUniqueId);
|
||||
|
||||
@ -220,7 +313,8 @@ TEST_F(NotificationEventDispatcherImplTest,
|
||||
auto replacement_listener = std::make_unique<TestNotificationListener>();
|
||||
dispatcher_->RegisterNonPersistentNotificationListener(
|
||||
kPrimaryUniqueId, replacement_listener->GetRemote(),
|
||||
main_rfh()->GetWeakDocumentPtr());
|
||||
main_rfh()->GetWeakDocumentPtr(),
|
||||
RenderProcessHost::NotificationServiceCreatorType::kDocument);
|
||||
|
||||
WaitForMojoTasksToComplete();
|
||||
|
||||
@ -233,7 +327,8 @@ TEST_F(NotificationEventDispatcherImplTest,
|
||||
auto original_listener = std::make_unique<TestNotificationListener>();
|
||||
dispatcher_->RegisterNonPersistentNotificationListener(
|
||||
kPrimaryUniqueId, original_listener->GetRemote(),
|
||||
main_rfh()->GetWeakDocumentPtr());
|
||||
main_rfh()->GetWeakDocumentPtr(),
|
||||
RenderProcessHost::NotificationServiceCreatorType::kDocument);
|
||||
|
||||
dispatcher_->DispatchNonPersistentShowEvent(kPrimaryUniqueId);
|
||||
|
||||
@ -244,7 +339,8 @@ TEST_F(NotificationEventDispatcherImplTest,
|
||||
auto replacement_listener = std::make_unique<TestNotificationListener>();
|
||||
dispatcher_->RegisterNonPersistentNotificationListener(
|
||||
kPrimaryUniqueId, replacement_listener->GetRemote(),
|
||||
main_rfh()->GetWeakDocumentPtr());
|
||||
main_rfh()->GetWeakDocumentPtr(),
|
||||
RenderProcessHost::NotificationServiceCreatorType::kDocument);
|
||||
|
||||
dispatcher_->DispatchNonPersistentShowEvent(kPrimaryUniqueId);
|
||||
|
||||
@ -259,14 +355,16 @@ TEST_F(NotificationEventDispatcherImplTest,
|
||||
auto original_listener = std::make_unique<TestNotificationListener>();
|
||||
dispatcher_->RegisterNonPersistentNotificationListener(
|
||||
kPrimaryUniqueId, original_listener->GetRemote(),
|
||||
main_rfh()->GetWeakDocumentPtr());
|
||||
main_rfh()->GetWeakDocumentPtr(),
|
||||
RenderProcessHost::NotificationServiceCreatorType::kDocument);
|
||||
|
||||
dispatcher_->DispatchNonPersistentShowEvent(kPrimaryUniqueId);
|
||||
|
||||
auto replacement_listener = std::make_unique<TestNotificationListener>();
|
||||
dispatcher_->RegisterNonPersistentNotificationListener(
|
||||
kPrimaryUniqueId, replacement_listener->GetRemote(),
|
||||
main_rfh()->GetWeakDocumentPtr());
|
||||
main_rfh()->GetWeakDocumentPtr(),
|
||||
RenderProcessHost::NotificationServiceCreatorType::kDocument);
|
||||
|
||||
WaitForMojoTasksToComplete();
|
||||
|
||||
@ -285,12 +383,13 @@ TEST_F(NotificationEventDispatcherImplTest,
|
||||
DispatchNonPersistentClickEvent_NotifiesCorrectRegisteredListener) {
|
||||
auto listener = std::make_unique<TestNotificationListener>();
|
||||
dispatcher_->RegisterNonPersistentNotificationListener(
|
||||
kPrimaryUniqueId, listener->GetRemote(),
|
||||
main_rfh()->GetWeakDocumentPtr());
|
||||
kPrimaryUniqueId, listener->GetRemote(), main_rfh()->GetWeakDocumentPtr(),
|
||||
RenderProcessHost::NotificationServiceCreatorType::kDocument);
|
||||
auto other_listener = std::make_unique<TestNotificationListener>();
|
||||
dispatcher_->RegisterNonPersistentNotificationListener(
|
||||
kSomeOtherUniqueId, other_listener->GetRemote(),
|
||||
main_rfh()->GetWeakDocumentPtr());
|
||||
main_rfh()->GetWeakDocumentPtr(),
|
||||
RenderProcessHost::NotificationServiceCreatorType::kDocument);
|
||||
|
||||
dispatcher_->DispatchNonPersistentClickEvent(kPrimaryUniqueId,
|
||||
base::DoNothing());
|
||||
@ -313,12 +412,13 @@ TEST_F(NotificationEventDispatcherImplTest,
|
||||
DispatchNonPersistentCloseEvent_NotifiesCorrectRegisteredListener) {
|
||||
auto listener = std::make_unique<TestNotificationListener>();
|
||||
dispatcher_->RegisterNonPersistentNotificationListener(
|
||||
kPrimaryUniqueId, listener->GetRemote(),
|
||||
main_rfh()->GetWeakDocumentPtr());
|
||||
kPrimaryUniqueId, listener->GetRemote(), main_rfh()->GetWeakDocumentPtr(),
|
||||
RenderProcessHost::NotificationServiceCreatorType::kDocument);
|
||||
auto other_listener = std::make_unique<TestNotificationListener>();
|
||||
dispatcher_->RegisterNonPersistentNotificationListener(
|
||||
kSomeOtherUniqueId, other_listener->GetRemote(),
|
||||
main_rfh()->GetWeakDocumentPtr());
|
||||
main_rfh()->GetWeakDocumentPtr(),
|
||||
RenderProcessHost::NotificationServiceCreatorType::kDocument);
|
||||
|
||||
dispatcher_->DispatchNonPersistentCloseEvent(kPrimaryUniqueId,
|
||||
base::DoNothing());
|
||||
@ -341,8 +441,8 @@ TEST_F(NotificationEventDispatcherImplTest,
|
||||
DispatchMultipleNonPersistentEvents_StopsNotifyingAfterClose) {
|
||||
auto listener = std::make_unique<TestNotificationListener>();
|
||||
dispatcher_->RegisterNonPersistentNotificationListener(
|
||||
kPrimaryUniqueId, listener->GetRemote(),
|
||||
main_rfh()->GetWeakDocumentPtr());
|
||||
kPrimaryUniqueId, listener->GetRemote(), main_rfh()->GetWeakDocumentPtr(),
|
||||
RenderProcessHost::NotificationServiceCreatorType::kDocument);
|
||||
|
||||
dispatcher_->DispatchNonPersistentShowEvent(kPrimaryUniqueId);
|
||||
dispatcher_->DispatchNonPersistentClickEvent(kPrimaryUniqueId,
|
||||
|
@ -155,9 +155,8 @@ void PlatformNotificationContextImpl::Initialize() {
|
||||
&PlatformNotificationServiceProxy::RecordNotificationUkmEvent,
|
||||
service_proxy_->AsWeakPtr());
|
||||
|
||||
service->GetDisplayedNotifications(
|
||||
base::BindOnce(&PlatformNotificationContextImpl::DidGetNotifications,
|
||||
this));
|
||||
service->GetDisplayedNotifications(base::BindOnce(
|
||||
&PlatformNotificationContextImpl::DidGetNotifications, this));
|
||||
}
|
||||
|
||||
void PlatformNotificationContextImpl::DidGetNotifications(
|
||||
@ -286,11 +285,13 @@ void PlatformNotificationContextImpl::CreateService(
|
||||
const url::Origin& origin,
|
||||
const GURL& document_url,
|
||||
const WeakDocumentPtr& weak_document_ptr,
|
||||
RenderProcessHost::NotificationServiceCreatorType creator_type,
|
||||
mojo::PendingReceiver<blink::mojom::NotificationService> receiver) {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
||||
services_.push_back(std::make_unique<BlinkNotificationServiceImpl>(
|
||||
this, browser_context_, service_worker_context_, render_process_host,
|
||||
origin, document_url, weak_document_ptr, std::move(receiver)));
|
||||
origin, document_url, weak_document_ptr, creator_type,
|
||||
std::move(receiver)));
|
||||
}
|
||||
|
||||
void PlatformNotificationContextImpl::RemoveService(
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "content/common/content_export.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/browser/platform_notification_context.h"
|
||||
#include "content/public/browser/render_process_host.h"
|
||||
#include "mojo/public/cpp/bindings/pending_receiver.h"
|
||||
#include "third_party/abseil-cpp/absl/types/optional.h"
|
||||
#include "third_party/blink/public/mojom/notifications/notification_service.mojom.h"
|
||||
@ -75,12 +76,16 @@ class CONTENT_EXPORT PlatformNotificationContextImpl
|
||||
void Shutdown();
|
||||
|
||||
// Creates a BlinkNotificationServiceImpl that is owned by this context.
|
||||
// |document_url| is empty when originating from a worker.
|
||||
// The `document_url` will be empty if the service is created by a worker.
|
||||
// The `weak_document_ptr` points to the document if it's the creator of the
|
||||
// notification service, or the worker's ancestor document if the notification
|
||||
// service is created by a dedicated worker, or is `nullptr` otherwise.
|
||||
void CreateService(
|
||||
RenderProcessHost* render_process_host,
|
||||
const url::Origin& origin,
|
||||
const GURL& document_url,
|
||||
const WeakDocumentPtr& weak_document_ptr,
|
||||
const RenderProcessHost::NotificationServiceCreatorType creator_type,
|
||||
mojo::PendingReceiver<blink::mojom::NotificationService> receiver);
|
||||
|
||||
// Removes |service| from the list of owned services, for example because the
|
||||
|
@ -10825,7 +10825,8 @@ void RenderFrameHostImpl::CreateWebTransportConnector(
|
||||
void RenderFrameHostImpl::CreateNotificationService(
|
||||
mojo::PendingReceiver<blink::mojom::NotificationService> receiver) {
|
||||
GetProcess()->CreateNotificationService(
|
||||
GetRoutingID(), GetLastCommittedOrigin(), std::move(receiver));
|
||||
this, RenderProcessHost::NotificationServiceCreatorType::kDocument,
|
||||
GetLastCommittedOrigin(), std::move(receiver));
|
||||
}
|
||||
|
||||
void RenderFrameHostImpl::CreateInstalledAppProvider(
|
||||
|
@ -2060,25 +2060,30 @@ void RenderProcessHostImpl::CreatePaymentManagerForOrigin(
|
||||
}
|
||||
|
||||
void RenderProcessHostImpl::CreateNotificationService(
|
||||
int render_frame_id,
|
||||
RenderFrameHost* rfh,
|
||||
const RenderProcessHost::NotificationServiceCreatorType creator_type,
|
||||
const url::Origin& origin,
|
||||
mojo::PendingReceiver<blink::mojom::NotificationService> receiver) {
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
||||
auto weak_document_ptr = rfh ? rfh->GetWeakDocumentPtr() : WeakDocumentPtr();
|
||||
switch (creator_type) {
|
||||
case RenderProcessHost::NotificationServiceCreatorType::kServiceWorker:
|
||||
case RenderProcessHost::NotificationServiceCreatorType::kSharedWorker:
|
||||
case RenderProcessHost::NotificationServiceCreatorType::kDedicatedWorker: {
|
||||
storage_partition_impl_->GetPlatformNotificationContext()->CreateService(
|
||||
this, origin, /*document_url=*/GURL(), weak_document_ptr,
|
||||
creator_type, std::move(receiver));
|
||||
break;
|
||||
}
|
||||
case RenderProcessHost::NotificationServiceCreatorType::kDocument: {
|
||||
CHECK(rfh);
|
||||
|
||||
// For workers:
|
||||
if (render_frame_id == MSG_ROUTING_NONE) {
|
||||
storage_partition_impl_->GetPlatformNotificationContext()->CreateService(
|
||||
this, origin, /*document_url=*/GURL(),
|
||||
/*weak_document_ptr=*/WeakDocumentPtr(), std::move(receiver));
|
||||
return;
|
||||
storage_partition_impl_->GetPlatformNotificationContext()->CreateService(
|
||||
this, origin, rfh->GetLastCommittedURL(), weak_document_ptr,
|
||||
creator_type, std::move(receiver));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// For document:
|
||||
RenderFrameHost* rfh = RenderFrameHost::FromID(GetID(), render_frame_id);
|
||||
CHECK(rfh);
|
||||
storage_partition_impl_->GetPlatformNotificationContext()->CreateService(
|
||||
this, origin, rfh->GetLastCommittedURL(), rfh->GetWeakDocumentPtr(),
|
||||
std::move(receiver));
|
||||
}
|
||||
|
||||
void RenderProcessHostImpl::CreateWebSocketConnector(
|
||||
|
@ -659,12 +659,13 @@ class CONTENT_EXPORT RenderProcessHostImpl
|
||||
const url::Origin& origin,
|
||||
mojo::PendingReceiver<payments::mojom::PaymentManager> receiver) override;
|
||||
|
||||
// Binds |receiver| to the NotificationService instance owned by
|
||||
// |storage_partition_impl_|, and is used by frames and workers via
|
||||
// BrowserInterfaceBroker. |render_frame_id| will identify the RenderFrameHost
|
||||
// when the service belongs to one, `MSG_ROUTING_NONE` for workers.
|
||||
// Binds `creator_type`, `origin`, `receiver` and the information obtained
|
||||
// from the `rfh` to the NotificationService instance owned by
|
||||
// `storage_partition_impl_`, and is used by documents and workers via
|
||||
// BrowserInterfaceBroker.
|
||||
void CreateNotificationService(
|
||||
int render_frame_id,
|
||||
RenderFrameHost* rfh,
|
||||
RenderProcessHost::NotificationServiceCreatorType creator_type,
|
||||
const url::Origin& origin,
|
||||
mojo::PendingReceiver<blink::mojom::NotificationService> receiver)
|
||||
override;
|
||||
|
@ -125,6 +125,13 @@ class CONTENT_EXPORT RenderProcessHost : public IPC::Sender,
|
||||
GENERATE_CRASH_DUMP,
|
||||
};
|
||||
|
||||
enum class NotificationServiceCreatorType {
|
||||
kDocument,
|
||||
kDedicatedWorker,
|
||||
kSharedWorker,
|
||||
kServiceWorker
|
||||
};
|
||||
|
||||
// General functions ---------------------------------------------------------
|
||||
|
||||
~RenderProcessHost() override {}
|
||||
@ -608,10 +615,13 @@ class CONTENT_EXPORT RenderProcessHost : public IPC::Sender,
|
||||
virtual void CreatePaymentManagerForOrigin(
|
||||
const url::Origin& origin,
|
||||
mojo::PendingReceiver<payments::mojom::PaymentManager> receiver) = 0;
|
||||
// |render_frame_id| is the frame associated with |receiver|, or
|
||||
// MSG_ROUTING_NONE if |receiver| is associated with a worker.
|
||||
// `rfh` is the document associated with the `receiver` if the notification
|
||||
// service is created by a document, or the ancestor document of the worker if
|
||||
// the notification service is created by a dedicated worker, or `nullptr`
|
||||
// otherwise.
|
||||
virtual void CreateNotificationService(
|
||||
int render_frame_id,
|
||||
RenderFrameHost* rfh,
|
||||
NotificationServiceCreatorType creator_type,
|
||||
const url::Origin& origin,
|
||||
mojo::PendingReceiver<blink::mojom::NotificationService> receiver) = 0;
|
||||
virtual void CreateWebSocketConnector(
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "base/observer_list.h"
|
||||
#include "build/build_config.h"
|
||||
#include "build/chromeos_buildflags.h"
|
||||
#include "content/public/browser/render_frame_host.h"
|
||||
#include "content/public/browser/render_process_host.h"
|
||||
#include "content/public/browser/render_process_host_factory.h"
|
||||
#include "content/public/browser/storage_partition_config.h"
|
||||
@ -255,7 +256,8 @@ class MockRenderProcessHost : public RenderProcessHost {
|
||||
mojo::PendingReceiver<payments::mojom::PaymentManager> receiver)
|
||||
override {}
|
||||
void CreateNotificationService(
|
||||
int render_frame_id,
|
||||
RenderFrameHost* rfh,
|
||||
RenderProcessHost::NotificationServiceCreatorType creator_type,
|
||||
const url::Origin& origin,
|
||||
mojo::PendingReceiver<blink::mojom::NotificationService> receiver)
|
||||
override {}
|
||||
|
Reference in New Issue
Block a user