WebContentsObserver::OnServiceWorkerAccessed
Instead of passing WebContentsGetter to ContentBrowserClient, add explicit
callbacks to WebContentsObserver taking RenderFrameHost* or NavigationHandle*
as a parameter.
This allows to attribute cookie/javascript accesses to the correct
frame or navigation request, which is a prerequisite for attributing
content settings to the correct document and making them per-document.
[email protected],[email protected]
BUG=998171,1061899
Change-Id: Iec55a1db235b26bab44f1c1de76900b73ac6614d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2151866
Commit-Queue: Alexander Timin <[email protected]>
Reviewed-by: Balazs Engedy <[email protected]>
Reviewed-by: Matt Falkenhagen <[email protected]>
Cr-Commit-Position: refs/heads/master@{#762018}
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn
index 691f3e2..59965808 100644
--- a/content/browser/BUILD.gn
+++ b/content/browser/BUILD.gn
@@ -1663,6 +1663,7 @@
"service_worker/embedded_worker_status.h",
"service_worker/payment_handler_support.cc",
"service_worker/payment_handler_support.h",
+ "service_worker/service_worker_accessed_callback.h",
"service_worker/service_worker_cache_writer.cc",
"service_worker/service_worker_cache_writer.h",
"service_worker/service_worker_client_info.cc",
diff --git a/content/browser/frame_host/navigation_request.cc b/content/browser/frame_host/navigation_request.cc
index 38f5ab2..fe04fabb 100644
--- a/content/browser/frame_host/navigation_request.cc
+++ b/content/browser/frame_host/navigation_request.cc
@@ -2258,6 +2258,19 @@
frame_tree_node_->navigator()->LogResourceRequestTime(timestamp,
common_params_->url);
}
+namespace {
+
+void OnServiceWorkerAccessedThreadSafeWrapper(
+ base::WeakPtr<NavigationRequest> navigation,
+ const GURL& scope,
+ AllowServiceWorkerResult allowed) {
+ RunOrPostTaskOnThread(
+ FROM_HERE, BrowserThread::UI,
+ base::BindOnce(&NavigationRequest::OnServiceWorkerAccessed, navigation,
+ scope, allowed));
+}
+
+} // namespace
void NavigationRequest::OnStartChecksComplete(
NavigationThrottle::ThrottleCheckResult result) {
@@ -2336,7 +2349,9 @@
static_cast<ServiceWorkerContextWrapper*>(
partition->GetServiceWorkerContext());
service_worker_handle_ = std::make_unique<ServiceWorkerMainResourceHandle>(
- service_worker_context);
+ service_worker_context,
+ base::BindRepeating(&OnServiceWorkerAccessedThreadSafeWrapper,
+ weak_factory_.GetWeakPtr()));
}
if (IsSchemeSupportedForAppCache(common_params_->url)) {
@@ -2443,6 +2458,12 @@
DCHECK(!render_frame_host_);
}
+void NavigationRequest::OnServiceWorkerAccessed(
+ const GURL& scope,
+ AllowServiceWorkerResult allowed) {
+ GetDelegate()->OnServiceWorkerAccessed(this, scope, allowed);
+}
+
void NavigationRequest::OnRedirectChecksComplete(
NavigationThrottle::ThrottleCheckResult result) {
DCHECK(result.action() != NavigationThrottle::DEFER);
diff --git a/content/browser/frame_host/navigation_request.h b/content/browser/frame_host/navigation_request.h
index 218ab3d1..9bf8cc97 100644
--- a/content/browser/frame_host/navigation_request.h
+++ b/content/browser/frame_host/navigation_request.h
@@ -27,6 +27,7 @@
#include "content/common/content_export.h"
#include "content/common/navigation_params.h"
#include "content/common/navigation_params.mojom.h"
+#include "content/public/browser/allow_service_worker_result.h"
#include "content/public/browser/global_routing_id.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/navigation_throttle.h"
@@ -574,6 +575,9 @@
// ->GetPageUkmSourceId() for main-frame cross-document navigations.
ukm::SourceId GetPreviousPageUkmSourceId();
+ void OnServiceWorkerAccessed(const GURL& scope,
+ AllowServiceWorkerResult allowed);
+
private:
friend class NavigationRequestTest;
diff --git a/content/browser/frame_host/navigator_delegate.h b/content/browser/frame_host/navigator_delegate.h
index f036fe2db..d34fcef 100644
--- a/content/browser/frame_host/navigator_delegate.h
+++ b/content/browser/frame_host/navigator_delegate.h
@@ -6,6 +6,7 @@
#define CONTENT_BROWSER_FRAME_HOST_NAVIGATOR_DELEGATE_H_
#include "base/strings/string16.h"
+#include "content/public/browser/allow_service_worker_result.h"
#include "content/public/browser/invalidate_type.h"
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/navigation_throttle.h"
@@ -127,6 +128,12 @@
// embedder and |nullptr| is returned.
virtual std::unique_ptr<NavigationUIData> GetNavigationUIData(
NavigationHandle* navigation_handle);
+
+ // Called when a navigation accessed ServiceWorker to check if it should be
+ // handled by the ServiceWorker or not.
+ virtual void OnServiceWorkerAccessed(NavigationHandle* navigation,
+ const GURL& scope,
+ AllowServiceWorkerResult allowed) {}
};
} // namespace content
diff --git a/content/browser/service_worker/service_worker_accessed_callback.h b/content/browser/service_worker/service_worker_accessed_callback.h
new file mode 100644
index 0000000..3c58a8be
--- /dev/null
+++ b/content/browser/service_worker/service_worker_accessed_callback.h
@@ -0,0 +1,22 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_ACCESSED_CALLBACK_H_
+#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_ACCESSED_CALLBACK_H_
+
+#include "base/callback.h"
+#include "content/public/browser/allow_service_worker_result.h"
+#include "url/gurl.h"
+
+namespace content {
+
+// This callback is used by a few places in the code but these places don't
+// share a header which they all include, so this definition has to placed
+// in a dedicated header.
+using ServiceWorkerAccessedCallback =
+ base::RepeatingCallback<void(const GURL&, AllowServiceWorkerResult)>;
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_ACCESSED_CALLBACK_H_
diff --git a/content/browser/service_worker/service_worker_container_host.cc b/content/browser/service_worker/service_worker_container_host.cc
index 634f0ff..05813fd 100644
--- a/content/browser/service_worker/service_worker_container_host.cc
+++ b/content/browser/service_worker/service_worker_container_host.cc
@@ -951,31 +951,40 @@
return remote_controller;
}
+namespace {
+
+void ReportServiceWorkerAccess(int process_id,
+ int frame_id,
+ const GURL& scope,
+ AllowServiceWorkerResult allowed) {
+ RenderFrameHost* rfh = RenderFrameHost::FromID(process_id, frame_id);
+ if (!rfh)
+ return;
+ WebContentsImpl* web_contents =
+ static_cast<WebContentsImpl*>(WebContents::FromRenderFrameHost(rfh));
+ web_contents->OnServiceWorkerAccessed(rfh, scope, allowed);
+}
+
+} // namespace
+
bool ServiceWorkerContainerHost::AllowServiceWorker(const GURL& scope,
const GURL& script_url) {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
DCHECK(context_);
+ AllowServiceWorkerResult allowed = AllowServiceWorkerResult::No();
if (ServiceWorkerContext::IsServiceWorkerOnUIEnabled()) {
- return GetContentClient()->browser()->AllowServiceWorkerOnUI(
+ allowed = GetContentClient()->browser()->AllowServiceWorkerOnUI(
scope, site_for_cookies().RepresentativeUrl(), top_frame_origin(),
- script_url, context_->wrapper()->browser_context(),
- base::BindRepeating(
- [](int process_id, int frame_id) {
- return WebContentsImpl::FromRenderFrameHostID(process_id,
- frame_id);
- },
- process_id_, frame_id_));
+ script_url, context_->wrapper()->browser_context());
} else {
- return GetContentClient()->browser()->AllowServiceWorkerOnIO(
+ allowed = GetContentClient()->browser()->AllowServiceWorkerOnIO(
scope, site_for_cookies().RepresentativeUrl(), top_frame_origin(),
- script_url, context_->wrapper()->resource_context(),
- base::BindRepeating(
- [](int process_id, int frame_id) {
- return WebContentsImpl::FromRenderFrameHostID(process_id,
- frame_id);
- },
- process_id_, frame_id_));
+ script_url, context_->wrapper()->resource_context());
}
+ RunOrPostTaskOnThread(FROM_HERE, BrowserThread::UI,
+ base::BindOnce(&ReportServiceWorkerAccess, process_id_,
+ frame_id_, scope, allowed));
+ return allowed;
}
bool ServiceWorkerContainerHost::IsContextSecureForServiceWorker() const {
diff --git a/content/browser/service_worker/service_worker_controllee_request_handler.cc b/content/browser/service_worker/service_worker_controllee_request_handler.cc
index 397b828b..679d926 100644
--- a/content/browser/service_worker/service_worker_controllee_request_handler.cc
+++ b/content/browser/service_worker/service_worker_controllee_request_handler.cc
@@ -21,6 +21,8 @@
#include "content/browser/service_worker/service_worker_object_host.h"
#include "content/browser/service_worker/service_worker_registration.h"
#include "content/common/service_worker/service_worker_utils.h"
+#include "content/public/browser/allow_service_worker_result.h"
+#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
@@ -67,12 +69,15 @@
base::WeakPtr<ServiceWorkerContextCore> context,
base::WeakPtr<ServiceWorkerContainerHost> container_host,
blink::mojom::ResourceType resource_type,
- bool skip_service_worker)
+ bool skip_service_worker,
+ ServiceWorkerAccessedCallback service_worker_accessed_callback)
: context_(std::move(context)),
container_host_(std::move(container_host)),
resource_type_(resource_type),
skip_service_worker_(skip_service_worker),
- force_update_started_(false) {
+ force_update_started_(false),
+ service_worker_accessed_callback_(
+ std::move(service_worker_accessed_callback)) {
DCHECK(ServiceWorkerUtils::IsMainResourceType(resource_type));
TRACE_EVENT_WITH_FLOW0("ServiceWorker",
"ServiceWorkerControlleeRequestHandler::"
@@ -278,23 +283,29 @@
return;
}
- bool allow_service_worker = false;
+ AllowServiceWorkerResult allow_service_worker =
+ AllowServiceWorkerResult::No();
if (ServiceWorkerContext::IsServiceWorkerOnUIEnabled()) {
allow_service_worker =
GetContentClient()->browser()->AllowServiceWorkerOnUI(
registration->scope(),
container_host_->site_for_cookies().RepresentativeUrl(),
container_host_->top_frame_origin(), /*script_url=*/GURL(),
- browser_context_, container_host_->web_contents_getter());
+ browser_context_);
} else {
allow_service_worker =
GetContentClient()->browser()->AllowServiceWorkerOnIO(
registration->scope(),
container_host_->site_for_cookies().RepresentativeUrl(),
container_host_->top_frame_origin(), /*script_url=*/GURL(),
- resource_context_, container_host_->web_contents_getter());
+ resource_context_);
}
+ RunOrPostTaskOnThread(
+ FROM_HERE, BrowserThread::UI,
+ base::BindOnce(service_worker_accessed_callback_, registration->scope(),
+ allow_service_worker));
+
if (!allow_service_worker) {
TRACE_EVENT_WITH_FLOW1(
"ServiceWorker",
diff --git a/content/browser/service_worker/service_worker_controllee_request_handler.h b/content/browser/service_worker/service_worker_controllee_request_handler.h
index 2e0a555..fe3b8be1 100644
--- a/content/browser/service_worker/service_worker_controllee_request_handler.h
+++ b/content/browser/service_worker/service_worker_controllee_request_handler.h
@@ -16,6 +16,7 @@
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
#include "content/browser/loader/single_request_url_loader_factory.h"
+#include "content/browser/service_worker/service_worker_accessed_callback.h"
#include "content/browser/service_worker/service_worker_navigation_loader.h"
#include "content/common/content_export.h"
#include "services/network/public/cpp/resource_request.h"
@@ -45,7 +46,8 @@
base::WeakPtr<ServiceWorkerContextCore> context,
base::WeakPtr<ServiceWorkerContainerHost> container_host,
blink::mojom::ResourceType resource_type,
- bool skip_service_worker);
+ bool skip_service_worker,
+ ServiceWorkerAccessedCallback service_worker_accessed_callback);
~ServiceWorkerControlleeRequestHandler();
// This could get called multiple times during the lifetime in redirect
@@ -121,6 +123,8 @@
ServiceWorkerLoaderCallback loader_callback_;
NavigationLoaderInterceptor::FallbackCallback fallback_callback_;
+ ServiceWorkerAccessedCallback service_worker_accessed_callback_;
+
base::WeakPtrFactory<ServiceWorkerControlleeRequestHandler> weak_factory_{
this};
diff --git a/content/browser/service_worker/service_worker_controllee_request_handler_unittest.cc b/content/browser/service_worker/service_worker_controllee_request_handler_unittest.cc
index bb2a12e..b751130 100644
--- a/content/browser/service_worker/service_worker_controllee_request_handler_unittest.cc
+++ b/content/browser/service_worker/service_worker_controllee_request_handler_unittest.cc
@@ -59,7 +59,8 @@
test->context()->AsWeakPtr(),
test->container_host_,
type,
- /*skip_service_worker=*/false)) {}
+ /*skip_service_worker=*/false,
+ base::DoNothing())) {}
void MaybeCreateLoader() {
network::ResourceRequest resource_request;
@@ -145,25 +146,23 @@
class ServiceWorkerTestContentBrowserClient : public TestContentBrowserClient {
public:
- ServiceWorkerTestContentBrowserClient() {}
- bool AllowServiceWorkerOnIO(
+ ServiceWorkerTestContentBrowserClient() = default;
+ AllowServiceWorkerResult AllowServiceWorkerOnIO(
const GURL& scope,
const GURL& site_for_cookies,
const base::Optional<url::Origin>& top_frame_origin,
const GURL& script_url,
- content::ResourceContext* context,
- base::RepeatingCallback<WebContents*()> wc_getter) override {
- return false;
+ content::ResourceContext* context) override {
+ return AllowServiceWorkerResult::No();
}
- bool AllowServiceWorkerOnUI(
+ AllowServiceWorkerResult AllowServiceWorkerOnUI(
const GURL& scope,
const GURL& site_for_cookies,
const base::Optional<url::Origin>& top_frame_origin,
const GURL& script_url,
- content::BrowserContext* context,
- base::RepeatingCallback<WebContents*()> wc_getter) override {
- return false;
+ content::BrowserContext* context) override {
+ return AllowServiceWorkerResult::No();
}
};
@@ -412,7 +411,7 @@
std::make_unique<ServiceWorkerControlleeRequestHandler>(
context()->AsWeakPtr(), container_host_,
blink::mojom::ResourceType::kMainFrame,
- /*skip_service_worker=*/true));
+ /*skip_service_worker=*/true, base::DoNothing()));
// Conduct a main resource load.
test_resources.MaybeCreateLoader();
@@ -453,7 +452,7 @@
std::make_unique<ServiceWorkerControlleeRequestHandler>(
context()->AsWeakPtr(), container_host_,
blink::mojom::ResourceType::kMainFrame,
- /*skip_service_worker=*/false));
+ /*skip_service_worker=*/false, base::DoNothing()));
// Destroy the context and make a new one.
helper_->context_wrapper()->DeleteAndStartOver();
diff --git a/content/browser/service_worker/service_worker_main_resource_handle.cc b/content/browser/service_worker/service_worker_main_resource_handle.cc
index 8983898..3fd46f7d 100644
--- a/content/browser/service_worker/service_worker_main_resource_handle.cc
+++ b/content/browser/service_worker/service_worker_main_resource_handle.cc
@@ -18,11 +18,13 @@
namespace content {
ServiceWorkerMainResourceHandle::ServiceWorkerMainResourceHandle(
- ServiceWorkerContextWrapper* context_wrapper)
+ ServiceWorkerContextWrapper* context_wrapper,
+ ServiceWorkerAccessedCallback on_service_worker_accessed)
: context_wrapper_(context_wrapper) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- core_ = new ServiceWorkerMainResourceHandleCore(weak_factory_.GetWeakPtr(),
- context_wrapper);
+ core_ = new ServiceWorkerMainResourceHandleCore(
+ weak_factory_.GetWeakPtr(), context_wrapper,
+ std::move(on_service_worker_accessed));
}
ServiceWorkerMainResourceHandle::~ServiceWorkerMainResourceHandle() {
diff --git a/content/browser/service_worker/service_worker_main_resource_handle.h b/content/browser/service_worker/service_worker_main_resource_handle.h
index 0d739eb..c7786a2 100644
--- a/content/browser/service_worker/service_worker_main_resource_handle.h
+++ b/content/browser/service_worker/service_worker_main_resource_handle.h
@@ -7,6 +7,7 @@
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
+#include "content/browser/service_worker/service_worker_accessed_callback.h"
#include "content/common/content_export.h"
#include "services/network/public/mojom/network_context.mojom.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_provider.mojom.h"
@@ -59,8 +60,9 @@
// ServiceWorkerMainResourceHandleCore on the core thread.
class CONTENT_EXPORT ServiceWorkerMainResourceHandle {
public:
- explicit ServiceWorkerMainResourceHandle(
- ServiceWorkerContextWrapper* context_wrapper);
+ ServiceWorkerMainResourceHandle(
+ ServiceWorkerContextWrapper* context_wrapper,
+ ServiceWorkerAccessedCallback on_service_worker_accessed);
~ServiceWorkerMainResourceHandle();
// Called after a ServiceWorkerProviderHost tied with |provider_info|
diff --git a/content/browser/service_worker/service_worker_main_resource_handle_core.cc b/content/browser/service_worker/service_worker_main_resource_handle_core.cc
index 9048297c3..7cd6d90 100644
--- a/content/browser/service_worker/service_worker_main_resource_handle_core.cc
+++ b/content/browser/service_worker/service_worker_main_resource_handle_core.cc
@@ -12,8 +12,12 @@
ServiceWorkerMainResourceHandleCore::ServiceWorkerMainResourceHandleCore(
base::WeakPtr<ServiceWorkerMainResourceHandle> ui_handle,
- ServiceWorkerContextWrapper* context_wrapper)
- : context_wrapper_(context_wrapper), ui_handle_(ui_handle) {
+ ServiceWorkerContextWrapper* context_wrapper,
+ ServiceWorkerAccessedCallback service_worker_accessed_callback)
+ : context_wrapper_(context_wrapper),
+ ui_handle_(ui_handle),
+ service_worker_accessed_callback_(
+ std::move(service_worker_accessed_callback)) {
// The ServiceWorkerMainResourceHandleCore is created on the UI thread but
// should only be accessed from the core thread afterwards.
DCHECK_CURRENTLY_ON(BrowserThread::UI);
diff --git a/content/browser/service_worker/service_worker_main_resource_handle_core.h b/content/browser/service_worker/service_worker_main_resource_handle_core.h
index 43d2b517..aac0082 100644
--- a/content/browser/service_worker/service_worker_main_resource_handle_core.h
+++ b/content/browser/service_worker/service_worker_main_resource_handle_core.h
@@ -11,6 +11,7 @@
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
+#include "content/browser/service_worker/service_worker_accessed_callback.h"
#include "content/browser/service_worker/service_worker_container_host.h"
#include "content/browser/service_worker/service_worker_controllee_request_handler.h"
#include "content/common/content_export.h"
@@ -36,7 +37,8 @@
public:
ServiceWorkerMainResourceHandleCore(
base::WeakPtr<ServiceWorkerMainResourceHandle> ui_handle,
- ServiceWorkerContextWrapper* context_wrapper);
+ ServiceWorkerContextWrapper* context_wrapper,
+ ServiceWorkerAccessedCallback on_service_worker_accessed);
~ServiceWorkerMainResourceHandleCore();
// Called by corresponding methods in ServiceWorkerMainResourceHandle. See
@@ -72,6 +74,10 @@
return interceptor_.get();
}
+ const ServiceWorkerAccessedCallback& service_worker_accessed_callback() {
+ return service_worker_accessed_callback_;
+ }
+
base::WeakPtr<ServiceWorkerMainResourceHandleCore> AsWeakPtr() {
return weak_factory_.GetWeakPtr();
}
@@ -81,6 +87,8 @@
base::WeakPtr<ServiceWorkerMainResourceHandle> ui_handle_;
base::WeakPtr<ServiceWorkerContainerHost> container_host_;
std::unique_ptr<ServiceWorkerControlleeRequestHandler> interceptor_;
+ ServiceWorkerAccessedCallback service_worker_accessed_callback_;
+
base::WeakPtrFactory<ServiceWorkerMainResourceHandleCore> weak_factory_{this};
DISALLOW_COPY_AND_ASSIGN(ServiceWorkerMainResourceHandleCore);
diff --git a/content/browser/service_worker/service_worker_navigation_loader_interceptor.cc b/content/browser/service_worker/service_worker_navigation_loader_interceptor.cc
index d247c30..bc6f148 100644
--- a/content/browser/service_worker/service_worker_navigation_loader_interceptor.cc
+++ b/content/browser/service_worker/service_worker_navigation_loader_interceptor.cc
@@ -137,7 +137,8 @@
handle_core->set_interceptor(
std::make_unique<ServiceWorkerControlleeRequestHandler>(
context_core->AsWeakPtr(), container_host, params.resource_type,
- params.skip_service_worker));
+ params.skip_service_worker,
+ handle_core->service_worker_accessed_callback()));
}
// If |initialize_container_host_only| is true, we have already determined
diff --git a/content/browser/service_worker/service_worker_provider_host_unittest.cc b/content/browser/service_worker/service_worker_provider_host_unittest.cc
index 27952002..4b4a06f 100644
--- a/content/browser/service_worker/service_worker_provider_host_unittest.cc
+++ b/content/browser/service_worker/service_worker_provider_host_unittest.cc
@@ -71,26 +71,24 @@
ServiceWorkerTestContentBrowserClient() {}
- bool AllowServiceWorkerOnIO(
+ AllowServiceWorkerResult AllowServiceWorkerOnIO(
const GURL& scope,
const GURL& site_for_cookies,
const base::Optional<url::Origin>& top_frame_origin,
const GURL& script_url,
- content::ResourceContext* context,
- base::RepeatingCallback<WebContents*()> wc_getter) override {
+ content::ResourceContext* context) override {
logs_.emplace_back(scope, site_for_cookies, top_frame_origin, script_url);
- return false;
+ return AllowServiceWorkerResult::No();
}
- bool AllowServiceWorkerOnUI(
+ AllowServiceWorkerResult AllowServiceWorkerOnUI(
const GURL& scope,
const GURL& site_for_cookies,
const base::Optional<url::Origin>& top_frame_origin,
const GURL& script_url,
- content::BrowserContext* context,
- base::RepeatingCallback<WebContents*()> wc_getter) override {
+ content::BrowserContext* context) override {
logs_.emplace_back(scope, site_for_cookies, top_frame_origin, script_url);
- return false;
+ return AllowServiceWorkerResult::No();
}
const std::vector<AllowServiceWorkerCallLog>& logs() const { return logs_; }
diff --git a/content/browser/service_worker/service_worker_registration_unittest.cc b/content/browser/service_worker/service_worker_registration_unittest.cc
index 97e8163..afe9900 100644
--- a/content/browser/service_worker/service_worker_registration_unittest.cc
+++ b/content/browser/service_worker/service_worker_registration_unittest.cc
@@ -77,24 +77,22 @@
class ServiceWorkerTestContentBrowserClient : public TestContentBrowserClient {
public:
- bool AllowServiceWorkerOnIO(
+ AllowServiceWorkerResult AllowServiceWorkerOnIO(
const GURL& scope,
const GURL& site_for_cookies,
const base::Optional<url::Origin>& top_frame_origin,
const GURL& script_url,
- content::ResourceContext* context,
- base::RepeatingCallback<WebContents*()> wc_getter) override {
- return false;
+ content::ResourceContext* context) override {
+ return AllowServiceWorkerResult::No();
}
- bool AllowServiceWorkerOnUI(
+ AllowServiceWorkerResult AllowServiceWorkerOnUI(
const GURL& scope,
const GURL& site_for_cookies,
const base::Optional<url::Origin>& top_frame_origin,
const GURL& script_url,
- content::BrowserContext* context,
- base::RepeatingCallback<WebContents*()> wc_getter) override {
- return false;
+ content::BrowserContext* context) override {
+ return AllowServiceWorkerResult::No();
}
};
diff --git a/content/browser/service_worker/service_worker_request_handler_unittest.cc b/content/browser/service_worker/service_worker_request_handler_unittest.cc
index 9bfd2c6..e801fd01 100644
--- a/content/browser/service_worker/service_worker_request_handler_unittest.cc
+++ b/content/browser/service_worker/service_worker_request_handler_unittest.cc
@@ -53,8 +53,8 @@
protected:
void InitializeHandlerForNavigationSimpleTest(const std::string& url,
bool expected_handler_created) {
- auto navigation_handle =
- std::make_unique<ServiceWorkerMainResourceHandle>(context_wrapper());
+ auto navigation_handle = std::make_unique<ServiceWorkerMainResourceHandle>(
+ context_wrapper(), base::DoNothing());
GURL gurl(url);
auto begin_params = mojom::BeginNavigationParams::New();
begin_params->request_context_type =
diff --git a/content/browser/service_worker/service_worker_version.cc b/content/browser/service_worker/service_worker_version.cc
index 7e4de17..fde9a4ae9 100644
--- a/content/browser/service_worker/service_worker_version.cc
+++ b/content/browser/service_worker/service_worker_version.cc
@@ -47,6 +47,8 @@
#include "content/public/common/content_client.h"
#include "content/public/common/content_features.h"
#include "content/public/common/result_codes.h"
+#include "ipc/ipc_message.h"
+#include "mojo/public/c/system/types.h"
#include "net/base/net_errors.h"
#include "net/http/http_response_headers.h"
#include "net/http/http_response_info.h"
@@ -2281,7 +2283,7 @@
if (ServiceWorkerContext::IsServiceWorkerOnUIEnabled()) {
if (!GetContentClient()->browser()->AllowServiceWorkerOnUI(
scope_, scope_, url::Origin::Create(scope_), script_url_,
- context_->wrapper()->browser_context(), base::NullCallback())) {
+ context_->wrapper()->browser_context())) {
return false;
}
} else {
@@ -2289,7 +2291,7 @@
if ((context_->wrapper()->resource_context() &&
!GetContentClient()->browser()->AllowServiceWorkerOnIO(
scope_, scope_, url::Origin::Create(scope_), script_url_,
- context_->wrapper()->resource_context(), base::NullCallback()))) {
+ context_->wrapper()->resource_context()))) {
return false;
}
}
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index 1ba6488..053ee60 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -5121,6 +5121,24 @@
observer.AppCacheAccessed(manifest_url, blocked_by_policy);
}
+void WebContentsImpl::OnServiceWorkerAccessed(
+ RenderFrameHost* render_frame_host,
+ const GURL& scope,
+ AllowServiceWorkerResult allowed) {
+ for (auto& observer : observers_) {
+ observer.OnServiceWorkerAccessed(render_frame_host, scope, allowed);
+ }
+}
+
+void WebContentsImpl::OnServiceWorkerAccessed(
+ NavigationHandle* navigation,
+ const GURL& scope,
+ AllowServiceWorkerResult allowed) {
+ for (auto& observer : observers_) {
+ observer.OnServiceWorkerAccessed(navigation, scope, allowed);
+ }
+}
+
void WebContentsImpl::OnColorChooserFactoryReceiver(
mojo::PendingReceiver<blink::mojom::ColorChooserFactory> receiver) {
color_chooser_factory_receivers_.Add(this, std::move(receiver));
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h
index ba495dc..f2e1b85c 100644
--- a/content/browser/web_contents/web_contents_impl.h
+++ b/content/browser/web_contents/web_contents_impl.h
@@ -823,6 +823,9 @@
NavigationHandle* navigation_handle) override;
std::unique_ptr<NavigationUIData> GetNavigationUIData(
NavigationHandle* navigation_handle) override;
+ void OnServiceWorkerAccessed(NavigationHandle* navigation,
+ const GURL& scope,
+ AllowServiceWorkerResult allowed) override;
// RenderWidgetHostDelegate --------------------------------------------------
@@ -1177,6 +1180,10 @@
// call this directly.
void OnAppCacheAccessed(const GURL& manifest_url, bool blocked_by_policy);
+ void OnServiceWorkerAccessed(RenderFrameHost* render_frame_host,
+ const GURL& scope,
+ AllowServiceWorkerResult allowed);
+
JavaScriptDialogNavigationDeferrer* GetJavaScriptDialogNavigationDeferrer() {
return javascript_dialog_navigation_deferrer_.get();
}
diff --git a/content/browser/web_contents/web_contents_observer_browsertest.cc b/content/browser/web_contents/web_contents_observer_browsertest.cc
new file mode 100644
index 0000000..f811f268
--- /dev/null
+++ b/content/browser/web_contents/web_contents_observer_browsertest.cc
@@ -0,0 +1,217 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/test/scoped_feature_list.h"
+#include "content/browser/frame_host/render_frame_host_impl.h"
+#include "content/browser/service_worker/embedded_worker_instance.h"
+#include "content/browser/service_worker/embedded_worker_status.h"
+#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/public/browser/allow_service_worker_result.h"
+#include "content/public/browser/web_contents_observer.h"
+#include "content/public/common/content_client.h"
+#include "content/public/common/content_features.h"
+#include "content/public/test/browser_test.h"
+#include "content/public/test/content_browser_test.h"
+#include "content/shell/browser/shell.h"
+#include "content/test/test_content_browser_client.h"
+#include "net/dns/mock_host_resolver.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using testing::_;
+using testing::NotNull;
+
+namespace content {
+
+class WebContentsObserverBrowserTest : public ContentBrowserTest {
+ public:
+ WebContentsObserverBrowserTest() = default;
+
+ protected:
+ void SetUpOnMainThread() override {
+ host_resolver()->AddRule("*", "127.0.0.1");
+ SetupCrossSiteRedirector(embedded_test_server());
+ ASSERT_TRUE(embedded_test_server()->Start());
+ }
+
+ WebContentsImpl* web_contents() const {
+ return static_cast<WebContentsImpl*>(shell()->web_contents());
+ }
+
+ RenderFrameHostImpl* top_frame_host() {
+ return static_cast<RenderFrameHostImpl*>(web_contents()->GetMainFrame());
+ }
+
+ base::test::ScopedFeatureList feature_list_;
+};
+
+namespace {
+
+class ServiceWorkerAccessObserver : public WebContentsObserver {
+ public:
+ ServiceWorkerAccessObserver(WebContentsImpl* web_contents)
+ : WebContentsObserver(web_contents) {}
+
+ MOCK_METHOD3(OnServiceWorkerAccessed,
+ void(NavigationHandle*, const GURL&, AllowServiceWorkerResult));
+ MOCK_METHOD3(OnServiceWorkerAccessed,
+ void(RenderFrameHost*, const GURL&, AllowServiceWorkerResult));
+};
+
+} // namespace
+
+IN_PROC_BROWSER_TEST_F(WebContentsObserverBrowserTest,
+ OnServiceWorkerAccessed) {
+ GURL service_worker_scope =
+ embedded_test_server()->GetURL("/service_worker/");
+ {
+ // 1) Navigate to a page and register a ServiceWorker. Expect a notification
+ // to be called when the service worker is accessed from a frame.
+ ServiceWorkerAccessObserver observer(web_contents());
+ base::RunLoop run_loop;
+ EXPECT_CALL(
+ observer,
+ OnServiceWorkerAccessed(
+ testing::Matcher<RenderFrameHost*>(NotNull()), service_worker_scope,
+ AllowServiceWorkerResult::FromPolicy(false, false)))
+ .WillOnce([&]() { run_loop.Quit(); });
+ EXPECT_TRUE(NavigateToURL(
+ web_contents(), embedded_test_server()->GetURL(
+ "/service_worker/create_service_worker.html")));
+ EXPECT_EQ("DONE",
+ EvalJs(top_frame_host(),
+ "register('fetch_event.js', '/service_worker/');"));
+ run_loop.Run();
+ }
+
+ {
+ // 2) Navigate to a page in scope of the previously registered ServiceWorker
+ // and expect to get a notification about ServiceWorker being accessed for
+ // a navigation.
+ ServiceWorkerAccessObserver observer(web_contents());
+ base::RunLoop run_loop;
+ EXPECT_CALL(observer,
+ OnServiceWorkerAccessed(
+ testing::Matcher<NavigationHandle*>(NotNull()),
+ service_worker_scope,
+ AllowServiceWorkerResult::FromPolicy(false, false)))
+ .WillOnce([&]() { run_loop.Quit(); });
+ EXPECT_TRUE(NavigateToURL(
+ web_contents(),
+ embedded_test_server()->GetURL("/service_worker/empty.html")));
+ run_loop.Run();
+ }
+}
+
+namespace {
+
+class ServiceWorkerAccessContentBrowserClient
+ : public TestContentBrowserClient {
+ public:
+ ServiceWorkerAccessContentBrowserClient() = default;
+
+ void SetJavascriptAllowed(bool allowed) { javascript_allowed_ = allowed; }
+
+ void SetCookiesAllowed(bool allowed) { cookies_allowed_ = allowed; }
+
+ AllowServiceWorkerResult AllowServiceWorkerOnUI(
+ const GURL& scope,
+ const GURL& site_for_cookies,
+ const base::Optional<url::Origin>& top_frame_origin,
+ const GURL& script_url,
+ BrowserContext* context) override {
+ return AllowServiceWorkerResult::FromPolicy(!javascript_allowed_,
+ !cookies_allowed_);
+ }
+
+ private:
+ bool cookies_allowed_ = true;
+ bool javascript_allowed_ = true;
+};
+
+} // namespace
+
+class WebContentsObserverWithSWonUIBrowserTest
+ : public WebContentsObserverBrowserTest {
+ public:
+ WebContentsObserverWithSWonUIBrowserTest() {
+ feature_list_.InitAndEnableFeature(features::kServiceWorkerOnUI);
+ }
+};
+
+IN_PROC_BROWSER_TEST_F(WebContentsObserverWithSWonUIBrowserTest,
+ OnServiceWorkerAccessed_ContentClientBlocked) {
+ GURL service_worker_scope =
+ embedded_test_server()->GetURL("/service_worker/");
+ {
+ // 1) Navigate to a page and register a ServiceWorker. Expect a notification
+ // to be called when the service worker is accessed from a frame.
+ ServiceWorkerAccessObserver observer(web_contents());
+ base::RunLoop run_loop;
+ EXPECT_CALL(
+ observer,
+ OnServiceWorkerAccessed(
+ testing::Matcher<RenderFrameHost*>(NotNull()), service_worker_scope,
+ AllowServiceWorkerResult::FromPolicy(false, false)))
+ .WillOnce([&]() { run_loop.Quit(); });
+ EXPECT_TRUE(NavigateToURL(
+ web_contents(), embedded_test_server()->GetURL(
+ "/service_worker/create_service_worker.html")));
+ EXPECT_EQ("DONE",
+ EvalJs(top_frame_host(),
+ "register('fetch_event.js', '/service_worker/');"));
+ run_loop.Run();
+ }
+
+ // 2) Set content client and disallow javascript.
+ ServiceWorkerAccessContentBrowserClient content_browser_client;
+ ContentBrowserClient* old_client =
+ SetBrowserClientForTesting(&content_browser_client);
+ content_browser_client.SetJavascriptAllowed(false);
+
+ {
+ // 2) Navigate to a page in scope of the previously registered ServiceWorker
+ // and expect to get a notification about ServiceWorker being accessed for
+ // a navigation. Javascript should be blocked according to the policy.
+ ServiceWorkerAccessObserver observer(web_contents());
+ base::RunLoop run_loop;
+ EXPECT_CALL(observer, OnServiceWorkerAccessed(
+ testing::Matcher<NavigationHandle*>(NotNull()),
+ service_worker_scope,
+ AllowServiceWorkerResult::FromPolicy(
+ /* javascript_blocked=*/true,
+ /* cookies_blocked=*/false)))
+ .WillOnce([&]() { run_loop.Quit(); });
+ EXPECT_TRUE(NavigateToURL(
+ web_contents(),
+ embedded_test_server()->GetURL("/service_worker/empty.html")));
+ run_loop.Run();
+ }
+
+ content_browser_client.SetJavascriptAllowed(true);
+ content_browser_client.SetCookiesAllowed(false);
+
+ {
+ // 3) Navigate to a page in scope of the previously registered ServiceWorker
+ // and expect to get a notification about ServiceWorker being accessed for
+ // a navigation. Cookies should be blocked according to the policy.
+ ServiceWorkerAccessObserver observer(web_contents());
+ base::RunLoop run_loop;
+ EXPECT_CALL(observer, OnServiceWorkerAccessed(
+ testing::Matcher<NavigationHandle*>(NotNull()),
+ service_worker_scope,
+ AllowServiceWorkerResult::FromPolicy(
+ /* javascript_blocked=*/false,
+ /* cookies_blocked=*/true)))
+ .WillOnce([&]() { run_loop.Quit(); });
+ EXPECT_TRUE(NavigateToURL(
+ web_contents(),
+ embedded_test_server()->GetURL("/service_worker/empty.html")));
+ run_loop.Run();
+ }
+
+ SetBrowserClientForTesting(old_client);
+}
+
+} // namespace content
diff --git a/content/browser/worker_host/dedicated_worker_host.cc b/content/browser/worker_host/dedicated_worker_host.cc
index f77943c..61a18f3 100644
--- a/content/browser/worker_host/dedicated_worker_host.cc
+++ b/content/browser/worker_host/dedicated_worker_host.cc
@@ -203,7 +203,7 @@
file_url_support_ = creator_origin_.scheme() == url::kFileScheme;
service_worker_handle_ = std::make_unique<ServiceWorkerMainResourceHandle>(
- storage_partition_impl->GetServiceWorkerContext());
+ storage_partition_impl->GetServiceWorkerContext(), base::DoNothing());
WorkerScriptFetchInitiator::Start(
worker_process_host_->GetID(), script_url, creator_render_frame_host,
diff --git a/content/browser/worker_host/shared_worker_host_unittest.cc b/content/browser/worker_host/shared_worker_host_unittest.cc
index 0922ede..8f23948 100644
--- a/content/browser/worker_host/shared_worker_host_unittest.cc
+++ b/content/browser/worker_host/shared_worker_host_unittest.cc
@@ -95,7 +95,7 @@
// Set up for service worker.
auto service_worker_handle =
std::make_unique<ServiceWorkerMainResourceHandle>(
- helper_->context_wrapper());
+ helper_->context_wrapper(), base::DoNothing());
mojo::PendingAssociatedRemote<blink::mojom::ServiceWorkerContainer>
client_remote;
mojo::PendingAssociatedReceiver<blink::mojom::ServiceWorkerContainerHost>
diff --git a/content/browser/worker_host/shared_worker_service_impl.cc b/content/browser/worker_host/shared_worker_service_impl.cc
index ba2aba9..eb2fa83c1 100644
--- a/content/browser/worker_host/shared_worker_service_impl.cc
+++ b/content/browser/worker_host/shared_worker_service_impl.cc
@@ -306,7 +306,7 @@
auto service_worker_handle =
std::make_unique<ServiceWorkerMainResourceHandle>(
- storage_partition_->GetServiceWorkerContext());
+ storage_partition_->GetServiceWorkerContext(), base::DoNothing());
auto* service_worker_handle_raw = service_worker_handle.get();
host->SetServiceWorkerHandle(std::move(service_worker_handle));
diff --git a/content/browser/worker_host/worker_script_loader_factory_unittest.cc b/content/browser/worker_host/worker_script_loader_factory_unittest.cc
index 88304ef..eecbe5801 100644
--- a/content/browser/worker_host/worker_script_loader_factory_unittest.cc
+++ b/content/browser/worker_host/worker_script_loader_factory_unittest.cc
@@ -57,7 +57,7 @@
// Set up a service worker host for the shared worker.
service_worker_handle_ = std::make_unique<ServiceWorkerMainResourceHandle>(
- helper_->context_wrapper());
+ helper_->context_wrapper(), base::DoNothing());
}
protected:
diff --git a/content/public/browser/BUILD.gn b/content/public/browser/BUILD.gn
index c783678..9cdae86 100644
--- a/content/public/browser/BUILD.gn
+++ b/content/public/browser/BUILD.gn
@@ -26,6 +26,8 @@
visibility = [ "//content/*" ]
sources = [
"accessibility_tree_formatter.h",
+ "allow_service_worker_result.cc",
+ "allow_service_worker_result.h",
"android/android_overlay_provider.h",
"android/child_process_importance.h",
"android/compositor.h",
diff --git a/content/public/browser/allow_service_worker_result.cc b/content/public/browser/allow_service_worker_result.cc
new file mode 100644
index 0000000..d3e0aaa
--- /dev/null
+++ b/content/public/browser/allow_service_worker_result.cc
@@ -0,0 +1,40 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/public/browser/allow_service_worker_result.h"
+
+namespace content {
+
+AllowServiceWorkerResult AllowServiceWorkerResult::Yes() {
+ return AllowServiceWorkerResult(true, false, false);
+}
+
+AllowServiceWorkerResult AllowServiceWorkerResult::No() {
+ return AllowServiceWorkerResult(false, false, false);
+}
+
+AllowServiceWorkerResult AllowServiceWorkerResult::FromPolicy(
+ bool javascript_blocked_by_policy,
+ bool cookies_blocked_by_policy) {
+ return AllowServiceWorkerResult(
+ !javascript_blocked_by_policy && !cookies_blocked_by_policy,
+ javascript_blocked_by_policy, cookies_blocked_by_policy);
+}
+
+AllowServiceWorkerResult::AllowServiceWorkerResult(
+ bool allowed,
+ bool javascript_blocked_by_policy,
+ bool cookies_blocked_by_policy)
+ : allowed_(allowed),
+ javascript_blocked_by_policy_(javascript_blocked_by_policy),
+ cookies_blocked_by_policy_(cookies_blocked_by_policy) {}
+
+bool AllowServiceWorkerResult::operator==(
+ const AllowServiceWorkerResult& other) const {
+ return allowed_ == other.allowed_ &&
+ javascript_blocked_by_policy_ == other.javascript_blocked_by_policy_ &&
+ cookies_blocked_by_policy_ == other.cookies_blocked_by_policy_;
+}
+
+} // namespace content
diff --git a/content/public/browser/allow_service_worker_result.h b/content/public/browser/allow_service_worker_result.h
new file mode 100644
index 0000000..e46bd7a
--- /dev/null
+++ b/content/public/browser/allow_service_worker_result.h
@@ -0,0 +1,41 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_PUBLIC_BROWSER_ALLOW_SERVICE_WORKER_RESULT_H_
+#define CONTENT_PUBLIC_BROWSER_ALLOW_SERVICE_WORKER_RESULT_H_
+
+#include "content/common/content_export.h"
+
+namespace content {
+
+class CONTENT_EXPORT AllowServiceWorkerResult {
+ public:
+ static AllowServiceWorkerResult Yes();
+ static AllowServiceWorkerResult No();
+ static AllowServiceWorkerResult FromPolicy(bool javascript_blocked_by_policy,
+ bool cookies_blocked_by_policy);
+
+ operator bool() { return allowed_; }
+
+ bool javascript_blocked_by_policy() const {
+ return javascript_blocked_by_policy_;
+ }
+
+ bool cookies_blocked_by_policy() const { return cookies_blocked_by_policy_; }
+
+ bool operator==(const AllowServiceWorkerResult& other) const;
+
+ private:
+ AllowServiceWorkerResult(bool allowed,
+ bool javacript_blocked_by_policy,
+ bool cookies_blocked_by_policy);
+
+ bool allowed_ = false;
+ bool javascript_blocked_by_policy_ = false;
+ bool cookies_blocked_by_policy_ = false;
+};
+
+} // namespace content
+
+#endif // CONTENT_PUBLIC_BROWSER_ALLOW_SERVICE_WORKER_RESULT_H_
diff --git a/content/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc
index c49222a1..599022823 100644
--- a/content/public/browser/content_browser_client.cc
+++ b/content/public/browser/content_browser_client.cc
@@ -304,24 +304,22 @@
return true;
}
-bool ContentBrowserClient::AllowServiceWorkerOnIO(
+AllowServiceWorkerResult ContentBrowserClient::AllowServiceWorkerOnIO(
const GURL& scope,
const GURL& site_for_cookies,
const base::Optional<url::Origin>& top_frame_origin,
const GURL& script_url,
- ResourceContext* context,
- base::RepeatingCallback<WebContents*()> wc_getter) {
- return true;
+ ResourceContext* context) {
+ return AllowServiceWorkerResult::Yes();
}
-bool ContentBrowserClient::AllowServiceWorkerOnUI(
+AllowServiceWorkerResult ContentBrowserClient::AllowServiceWorkerOnUI(
const GURL& scope,
const GURL& site_for_cookies,
const base::Optional<url::Origin>& top_frame_origin,
const GURL& script_url,
- BrowserContext* context,
- base::RepeatingCallback<WebContents*()> wc_getter) {
- return true;
+ BrowserContext* context) {
+ return AllowServiceWorkerResult::Yes();
}
bool ContentBrowserClient::AllowSharedWorker(
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h
index 728f71d7..7c7a70b9 100644
--- a/content/public/browser/content_browser_client.h
+++ b/content/public/browser/content_browser_client.h
@@ -24,6 +24,7 @@
#include "base/util/type_safety/strong_alias.h"
#include "build/build_config.h"
#include "content/common/content_export.h"
+#include "content/public/browser/allow_service_worker_result.h"
#include "content/public/browser/certificate_request_result_type.h"
#include "content/public/browser/generated_code_cache_settings.h"
#include "content/public/common/page_visibility_state.h"
@@ -50,6 +51,7 @@
#include "ui/gfx/image/image_skia.h"
#include "url/gurl.h"
#include "url/origin.h"
+#include "url/url_constants.h"
#if (defined(OS_POSIX) && !defined(OS_MACOSX)) || defined(OS_FUCHSIA)
#include "base/posix/global_descriptors.h"
@@ -591,24 +593,20 @@
// made to access the registration but there is no specific service worker in
// the registration being acted on.
//
- // A null |wc_getter| callback indicates this is for starting a service
- // worker, which is not necessarily associated with a particular tab.
// This is called on the IO thread.
- virtual bool AllowServiceWorkerOnIO(
+ virtual AllowServiceWorkerResult AllowServiceWorkerOnIO(
const GURL& scope,
const GURL& site_for_cookies,
const base::Optional<url::Origin>& top_frame_origin,
const GURL& script_url,
- ResourceContext* context,
- base::RepeatingCallback<WebContents*()> wc_getter);
+ ResourceContext* context);
// Same but for the UI thread.
- virtual bool AllowServiceWorkerOnUI(
+ virtual AllowServiceWorkerResult AllowServiceWorkerOnUI(
const GURL& scope,
const GURL& site_for_cookies,
const base::Optional<url::Origin>& top_frame_origin,
const GURL& script_url,
- BrowserContext* context,
- base::RepeatingCallback<WebContents*()> wc_getter);
+ BrowserContext* context);
// Allow the embedder to control if a Shared Worker can be connected from a
// given tab.
diff --git a/content/public/browser/web_contents_observer.h b/content/public/browser/web_contents_observer.h
index 317c46f4..5435b9f7 100644
--- a/content/public/browser/web_contents_observer.h
+++ b/content/public/browser/web_contents_observer.h
@@ -11,8 +11,10 @@
#include "base/optional.h"
#include "base/process/kill.h"
#include "base/process/process_handle.h"
+#include "base/threading/thread_restrictions.h"
#include "components/viz/common/vertical_scroll_direction.h"
#include "content/common/content_export.h"
+#include "content/public/browser/allow_service_worker_result.h"
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/reload_type.h"
#include "content/public/browser/visibility.h"
@@ -613,6 +615,18 @@
// subsequently be destroyed if it is not adopted.
virtual void DidActivatePortal(WebContents* predecessor_contents) {}
+ // Called when the RenderFrameHost tries to use a ServiceWorker
+ // (e.g. via navigation.serviceWorker API).
+ virtual void OnServiceWorkerAccessed(RenderFrameHost* render_frame_host,
+ const GURL& scope,
+ AllowServiceWorkerResult allowed) {}
+ // Called when the NavigationHandle accesses ServiceWorker to see if the
+ // network request should be handled by the ServiceWorker instead
+ // (e.g. for navigations to URLs which are in scope of a ServiceWorker).
+ virtual void OnServiceWorkerAccessed(NavigationHandle* navigation_handle,
+ const GURL& scope,
+ AllowServiceWorkerResult allowed) {}
+
// IPC::Listener implementation.
// DEPRECATED: Use (i.e. override) the other overload instead:
// virtual bool OnMessageReceived(const IPC::Message& message,
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn
index b3a81d2a..d2ccdde 100644
--- a/content/test/BUILD.gn
+++ b/content/test/BUILD.gn
@@ -1075,6 +1075,7 @@
"../browser/vibration_browsertest.cc",
"../browser/web_contents/opened_by_dom_browsertest.cc",
"../browser/web_contents/web_contents_impl_browsertest.cc",
+ "../browser/web_contents/web_contents_observer_browsertest.cc",
"../browser/web_contents/web_contents_view_aura_browsertest.cc",
"../browser/web_contents_receiver_set_browsertest.cc",
"../browser/web_package/save_page_as_web_bundle_browsertest.cc",