summaryrefslogtreecommitdiff
path: root/chromium/content/browser/service_worker
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/content/browser/service_worker')
-rw-r--r--chromium/content/browser/service_worker/README.md5
-rw-r--r--chromium/content/browser/service_worker/embedded_worker_instance.cc83
-rw-r--r--chromium/content/browser/service_worker/embedded_worker_instance.h2
-rw-r--r--chromium/content/browser/service_worker/embedded_worker_instance_unittest.cc2
-rw-r--r--chromium/content/browser/service_worker/embedded_worker_test_helper.cc2
-rw-r--r--chromium/content/browser/service_worker/fake_service_worker.cc11
-rw-r--r--chromium/content/browser/service_worker/fake_service_worker.h3
-rw-r--r--chromium/content/browser/service_worker/service_worker_browsertest.cc155
-rw-r--r--chromium/content/browser/service_worker/service_worker_cache_writer.cc206
-rw-r--r--chromium/content/browser/service_worker/service_worker_cache_writer.h48
-rw-r--r--chromium/content/browser/service_worker/service_worker_cache_writer_unittest.cc471
-rw-r--r--chromium/content/browser/service_worker/service_worker_client_info.cc21
-rw-r--r--chromium/content/browser/service_worker/service_worker_client_info.h29
-rw-r--r--chromium/content/browser/service_worker/service_worker_client_utils.cc14
-rw-r--r--chromium/content/browser/service_worker/service_worker_container_host.cc54
-rw-r--r--chromium/content/browser/service_worker/service_worker_container_host.h47
-rw-r--r--chromium/content/browser/service_worker/service_worker_container_host_unittest.cc233
-rw-r--r--chromium/content/browser/service_worker/service_worker_context_core.cc44
-rw-r--r--chromium/content/browser/service_worker/service_worker_context_core.h20
-rw-r--r--chromium/content/browser/service_worker/service_worker_context_core_observer.h21
-rw-r--r--chromium/content/browser/service_worker/service_worker_context_core_unittest.cc2
-rw-r--r--chromium/content/browser/service_worker/service_worker_context_unittest.cc80
-rw-r--r--chromium/content/browser/service_worker/service_worker_context_watcher.cc27
-rw-r--r--chromium/content/browser/service_worker/service_worker_context_watcher.h2
-rw-r--r--chromium/content/browser/service_worker/service_worker_context_wrapper.cc292
-rw-r--r--chromium/content/browser/service_worker/service_worker_context_wrapper.h72
-rw-r--r--chromium/content/browser/service_worker/service_worker_context_wrapper_unittest.cc317
-rw-r--r--chromium/content/browser/service_worker/service_worker_controllee_request_handler.cc10
-rw-r--r--chromium/content/browser/service_worker/service_worker_controllee_request_handler.h8
-rw-r--r--chromium/content/browser/service_worker/service_worker_controllee_request_handler_unittest.cc6
-rw-r--r--chromium/content/browser/service_worker/service_worker_database.cc80
-rw-r--r--chromium/content/browser/service_worker/service_worker_database.h19
-rw-r--r--chromium/content/browser/service_worker/service_worker_database_unittest.cc46
-rw-r--r--chromium/content/browser/service_worker/service_worker_fetch_dispatcher.cc85
-rw-r--r--chromium/content/browser/service_worker/service_worker_fetch_dispatcher.h12
-rw-r--r--chromium/content/browser/service_worker/service_worker_host.cc (renamed from chromium/content/browser/service_worker/service_worker_provider_host.cc)40
-rw-r--r--chromium/content/browser/service_worker/service_worker_host.h (renamed from chromium/content/browser/service_worker/service_worker_provider_host.h)52
-rw-r--r--chromium/content/browser/service_worker/service_worker_info.h2
-rw-r--r--chromium/content/browser/service_worker/service_worker_installed_scripts_sender_unittest.cc3
-rw-r--r--chromium/content/browser/service_worker/service_worker_internals_ui.cc16
-rw-r--r--chromium/content/browser/service_worker/service_worker_job_unittest.cc34
-rw-r--r--chromium/content/browser/service_worker/service_worker_main_resource_handle.cc27
-rw-r--r--chromium/content/browser/service_worker/service_worker_main_resource_handle.h59
-rw-r--r--chromium/content/browser/service_worker/service_worker_main_resource_handle_core.cc5
-rw-r--r--chromium/content/browser/service_worker/service_worker_main_resource_handle_core.h1
-rw-r--r--chromium/content/browser/service_worker/service_worker_main_resource_loader.cc (renamed from chromium/content/browser/service_worker/service_worker_navigation_loader.cc)129
-rw-r--r--chromium/content/browser/service_worker/service_worker_main_resource_loader.h (renamed from chromium/content/browser/service_worker/service_worker_navigation_loader.h)36
-rw-r--r--chromium/content/browser/service_worker/service_worker_main_resource_loader_interceptor.cc (renamed from chromium/content/browser/service_worker/service_worker_navigation_loader_interceptor.cc)120
-rw-r--r--chromium/content/browser/service_worker/service_worker_main_resource_loader_interceptor.h (renamed from chromium/content/browser/service_worker/service_worker_navigation_loader_interceptor.h)32
-rw-r--r--chromium/content/browser/service_worker/service_worker_main_resource_loader_interceptor_unittest.cc79
-rw-r--r--chromium/content/browser/service_worker/service_worker_main_resource_loader_unittest.cc (renamed from chromium/content/browser/service_worker/service_worker_navigation_loader_unittest.cc)165
-rw-r--r--chromium/content/browser/service_worker/service_worker_metrics.cc15
-rw-r--r--chromium/content/browser/service_worker/service_worker_metrics.h4
-rw-r--r--chromium/content/browser/service_worker/service_worker_navigation_loader_interceptor_unittest.cc45
-rw-r--r--chromium/content/browser/service_worker/service_worker_new_script_loader.cc2
-rw-r--r--chromium/content/browser/service_worker/service_worker_object_host.cc12
-rw-r--r--chromium/content/browser/service_worker/service_worker_object_host_unittest.cc8
-rw-r--r--chromium/content/browser/service_worker/service_worker_offline_capability_check_browsertest.cc20
-rw-r--r--chromium/content/browser/service_worker/service_worker_offline_capability_checker.cc28
-rw-r--r--chromium/content/browser/service_worker/service_worker_process_manager.cc3
-rw-r--r--chromium/content/browser/service_worker/service_worker_process_manager_unittest.cc8
-rw-r--r--chromium/content/browser/service_worker/service_worker_quota_client.cc78
-rw-r--r--chromium/content/browser/service_worker/service_worker_quota_client.h11
-rw-r--r--chromium/content/browser/service_worker/service_worker_register_job.cc1
-rw-r--r--chromium/content/browser/service_worker/service_worker_registration.cc4
-rw-r--r--chromium/content/browser/service_worker/service_worker_registration.h1
-rw-r--r--chromium/content/browser/service_worker/service_worker_registration_object_host.cc4
-rw-r--r--chromium/content/browser/service_worker/service_worker_registration_unittest.cc41
-rw-r--r--chromium/content/browser/service_worker/service_worker_registry.cc90
-rw-r--r--chromium/content/browser/service_worker/service_worker_registry.h40
-rw-r--r--chromium/content/browser/service_worker/service_worker_registry_unittest.cc198
-rw-r--r--chromium/content/browser/service_worker/service_worker_script_cache_map.h2
-rw-r--r--chromium/content/browser/service_worker/service_worker_script_loader_factory.cc29
-rw-r--r--chromium/content/browser/service_worker/service_worker_script_loader_factory.h6
-rw-r--r--chromium/content/browser/service_worker/service_worker_script_loader_factory_unittest.cc12
-rw-r--r--chromium/content/browser/service_worker/service_worker_single_script_update_checker.cc9
-rw-r--r--chromium/content/browser/service_worker/service_worker_single_script_update_checker_unittest.cc355
-rw-r--r--chromium/content/browser/service_worker/service_worker_storage.cc92
-rw-r--r--chromium/content/browser/service_worker/service_worker_storage.h30
-rw-r--r--chromium/content/browser/service_worker/service_worker_storage_control_impl.cc258
-rw-r--r--chromium/content/browser/service_worker/service_worker_storage_control_impl.h59
-rw-r--r--chromium/content/browser/service_worker/service_worker_storage_control_impl_unittest.cc325
-rw-r--r--chromium/content/browser/service_worker/service_worker_storage_unittest.cc247
-rw-r--r--chromium/content/browser/service_worker/service_worker_test_utils.cc179
-rw-r--r--chromium/content/browser/service_worker/service_worker_test_utils.h81
-rw-r--r--chromium/content/browser/service_worker/service_worker_updated_script_loader.cc2
-rw-r--r--chromium/content/browser/service_worker/service_worker_version.cc135
-rw-r--r--chromium/content/browser/service_worker/service_worker_version.h59
-rw-r--r--chromium/content/browser/service_worker/service_worker_version_browsertest.cc4
-rw-r--r--chromium/content/browser/service_worker/service_worker_version_unittest.cc70
90 files changed, 3857 insertions, 2039 deletions
diff --git a/chromium/content/browser/service_worker/README.md b/chromium/content/browser/service_worker/README.md
index a1dacf3b02a..5f35ce8c5fe 100644
--- a/chromium/content/browser/service_worker/README.md
+++ b/chromium/content/browser/service_worker/README.md
@@ -169,9 +169,8 @@ to request the renderer to start and stop the service worker thread.
> use the same "embedded worker" classes. But it turned out only service workers
> use it.
-A running service worker has a corresponding host in the browser process
-called `ServiceWorkerProviderHost` ([to be renamed
-`ServiceWorkerHost`](https://crbug.com/931087)).
+A running service worker has a corresponding host in the browser process called
+`ServiceWorkerHost`.
In addition, service worker clients (windows and web workers) are represented by
a `ServiceWorkerContainerHost` in the browser process. This host holds
diff --git a/chromium/content/browser/service_worker/embedded_worker_instance.cc b/chromium/content/browser/service_worker/embedded_worker_instance.cc
index e91552b52fe..cbbcb54f1e4 100644
--- a/chromium/content/browser/service_worker/embedded_worker_instance.cc
+++ b/chromium/content/browser/service_worker/embedded_worker_instance.cc
@@ -14,7 +14,6 @@
#include "base/metrics/histogram_macros.h"
#include "base/no_destructor.h"
#include "base/optional.h"
-#include "base/task/post_task.h"
#include "base/trace_event/trace_event.h"
#include "content/browser/bad_message.h"
#include "content/browser/data_url_loader_factory.h"
@@ -27,7 +26,7 @@
#include "content/browser/service_worker/service_worker_content_settings_proxy_impl.h"
#include "content/browser/service_worker/service_worker_context_core.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
-#include "content/browser/service_worker/service_worker_provider_host.h"
+#include "content/browser/service_worker/service_worker_host.h"
#include "content/browser/service_worker/service_worker_script_loader_factory.h"
#include "content/browser/url_loader_factory_getter.h"
#include "content/browser/url_loader_factory_params_helper.h"
@@ -91,10 +90,10 @@ void NotifyUpdateCrossOriginEmbedderPolicyOnUI(
std::move(cross_origin_embedder_policy), std::move(coep_reporter));
}
-void NotifyWorkerDestroyedOnUI(int worker_process_id, int worker_route_id) {
+void NotifyWorkerStoppedOnUI(int worker_process_id, int worker_route_id) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- ServiceWorkerDevToolsManager::GetInstance()->WorkerDestroyed(
- worker_process_id, worker_route_id);
+ ServiceWorkerDevToolsManager::GetInstance()->WorkerStopped(worker_process_id,
+ worker_route_id);
}
void NotifyWorkerVersionInstalledOnUI(int worker_process_id,
@@ -104,10 +103,14 @@ void NotifyWorkerVersionInstalledOnUI(int worker_process_id,
worker_process_id, worker_route_id);
}
-void NotifyWorkerVersionDoomedOnUI(int worker_process_id, int worker_route_id) {
+void NotifyWorkerVersionDoomedOnUI(
+ int worker_process_id,
+ int worker_route_id,
+ scoped_refptr<ServiceWorkerContextWrapper> context_wrapper,
+ int64_t version_id) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
ServiceWorkerDevToolsManager::GetInstance()->WorkerVersionDoomed(
- worker_process_id, worker_route_id);
+ worker_process_id, worker_route_id, context_wrapper, version_id);
}
using CreateFactoryBundlesOnUICallback = base::OnceCallback<void(
@@ -223,8 +226,7 @@ void SetupOnUIThread(
cross_origin_embedder_policy,
blink::mojom::EmbeddedWorkerStartParamsPtr params,
mojo::PendingReceiver<blink::mojom::EmbeddedWorkerInstanceClient> receiver,
- ServiceWorkerContextCore* context,
- base::WeakPtr<ServiceWorkerContextCore> weak_context,
+ scoped_refptr<ServiceWorkerContextWrapper> context_wrapper,
const base::Optional<base::Time>& io_post_time,
SetupProcessCallback callback) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
@@ -324,15 +326,15 @@ void SetupOnUIThread(
}
// Register to DevTools and update params accordingly.
const int routing_id = rph->GetNextRoutingID();
- ServiceWorkerDevToolsManager::GetInstance()->WorkerCreated(
- process_id, routing_id, context, weak_context,
+ ServiceWorkerDevToolsManager::GetInstance()->WorkerStarting(
+ process_id, routing_id, std::move(context_wrapper),
params->service_worker_version_id, params->script_url, params->scope,
params->is_installed, cross_origin_embedder_policy,
std::move(coep_reporter_for_devtools), &params->devtools_worker_token,
&params->wait_for_debugger);
params->service_worker_route_id = routing_id;
// Create DevToolsProxy here to ensure that the WorkerCreated() call is
- // balanced by DevToolsProxy's destructor calling WorkerDestroyed().
+ // balanced by DevToolsProxy's destructor calling WorkerStopped().
devtools_proxy = std::make_unique<EmbeddedWorkerInstance::DevToolsProxy>(
process_id, routing_id);
@@ -441,22 +443,24 @@ void BindCacheStorageOnUIThread(
} // namespace
-// Created on UI thread and moved to core thread. Proxies notifications to
-// DevToolsManager that lives on UI thread. Owned by EmbeddedWorkerInstance.
+// Created on the UI thread when the worker version is allcated a render process
+// and then moved to the core thread. It is destroyed when the worker stops.
+// Proxies notifications to DevToolsManager that lives on UI thread.
+// Owned by EmbeddedWorkerInstance.
class EmbeddedWorkerInstance::DevToolsProxy {
public:
DevToolsProxy(int process_id, int agent_route_id)
: process_id_(process_id),
agent_route_id_(agent_route_id),
- ui_task_runner_(base::CreateSequencedTaskRunner({BrowserThread::UI})) {}
+ ui_task_runner_(GetUIThreadTaskRunner({})) {}
~DevToolsProxy() {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
if (ServiceWorkerContext::IsServiceWorkerOnUIEnabled()) {
- NotifyWorkerDestroyedOnUI(process_id_, agent_route_id_);
+ NotifyWorkerStoppedOnUI(process_id_, agent_route_id_);
} else {
ui_task_runner_->PostTask(
- FROM_HERE, base::BindOnce(NotifyWorkerDestroyedOnUI, process_id_,
+ FROM_HERE, base::BindOnce(NotifyWorkerStoppedOnUI, process_id_,
agent_route_id_));
}
}
@@ -489,17 +493,6 @@ class EmbeddedWorkerInstance::DevToolsProxy {
}
}
- void NotifyWorkerVersionDoomed() {
- DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
- if (ServiceWorkerContext::IsServiceWorkerOnUIEnabled()) {
- NotifyWorkerVersionDoomedOnUI(process_id_, agent_route_id_);
- } else {
- ui_task_runner_->PostTask(
- FROM_HERE, base::BindOnce(NotifyWorkerVersionDoomedOnUI, process_id_,
- agent_route_id_));
- }
- }
-
bool ShouldNotifyWorkerStopIgnored() const {
return !worker_stop_ignored_notified_;
}
@@ -698,8 +691,8 @@ class EmbeddedWorkerInstance::StartTask {
SetupOnUIThread(
instance_->embedded_worker_id(), process_manager,
can_use_existing_process, cross_origin_embedder_policy,
- std::move(params), std::move(receiver_), context.get(), context,
- base::nullopt,
+ std::move(params), std::move(receiver_),
+ base::WrapRefCounted(context->wrapper()), base::nullopt,
base::BindOnce(&StartTask::OnSetupCompleted,
weak_factory_.GetWeakPtr(), process_manager));
} else {
@@ -709,7 +702,7 @@ class EmbeddedWorkerInstance::StartTask {
&SetupOnUIThread, instance_->embedded_worker_id(),
process_manager, can_use_existing_process,
cross_origin_embedder_policy, std::move(params),
- std::move(receiver_), context.get(), context,
+ std::move(receiver_), base::WrapRefCounted(context->wrapper()),
base::make_optional<base::Time>(base::Time::Now()),
base::BindOnce(&StartTask::OnSetupCompleted,
weak_factory_.GetWeakPtr(), process_manager)));
@@ -780,10 +773,6 @@ class EmbeddedWorkerInstance::StartTask {
instance_->embedded_worker_id()),
TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "StartSituation",
ServiceWorkerMetrics::StartSituationToString(start_situation));
- if (is_installed_) {
- ServiceWorkerMetrics::RecordProcessCreated(
- start_situation == ServiceWorkerMetrics::StartSituation::NEW_PROCESS);
- }
if (started_during_browser_startup_)
start_situation = ServiceWorkerMetrics::StartSituation::DURING_STARTUP;
@@ -858,7 +847,6 @@ class EmbeddedWorkerInstance::StartTask {
EmbeddedWorkerInstance::~EmbeddedWorkerInstance() {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
- devtools_proxy_.reset();
ReleaseProcess();
}
@@ -954,7 +942,7 @@ EmbeddedWorkerInstance::EmbeddedWorkerInstance(
devtools_attached_(false),
network_accessed_for_script_(false),
foreground_notified_(false),
- ui_task_runner_(base::CreateSequencedTaskRunner({BrowserThread::UI})) {
+ ui_task_runner_(GetUIThreadTaskRunner({})) {
DCHECK(owner_version_);
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
DCHECK(context_);
@@ -1000,8 +988,7 @@ void EmbeddedWorkerInstance::SendStartWorker(
content_settings_ =
base::SequenceBound<ServiceWorkerContentSettingsProxyImpl>(
- base::CreateSequencedTaskRunner({BrowserThread::UI}),
- params->script_url,
+ GetUIThreadTaskRunner({}), params->script_url,
scoped_refptr<ServiceWorkerContextWrapper>(context_->wrapper()),
params->content_settings_proxy.InitWithNewPipeAndPassReceiver());
@@ -1009,7 +996,7 @@ void EmbeddedWorkerInstance::SendStartWorker(
inflight_start_task_->set_start_worker_sent_time(base::TimeTicks::Now());
// The host must be alive as long as |params->provider_info| is alive.
- owner_version_->provider_host()->CompleteStartWorkerPreparation(
+ owner_version_->worker_host()->CompleteStartWorkerPreparation(
process_id(), params->provider_info->browser_interface_broker
.InitWithNewPipeAndPassReceiver());
@@ -1072,8 +1059,18 @@ void EmbeddedWorkerInstance::OnWorkerVersionInstalled() {
}
void EmbeddedWorkerInstance::OnWorkerVersionDoomed() {
- if (devtools_proxy_)
- devtools_proxy_->NotifyWorkerVersionDoomed();
+ if (ServiceWorkerContext::IsServiceWorkerOnUIEnabled()) {
+ NotifyWorkerVersionDoomedOnUI(process_id(),
+ worker_devtools_agent_route_id(),
+ base::WrapRefCounted(context_->wrapper()),
+ owner_version_->version_id());
+ } else {
+ ui_task_runner_->PostTask(
+ FROM_HERE, base::BindOnce(NotifyWorkerVersionDoomedOnUI, process_id(),
+ worker_devtools_agent_route_id(),
+ base::WrapRefCounted(context_->wrapper()),
+ owner_version_->version_id()));
+ }
}
void EmbeddedWorkerInstance::OnScriptEvaluationStart() {
@@ -1477,7 +1474,7 @@ EmbeddedWorkerInstance::MakeScriptLoaderFactoryRemote(
std::move(script_bundle));
script_loader_factory_ = mojo::MakeSelfOwnedReceiver(
std::make_unique<ServiceWorkerScriptLoaderFactory>(
- context_, owner_version_->provider_host()->GetWeakPtr(),
+ context_, owner_version_->worker_host()->GetWeakPtr(),
std::move(script_bundle_factory)),
script_loader_factory_remote.InitWithNewPipeAndPassReceiver());
diff --git a/chromium/content/browser/service_worker/embedded_worker_instance.h b/chromium/content/browser/service_worker/embedded_worker_instance.h
index 2849085fbb7..93f017347d1 100644
--- a/chromium/content/browser/service_worker/embedded_worker_instance.h
+++ b/chromium/content/browser/service_worker/embedded_worker_instance.h
@@ -11,8 +11,8 @@
#include <string>
#include "base/callback_forward.h"
+#include "base/check_op.h"
#include "base/gtest_prod_util.h"
-#include "base/logging.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
diff --git a/chromium/content/browser/service_worker/embedded_worker_instance_unittest.cc b/chromium/content/browser/service_worker/embedded_worker_instance_unittest.cc
index bb469e8adf2..7588ade7972 100644
--- a/chromium/content/browser/service_worker/embedded_worker_instance_unittest.cc
+++ b/chromium/content/browser/service_worker/embedded_worker_instance_unittest.cc
@@ -173,7 +173,7 @@ class EmbeddedWorkerInstanceTest : public testing::Test,
scoped_refptr<ServiceWorkerVersion> version) {
auto provider_info =
blink::mojom::ServiceWorkerProviderInfoForStartWorker::New();
- version->provider_host_ = std::make_unique<ServiceWorkerProviderHost>(
+ version->worker_host_ = std::make_unique<ServiceWorkerHost>(
provider_info->host_remote.InitWithNewEndpointAndPassReceiver(),
version.get(), context()->AsWeakPtr());
return provider_info;
diff --git a/chromium/content/browser/service_worker/embedded_worker_test_helper.cc b/chromium/content/browser/service_worker/embedded_worker_test_helper.cc
index 534704c9d65..900309a3b27 100644
--- a/chromium/content/browser/service_worker/embedded_worker_test_helper.cc
+++ b/chromium/content/browser/service_worker/embedded_worker_test_helper.cc
@@ -16,8 +16,6 @@
#include "content/public/test/mock_render_process_host.h"
#include "content/public/test/test_browser_context.h"
#include "content/test/fake_network_url_loader_factory.h"
-#include "mojo/public/cpp/bindings/associated_binding_set.h"
-#include "mojo/public/cpp/bindings/interface_request.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "third_party/blink/public/common/service_worker/service_worker_utils.h"
#include "third_party/blink/public/common/user_agent/user_agent_metadata.h"
diff --git a/chromium/content/browser/service_worker/fake_service_worker.cc b/chromium/content/browser/service_worker/fake_service_worker.cc
index 541f2a5ea16..6b60f6316d0 100644
--- a/chromium/content/browser/service_worker/fake_service_worker.cc
+++ b/chromium/content/browser/service_worker/fake_service_worker.cc
@@ -36,6 +36,10 @@ void FakeServiceWorker::RunUntilInitializeGlobalScope() {
loop.Run();
}
+void FakeServiceWorker::FlushForTesting() {
+ receiver_.FlushForTesting();
+}
+
void FakeServiceWorker::InitializeGlobalScope(
mojo::PendingAssociatedRemote<blink::mojom::ServiceWorkerHost>
service_worker_host,
@@ -128,8 +132,11 @@ void FakeServiceWorker::DispatchFetchEventForMainResource(
response->response_type = network::mojom::FetchResponseType::kDefault;
mojo::Remote<blink::mojom::ServiceWorkerFetchResponseCallback>
response_callback(std::move(pending_response_callback));
- response_callback->OnResponse(
- std::move(response), blink::mojom::ServiceWorkerFetchEventTiming::New());
+ auto timing = blink::mojom::ServiceWorkerFetchEventTiming::New();
+ auto now = base::TimeTicks::Now();
+ timing->respond_with_settled_time = now;
+ timing->dispatch_event_time = now;
+ response_callback->OnResponse(std::move(response), std::move(timing));
std::move(callback).Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED);
}
diff --git a/chromium/content/browser/service_worker/fake_service_worker.h b/chromium/content/browser/service_worker/fake_service_worker.h
index 7451f68f36f..7fbdfecddd8 100644
--- a/chromium/content/browser/service_worker/fake_service_worker.h
+++ b/chromium/content/browser/service_worker/fake_service_worker.h
@@ -50,6 +50,9 @@ class FakeServiceWorker : public blink::mojom::ServiceWorker {
return fetch_handler_existence_;
}
+ // Flush messages in the message pipe.
+ void FlushForTesting();
+
protected:
// blink::mojom::ServiceWorker overrides:
void InitializeGlobalScope(
diff --git a/chromium/content/browser/service_worker/service_worker_browsertest.cc b/chromium/content/browser/service_worker/service_worker_browsertest.cc
index 0d6f21c2ed9..ec633594fcd 100644
--- a/chromium/content/browser/service_worker/service_worker_browsertest.cc
+++ b/chromium/content/browser/service_worker/service_worker_browsertest.cc
@@ -13,6 +13,7 @@
#include "base/bind_helpers.h"
#include "base/callback.h"
#include "base/command_line.h"
+#include "base/guid.h"
#include "base/json/json_reader.h"
#include "base/memory/ref_counted.h"
#include "base/metrics/statistics_recorder.h"
@@ -40,6 +41,7 @@
#include "content/browser/service_worker/service_worker_context_core.h"
#include "content/browser/service_worker/service_worker_context_core_observer.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
+#include "content/browser/service_worker/service_worker_fetch_dispatcher.h"
#include "content/browser/service_worker/service_worker_registration.h"
#include "content/browser/service_worker/service_worker_test_utils.h"
#include "content/browser/service_worker/service_worker_version.h"
@@ -937,6 +939,157 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerBrowserTest, GetRunningServiceWorkerInfos) {
running_info.render_process_id);
}
+// Make sure that a fetch event is dispatched to a stopped worker in the task
+// which calls ServiceWorkerFetchDispatcher::Run().
+IN_PROC_BROWSER_TEST_F(ServiceWorkerBrowserTest,
+ DispatchFetchEventToStoppedWorkerSynchronously) {
+ // Setup the server so that the test doesn't crash when tearing down.
+ StartServerAndNavigateToSetup();
+ // This test is meaningful only when ServiceWorkerOnUI is enabled.
+ if (!ServiceWorkerContext::IsServiceWorkerOnUIEnabled())
+ return;
+
+ WorkerRunningStatusObserver observer(public_context());
+ EXPECT_TRUE(NavigateToURL(shell(),
+ embedded_test_server()->GetURL(
+ "/service_worker/create_service_worker.html")));
+ EXPECT_EQ("DONE", EvalJs(shell(), "register('fetch_event.js');"));
+ observer.WaitUntilRunning();
+
+ ASSERT_TRUE(
+ BrowserThread::CurrentlyOn(ServiceWorkerContext::GetCoreThreadId()));
+ scoped_refptr<ServiceWorkerVersion> version =
+ wrapper()->GetLiveVersion(observer.version_id());
+ EXPECT_EQ(EmbeddedWorkerStatus::RUNNING, version->running_status());
+
+ {
+ base::RunLoop loop;
+ version->StopWorker(loop.QuitClosure());
+ loop.Run();
+ EXPECT_EQ(EmbeddedWorkerStatus::STOPPED, version->running_status());
+ }
+
+ bool is_prepare_callback_called = false;
+ base::RunLoop fetch_loop;
+ blink::ServiceWorkerStatusCode fetch_status;
+ ServiceWorkerFetchDispatcher::FetchEventResult fetch_result;
+ blink::mojom::FetchAPIResponsePtr fetch_response;
+
+ auto request = blink::mojom::FetchAPIRequest::New();
+ request->url = embedded_test_server()->GetURL("/service_worker/in-scope");
+ request->method = "GET";
+ request->is_main_resource_load = true;
+ auto dispatcher = std::make_unique<ServiceWorkerFetchDispatcher>(
+ std::move(request), blink::mojom::ResourceType::kMainFrame,
+ /*client_id=*/base::GenerateGUID(), version,
+ base::BindLambdaForTesting([&]() { is_prepare_callback_called = true; }),
+ base::BindLambdaForTesting(
+ [&](blink::ServiceWorkerStatusCode status,
+ ServiceWorkerFetchDispatcher::FetchEventResult result,
+ blink::mojom::FetchAPIResponsePtr response,
+ blink::mojom::ServiceWorkerStreamHandlePtr,
+ blink::mojom::ServiceWorkerFetchEventTimingPtr,
+ scoped_refptr<ServiceWorkerVersion>) {
+ fetch_status = status;
+ fetch_result = result;
+ fetch_response = std::move(response);
+ fetch_loop.Quit();
+ }),
+ /*is_offline_capability_check=*/false);
+
+ // DispatchFetchEvent is called synchronously with dispatcher->Run() even if
+ // the worker is stopped.
+ dispatcher->Run();
+ EXPECT_TRUE(is_prepare_callback_called);
+ EXPECT_FALSE(fetch_response);
+
+ // Check if the fetch event is handled by fetch_event.js correctly.
+ fetch_loop.Run();
+ ASSERT_TRUE(fetch_response);
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk, fetch_status);
+ EXPECT_EQ(ServiceWorkerFetchDispatcher::FetchEventResult::kGotResponse,
+ fetch_result);
+ EXPECT_EQ(301, fetch_response->status_code);
+}
+
+// Check if a fetch event can be failed without crashing if starting a service
+// worker fails. This is a regression test for https://crbug.com/1106977.
+IN_PROC_BROWSER_TEST_F(ServiceWorkerBrowserTest,
+ DispatchFetchEventToBrokenWorker) {
+ // Setup the server so that the test doesn't crash when tearing down.
+ StartServerAndNavigateToSetup();
+ // This test is meaningful only when ServiceWorkerOnUI is enabled.
+ if (!ServiceWorkerContext::IsServiceWorkerOnUIEnabled())
+ return;
+
+ WorkerRunningStatusObserver observer(public_context());
+ EXPECT_TRUE(NavigateToURL(shell(),
+ embedded_test_server()->GetURL(
+ "/service_worker/create_service_worker.html")));
+ EXPECT_EQ("DONE", EvalJs(shell(), "register('fetch_event.js');"));
+ observer.WaitUntilRunning();
+
+ ASSERT_TRUE(
+ BrowserThread::CurrentlyOn(ServiceWorkerContext::GetCoreThreadId()));
+ scoped_refptr<ServiceWorkerVersion> version =
+ wrapper()->GetLiveVersion(observer.version_id());
+ EXPECT_EQ(EmbeddedWorkerStatus::RUNNING, version->running_status());
+
+ {
+ base::RunLoop loop;
+ version->StopWorker(loop.QuitClosure());
+ loop.Run();
+ EXPECT_EQ(EmbeddedWorkerStatus::STOPPED, version->running_status());
+ }
+
+ // Set a non-existent resource to the version.
+ std::vector<storage::mojom::ServiceWorkerResourceRecordPtr> resources;
+ resources.push_back(storage::mojom::ServiceWorkerResourceRecord::New(
+ 123456789, version->script_url(), 100));
+ version->script_cache_map()->resource_map_.clear();
+ version->script_cache_map()->SetResources(resources);
+
+ bool is_prepare_callback_called = false;
+ base::RunLoop fetch_loop;
+ blink::ServiceWorkerStatusCode fetch_status;
+ ServiceWorkerFetchDispatcher::FetchEventResult fetch_result;
+
+ auto request = blink::mojom::FetchAPIRequest::New();
+ request->url = embedded_test_server()->GetURL("/service_worker/in-scope");
+ request->method = "GET";
+ request->is_main_resource_load = true;
+ auto dispatcher = std::make_unique<ServiceWorkerFetchDispatcher>(
+ std::move(request), blink::mojom::ResourceType::kMainFrame,
+ /*client_id=*/base::GenerateGUID(), version,
+ base::BindLambdaForTesting([&]() { is_prepare_callback_called = true; }),
+ base::BindLambdaForTesting(
+ [&](blink::ServiceWorkerStatusCode status,
+ ServiceWorkerFetchDispatcher::FetchEventResult result,
+ blink::mojom::FetchAPIResponsePtr response,
+ blink::mojom::ServiceWorkerStreamHandlePtr,
+ blink::mojom::ServiceWorkerFetchEventTimingPtr,
+ scoped_refptr<ServiceWorkerVersion>) {
+ fetch_status = status;
+ fetch_result = result;
+ fetch_loop.Quit();
+ }),
+ /*is_offline_capability_check=*/false);
+
+ // DispatchFetchEvent is called synchronously with dispatcher->Run() even if
+ // the worker is stopped.
+ dispatcher->Run();
+ EXPECT_TRUE(is_prepare_callback_called);
+
+ // Check if the fetch event fails due to error of reading the resource.
+ fetch_loop.Run();
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kErrorDiskCache, fetch_status);
+ EXPECT_EQ(ServiceWorkerFetchDispatcher::FetchEventResult::kShouldFallback,
+ fetch_result);
+
+ // Make sure that no crash happens in the remaining tasks.
+ base::RunLoop().RunUntilIdle();
+}
+
class ServiceWorkerEagerCacheStorageSetupTest
: public ServiceWorkerBrowserTest {
public:
@@ -2208,8 +2361,6 @@ class CodeCacheHostInterceptor
class CacheStorageContextForBadOrigin : public CacheStorageContextImpl {
public:
- CacheStorageContextForBadOrigin() : CacheStorageContextImpl(nullptr) {}
-
scoped_refptr<CacheStorageManager> CacheManager() override {
// The CodeCacheHostImpl should not try to access the CacheManager()
// if the origin is bad.
diff --git a/chromium/content/browser/service_worker/service_worker_cache_writer.cc b/chromium/content/browser/service_worker/service_worker_cache_writer.cc
index cb817330492..f7f15fa2400 100644
--- a/chromium/content/browser/service_worker/service_worker_cache_writer.cc
+++ b/chromium/content/browser/service_worker/service_worker_cache_writer.cc
@@ -11,6 +11,8 @@
#include "base/memory/ptr_util.h"
#include "content/browser/service_worker/service_worker_disk_cache.h"
#include "content/common/service_worker/service_worker_utils.h"
+#include "mojo/public/cpp/system/simple_watcher.h"
+#include "services/network/public/cpp/net_adapters.h"
#include "services/network/public/mojom/url_loader_factory.mojom.h"
namespace {
@@ -74,6 +76,12 @@ class ServiceWorkerCacheWriter::ReadResponseHeadCallbackAdapter
owner_->AsyncDoLoop(result);
}
+ void DidReadResponseHead(int result,
+ network::mojom::URLResponseHeadPtr response_head,
+ base::Optional<mojo_base::BigBuffer>) {
+ DidReadResponseInfo(result, std::move(response_head), nullptr);
+ }
+
void SetAsync() { async_ = true; }
int result() { return result_; }
@@ -162,6 +170,19 @@ ServiceWorkerCacheWriter::ServiceWorkerCacheWriter(
io_pending_(false),
comparing_(false),
pause_when_not_identical_(pause_when_not_identical),
+ legacy_compare_reader_(std::move(compare_reader)),
+ legacy_copy_reader_(std::move(copy_reader)),
+ writer_(std::move(writer)) {}
+
+ServiceWorkerCacheWriter::ServiceWorkerCacheWriter(
+ mojo::Remote<storage::mojom::ServiceWorkerResourceReader> compare_reader,
+ mojo::Remote<storage::mojom::ServiceWorkerResourceReader> copy_reader,
+ std::unique_ptr<ServiceWorkerResponseWriter> writer,
+ bool pause_when_not_identical)
+ : state_(STATE_START),
+ io_pending_(false),
+ comparing_(false),
+ pause_when_not_identical_(pause_when_not_identical),
compare_reader_(std::move(compare_reader)),
copy_reader_(std::move(copy_reader)),
writer_(std::move(writer)) {}
@@ -180,6 +201,18 @@ ServiceWorkerCacheWriter::CreateForCopy(
}
std::unique_ptr<ServiceWorkerCacheWriter>
+ServiceWorkerCacheWriter::CreateForCopy(
+ mojo::Remote<storage::mojom::ServiceWorkerResourceReader> copy_reader,
+ std::unique_ptr<ServiceWorkerResponseWriter> writer) {
+ DCHECK(copy_reader);
+ DCHECK(writer);
+ mojo::Remote<storage::mojom::ServiceWorkerResourceReader> null_remote;
+ return base::WrapUnique(new ServiceWorkerCacheWriter(
+ std::move(null_remote) /* compare_reader */, std::move(copy_reader),
+ std::move(writer), false /* pause_when_not_identical*/));
+}
+
+std::unique_ptr<ServiceWorkerCacheWriter>
ServiceWorkerCacheWriter::CreateForWriteBack(
std::unique_ptr<ServiceWorkerResponseWriter> writer) {
DCHECK(writer);
@@ -204,6 +237,22 @@ ServiceWorkerCacheWriter::CreateForComparison(
pause_when_not_identical));
}
+std::unique_ptr<ServiceWorkerCacheWriter>
+ServiceWorkerCacheWriter::CreateForComparison(
+ mojo::Remote<storage::mojom::ServiceWorkerResourceReader> compare_reader,
+ mojo::Remote<storage::mojom::ServiceWorkerResourceReader> copy_reader,
+ std::unique_ptr<ServiceWorkerResponseWriter> writer,
+ bool pause_when_not_identical) {
+ // |compare_reader| reads data for the comparison. |copy_reader| reads
+ // data for copy.
+ DCHECK(compare_reader);
+ DCHECK(copy_reader);
+ DCHECK(writer);
+ return base::WrapUnique(new ServiceWorkerCacheWriter(
+ std::move(compare_reader), std::move(copy_reader), std::move(writer),
+ pause_when_not_identical));
+}
+
net::Error ServiceWorkerCacheWriter::MaybeWriteHeaders(
network::mojom::URLResponseHeadPtr response_head,
OnWriteCompleteCallback callback) {
@@ -332,7 +381,8 @@ net::Error ServiceWorkerCacheWriter::StartCopy(
}
bool ServiceWorkerCacheWriter::IsCopying() const {
- return !compare_reader_ && copy_reader_;
+ return !(compare_reader_ || legacy_compare_reader_) &&
+ (copy_reader_ || legacy_copy_reader_);
}
int64_t ServiceWorkerCacheWriter::WriterResourceId() const {
@@ -342,7 +392,7 @@ int64_t ServiceWorkerCacheWriter::WriterResourceId() const {
int ServiceWorkerCacheWriter::DoStart(int result) {
bytes_written_ = 0;
- if (compare_reader_) {
+ if (compare_reader_ || legacy_compare_reader_) {
state_ = STATE_READ_HEADERS_FOR_COMPARE;
comparing_ = true;
} else if (IsCopying()) {
@@ -361,7 +411,11 @@ int ServiceWorkerCacheWriter::DoReadHeadersForCompare(int result) {
DCHECK(response_head_to_write_);
state_ = STATE_READ_HEADERS_FOR_COMPARE_DONE;
- return ReadResponseHead(compare_reader_);
+ if (compare_reader_) {
+ return ReadResponseHead(compare_reader_.get());
+ } else {
+ return ReadResponseHead(legacy_compare_reader_);
+ }
}
int ServiceWorkerCacheWriter::DoReadHeadersForCompareDone(int result) {
@@ -385,14 +439,19 @@ int ServiceWorkerCacheWriter::DoReadDataForCompare(int result) {
state_ = STATE_READ_DATA_FOR_COMPARE_DONE;
compare_offset_ = 0;
// If this was an EOF, don't issue a read.
- if (len_to_write_ > 0)
- result = ReadDataHelper(compare_reader_, data_to_read_.get(), len_to_read_);
+ if (len_to_write_ > 0) {
+ if (compare_reader_) {
+ result = ReadDataHelper(compare_reader_.get(), compare_data_pipe_reader_,
+ data_to_read_.get(), len_to_read_);
+ } else {
+ result = ReadDataHelper(legacy_compare_reader_, data_to_read_.get(),
+ len_to_read_);
+ }
+ }
return result;
}
int ServiceWorkerCacheWriter::DoReadDataForCompareDone(int result) {
- DCHECK(data_to_read_);
- DCHECK(data_to_write_);
DCHECK_EQ(len_to_read_, len_to_write_);
if (result < 0) {
@@ -411,6 +470,9 @@ int ServiceWorkerCacheWriter::DoReadDataForCompareDone(int result) {
return pause_when_not_identical_ ? net::ERR_IO_PENDING : net::OK;
}
+ DCHECK(data_to_read_);
+ DCHECK(data_to_write_);
+
// Compare the data from the ServiceWorker script cache to the data from the
// network.
if (memcmp(data_to_read_->data(), data_to_write_->data() + compare_offset_,
@@ -435,8 +497,14 @@ int ServiceWorkerCacheWriter::DoReadDataForCompareDone(int result) {
// that this reuses the same IOBuffer.
if (compare_offset_ < static_cast<size_t>(len_to_read_)) {
state_ = STATE_READ_DATA_FOR_COMPARE_DONE;
- return ReadDataHelper(compare_reader_, data_to_read_.get(),
- len_to_read_ - compare_offset_);
+ if (compare_reader_) {
+ return ReadDataHelper(compare_reader_.get(), compare_data_pipe_reader_,
+ data_to_read_.get(),
+ len_to_read_ - compare_offset_);
+ } else {
+ return ReadDataHelper(legacy_compare_reader_, data_to_read_.get(),
+ len_to_read_ - compare_offset_);
+ }
}
// Cached entry is longer than the network entry but the prefix matches. Copy
@@ -455,11 +523,15 @@ int ServiceWorkerCacheWriter::DoReadDataForCompareDone(int result) {
int ServiceWorkerCacheWriter::DoReadHeadersForCopy(int result) {
DCHECK_GE(result, 0);
- DCHECK(copy_reader_);
+ DCHECK(copy_reader_ || legacy_copy_reader_);
bytes_copied_ = 0;
data_to_copy_ = base::MakeRefCounted<net::IOBuffer>(kCopyBufferSize);
state_ = STATE_READ_HEADERS_FOR_COPY_DONE;
- return ReadResponseHead(copy_reader_);
+ if (copy_reader_) {
+ return ReadResponseHead(copy_reader_.get());
+ } else {
+ return ReadResponseHead(legacy_copy_reader_);
+ }
}
int ServiceWorkerCacheWriter::DoReadHeadersForCopyDone(int result) {
@@ -518,7 +590,12 @@ int ServiceWorkerCacheWriter::DoReadDataForCopy(int result) {
return net::OK;
}
state_ = STATE_READ_DATA_FOR_COPY_DONE;
- return ReadDataHelper(copy_reader_, data_to_copy_.get(), to_read);
+ if (copy_reader_) {
+ return ReadDataHelper(copy_reader_.get(), copy_data_pipe_reader_,
+ data_to_copy_.get(), to_read);
+ } else {
+ return ReadDataHelper(legacy_copy_reader_, data_to_copy_.get(), to_read);
+ }
}
int ServiceWorkerCacheWriter::DoReadDataForCopyDone(int result) {
@@ -592,6 +669,16 @@ int ServiceWorkerCacheWriter::DoDone(int result) {
// asynchronous completions.
int ServiceWorkerCacheWriter::ReadResponseHead(
+ storage::mojom::ServiceWorkerResourceReader* reader) {
+ auto adapter = base::MakeRefCounted<ReadResponseHeadCallbackAdapter>(
+ weak_factory_.GetWeakPtr());
+ reader->ReadResponseHead(base::BindOnce(
+ &ReadResponseHeadCallbackAdapter::DidReadResponseHead, adapter));
+ adapter->SetAsync();
+ return adapter->result();
+}
+
+int ServiceWorkerCacheWriter::ReadResponseHead(
const std::unique_ptr<ServiceWorkerResponseReader>& reader) {
auto adapter = base::MakeRefCounted<ReadResponseHeadCallbackAdapter>(
weak_factory_.GetWeakPtr());
@@ -617,6 +704,101 @@ int ServiceWorkerCacheWriter::ReadDataHelper(
return adaptor->result();
}
+class ServiceWorkerCacheWriter::DataPipeReader {
+ public:
+ DataPipeReader(storage::mojom::ServiceWorkerResourceReader* reader,
+ ServiceWorkerCacheWriter* owner,
+ scoped_refptr<base::SequencedTaskRunner> runner)
+ : reader_(reader),
+ owner_(owner),
+ watcher_(FROM_HERE, mojo::SimpleWatcher::ArmingPolicy::MANUAL, runner),
+ task_runner_(runner) {}
+
+ // Reads the body up to |num_bytes| bytes. |callback| is always called
+ // asynchronously.
+ using ReadCallback = base::OnceCallback<void(int /* result */)>;
+ void Read(net::IOBuffer* buffer, int num_bytes, ReadCallback callback) {
+ DCHECK(buffer);
+ buffer_ = buffer;
+ num_bytes_to_read_ = num_bytes;
+ callback_ = std::move(callback);
+
+ if (!data_.is_valid()) {
+ // This is the initial call of Read(). Call ReadData() to get a data pipe
+ // to read the body.
+ reader_->ReadData(
+ -1,
+ base::BindOnce(&ServiceWorkerCacheWriter::DataPipeReader::OnReadData,
+ weak_factory_.GetWeakPtr()));
+ return;
+ }
+ task_runner_->PostTask(
+ FROM_HERE,
+ base::BindOnce(&ServiceWorkerCacheWriter::DataPipeReader::ReadInternal,
+ weak_factory_.GetWeakPtr(), MOJO_RESULT_OK));
+ }
+
+ private:
+ void ReadInternal(MojoResult) {
+ MojoResult result = data_->ReadData(buffer_->data(), &num_bytes_to_read_,
+ MOJO_READ_DATA_FLAG_NONE);
+ if (result == MOJO_RESULT_SHOULD_WAIT) {
+ watcher_.ArmOrNotify();
+ return;
+ }
+ if (result != MOJO_RESULT_OK) {
+ // Disconnected means it's the end of the body or an error occurs during
+ // reading the body.
+ // TODO(https://crbug.com/1055677): notify of errors.
+ num_bytes_to_read_ = 0;
+ }
+ owner_->AsyncDoLoop(num_bytes_to_read_);
+ }
+
+ void OnReadData(mojo::ScopedDataPipeConsumerHandle data) {
+ data_ = std::move(data);
+ watcher_.Watch(data_.get(),
+ MOJO_HANDLE_SIGNAL_READABLE | MOJO_HANDLE_SIGNAL_PEER_CLOSED,
+ base::BindRepeating(
+ &ServiceWorkerCacheWriter::DataPipeReader::ReadInternal,
+ weak_factory_.GetWeakPtr()));
+ ReadInternal(MOJO_RESULT_OK);
+ }
+
+ // Parameters set on Read().
+ net::IOBuffer* buffer_ = nullptr;
+ uint32_t num_bytes_to_read_ = 0;
+ ReadCallback callback_;
+
+ // |reader_| is safe to be kept as a rawptr because |owner_| owns |this| and
+ // |reader_|, and |owner_| keeps |reader_| until it's destroyed.
+ storage::mojom::ServiceWorkerResourceReader* const reader_;
+ ServiceWorkerCacheWriter* const owner_;
+
+ // Mojo data pipe and the watcher is set up when Read() is called for the
+ // first time.
+ mojo::ScopedDataPipeConsumerHandle data_;
+ mojo::SimpleWatcher watcher_;
+ scoped_refptr<base::SequencedTaskRunner> task_runner_;
+
+ base::WeakPtrFactory<DataPipeReader> weak_factory_{this};
+};
+
+int ServiceWorkerCacheWriter::ReadDataHelper(
+ storage::mojom::ServiceWorkerResourceReader* reader,
+ std::unique_ptr<DataPipeReader>& data_pipe_reader,
+ net::IOBuffer* buf,
+ int buf_len) {
+ if (!data_pipe_reader) {
+ data_pipe_reader = std::make_unique<DataPipeReader>(
+ reader, this, base::SequencedTaskRunnerHandle::Get());
+ }
+ data_pipe_reader->Read(buf, buf_len,
+ base::BindOnce(&ServiceWorkerCacheWriter::AsyncDoLoop,
+ weak_factory_.GetWeakPtr()));
+ return net::ERR_IO_PENDING;
+}
+
int ServiceWorkerCacheWriter::WriteResponseHeadToResponseWriter(
const network::mojom::URLResponseHead& response_head,
int response_data_size) {
diff --git a/chromium/content/browser/service_worker/service_worker_cache_writer.h b/chromium/content/browser/service_worker/service_worker_cache_writer.h
index 8939d623ba6..111f902c41b 100644
--- a/chromium/content/browser/service_worker/service_worker_cache_writer.h
+++ b/chromium/content/browser/service_worker/service_worker_cache_writer.h
@@ -13,7 +13,9 @@
#include "base/callback.h"
#include "base/memory/weak_ptr.h"
+#include "components/services/storage/public/mojom/service_worker_storage_control.mojom.h"
#include "content/common/content_export.h"
+#include "mojo/public/cpp/bindings/remote.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
#include "services/network/public/mojom/url_response_head.mojom.h"
@@ -35,6 +37,12 @@ class ServiceWorkerResponseWriter;
//
// This class's behavior is modelled as a state machine; see the DoLoop function
// for comments about this.
+//
+// Note that currently we have two types of interfaces to create an instance of
+// ServiceWorkerCacheWriter: storage service and non storage service.
+// After storage service is shipped, we use Mojo connection to read and write
+// the resource.
+// See https://crbug.com/1055677 for more info.
class CONTENT_EXPORT ServiceWorkerCacheWriter {
public:
using OnWriteCompleteCallback = base::OnceCallback<void(net::Error)>;
@@ -63,9 +71,14 @@ class CONTENT_EXPORT ServiceWorkerCacheWriter {
// Create a cache writer instance that copies a script already in storage. The
// script is read by |copy_reader|.
+ // Non-storage service:
static std::unique_ptr<ServiceWorkerCacheWriter> CreateForCopy(
std::unique_ptr<ServiceWorkerResponseReader> copy_reader,
std::unique_ptr<ServiceWorkerResponseWriter> writer);
+ // Storage service:
+ static std::unique_ptr<ServiceWorkerCacheWriter> CreateForCopy(
+ mojo::Remote<storage::mojom::ServiceWorkerResourceReader> copy_reader,
+ std::unique_ptr<ServiceWorkerResponseWriter> writer);
// Create a cache writer instance that unconditionally write back data
// supplied to |MaybeWriteHeaders| and |MaybeWriteData| to storage.
@@ -82,11 +95,18 @@ class CONTENT_EXPORT ServiceWorkerCacheWriter {
// resumed later. If |pause_when_not_identical| is false, and the data is
// different, it would be written to storage directly. |copy_reader| is used
// for copying identical data blocks during writing.
+ // Non-storage service:
static std::unique_ptr<ServiceWorkerCacheWriter> CreateForComparison(
std::unique_ptr<ServiceWorkerResponseReader> compare_reader,
std::unique_ptr<ServiceWorkerResponseReader> copy_reader,
std::unique_ptr<ServiceWorkerResponseWriter> writer,
bool pause_when_not_identical);
+ // Storage service:
+ static std::unique_ptr<ServiceWorkerCacheWriter> CreateForComparison(
+ mojo::Remote<storage::mojom::ServiceWorkerResourceReader> compare_reader,
+ mojo::Remote<storage::mojom::ServiceWorkerResourceReader> copy_reader,
+ std::unique_ptr<ServiceWorkerResponseWriter> writer,
+ bool pause_when_not_identical);
~ServiceWorkerCacheWriter();
@@ -140,6 +160,7 @@ class CONTENT_EXPORT ServiceWorkerCacheWriter {
private:
class ReadResponseHeadCallbackAdapter;
+ class DataPipeReader;
friend class ServiceWorkerUpdateCheckTestUtils;
@@ -200,11 +221,18 @@ class CONTENT_EXPORT ServiceWorkerCacheWriter {
STATE_DONE,
};
+ // Non-storage service:
ServiceWorkerCacheWriter(
std::unique_ptr<ServiceWorkerResponseReader> compare_reader,
std::unique_ptr<ServiceWorkerResponseReader> copy_reader,
std::unique_ptr<ServiceWorkerResponseWriter> writer,
bool pause_when_not_identical);
+ // Storage service:
+ ServiceWorkerCacheWriter(
+ mojo::Remote<storage::mojom::ServiceWorkerResourceReader> compare_reader,
+ mojo::Remote<storage::mojom::ServiceWorkerResourceReader> copy_reader,
+ std::unique_ptr<ServiceWorkerResponseWriter> writer,
+ bool pause_when_not_identical);
// Drives this class's state machine. This function steps the state machine
// until one of:
@@ -244,11 +272,20 @@ class CONTENT_EXPORT ServiceWorkerCacheWriter {
// a) Return ERR_IO_PENDING, and schedule a callback to run the state
// machine's Run() later, or
// b) Return some other value and do not schedule a callback.
+ // Non-storage service:
int ReadResponseHead(
const std::unique_ptr<ServiceWorkerResponseReader>& reader);
int ReadDataHelper(const std::unique_ptr<ServiceWorkerResponseReader>& reader,
net::IOBuffer* buf,
int buf_len);
+ // Storage service:
+ // These are always case a) above.
+ int ReadResponseHead(storage::mojom::ServiceWorkerResourceReader* reader);
+ int ReadDataHelper(storage::mojom::ServiceWorkerResourceReader* reader,
+ std::unique_ptr<DataPipeReader>& data_pipe_reader,
+ net::IOBuffer* buf,
+ int buf_len);
+
// If no write observer is set through set_write_observer(),
// WriteResponseHead() operates the same as
// WriteResponseHeadToResponseWriter() and WriteData() operates the same as
@@ -318,8 +355,15 @@ class CONTENT_EXPORT ServiceWorkerCacheWriter {
WriteObserver* write_observer_ = nullptr;
- std::unique_ptr<ServiceWorkerResponseReader> compare_reader_;
- std::unique_ptr<ServiceWorkerResponseReader> copy_reader_;
+ // Non-storage service:
+ std::unique_ptr<ServiceWorkerResponseReader> legacy_compare_reader_;
+ std::unique_ptr<ServiceWorkerResponseReader> legacy_copy_reader_;
+ // Storage service:
+ mojo::Remote<storage::mojom::ServiceWorkerResourceReader> compare_reader_;
+ std::unique_ptr<DataPipeReader> compare_data_pipe_reader_;
+ mojo::Remote<storage::mojom::ServiceWorkerResourceReader> copy_reader_;
+ std::unique_ptr<DataPipeReader> copy_data_pipe_reader_;
+
std::unique_ptr<ServiceWorkerResponseWriter> writer_;
base::WeakPtrFactory<ServiceWorkerCacheWriter> weak_factory_{this};
};
diff --git a/chromium/content/browser/service_worker/service_worker_cache_writer_unittest.cc b/chromium/content/browser/service_worker/service_worker_cache_writer_unittest.cc
index b3e1810b360..1a8da42fd24 100644
--- a/chromium/content/browser/service_worker/service_worker_cache_writer_unittest.cc
+++ b/chromium/content/browser/service_worker/service_worker_cache_writer_unittest.cc
@@ -14,6 +14,7 @@
#include "base/containers/queue.h"
#include "base/memory/ptr_util.h"
#include "base/stl_util.h"
+#include "base/test/task_environment.h"
#include "content/browser/service_worker/service_worker_disk_cache.h"
#include "content/browser/service_worker/service_worker_test_utils.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -111,19 +112,24 @@ class ServiceWorkerCacheWriterTest : public ::testing::Test {
}
protected:
+ base::test::SingleThreadTaskEnvironment task_environment_;
std::list<std::unique_ptr<MockServiceWorkerResponseReader>> readers_;
std::list<std::unique_ptr<MockServiceWorkerResponseWriter>> writers_;
std::unique_ptr<ServiceWorkerCacheWriter> cache_writer_;
bool write_complete_ = false;
net::Error last_error_;
- std::unique_ptr<ServiceWorkerResponseReader> CreateReader() {
+ mojo::Remote<storage::mojom::ServiceWorkerResourceReader> CreateReader() {
+ mojo::Remote<storage::mojom::ServiceWorkerResourceReader> remote;
if (readers_.empty())
- return base::WrapUnique<ServiceWorkerResponseReader>(nullptr);
- std::unique_ptr<ServiceWorkerResponseReader> reader(
- std::move(readers_.front()));
+ return remote;
+ auto* reader_rawptr = readers_.front().get();
+ remote.Bind(reader_rawptr->BindNewPipeAndPassRemote(
+ // Keep the instance alive until the connection is destroyed.
+ base::BindOnce([](std::unique_ptr<MockServiceWorkerResponseReader>) {},
+ std::move(readers_.front()))));
readers_.pop_front();
- return reader;
+ return remote;
}
std::unique_ptr<ServiceWorkerResponseWriter> CreateWriter() {
@@ -151,15 +157,18 @@ class ServiceWorkerCacheWriterTest : public ::testing::Test {
response_head->headers = base::MakeRefCounted<net::HttpResponseHeaders>(
std::string(data, base::size(data)));
response_head->content_length = len;
- return cache_writer_->MaybeWriteHeaders(std::move(response_head),
- CreateWriteCallback());
+ net::Error error = cache_writer_->MaybeWriteHeaders(
+ std::move(response_head), CreateWriteCallback());
+ return error;
}
net::Error WriteData(const std::string& data) {
scoped_refptr<net::IOBuffer> buf =
base::MakeRefCounted<net::StringIOBuffer>(data);
- return cache_writer_->MaybeWriteData(buf.get(), data.size(),
- CreateWriteCallback());
+ net::Error error = cache_writer_->MaybeWriteData(buf.get(), data.size(),
+ CreateWriteCallback());
+ base::RunLoop().RunUntilIdle();
+ return error;
}
private:
@@ -322,134 +331,6 @@ TEST_F(ServiceWorkerCacheWriterTest, PassthroughDataFailAsync) {
// For the Compare* tests below, the ServiceWorkerCacheWriter under test has a
// reader for an existing cached response, so it will compare the response being
// written to it against the existing cached response.
-
-TEST_F(ServiceWorkerCacheWriterTest, CompareHeadersSync) {
- size_t response_size = 3;
- MockServiceWorkerResponseWriter* writer = ExpectWriter();
- MockServiceWorkerResponseReader* reader = ExpectReader();
-
- // Create a copy reader as it's needed to create cache writer for comparison
- // though not used in this test.
- ExpectReader();
-
- reader->ExpectReadInfoOk(response_size, false);
- Initialize(CacheWriterUsage::kForComparison,
- false /* pause_when_not_identical */);
-
- net::Error error = WriteHeaders(response_size);
- EXPECT_EQ(net::OK, error);
- EXPECT_TRUE(writer->AllExpectedWritesDone());
- EXPECT_TRUE(reader->AllExpectedReadsDone());
-}
-
-TEST_F(ServiceWorkerCacheWriterTest, CompareDataOkSync) {
- const std::string data1 = "abcdef";
- size_t response_size = data1.size();
-
- MockServiceWorkerResponseWriter* writer = ExpectWriter();
- MockServiceWorkerResponseReader* reader = ExpectReader();
-
- // Create a copy reader as it's needed to create cache writer for comparison
- // though not used in this test.
- ExpectReader();
-
- reader->ExpectReadInfoOk(response_size, false);
- reader->ExpectReadDataOk(data1, false);
- Initialize(CacheWriterUsage::kForComparison,
- false /* pause_when_not_identical */);
-
- net::Error error = WriteHeaders(response_size);
- EXPECT_EQ(net::OK, error);
-
- error = WriteData(data1);
- EXPECT_EQ(net::OK, error);
-
- EXPECT_TRUE(writer->AllExpectedWritesDone());
- EXPECT_TRUE(reader->AllExpectedReadsDone());
- EXPECT_EQ(0U, cache_writer_->bytes_written());
-}
-
-TEST_F(ServiceWorkerCacheWriterTest, CompareHeadersFailSync) {
- size_t response_size = 3;
- MockServiceWorkerResponseWriter* writer = ExpectWriter();
- MockServiceWorkerResponseReader* reader = ExpectReader();
-
- // Create a copy reader as it's needed to create cache writer for comparison
- // though not used in this test.
- ExpectReader();
-
- reader->ExpectReadInfo(response_size, false, net::ERR_FAILED);
- Initialize(CacheWriterUsage::kForComparison,
- false /* pause_when_not_identical */);
-
- EXPECT_EQ(net::ERR_FAILED, WriteHeaders(response_size));
- EXPECT_TRUE(writer->AllExpectedWritesDone());
- EXPECT_TRUE(reader->AllExpectedReadsDone());
-}
-
-TEST_F(ServiceWorkerCacheWriterTest, CompareDataFailSync) {
- const std::string data1 = "abcdef";
- size_t response_size = data1.size();
-
- MockServiceWorkerResponseWriter* writer = ExpectWriter();
- MockServiceWorkerResponseReader* reader = ExpectReader();
-
- // Create a copy reader as it's needed to create cache writer for comparison
- // though not used in this test.
- ExpectReader();
-
- reader->ExpectReadInfoOk(response_size, false);
- reader->ExpectReadData(data1.c_str(), data1.length(), false, net::ERR_FAILED);
- Initialize(CacheWriterUsage::kForComparison,
- false /* pause_when_not_identical */);
-
- net::Error error = WriteHeaders(response_size);
- EXPECT_EQ(net::OK, error);
-
- EXPECT_EQ(net::ERR_FAILED, WriteData(data1));
-
- EXPECT_TRUE(writer->AllExpectedWritesDone());
- EXPECT_TRUE(reader->AllExpectedReadsDone());
- EXPECT_EQ(0U, cache_writer_->bytes_written());
-}
-
-TEST_F(ServiceWorkerCacheWriterTest, CompareShortCacheReads) {
- const size_t kHeaderSize = 16;
- const std::string& data1 = "abcdef";
- const std::string& cache_data2 = "ghi";
- const std::string& cache_data3 = "j";
- const std::string& cache_data4 = "kl";
- const std::string& net_data2 = "ghijkl";
- const std::string& data5 = "mnopqrst";
-
- MockServiceWorkerResponseReader* reader = ExpectReader();
- reader->ExpectReadInfo(kHeaderSize, false, kHeaderSize);
- reader->ExpectReadDataOk(data1, false);
- reader->ExpectReadDataOk(cache_data2, false);
- reader->ExpectReadDataOk(cache_data3, false);
- reader->ExpectReadDataOk(cache_data4, false);
- reader->ExpectReadDataOk(data5, false);
-
- // Create a copy reader and writer as they're needed to create cache writer
- // for comparison though not used in this test.
- ExpectReader();
- ExpectWriter();
-
- Initialize(CacheWriterUsage::kForComparison,
- false /* pause_when_not_identical */);
-
- net::Error error = WriteHeaders(kHeaderSize);
- EXPECT_EQ(net::OK, error);
- error = WriteData(data1);
- EXPECT_EQ(net::OK, error);
- error = WriteData(net_data2);
- EXPECT_EQ(net::OK, error);
- error = WriteData(data5);
- EXPECT_EQ(net::OK, error);
- EXPECT_TRUE(reader->AllExpectedReadsDone());
- EXPECT_EQ(0U, cache_writer_->bytes_written());
-}
-
TEST_F(ServiceWorkerCacheWriterTest, CompareDataOkAsync) {
const std::string data1 = "abcdef";
size_t response_size = data1.size();
@@ -461,8 +342,8 @@ TEST_F(ServiceWorkerCacheWriterTest, CompareDataOkAsync) {
ExpectReader();
ExpectWriter();
- reader->ExpectReadInfoOk(response_size, true);
- reader->ExpectReadDataOk(data1, true);
+ reader->ExpectReadInfoOk(response_size);
+ reader->ExpectReadDataOk(data1);
Initialize(CacheWriterUsage::kForComparison,
false /* pause_when_not_identical */);
@@ -486,8 +367,8 @@ TEST_F(ServiceWorkerCacheWriterTest, CompareDataManyOkAsync) {
"stuvwxyz",
};
size_t response_size = 0;
- for (size_t i = 0; i < base::size(expected_data); ++i)
- response_size += expected_data[i].size();
+ for (const auto& chunk : expected_data)
+ response_size += chunk.size();
MockServiceWorkerResponseReader* reader = ExpectReader();
@@ -496,9 +377,9 @@ TEST_F(ServiceWorkerCacheWriterTest, CompareDataManyOkAsync) {
ExpectReader();
ExpectWriter();
- reader->ExpectReadInfoOk(response_size, true);
- for (size_t i = 0; i < base::size(expected_data); ++i) {
- reader->ExpectReadDataOk(expected_data[i], true);
+ reader->ExpectReadInfoOk(response_size);
+ for (const auto& chunk : expected_data) {
+ reader->ExpectReadDataOk(chunk);
}
Initialize(CacheWriterUsage::kForComparison,
false /* pause_when_not_identical */);
@@ -507,8 +388,8 @@ TEST_F(ServiceWorkerCacheWriterTest, CompareDataManyOkAsync) {
EXPECT_EQ(net::ERR_IO_PENDING, error);
reader->CompletePendingRead();
- for (size_t i = 0; i < base::size(expected_data); ++i) {
- error = WriteData(expected_data[i]);
+ for (const auto& chunk : expected_data) {
+ error = WriteData(chunk);
EXPECT_EQ(net::ERR_IO_PENDING, error);
reader->CompletePendingRead();
EXPECT_EQ(net::OK, last_error_);
@@ -534,12 +415,12 @@ TEST_F(ServiceWorkerCacheWriterTest, CompareFailedCopySync) {
MockServiceWorkerResponseReader* compare_reader = ExpectReader();
MockServiceWorkerResponseReader* copy_reader = ExpectReader();
- compare_reader->ExpectReadInfoOk(cache_response_size, false);
- compare_reader->ExpectReadDataOk(data1, false);
- compare_reader->ExpectReadDataOk(cache_data2, false);
+ compare_reader->ExpectReadInfoOk(cache_response_size);
+ compare_reader->ExpectReadDataOk(data1);
+ compare_reader->ExpectReadDataOk(cache_data2);
- copy_reader->ExpectReadInfoOk(cache_response_size, false);
- copy_reader->ExpectReadDataOk(data1, false);
+ copy_reader->ExpectReadInfoOk(cache_response_size);
+ copy_reader->ExpectReadDataOk(data1);
writer->ExpectWriteInfoOk(net_response_size, false);
writer->ExpectWriteDataOk(data1.size(), false);
@@ -550,11 +431,25 @@ TEST_F(ServiceWorkerCacheWriterTest, CompareFailedCopySync) {
false /* pause_when_not_identical */);
net::Error error = WriteHeaders(net_response_size);
- EXPECT_EQ(net::OK, error);
+ EXPECT_EQ(net::ERR_IO_PENDING, error);
+ compare_reader->CompletePendingRead();
+ EXPECT_EQ(net::OK, last_error_);
+
error = WriteData(data1);
- EXPECT_EQ(net::OK, error);
+ EXPECT_EQ(net::ERR_IO_PENDING, error);
+ compare_reader->CompletePendingRead();
+ EXPECT_EQ(net::OK, last_error_);
+
error = WriteData(net_data2);
- EXPECT_EQ(net::OK, error);
+ EXPECT_EQ(net::ERR_IO_PENDING, error);
+ compare_reader->CompletePendingRead();
+
+ // At this point, |copy_reader| is asked to read the header and data1.
+ copy_reader->CompletePendingRead();
+ copy_reader->CompletePendingRead();
+ EXPECT_EQ(net::OK, last_error_);
+
+ // |data3| goes directly to the response writer.
error = WriteData(data3);
EXPECT_EQ(net::OK, error);
@@ -576,13 +471,13 @@ TEST_F(ServiceWorkerCacheWriterTest, CompareFailedCopyShort) {
MockServiceWorkerResponseReader* compare_reader = ExpectReader();
MockServiceWorkerResponseReader* copy_reader = ExpectReader();
- compare_reader->ExpectReadInfoOk(cache_response_size, false);
- compare_reader->ExpectReadDataOk(data1, false);
- compare_reader->ExpectReadDataOk(cache_data2, false);
- compare_reader->ExpectReadDataOk("", false); // EOF read
+ compare_reader->ExpectReadInfoOk(cache_response_size);
+ compare_reader->ExpectReadDataOk(data1);
+ compare_reader->ExpectReadDataOk(cache_data2);
+ compare_reader->ExpectReadDataOk(""); // EOF read
- copy_reader->ExpectReadInfoOk(cache_response_size, false);
- copy_reader->ExpectReadDataOk(data1, false);
+ copy_reader->ExpectReadInfoOk(cache_response_size);
+ copy_reader->ExpectReadDataOk(data1);
writer->ExpectWriteInfoOk(net_response_size, false);
writer->ExpectWriteDataOk(data1.size(), false);
@@ -593,12 +488,30 @@ TEST_F(ServiceWorkerCacheWriterTest, CompareFailedCopyShort) {
false /* pause_when_not_identical */);
net::Error error = WriteHeaders(net_response_size);
- EXPECT_EQ(net::OK, error);
+ EXPECT_EQ(net::ERR_IO_PENDING, error);
+ // Read the header from |compare_reader|.
+ compare_reader->CompletePendingRead();
+ EXPECT_EQ(net::OK, last_error_);
+
error = WriteData(data1);
- EXPECT_EQ(net::OK, error);
+ EXPECT_EQ(net::ERR_IO_PENDING, error);
+ // Read |data1| from |compare_reader| for the comparison.
+ compare_reader->CompletePendingRead();
+ EXPECT_EQ(net::OK, last_error_);
+
error = WriteData(net_data2);
- EXPECT_EQ(net::OK, error);
+ EXPECT_EQ(net::ERR_IO_PENDING, error);
+ // Read |cache_data2| and |data3| from |compare_reader|.
+ compare_reader->CompletePendingRead();
+ compare_reader->CompletePendingRead();
+ // After that, the cache writer uses |copy_reader| to read the header and
+ // |data1|.
+ copy_reader->CompletePendingRead();
+ copy_reader->CompletePendingRead();
+ EXPECT_EQ(net::OK, last_error_);
+
error = WriteData(data3);
+ // |data3| is directly written to the disk.
EXPECT_EQ(net::OK, error);
EXPECT_TRUE(writer->AllExpectedWritesDone());
@@ -619,16 +532,16 @@ TEST_F(ServiceWorkerCacheWriterTest, CompareFailedCopyLong) {
MockServiceWorkerResponseReader* compare_reader = ExpectReader();
MockServiceWorkerResponseReader* copy_reader = ExpectReader();
- compare_reader->ExpectReadInfoOk(cached_size, false);
- compare_reader->ExpectReadDataOk(data1, false);
- compare_reader->ExpectReadDataOk(cache_data2, false);
+ compare_reader->ExpectReadInfoOk(cached_size);
+ compare_reader->ExpectReadDataOk(data1);
+ compare_reader->ExpectReadDataOk(cache_data2);
// The comparison should fail at the end of |cache_data2|, when the cache
// writer realizes the two responses are different sizes, and then the network
// data should be written back starting with |net_data2|.
- copy_reader->ExpectReadInfoOk(cached_size, false);
- copy_reader->ExpectReadDataOk(data1, false);
- copy_reader->ExpectReadDataOk(net_data2, false);
+ copy_reader->ExpectReadInfoOk(cached_size);
+ copy_reader->ExpectReadDataOk(data1);
+ copy_reader->ExpectReadDataOk(net_data2);
writer->ExpectWriteInfoOk(net_size, false);
writer->ExpectWriteDataOk(data1.size(), false);
@@ -638,13 +551,33 @@ TEST_F(ServiceWorkerCacheWriterTest, CompareFailedCopyLong) {
false /* pause_when_not_identical */);
net::Error error = WriteHeaders(net_size);
- EXPECT_EQ(net::OK, error);
+ EXPECT_EQ(net::ERR_IO_PENDING, error);
+ // Read the header from |compare_reader| for the comparison.
+ compare_reader->CompletePendingRead();
+ EXPECT_EQ(net::OK, last_error_);
+
error = WriteData(data1);
- EXPECT_EQ(net::OK, error);
+ EXPECT_EQ(net::ERR_IO_PENDING, error);
+ // Read |data1| from |compare_reader| for the comparison.
+ compare_reader->CompletePendingRead();
+ EXPECT_EQ(net::OK, last_error_);
+
error = WriteData(net_data2);
- EXPECT_EQ(net::OK, error);
+ EXPECT_EQ(net::ERR_IO_PENDING, error);
+ // Read |cache_data2| from |compare_reader| for the comparison.
+ compare_reader->CompletePendingRead();
+ EXPECT_EQ(net::OK, last_error_);
+
error = WriteData("");
- EXPECT_EQ(net::OK, error);
+ EXPECT_EQ(net::ERR_IO_PENDING, error);
+ // Diff is found and copying starts.
+ // Read the header from |copy_reader|.
+ copy_reader->CompletePendingRead();
+ // Read |data1| from |copy_reader| to copy.
+ copy_reader->CompletePendingRead();
+ // Read |net_data_2| from |copy_reader|.
+ copy_reader->CompletePendingRead();
+ EXPECT_EQ(net::OK, last_error_);
EXPECT_TRUE(writer->AllExpectedWritesDone());
EXPECT_TRUE(compare_reader->AllExpectedReadsDone());
@@ -686,13 +619,13 @@ TEST_F(ServiceWorkerCacheWriterTest, MultipleComparisonInSingleWrite) {
MockServiceWorkerResponseReader* compare_reader = ExpectReader();
MockServiceWorkerResponseReader* copy_reader = ExpectReader();
- compare_reader->ExpectReadInfoOk(bytes_cached, false);
+ compare_reader->ExpectReadInfoOk(bytes_cached);
for (const auto& data : data_from_cache)
- compare_reader->ExpectReadDataOk(data, false);
+ compare_reader->ExpectReadDataOk(data);
- copy_reader->ExpectReadInfoOk(bytes_common, false);
+ copy_reader->ExpectReadInfoOk(bytes_common);
for (const auto& data : data_to_copy)
- copy_reader->ExpectReadDataOk(data, false);
+ copy_reader->ExpectReadDataOk(data);
writer->ExpectWriteInfoOk(bytes_from_net, false);
for (const auto& data : data_expected)
@@ -702,82 +635,30 @@ TEST_F(ServiceWorkerCacheWriterTest, MultipleComparisonInSingleWrite) {
false /* pause_when_not_identical */);
net::Error error = WriteHeaders(bytes_from_net);
- EXPECT_EQ(net::OK, error);
+ EXPECT_EQ(net::ERR_IO_PENDING, error);
+ // Read the header from |compare_reader| for the comparison.
+ compare_reader->CompletePendingRead();
+ EXPECT_EQ(net::OK, last_error_);
+
for (const auto& data : data_from_net) {
error = WriteData(data);
- EXPECT_EQ(net::OK, error);
+ EXPECT_EQ(net::ERR_IO_PENDING, error);
+ for (size_t i = 0; i < data.size(); ++i) {
+ // Read the body from |compare_reader|. Repeat data.size() times because
+ // each chunk in |data_from_cache| is 1 byte.
+ compare_reader->CompletePendingRead();
+ EXPECT_EQ(net::OK, last_error_);
+ }
}
- EXPECT_TRUE(writer->AllExpectedWritesDone());
- EXPECT_TRUE(compare_reader->AllExpectedReadsDone());
- EXPECT_TRUE(copy_reader->AllExpectedReadsDone());
-}
-
-// Tests behavior when |pause_when_not_identical| is enabled and cache writer
-// finishes synchronously.
-TEST_F(ServiceWorkerCacheWriterTest, PauseWhenNotIdentical_SyncWriteData) {
- // Data from |compare_reader|.
- const std::vector<std::string> data_from_cache{"abcd"};
-
- // Data for |writer|. The comparison should stop at the first block of the
- // data.
- const std::vector<std::string> data_from_net{"abxx"};
-
- // We don't need |data_to_copy| because the network data and the cached data
- // have no common blocks.
-
- // The written data should be the same as |data_from_net|.
- const std::vector<std::string> data_expected{"abxx"};
-
- size_t bytes_cached = 0;
- size_t bytes_from_net = 0;
- size_t bytes_expected = 0;
-
- for (const auto& data : data_from_cache)
- bytes_cached += data.size();
-
- for (const auto& data : data_from_net)
- bytes_from_net += data.size();
-
- for (const auto& data : data_expected)
- bytes_expected += data.size();
-
- MockServiceWorkerResponseWriter* writer = ExpectWriter();
- MockServiceWorkerResponseReader* compare_reader = ExpectReader();
- MockServiceWorkerResponseReader* copy_reader = ExpectReader();
-
- compare_reader->ExpectReadInfoOk(bytes_cached, false);
- for (const auto& data : data_from_cache)
- compare_reader->ExpectReadDataOk(data, false);
-
- copy_reader->ExpectReadInfoOk(bytes_cached, false);
-
- writer->ExpectWriteInfoOk(bytes_expected, false);
- for (const auto& data : data_expected)
- writer->ExpectWriteDataOk(data.size(), false);
-
- Initialize(CacheWriterUsage::kForComparison,
- true /* pause_when_not_identical */);
-
- net::Error error = WriteHeaders(bytes_from_net);
- EXPECT_EQ(net::OK, error);
-
- // |cache_writer_| stops the comparison at the first block of the data.
- // It should return net::ERR_IO_PENDING and |write_complete_| should remain
- // false since |pause_when_not_identical| forbids proceeding to the next step.
- write_complete_ = false;
- error = WriteData(data_from_net[0]);
- EXPECT_EQ(net::ERR_IO_PENDING, error);
- EXPECT_FALSE(write_complete_);
- EXPECT_EQ(0U, cache_writer_->bytes_written());
+ // At the end of the chunk, there's a diff so the header and a chunk of body
+ // is read from |copy_reader|. Read the header from |compare_reader|.
+ copy_reader->CompletePendingRead();
+ EXPECT_EQ(net::OK, last_error_);
- // Resume |cache_writer_| with a callback. The passed callback shouldn't be
- // called because this is a synchronous write. This time, the result should be
- // net::OK and the expected data should be written to the storage.
- error =
- cache_writer_->Resume(base::BindOnce([](net::Error) { NOTREACHED(); }));
- EXPECT_EQ(net::OK, error);
- EXPECT_EQ(bytes_expected, cache_writer_->bytes_written());
+ // Read the first chunk from |compare_reader|.
+ copy_reader->CompletePendingRead();
+ EXPECT_EQ(net::OK, last_error_);
EXPECT_TRUE(writer->AllExpectedWritesDone());
EXPECT_TRUE(compare_reader->AllExpectedReadsDone());
@@ -817,11 +698,11 @@ TEST_F(ServiceWorkerCacheWriterTest, PauseWhenNotIdentical_AsyncWriteData) {
MockServiceWorkerResponseReader* compare_reader = ExpectReader();
MockServiceWorkerResponseReader* copy_reader = ExpectReader();
- compare_reader->ExpectReadInfoOk(bytes_cached, true);
+ compare_reader->ExpectReadInfoOk(bytes_cached);
for (const auto& data : data_from_cache)
- compare_reader->ExpectReadDataOk(data, true);
+ compare_reader->ExpectReadDataOk(data);
- copy_reader->ExpectReadInfoOk(bytes_cached, true);
+ copy_reader->ExpectReadInfoOk(bytes_cached);
writer->ExpectWriteInfoOk(bytes_expected, true);
for (const auto& data : data_expected)
@@ -906,9 +787,9 @@ TEST_F(ServiceWorkerCacheWriterTest, CopyScript_Async) {
MockServiceWorkerResponseWriter* writer = ExpectWriter();
MockServiceWorkerResponseReader* copy_reader = ExpectReader();
- copy_reader->ExpectReadInfoOk(bytes_cached, true);
+ copy_reader->ExpectReadInfoOk(bytes_cached);
for (const auto& data : data_from_cache)
- copy_reader->ExpectReadDataOk(data, true);
+ copy_reader->ExpectReadDataOk(data);
writer->ExpectWriteInfoOk(bytes_expected, true);
for (const auto& data : data_expected)
@@ -968,9 +849,9 @@ TEST_F(ServiceWorkerCacheWriterTest, CopyScript_AsyncMultipleRead) {
MockServiceWorkerResponseWriter* writer = ExpectWriter();
MockServiceWorkerResponseReader* copy_reader = ExpectReader();
- copy_reader->ExpectReadInfoOk(bytes_cached, true);
+ copy_reader->ExpectReadInfoOk(bytes_cached);
for (const auto& data : data_from_cache)
- copy_reader->ExpectReadDataOk(data, true);
+ copy_reader->ExpectReadDataOk(data);
writer->ExpectWriteInfoOk(bytes_expected, true);
for (const auto& data : data_expected)
@@ -1029,86 +910,6 @@ TEST_F(ServiceWorkerCacheWriterTest, CopyScript_AsyncMultipleRead) {
EXPECT_TRUE(writer->AllExpectedWritesDone());
}
-// Tests behavior of a cache writer used to copy script which finishes
-// synchronously.
-TEST_F(ServiceWorkerCacheWriterTest, CopyScript_Sync) {
- // Data from |copy_reader|.
- const std::vector<std::string> data_from_cache{"abcd"};
-
- // The written data should be the same as |data_from_cache|.
- const std::vector<std::string> data_expected{"abcd"};
-
- size_t bytes_cached = 0;
- size_t bytes_expected = 0;
-
- for (const auto& data : data_from_cache)
- bytes_cached += data.size();
-
- for (const auto& data : data_expected)
- bytes_expected += data.size();
-
- MockServiceWorkerResponseWriter* writer = ExpectWriter();
- MockServiceWorkerResponseReader* copy_reader = ExpectReader();
-
- copy_reader->ExpectReadInfoOk(bytes_cached, false);
- for (const auto& data : data_from_cache)
- copy_reader->ExpectReadDataOk(data, false);
-
- writer->ExpectWriteInfoOk(bytes_expected, false);
- for (const auto& data : data_expected)
- writer->ExpectWriteDataOk(data.size(), false);
-
- Initialize(CacheWriterUsage::kForCopy, false /* pause_when_not_identical */);
-
- net::Error error = cache_writer_->StartCopy(CreateWriteCallback());
-
- // In synchronous read and write, everything finishes synchronously.
- EXPECT_EQ(net::OK, error);
- EXPECT_EQ(bytes_expected, cache_writer_->bytes_written());
- EXPECT_TRUE(copy_reader->AllExpectedReadsDone());
- EXPECT_TRUE(writer->AllExpectedWritesDone());
-}
-
-// Tests behavior of a cache writer used to copy script that read multiple
-// times and finishes synchronously.
-TEST_F(ServiceWorkerCacheWriterTest, CopyScript_SyncMultiRead) {
- // Data from |copy_reader|.
- const std::vector<std::string> data_from_cache{"a", "bc", "d"};
-
- // The written data should be the same as |data_from_cache|.
- const std::vector<std::string> data_expected{"a", "bc", "d"};
-
- size_t bytes_cached = 0;
- size_t bytes_expected = 0;
-
- for (const auto& data : data_from_cache)
- bytes_cached += data.size();
-
- for (const auto& data : data_expected)
- bytes_expected += data.size();
-
- MockServiceWorkerResponseWriter* writer = ExpectWriter();
- MockServiceWorkerResponseReader* copy_reader = ExpectReader();
-
- copy_reader->ExpectReadInfoOk(bytes_cached, false);
- for (const auto& data : data_from_cache)
- copy_reader->ExpectReadDataOk(data, false);
-
- writer->ExpectWriteInfoOk(bytes_expected, false);
- for (const auto& data : data_expected)
- writer->ExpectWriteDataOk(data.size(), false);
-
- Initialize(CacheWriterUsage::kForCopy, false /* pause_when_not_identical */);
-
- net::Error error = cache_writer_->StartCopy(CreateWriteCallback());
-
- // In synchronous read and write, everything finishes synchronously.
- EXPECT_EQ(net::OK, error);
- EXPECT_EQ(bytes_expected, cache_writer_->bytes_written());
- EXPECT_TRUE(copy_reader->AllExpectedReadsDone());
- EXPECT_TRUE(writer->AllExpectedWritesDone());
-}
-
// The observer and the response writer all run synchronously.
TEST_F(ServiceWorkerCacheWriterTest, ObserverSyncResponseWriterSync) {
const size_t kHeaderSize = 16;
diff --git a/chromium/content/browser/service_worker/service_worker_client_info.cc b/chromium/content/browser/service_worker/service_worker_client_info.cc
deleted file mode 100644
index 54e413c3e3b..00000000000
--- a/chromium/content/browser/service_worker/service_worker_client_info.cc
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2018 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/browser/service_worker/service_worker_client_info.h"
-
-namespace content {
-
-ServiceWorkerClientInfo::ServiceWorkerClientInfo(
- blink::mojom::ServiceWorkerClientType type,
- int frame_tree_node_id)
- : type(type), frame_tree_node_id(frame_tree_node_id) {
- DCHECK_NE(type, blink::mojom::ServiceWorkerClientType::kAll);
-}
-
-ServiceWorkerClientInfo::ServiceWorkerClientInfo(
- const ServiceWorkerClientInfo& other) = default;
-
-ServiceWorkerClientInfo::~ServiceWorkerClientInfo() = default;
-
-} // namespace content
diff --git a/chromium/content/browser/service_worker/service_worker_client_info.h b/chromium/content/browser/service_worker/service_worker_client_info.h
deleted file mode 100644
index 2f7353e6da5..00000000000
--- a/chromium/content/browser/service_worker/service_worker_client_info.h
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2018 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_CLIENT_INFO_H_
-#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_CLIENT_INFO_H_
-
-#include "content/common/content_export.h"
-#include "third_party/blink/public/mojom/service_worker/service_worker_client.mojom.h"
-
-namespace content {
-
-// Holds information about a single service worker client:
-// https://w3c.github.io/ServiceWorker/#client
-struct CONTENT_EXPORT ServiceWorkerClientInfo {
- ServiceWorkerClientInfo(blink::mojom::ServiceWorkerClientType type,
- int frame_tree_node_id);
- ServiceWorkerClientInfo(const ServiceWorkerClientInfo& other);
- ~ServiceWorkerClientInfo();
-
- // The client type.
- blink::mojom::ServiceWorkerClientType type;
-
- int frame_tree_node_id;
-};
-
-} // namespace content
-
-#endif // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_CLIENT_INFO_H_
diff --git a/chromium/content/browser/service_worker/service_worker_client_utils.cc b/chromium/content/browser/service_worker/service_worker_client_utils.cc
index 52933cd0851..bf55bcf7e6d 100644
--- a/chromium/content/browser/service_worker/service_worker_client_utils.cc
+++ b/chromium/content/browser/service_worker/service_worker_client_utils.cc
@@ -293,7 +293,7 @@ void NavigateClientOnUI(const GURL& url,
// navigation. Not rejecting it would allow websites to prevent the user from
// navigating away. See https://crbug.com/930154.
NavigationRequest* ongoing_navigation_request =
- rfhi->frame_tree_node()->frame_tree()->root()->navigation_request();
+ rfhi->frame_tree()->root()->navigation_request();
if (ongoing_navigation_request &&
ongoing_navigation_request->browser_initiated()) {
RunOrPostTaskOnThread(
@@ -304,8 +304,8 @@ void NavigateClientOnUI(const GURL& url,
}
int frame_tree_node_id = rfhi->frame_tree_node()->frame_tree_node_id();
- Navigator* navigator = rfhi->frame_tree_node()->navigator();
- navigator->RequestOpenURL(
+ Navigator& navigator = rfhi->frame_tree_node()->navigator();
+ navigator.RequestOpenURL(
rfhi, url, GlobalFrameRoutingId() /* initiator_routing_id */,
url::Origin::Create(script_url), nullptr /* post_body */,
std::string() /* extra_headers */,
@@ -535,8 +535,8 @@ void DidGetExecutionReadyClient(
std::move(info));
} else {
- base::PostTaskAndReplyWithResult(
- FROM_HERE, {BrowserThread::UI},
+ GetUIThreadTaskRunner({})->PostTaskAndReplyWithResult(
+ FROM_HERE,
base::BindOnce(&GetWindowClientInfoOnUI, container_host->process_id(),
container_host->frame_id(),
container_host->create_time(),
@@ -559,8 +559,8 @@ void FocusWindowClient(ServiceWorkerContainerHost* container_host,
container_host->create_time(), container_host->client_uuid());
std::move(callback).Run(std::move(info));
} else {
- base::PostTaskAndReplyWithResult(
- FROM_HERE, {BrowserThread::UI},
+ GetUIThreadTaskRunner({})->PostTaskAndReplyWithResult(
+ FROM_HERE,
base::BindOnce(&FocusOnUI, container_host->process_id(),
container_host->frame_id(),
container_host->create_time(),
diff --git a/chromium/content/browser/service_worker/service_worker_container_host.cc b/chromium/content/browser/service_worker/service_worker_container_host.cc
index ba6f1e4dcad..69ea2e43fff 100644
--- a/chromium/content/browser/service_worker/service_worker_container_host.cc
+++ b/chromium/content/browser/service_worker/service_worker_container_host.cc
@@ -20,6 +20,7 @@
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/common/content_navigation_policy.h"
#include "content/common/service_worker/service_worker_utils.h"
+#include "content/public/browser/global_routing_id.h"
#include "content/public/common/content_client.h"
#include "content/public/common/origin_util.h"
#include "mojo/public/cpp/bindings/callback_helpers.h"
@@ -102,8 +103,7 @@ ServiceWorkerContainerHost::ServiceWorkerContainerHost(
client_uuid_(base::GenerateGUID()),
is_parent_frame_secure_(is_parent_frame_secure),
container_(std::move(container_remote)),
- client_type_(blink::mojom::ServiceWorkerClientType::kWindow),
- frame_tree_node_id_(frame_tree_node_id) {
+ client_info_(frame_tree_node_id) {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
DCHECK(IsContainerForWindowClient());
DCHECK(context_);
@@ -115,17 +115,13 @@ ServiceWorkerContainerHost::ServiceWorkerContainerHost(
int process_id,
mojo::PendingAssociatedRemote<blink::mojom::ServiceWorkerContainer>
container_remote,
- blink::mojom::ServiceWorkerClientType client_type,
- DedicatedWorkerId dedicated_worker_id,
- SharedWorkerId shared_worker_id)
+ ServiceWorkerClientInfo client_info)
: context_(std::move(context)),
create_time_(base::TimeTicks::Now()),
client_uuid_(base::GenerateGUID()),
process_id_(process_id),
container_(std::move(container_remote)),
- client_type_(client_type),
- dedicated_worker_id_(dedicated_worker_id),
- shared_worker_id_(shared_worker_id) {
+ client_info_(client_info) {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
DCHECK(IsContainerForWorkerClient());
DCHECK(context_);
@@ -685,35 +681,35 @@ void ServiceWorkerContainerHost::RemoveServiceWorkerObjectHost(
bool ServiceWorkerContainerHost::IsContainerForServiceWorker() const {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
- return client_type_ == base::nullopt;
+ return client_info_ == base::nullopt;
}
bool ServiceWorkerContainerHost::IsContainerForClient() const {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
- return client_type_ != base::nullopt;
+ return client_info_ != base::nullopt;
}
blink::mojom::ServiceWorkerClientType
ServiceWorkerContainerHost::GetClientType() const {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
- DCHECK(client_type_);
- return *client_type_;
+ DCHECK(client_info_);
+ return client_info_->type();
}
bool ServiceWorkerContainerHost::IsContainerForWindowClient() const {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
- return client_type_ &&
- *client_type_ == blink::mojom::ServiceWorkerClientType::kWindow;
+ return client_info_ &&
+ client_info_->type() == blink::mojom::ServiceWorkerClientType::kWindow;
}
bool ServiceWorkerContainerHost::IsContainerForWorkerClient() const {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
using blink::mojom::ServiceWorkerClientType;
- if (!client_type_)
+ if (!client_info_)
return false;
- return *client_type_ == ServiceWorkerClientType::kDedicatedWorker ||
- *client_type_ == ServiceWorkerClientType::kSharedWorker;
+ return client_info_->type() == ServiceWorkerClientType::kDedicatedWorker ||
+ client_info_->type() == ServiceWorkerClientType::kSharedWorker;
}
ServiceWorkerClientInfo ServiceWorkerContainerHost::GetServiceWorkerClientInfo()
@@ -721,7 +717,7 @@ ServiceWorkerClientInfo ServiceWorkerContainerHost::GetServiceWorkerClientInfo()
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
DCHECK(IsContainerForClient());
- return ServiceWorkerClientInfo(*client_type_, frame_tree_node_id_);
+ return *client_info_;
}
void ServiceWorkerContainerHost::OnBeginNavigationCommit(
@@ -778,6 +774,19 @@ void ServiceWorkerContainerHost::OnBeginNavigationCommit(
TransitionToClientPhase(ClientPhase::kResponseCommitted);
}
+void ServiceWorkerContainerHost::OnEndNavigationCommit() {
+ DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
+ DCHECK(IsContainerForWindowClient());
+
+ DCHECK(!navigation_commit_ended_);
+ navigation_commit_ended_ = true;
+
+ if (controller_) {
+ controller_->OnControlleeNavigationCommitted(client_uuid_, process_id_,
+ frame_id_);
+ }
+}
+
void ServiceWorkerContainerHost::CompleteWebWorkerPreparation(
const network::CrossOriginEmbedderPolicy& cross_origin_embedder_policy) {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
@@ -823,7 +832,8 @@ void ServiceWorkerContainerHost::UpdateUrls(
auto* registry = FrameTreeNodeIdRegistry::GetInstance();
registry->Remove(fetch_request_window_id_);
fetch_request_window_id_ = base::UnguessableToken::Create();
- registry->Add(fetch_request_window_id_, frame_tree_node_id_);
+ registry->Add(fetch_request_window_id_,
+ client_info_->GetFrameTreeNodeId());
}
}
@@ -963,7 +973,7 @@ bool ServiceWorkerContainerHost::IsContextSecureForServiceWorker() const {
return true;
std::set<std::string> schemes;
- GetContentClient()->browser()->GetSchemesBypassingSecureContextCheckWhitelist(
+ GetContentClient()->browser()->GetSchemesBypassingSecureContextCheckAllowlist(
&schemes);
return schemes.find(url_.scheme()) != schemes.end();
}
@@ -1042,14 +1052,14 @@ ServiceWorkerRegistration* ServiceWorkerContainerHost::controller_registration()
}
void ServiceWorkerContainerHost::set_service_worker_host(
- ServiceWorkerProviderHost* service_worker_host) {
+ ServiceWorkerHost* service_worker_host) {
DCHECK(IsContainerForServiceWorker());
DCHECK(!service_worker_host_);
DCHECK(service_worker_host);
service_worker_host_ = service_worker_host;
}
-ServiceWorkerProviderHost* ServiceWorkerContainerHost::service_worker_host() {
+ServiceWorkerHost* ServiceWorkerContainerHost::service_worker_host() {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
DCHECK(IsContainerForServiceWorker());
return service_worker_host_;
diff --git a/chromium/content/browser/service_worker/service_worker_container_host.h b/chromium/content/browser/service_worker/service_worker_container_host.h
index 9e904186115..3cd1c8daf3b 100644
--- a/chromium/content/browser/service_worker/service_worker_container_host.h
+++ b/chromium/content/browser/service_worker/service_worker_container_host.h
@@ -15,11 +15,9 @@
#include "base/optional.h"
#include "base/time/time.h"
#include "content/browser/frame_host/back_forward_cache_metrics.h"
-#include "content/browser/frame_host/frame_tree_node.h"
#include "content/browser/service_worker/service_worker_registration.h"
#include "content/common/content_export.h"
-#include "content/public/browser/dedicated_worker_id.h"
-#include "content/public/browser/shared_worker_id.h"
+#include "content/public/browser/service_worker_client_info.h"
#include "content/public/common/child_process_host.h"
#include "mojo/public/cpp/bindings/associated_remote.h"
#include "mojo/public/cpp/bindings/receiver_set.h"
@@ -42,8 +40,8 @@ class ServiceWorkerObjectHostTest;
}
class ServiceWorkerContextCore;
+class ServiceWorkerHost;
class ServiceWorkerObjectHost;
-class ServiceWorkerProviderHost;
class ServiceWorkerRegistrationObjectHost;
class ServiceWorkerVersion;
@@ -84,9 +82,9 @@ class ServiceWorkerVersion;
// registration settles, if need.
//
// For service worker execution contexts, ServiceWorkerContainerHost is owned
-// by ServiceWorkerProviderHost, which in turn is owned by ServiceWorkerVersion.
-// The container host and provider host are destructed when the service worker
-// is stopped.
+// by ServiceWorkerHost, which in turn is owned by ServiceWorkerVersion. The
+// container host and worker host are destructed when the service worker is
+// stopped.
class CONTENT_EXPORT ServiceWorkerContainerHost final
: public blink::mojom::ServiceWorkerContainerHost,
public ServiceWorkerRegistration::Listener {
@@ -111,9 +109,7 @@ class CONTENT_EXPORT ServiceWorkerContainerHost final
int process_id,
mojo::PendingAssociatedRemote<blink::mojom::ServiceWorkerContainer>
container_remote,
- blink::mojom::ServiceWorkerClientType client_type,
- DedicatedWorkerId dedicated_worker_id,
- SharedWorkerId shared_worker_id);
+ ServiceWorkerClientInfo client_info);
~ServiceWorkerContainerHost() override;
@@ -272,6 +268,11 @@ class CONTENT_EXPORT ServiceWorkerContainerHost final
mojo::PendingRemote<network::mojom::CrossOriginEmbedderPolicyReporter>
coep_reporter);
+ // For service worker window clients. Called after the navigation commits to a
+ // render frame host. At this point, the previous ServiceWorkerContainerHost
+ // for that render frame host no longer exists.
+ void OnEndNavigationCommit();
+
// For service worker clients that are shared workers or dedicated workers.
// Called when the web worker main script resource has finished loading.
// Updates this host with information about the worker.
@@ -407,7 +408,7 @@ class CONTENT_EXPORT ServiceWorkerContainerHost final
base::TimeTicks create_time() const { return create_time_; }
int process_id() const { return process_id_; }
int frame_id() const { return frame_id_; }
- int frame_tree_node_id() const { return frame_tree_node_id_; }
+ int frame_tree_node_id() const { return client_info_->GetFrameTreeNodeId(); }
// For service worker clients.
const std::string& client_uuid() const;
@@ -424,8 +425,8 @@ class CONTENT_EXPORT ServiceWorkerContainerHost final
ServiceWorkerRegistration* controller_registration() const;
// For service worker execution contexts.
- void set_service_worker_host(ServiceWorkerProviderHost* service_worker_host);
- ServiceWorkerProviderHost* service_worker_host();
+ void set_service_worker_host(ServiceWorkerHost* service_worker_host);
+ ServiceWorkerHost* service_worker_host();
// BackForwardCache:
// For service worker clients that are windows.
@@ -439,6 +440,8 @@ class CONTENT_EXPORT ServiceWorkerContainerHost final
// OnRestoreFromBackForwardCache will not be called.
void OnRestoreFromBackForwardCache();
+ bool navigation_commit_ended() const { return navigation_commit_ended_; }
+
void EnterBackForwardCacheForTesting() { is_in_back_forward_cache_ = true; }
void LeaveBackForwardCacheForTesting() { is_in_back_forward_cache_ = false; }
@@ -644,13 +647,10 @@ class CONTENT_EXPORT ServiceWorkerContainerHost final
mojo::AssociatedRemote<blink::mojom::ServiceWorkerContainer> container_;
// The type of client.
- const base::Optional<blink::mojom::ServiceWorkerClientType> client_type_;
+ const base::Optional<ServiceWorkerClientInfo> client_info_;
// For window clients only ---------------------------------------------------
- // The ID of the frame tree node where the navigation occurs.
- const int frame_tree_node_id_ = FrameTreeNode::kFrameTreeNodeInvalidId;
-
// A token used internally to identify this context in requests. Corresponds
// to the Fetch specification's concept of a request's associated window:
// https://fetch.spec.whatwg.org/#concept-request-window. This gets reset on
@@ -680,18 +680,13 @@ class CONTENT_EXPORT ServiceWorkerContainerHost final
// and RenderFrameHost have the same lifetime.
bool is_in_back_forward_cache_ = false;
- // For worker clients only ---------------------------------------------------
-
- // The ID of the client, if the client is a dedicated worker.
- DedicatedWorkerId dedicated_worker_id_;
-
- // The ID of the client, if the client is a shared worker.
- SharedWorkerId shared_worker_id_;
+ // Indicates if OnEndNavigationCommit() was called on this container host.
+ bool navigation_commit_ended_ = false;
// For service worker execution contexts -------------------------------------
- // The ServiceWorkerProviderHost that owns |this|.
- ServiceWorkerProviderHost* service_worker_host_ = nullptr;
+ // The ServiceWorkerHost that owns |this|.
+ ServiceWorkerHost* service_worker_host_ = nullptr;
base::WeakPtrFactory<ServiceWorkerContainerHost> weak_factory_{this};
};
diff --git a/chromium/content/browser/service_worker/service_worker_container_host_unittest.cc b/chromium/content/browser/service_worker/service_worker_container_host_unittest.cc
index 7142ed53fa4..962d219f688 100644
--- a/chromium/content/browser/service_worker/service_worker_container_host_unittest.cc
+++ b/chromium/content/browser/service_worker/service_worker_container_host_unittest.cc
@@ -14,12 +14,15 @@
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/run_loop.h"
+#include "base/scoped_observer.h"
#include "base/test/scoped_feature_list.h"
#include "base/threading/thread_task_runner_handle.h"
#include "content/browser/frame_host/frame_tree_node.h"
#include "content/browser/service_worker/embedded_worker_test_helper.h"
#include "content/browser/service_worker/service_worker_context_core.h"
-#include "content/browser/service_worker/service_worker_provider_host.h"
+#include "content/browser/service_worker/service_worker_context_core_observer.h"
+#include "content/browser/service_worker/service_worker_context_wrapper.h"
+#include "content/browser/service_worker/service_worker_host.h"
#include "content/browser/service_worker/service_worker_register_job.h"
#include "content/browser/service_worker/service_worker_registration.h"
#include "content/browser/service_worker/service_worker_test_utils.h"
@@ -33,7 +36,7 @@
#include "content/public/test/test_utils.h"
#include "content/test/test_content_browser_client.h"
#include "content/test/test_content_client.h"
-#include "mojo/core/embedder/embedder.h"
+#include "mojo/public/cpp/system/functions.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_object.mojom.h"
@@ -113,7 +116,7 @@ class ServiceWorkerContainerHostTest : public testing::Test {
void SetUp() override {
old_content_browser_client_ =
SetBrowserClientForTesting(&test_content_browser_client_);
- mojo::core::SetDefaultProcessErrorCallback(base::BindRepeating(
+ mojo::SetDefaultProcessErrorHandler(base::BindRepeating(
&ServiceWorkerContainerHostTest::OnMojoError, base::Unretained(this)));
helper_.reset(new EmbeddedWorkerTestHelper(base::FilePath()));
@@ -142,13 +145,12 @@ class ServiceWorkerContainerHostTest : public testing::Test {
registration3_ = nullptr;
helper_.reset();
SetBrowserClientForTesting(old_content_browser_client_);
- mojo::core::SetDefaultProcessErrorCallback(
- mojo::core::ProcessErrorCallback());
+ mojo::SetDefaultProcessErrorHandler(base::NullCallback());
}
- ServiceWorkerRemoteProviderEndpoint PrepareServiceWorkerContainerHost(
+ ServiceWorkerRemoteContainerEndpoint PrepareServiceWorkerContainerHost(
const GURL& document_url) {
- ServiceWorkerRemoteProviderEndpoint remote_endpoint;
+ ServiceWorkerRemoteContainerEndpoint remote_endpoint;
net::SiteForCookies site_for_cookies =
net::SiteForCookies::FromUrl(document_url);
url::Origin top_frame_origin = url::Origin::Create(document_url);
@@ -157,12 +159,12 @@ class ServiceWorkerContainerHostTest : public testing::Test {
return remote_endpoint;
}
- ServiceWorkerRemoteProviderEndpoint
+ ServiceWorkerRemoteContainerEndpoint
PrepareServiceWorkerContainerHostWithSiteForCookies(
const GURL& document_url,
const net::SiteForCookies& site_for_cookies,
const base::Optional<url::Origin>& top_frame_origin) {
- ServiceWorkerRemoteProviderEndpoint remote_endpoint;
+ ServiceWorkerRemoteContainerEndpoint remote_endpoint;
CreateContainerHostInternal(document_url, site_for_cookies,
top_frame_origin, &remote_endpoint);
return remote_endpoint;
@@ -303,12 +305,10 @@ class ServiceWorkerContainerHostTest : public testing::Test {
return !container_host->versions_to_update_.empty();
}
- void TestReservedClientsAreNotExposed(
- blink::mojom::ServiceWorkerClientType client_type,
- const GURL& url);
- void TestClientPhaseTransition(
- blink::mojom::ServiceWorkerClientType client_type,
- const GURL& url);
+ void TestReservedClientsAreNotExposed(ServiceWorkerClientInfo client_info,
+ const GURL& url);
+ void TestClientPhaseTransition(ServiceWorkerClientInfo client_info,
+ const GURL& url);
void TestBackForwardCachedClientsAreNotExposed(const GURL& url);
@@ -323,7 +323,7 @@ class ServiceWorkerContainerHostTest : public testing::Test {
ServiceWorkerTestContentClient test_content_client_;
TestContentBrowserClient test_content_browser_client_;
ContentBrowserClient* old_content_browser_client_;
- std::vector<ServiceWorkerRemoteProviderEndpoint> remote_endpoints_;
+ std::vector<ServiceWorkerRemoteContainerEndpoint> remote_endpoints_;
std::vector<std::string> bad_messages_;
private:
@@ -331,7 +331,7 @@ class ServiceWorkerContainerHostTest : public testing::Test {
const GURL& document_url,
const net::SiteForCookies& site_for_cookies,
const base::Optional<url::Origin>& top_frame_origin,
- ServiceWorkerRemoteProviderEndpoint* remote_endpoint) {
+ ServiceWorkerRemoteContainerEndpoint* remote_endpoint) {
base::WeakPtr<ServiceWorkerContainerHost> container_host =
CreateContainerHostForWindow(helper_->mock_render_process_id(),
true /* is_parent_frame_secure */,
@@ -626,7 +626,7 @@ TEST_F(ServiceWorkerContainerHostTest,
ContentBrowserClient* old_browser_client =
SetBrowserClientForTesting(&test_browser_client);
- ServiceWorkerRemoteProviderEndpoint remote_endpoint =
+ ServiceWorkerRemoteContainerEndpoint remote_endpoint =
PrepareServiceWorkerContainerHostWithSiteForCookies(
GURL("https://www.example.com/foo"),
net::SiteForCookies::FromUrl(GURL("https://www.example.com/top")),
@@ -688,12 +688,11 @@ TEST_F(ServiceWorkerContainerHostTest, AllowsServiceWorker) {
helper_->context()->AsWeakPtr());
registration1_->SetActiveVersion(version);
- ServiceWorkerRemoteProviderEndpoint remote_endpoint;
- std::unique_ptr<ServiceWorkerProviderHost> provider_host =
- CreateProviderHostForServiceWorkerContext(
- helper_->mock_render_process_id(), true /* is_parent_frame_secure */,
- version.get(), helper_->context()->AsWeakPtr(), &remote_endpoint);
- ServiceWorkerContainerHost* container_host = provider_host->container_host();
+ ServiceWorkerRemoteContainerEndpoint remote_endpoint;
+ std::unique_ptr<ServiceWorkerHost> worker_host = CreateServiceWorkerHost(
+ helper_->mock_render_process_id(), true /* is_parent_frame_secure */,
+ version.get(), helper_->context()->AsWeakPtr(), &remote_endpoint);
+ ServiceWorkerContainerHost* container_host = worker_host->container_host();
ServiceWorkerTestContentBrowserClient test_browser_client;
ContentBrowserClient* old_browser_client =
@@ -715,7 +714,7 @@ TEST_F(ServiceWorkerContainerHostTest, AllowsServiceWorker) {
}
TEST_F(ServiceWorkerContainerHostTest, Register_HTTPS) {
- ServiceWorkerRemoteProviderEndpoint remote_endpoint =
+ ServiceWorkerRemoteContainerEndpoint remote_endpoint =
PrepareServiceWorkerContainerHost(GURL("https://www.example.com/foo"));
EXPECT_EQ(blink::mojom::ServiceWorkerErrorType::kNone,
@@ -725,7 +724,7 @@ TEST_F(ServiceWorkerContainerHostTest, Register_HTTPS) {
}
TEST_F(ServiceWorkerContainerHostTest, Register_NonSecureTransportLocalhost) {
- ServiceWorkerRemoteProviderEndpoint remote_endpoint =
+ ServiceWorkerRemoteContainerEndpoint remote_endpoint =
PrepareServiceWorkerContainerHost(GURL("http://127.0.0.3:81/foo"));
EXPECT_EQ(blink::mojom::ServiceWorkerErrorType::kNone,
@@ -735,7 +734,7 @@ TEST_F(ServiceWorkerContainerHostTest, Register_NonSecureTransportLocalhost) {
}
TEST_F(ServiceWorkerContainerHostTest, Register_InvalidScopeShouldFail) {
- ServiceWorkerRemoteProviderEndpoint remote_endpoint =
+ ServiceWorkerRemoteContainerEndpoint remote_endpoint =
PrepareServiceWorkerContainerHost(GURL("https://www.example.com/foo"));
ASSERT_TRUE(bad_messages_.empty());
@@ -745,7 +744,7 @@ TEST_F(ServiceWorkerContainerHostTest, Register_InvalidScopeShouldFail) {
}
TEST_F(ServiceWorkerContainerHostTest, Register_InvalidScriptShouldFail) {
- ServiceWorkerRemoteProviderEndpoint remote_endpoint =
+ ServiceWorkerRemoteContainerEndpoint remote_endpoint =
PrepareServiceWorkerContainerHost(GURL("https://www.example.com/foo"));
ASSERT_TRUE(bad_messages_.empty());
@@ -755,7 +754,7 @@ TEST_F(ServiceWorkerContainerHostTest, Register_InvalidScriptShouldFail) {
}
TEST_F(ServiceWorkerContainerHostTest, Register_NonSecureOriginShouldFail) {
- ServiceWorkerRemoteProviderEndpoint remote_endpoint =
+ ServiceWorkerRemoteContainerEndpoint remote_endpoint =
PrepareServiceWorkerContainerHost(GURL("http://www.example.com/foo"));
ASSERT_TRUE(bad_messages_.empty());
@@ -765,7 +764,7 @@ TEST_F(ServiceWorkerContainerHostTest, Register_NonSecureOriginShouldFail) {
}
TEST_F(ServiceWorkerContainerHostTest, Register_CrossOriginShouldFail) {
- ServiceWorkerRemoteProviderEndpoint remote_endpoint =
+ ServiceWorkerRemoteContainerEndpoint remote_endpoint =
PrepareServiceWorkerContainerHost(GURL("https://www.example.com/foo"));
ASSERT_TRUE(bad_messages_.empty());
@@ -804,7 +803,7 @@ TEST_F(ServiceWorkerContainerHostTest, Register_CrossOriginShouldFail) {
}
TEST_F(ServiceWorkerContainerHostTest, Register_BadCharactersShouldFail) {
- ServiceWorkerRemoteProviderEndpoint remote_endpoint =
+ ServiceWorkerRemoteContainerEndpoint remote_endpoint =
PrepareServiceWorkerContainerHost(GURL("https://www.example.com"));
ASSERT_TRUE(bad_messages_.empty());
@@ -840,7 +839,7 @@ TEST_F(ServiceWorkerContainerHostTest, Register_BadCharactersShouldFail) {
}
TEST_F(ServiceWorkerContainerHostTest, Register_FileSystemDocumentShouldFail) {
- ServiceWorkerRemoteProviderEndpoint remote_endpoint =
+ ServiceWorkerRemoteContainerEndpoint remote_endpoint =
PrepareServiceWorkerContainerHost(
GURL("filesystem:https://www.example.com/temporary/a"));
@@ -863,7 +862,7 @@ TEST_F(ServiceWorkerContainerHostTest, Register_FileSystemDocumentShouldFail) {
TEST_F(ServiceWorkerContainerHostTest,
Register_FileSystemScriptOrScopeShouldFail) {
- ServiceWorkerRemoteProviderEndpoint remote_endpoint =
+ ServiceWorkerRemoteContainerEndpoint remote_endpoint =
PrepareServiceWorkerContainerHost(
GURL("https://www.example.com/temporary/"));
@@ -885,7 +884,7 @@ TEST_F(ServiceWorkerContainerHostTest,
}
TEST_F(ServiceWorkerContainerHostTest, EarlyContextDeletion) {
- ServiceWorkerRemoteProviderEndpoint remote_endpoint =
+ ServiceWorkerRemoteContainerEndpoint remote_endpoint =
PrepareServiceWorkerContainerHost(GURL("https://www.example.com/foo"));
helper_->ShutdownContext();
@@ -899,7 +898,7 @@ TEST_F(ServiceWorkerContainerHostTest, EarlyContextDeletion) {
}
TEST_F(ServiceWorkerContainerHostTest, GetRegistration_Success) {
- ServiceWorkerRemoteProviderEndpoint remote_endpoint =
+ ServiceWorkerRemoteContainerEndpoint remote_endpoint =
PrepareServiceWorkerContainerHost(GURL("https://www.example.com/foo"));
const GURL kScope("https://www.example.com/");
@@ -916,7 +915,7 @@ TEST_F(ServiceWorkerContainerHostTest, GetRegistration_Success) {
TEST_F(ServiceWorkerContainerHostTest,
GetRegistration_NotFoundShouldReturnNull) {
- ServiceWorkerRemoteProviderEndpoint remote_endpoint =
+ ServiceWorkerRemoteContainerEndpoint remote_endpoint =
PrepareServiceWorkerContainerHost(GURL("https://www.example.com/foo"));
blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info;
@@ -927,7 +926,7 @@ TEST_F(ServiceWorkerContainerHostTest,
}
TEST_F(ServiceWorkerContainerHostTest, GetRegistration_CrossOriginShouldFail) {
- ServiceWorkerRemoteProviderEndpoint remote_endpoint =
+ ServiceWorkerRemoteContainerEndpoint remote_endpoint =
PrepareServiceWorkerContainerHost(GURL("https://www.example.com/foo"));
ASSERT_TRUE(bad_messages_.empty());
@@ -937,7 +936,7 @@ TEST_F(ServiceWorkerContainerHostTest, GetRegistration_CrossOriginShouldFail) {
}
TEST_F(ServiceWorkerContainerHostTest, GetRegistration_InvalidScopeShouldFail) {
- ServiceWorkerRemoteProviderEndpoint remote_endpoint =
+ ServiceWorkerRemoteContainerEndpoint remote_endpoint =
PrepareServiceWorkerContainerHost(GURL("https://www.example.com/foo"));
ASSERT_TRUE(bad_messages_.empty());
@@ -947,7 +946,7 @@ TEST_F(ServiceWorkerContainerHostTest, GetRegistration_InvalidScopeShouldFail) {
TEST_F(ServiceWorkerContainerHostTest,
GetRegistration_NonSecureOriginShouldFail) {
- ServiceWorkerRemoteProviderEndpoint remote_endpoint =
+ ServiceWorkerRemoteContainerEndpoint remote_endpoint =
PrepareServiceWorkerContainerHost(GURL("http://www.example.com/foo"));
ASSERT_TRUE(bad_messages_.empty());
@@ -957,7 +956,7 @@ TEST_F(ServiceWorkerContainerHostTest,
}
TEST_F(ServiceWorkerContainerHostTest, GetRegistrations_SecureOrigin) {
- ServiceWorkerRemoteProviderEndpoint remote_endpoint =
+ ServiceWorkerRemoteContainerEndpoint remote_endpoint =
PrepareServiceWorkerContainerHost(GURL("https://www.example.com/foo"));
EXPECT_EQ(blink::mojom::ServiceWorkerErrorType::kNone,
@@ -966,7 +965,7 @@ TEST_F(ServiceWorkerContainerHostTest, GetRegistrations_SecureOrigin) {
TEST_F(ServiceWorkerContainerHostTest,
GetRegistrations_NonSecureOriginShouldFail) {
- ServiceWorkerRemoteProviderEndpoint remote_endpoint =
+ ServiceWorkerRemoteContainerEndpoint remote_endpoint =
PrepareServiceWorkerContainerHost(GURL("http://www.example.com/foo"));
ASSERT_TRUE(bad_messages_.empty());
@@ -978,25 +977,24 @@ TEST_F(ServiceWorkerContainerHostTest,
// when iterating over client container hosts. If it were, it'd be undesirably
// exposed via the Clients API.
void ServiceWorkerContainerHostTest::TestReservedClientsAreNotExposed(
- blink::mojom::ServiceWorkerClientType client_type,
+ ServiceWorkerClientInfo client_info,
const GURL& url) {
{
mojo::PendingAssociatedRemote<blink::mojom::ServiceWorkerContainer>
client_remote;
mojo::PendingAssociatedReceiver<blink::mojom::ServiceWorkerContainerHost>
host_receiver;
- auto provider_info =
- blink::mojom::ServiceWorkerProviderInfoForClient::New();
- provider_info->client_receiver =
+ auto container_info =
+ blink::mojom::ServiceWorkerContainerInfoForClient::New();
+ container_info->client_receiver =
client_remote.InitWithNewEndpointAndPassReceiver();
host_receiver =
- provider_info->host_remote.InitWithNewEndpointAndPassReceiver();
+ container_info->host_remote.InitWithNewEndpointAndPassReceiver();
base::WeakPtr<ServiceWorkerContainerHost> container_host =
context_->CreateContainerHostForWorker(
std::move(host_receiver), helper_->mock_render_process_id(),
- std::move(client_remote), client_type, DedicatedWorkerId(),
- SharedWorkerId());
+ std::move(client_remote), client_info);
container_host->UpdateUrls(url, net::SiteForCookies::FromUrl(url),
url::Origin::Create(url));
EXPECT_FALSE(CanFindClientContainerHost(container_host.get()));
@@ -1011,7 +1009,7 @@ void ServiceWorkerContainerHostTest::TestReservedClientsAreNotExposed(
/*are_ancestors_secure=*/true);
base::WeakPtr<ServiceWorkerContainerHost> container_host =
std::move(host_and_info->host);
- ServiceWorkerRemoteProviderEndpoint remote_endpoint;
+ ServiceWorkerRemoteContainerEndpoint remote_endpoint;
remote_endpoint.BindForWindow(std::move(host_and_info->info));
FinishNavigation(container_host.get());
@@ -1030,14 +1028,14 @@ TEST_F(ServiceWorkerContainerHostTestWithPlzDedicatedWorker,
ASSERT_TRUE(
base::FeatureList::IsEnabled(blink::features::kPlzDedicatedWorker));
TestReservedClientsAreNotExposed(
- blink::mojom::ServiceWorkerClientType::kDedicatedWorker,
+ ServiceWorkerClientInfo(DedicatedWorkerId()),
GURL("https://www.example.com/dedicated_worker.js"));
}
TEST_F(ServiceWorkerContainerHostTest,
ReservedClientsAreNotExposedToClientsApiForSharedWorker) {
TestReservedClientsAreNotExposed(
- blink::mojom::ServiceWorkerClientType::kSharedWorker,
+ ServiceWorkerClientInfo(SharedWorkerId()),
GURL("https://www.example.com/shared_worker.js"));
}
@@ -1048,7 +1046,7 @@ TEST_F(ServiceWorkerContainerHostTest, ClientPhaseForWindow) {
/*are_ancestors_secure=*/true);
base::WeakPtr<ServiceWorkerContainerHost> container_host =
std::move(host_and_info->host);
- ServiceWorkerRemoteProviderEndpoint remote_endpoint;
+ ServiceWorkerRemoteContainerEndpoint remote_endpoint;
remote_endpoint.BindForWindow(std::move(host_and_info->info));
EXPECT_FALSE(container_host->is_response_committed());
EXPECT_FALSE(container_host->is_execution_ready());
@@ -1067,23 +1065,23 @@ TEST_F(ServiceWorkerContainerHostTest, ClientPhaseForWindow) {
// Tests the client phase transitions for workers.
void ServiceWorkerContainerHostTest::TestClientPhaseTransition(
- blink::mojom::ServiceWorkerClientType client_type,
+ ServiceWorkerClientInfo client_info,
const GURL& url) {
mojo::PendingAssociatedRemote<blink::mojom::ServiceWorkerContainer>
client_remote;
mojo::PendingAssociatedReceiver<blink::mojom::ServiceWorkerContainerHost>
host_receiver;
- auto provider_info = blink::mojom::ServiceWorkerProviderInfoForClient::New();
- provider_info->client_receiver =
+ auto container_info =
+ blink::mojom::ServiceWorkerContainerInfoForClient::New();
+ container_info->client_receiver =
client_remote.InitWithNewEndpointAndPassReceiver();
host_receiver =
- provider_info->host_remote.InitWithNewEndpointAndPassReceiver();
+ container_info->host_remote.InitWithNewEndpointAndPassReceiver();
base::WeakPtr<ServiceWorkerContainerHost> container_host =
helper_->context()->CreateContainerHostForWorker(
std::move(host_receiver), helper_->mock_render_process_id(),
- std::move(client_remote), client_type, DedicatedWorkerId(),
- SharedWorkerId());
+ std::move(client_remote), client_info);
EXPECT_FALSE(container_host->is_response_committed());
EXPECT_FALSE(container_host->is_execution_ready());
@@ -1101,14 +1099,13 @@ TEST_F(ServiceWorkerContainerHostTestWithPlzDedicatedWorker,
ASSERT_TRUE(
base::FeatureList::IsEnabled(blink::features::kPlzDedicatedWorker));
TestClientPhaseTransition(
- blink::mojom::ServiceWorkerClientType::kDedicatedWorker,
+ ServiceWorkerClientInfo(DedicatedWorkerId()),
GURL("https://www.example.com/dedicated_worker.js"));
}
TEST_F(ServiceWorkerContainerHostTest, ClientPhaseForSharedWorker) {
- TestClientPhaseTransition(
- blink::mojom::ServiceWorkerClientType::kSharedWorker,
- GURL("https://www.example.com/shared_worker.js"));
+ TestClientPhaseTransition(ServiceWorkerClientInfo(SharedWorkerId()),
+ GURL("https://www.example.com/shared_worker.js"));
}
// Run tests with BackForwardCache.
@@ -1137,7 +1134,7 @@ class ServiceWorkerContainerHostTestWithBackForwardCache
// exposed via the Clients API.
void ServiceWorkerContainerHostTest::TestBackForwardCachedClientsAreNotExposed(
const GURL& url) {
- std::unique_ptr<ServiceWorkerProviderHost> provider_host;
+ std::unique_ptr<ServiceWorkerHost> worker_host;
{
// Create an active version.
scoped_refptr<ServiceWorkerVersion> version =
@@ -1146,11 +1143,11 @@ void ServiceWorkerContainerHostTest::TestBackForwardCachedClientsAreNotExposed(
1 /* version_id */, helper_->context()->AsWeakPtr());
registration1_->SetActiveVersion(version);
- ServiceWorkerRemoteProviderEndpoint remote_endpoint;
- provider_host = CreateProviderHostForServiceWorkerContext(
+ ServiceWorkerRemoteContainerEndpoint remote_endpoint;
+ worker_host = CreateServiceWorkerHost(
helper_->mock_render_process_id(), true /* is_parent_frame_secure */,
version.get(), helper_->context()->AsWeakPtr(), &remote_endpoint);
- ASSERT_TRUE(provider_host);
+ ASSERT_TRUE(worker_host);
}
{
std::unique_ptr<ServiceWorkerContainerHostAndInfo> host_and_info =
@@ -1158,7 +1155,7 @@ void ServiceWorkerContainerHostTest::TestBackForwardCachedClientsAreNotExposed(
/*are_ancestors_secure=*/true);
base::WeakPtr<ServiceWorkerContainerHost> container_host =
std::move(host_and_info->host);
- ServiceWorkerRemoteProviderEndpoint remote_endpoint;
+ ServiceWorkerRemoteContainerEndpoint remote_endpoint;
remote_endpoint.BindForWindow(std::move(host_and_info->info));
FinishNavigation(container_host.get());
@@ -1185,6 +1182,108 @@ TEST_F(ServiceWorkerContainerHostTestWithBackForwardCache,
GURL("https://www.example.com/sw.js"));
}
+class TestServiceWorkerContextCoreObserver
+ : public ServiceWorkerContextCoreObserver {
+ public:
+ explicit TestServiceWorkerContextCoreObserver(
+ ServiceWorkerContextWrapper* wrapper)
+ : observer_(this) {
+ observer_.Add(wrapper);
+ }
+
+ void OnControlleeAdded(int64_t version_id,
+ const std::string& uuid,
+ const ServiceWorkerClientInfo& info) override {
+ ++on_controllee_added_count_;
+ }
+ void OnControlleeRemoved(int64_t version_id,
+ const std::string& uuid) override {
+ ++on_controllee_removed_count_;
+ }
+ void OnControlleeNavigationCommitted(
+ int64_t version_id,
+ const std::string& uuid,
+ GlobalFrameRoutingId render_frame_host_id) override {
+ ++on_controllee_navigation_committed_count_;
+ }
+
+ int on_controllee_added_count() const { return on_controllee_added_count_; }
+ int on_controllee_removed_count() const {
+ return on_controllee_removed_count_;
+ }
+ int on_controllee_navigation_committed_count() const {
+ return on_controllee_navigation_committed_count_;
+ }
+
+ private:
+ int on_controllee_added_count_ = 0;
+ int on_controllee_removed_count_ = 0;
+ int on_controllee_navigation_committed_count_ = 0;
+
+ ScopedObserver<ServiceWorkerContextWrapper, ServiceWorkerContextCoreObserver>
+ observer_;
+};
+
+TEST_F(ServiceWorkerContainerHostTestWithBackForwardCache, ControlleeEvents) {
+ TestServiceWorkerContextCoreObserver observer(helper_->context_wrapper());
+
+ // Create a host.
+ std::unique_ptr<ServiceWorkerContainerHostAndInfo> host_and_info =
+ CreateContainerHostAndInfoForWindow(helper_->context()->AsWeakPtr(),
+ /*are_ancestors_secure=*/true);
+ base::WeakPtr<ServiceWorkerContainerHost> container_host =
+ std::move(host_and_info->host);
+ remote_endpoints_.emplace_back();
+ remote_endpoints_.back().BindForWindow(std::move(host_and_info->info));
+ auto container = std::make_unique<MockServiceWorkerContainer>(
+ std::move(*remote_endpoints_.back().client_receiver()));
+
+ // Create an active version and then start the navigation.
+ scoped_refptr<ServiceWorkerVersion> version = new ServiceWorkerVersion(
+ registration1_.get(), GURL("https://www.example.com/sw.js"),
+ blink::mojom::ScriptType::kClassic, 1 /* version_id */,
+ helper_->context()->AsWeakPtr());
+ version->set_fetch_handler_existence(
+ ServiceWorkerVersion::FetchHandlerExistence::EXISTS);
+ version->SetStatus(ServiceWorkerVersion::ACTIVATED);
+ registration1_->SetActiveVersion(version);
+
+ // Finish the navigation.
+ FinishNavigation(container_host.get());
+ container_host->SetControllerRegistration(
+ registration1_, false /* notify_controllerchange */);
+ remote_endpoints_.back().host_remote()->get()->OnExecutionReady();
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_EQ(observer.on_controllee_added_count(), 1);
+ EXPECT_EQ(observer.on_controllee_navigation_committed_count(), 0);
+ EXPECT_EQ(observer.on_controllee_removed_count(), 0);
+
+ // The navigation commit ending should send the
+ // OnControlleeNavigationCommitted() notification.
+ container_host->OnEndNavigationCommit();
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_EQ(observer.on_controllee_added_count(), 1);
+ EXPECT_EQ(observer.on_controllee_navigation_committed_count(), 1);
+ EXPECT_EQ(observer.on_controllee_removed_count(), 0);
+
+ version->MoveControlleeToBackForwardCacheMap(container_host->client_uuid());
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_EQ(observer.on_controllee_added_count(), 1);
+ EXPECT_EQ(observer.on_controllee_navigation_committed_count(), 1);
+ EXPECT_EQ(observer.on_controllee_removed_count(), 1);
+
+ version->RestoreControlleeFromBackForwardCacheMap(
+ container_host->client_uuid());
+ base::RunLoop().RunUntilIdle();
+
+ EXPECT_EQ(observer.on_controllee_added_count(), 2);
+ EXPECT_EQ(observer.on_controllee_navigation_committed_count(), 2);
+ EXPECT_EQ(observer.on_controllee_removed_count(), 1);
+}
+
// Tests that the service worker involved with a navigation (via
// AddServiceWorkerToUpdate) is updated when the host for the navigation is
// destroyed.
diff --git a/chromium/content/browser/service_worker/service_worker_context_core.cc b/chromium/content/browser/service_worker/service_worker_context_core.cc
index 331e16f4a02..7818fc7bb9e 100644
--- a/chromium/content/browser/service_worker/service_worker_context_core.cc
+++ b/chromium/content/browser/service_worker/service_worker_context_core.cc
@@ -18,7 +18,6 @@
#include "base/memory/ptr_util.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/string_util.h"
-#include "base/task/post_task.h"
#include "base/threading/thread_task_runner_handle.h"
#include "content/browser/frame_host/frame_tree_node.h"
#include "content/browser/frame_host/render_frame_host_impl.h"
@@ -221,7 +220,7 @@ class ClearAllServiceWorkersHelper
friend class base::RefCounted<ClearAllServiceWorkersHelper>;
~ClearAllServiceWorkersHelper() {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
- base::PostTask(FROM_HERE, {BrowserThread::UI}, std::move(callback_));
+ GetUIThreadTaskRunner({})->PostTask(FROM_HERE, std::move(callback_));
}
base::OnceClosure callback_;
@@ -391,8 +390,8 @@ void ServiceWorkerContextCore::HasMainFrameWindowClient(const GURL& origin,
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(std::move(callback), result));
} else {
- base::PostTaskAndReplyWithResult(
- FROM_HERE, {BrowserThread::UI},
+ GetUIThreadTaskRunner({})->PostTaskAndReplyWithResult(
+ FROM_HERE,
base::BindOnce(&FrameListContainsMainFrameOnUI,
std::move(render_frames)),
std::move(callback));
@@ -433,12 +432,9 @@ ServiceWorkerContextCore::CreateContainerHostForWorker(
int process_id,
mojo::PendingAssociatedRemote<blink::mojom::ServiceWorkerContainer>
container_remote,
- blink::mojom::ServiceWorkerClientType client_type,
- DedicatedWorkerId dedicated_worker_id,
- SharedWorkerId shared_worker_id) {
+ ServiceWorkerClientInfo client_info) {
auto container_host = std::make_unique<ServiceWorkerContainerHost>(
- AsWeakPtr(), process_id, std::move(container_remote), client_type,
- dedicated_worker_id, shared_worker_id);
+ AsWeakPtr(), process_id, std::move(container_remote), client_info);
ServiceWorkerContainerHost* container_host_ptr = container_host.get();
@@ -703,6 +699,7 @@ void ServiceWorkerContextCore::AddLiveRegistration(
}
void ServiceWorkerContextCore::RemoveLiveRegistration(int64_t id) {
+ DCHECK(live_registrations_.find(id) != live_registrations_.end());
live_registrations_.erase(id);
}
@@ -878,6 +875,15 @@ void ServiceWorkerContextCore::NotifyRegistrationStored(int64_t registration_id,
registration_id, scope);
}
+void ServiceWorkerContextCore::NotifyAllRegistrationsDeletedForOrigin(
+ const url::Origin& origin) {
+ DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
+ observer_list_->Notify(
+ FROM_HERE,
+ &ServiceWorkerContextCoreObserver::OnAllRegistrationsDeletedForOrigin,
+ origin);
+}
+
void ServiceWorkerContextCore::OnStorageWiped() {
observer_list_->Notify(FROM_HERE,
&ServiceWorkerContextCoreObserver::OnStorageWiped);
@@ -896,9 +902,9 @@ void ServiceWorkerContextCore::OnControlleeAdded(
const std::string& client_uuid,
const ServiceWorkerClientInfo& client_info) {
DCHECK_EQ(this, version->context().get());
- observer_list_->Notify(
- FROM_HERE, &ServiceWorkerContextCoreObserver::OnControlleeAdded,
- version->version_id(), version->scope(), client_uuid, client_info);
+ observer_list_->Notify(FROM_HERE,
+ &ServiceWorkerContextCoreObserver::OnControlleeAdded,
+ version->version_id(), client_uuid, client_info);
}
void ServiceWorkerContextCore::OnControlleeRemoved(
@@ -907,7 +913,7 @@ void ServiceWorkerContextCore::OnControlleeRemoved(
DCHECK_EQ(this, version->context().get());
observer_list_->Notify(FROM_HERE,
&ServiceWorkerContextCoreObserver::OnControlleeRemoved,
- version->version_id(), version->scope(), client_uuid);
+ version->version_id(), client_uuid);
}
void ServiceWorkerContextCore::OnNoControllees(ServiceWorkerVersion* version) {
@@ -923,6 +929,18 @@ void ServiceWorkerContextCore::OnNoControllees(ServiceWorkerVersion* version) {
version->version_id(), version->scope());
}
+void ServiceWorkerContextCore::OnControlleeNavigationCommitted(
+ ServiceWorkerVersion* version,
+ const std::string& client_uuid,
+ GlobalFrameRoutingId render_frame_host_id) {
+ DCHECK_EQ(this, version->context().get());
+
+ observer_list_->Notify(
+ FROM_HERE,
+ &ServiceWorkerContextCoreObserver::OnControlleeNavigationCommitted,
+ version->version_id(), client_uuid, render_frame_host_id);
+}
+
void ServiceWorkerContextCore::OnRunningStateChanged(
ServiceWorkerVersion* version) {
DCHECK_EQ(this, version->context().get());
diff --git a/chromium/content/browser/service_worker/service_worker_context_core.h b/chromium/content/browser/service_worker/service_worker_context_core.h
index aa95543013b..bec8b4d81c5 100644
--- a/chromium/content/browser/service_worker/service_worker_context_core.h
+++ b/chromium/content/browser/service_worker/service_worker_context_core.h
@@ -25,6 +25,7 @@
#include "content/browser/service_worker/service_worker_storage.h"
#include "content/common/content_export.h"
#include "content/public/browser/dedicated_worker_id.h"
+#include "content/public/browser/global_routing_id.h"
#include "content/public/browser/service_worker_context.h"
#include "content/public/browser/shared_worker_id.h"
#include "mojo/public/cpp/bindings/associated_receiver_set.h"
@@ -141,6 +142,14 @@ class CONTENT_EXPORT ServiceWorkerContextCore
void OnControlleeRemoved(ServiceWorkerVersion* version,
const std::string& client_uuid);
+ // Called when the navigation for a window client commits to a render frame
+ // host. Also called asynchronously to preserve the ordering with
+ // OnControlleeAdded and OnControlleeRemoved.
+ void OnControlleeNavigationCommitted(
+ ServiceWorkerVersion* version,
+ const std::string& client_uuid,
+ GlobalFrameRoutingId render_frame_host_id);
+
// Called when all controllees are removed.
// Note regarding BackForwardCache integration:
// Clients in back-forward cache don't count as controllees.
@@ -217,9 +226,7 @@ class CONTENT_EXPORT ServiceWorkerContextCore
int process_id,
mojo::PendingAssociatedRemote<blink::mojom::ServiceWorkerContainer>
container_remote,
- blink::mojom::ServiceWorkerClientType client_type,
- DedicatedWorkerId dedicated_worker_id,
- SharedWorkerId shared_worker_id);
+ ServiceWorkerClientInfo client_info);
// Updates the client UUID of an existing container host.
void UpdateContainerHostClientID(const std::string& current_client_uuid,
@@ -282,6 +289,8 @@ class CONTENT_EXPORT ServiceWorkerContextCore
// does not own these object or influence their lifetime.
ServiceWorkerRegistration* GetLiveRegistration(int64_t registration_id);
void AddLiveRegistration(ServiceWorkerRegistration* registration);
+ // RemoveLiveRegistration removes registration from |live_registrations_|
+ // and notifies all observers of the id of the registration removed.
void RemoveLiveRegistration(int64_t registration_id);
const std::map<int64_t, ServiceWorkerRegistration*>& GetLiveRegistrations()
const {
@@ -332,6 +341,9 @@ class CONTENT_EXPORT ServiceWorkerContextCore
// Called by ServiceWorkerStorage when StoreRegistration() succeeds.
void NotifyRegistrationStored(int64_t registration_id, const GURL& scope);
+ // Called on the core thread and notifies observers that all registrations
+ // have been deleted for a particular origin.
+ void NotifyAllRegistrationsDeletedForOrigin(const url::Origin& origin);
URLLoaderFactoryGetter* loader_factory_getter() {
return loader_factory_getter_.get();
@@ -402,7 +414,7 @@ class CONTENT_EXPORT ServiceWorkerContextCore
// |container_host_by_uuid_| owns container hosts for service worker clients.
// Container hosts for service worker execution contexts are owned by
- // ServiceWorkerProviderHost.
+ // ServiceWorkerHost.
ContainerHostByClientUUIDMap container_host_by_uuid_;
std::unique_ptr<
diff --git a/chromium/content/browser/service_worker/service_worker_context_core_observer.h b/chromium/content/browser/service_worker/service_worker_context_core_observer.h
index fec34e98652..e8ebdb686e7 100644
--- a/chromium/content/browser/service_worker/service_worker_context_core_observer.h
+++ b/chromium/content/browser/service_worker/service_worker_context_core_observer.h
@@ -13,6 +13,7 @@
#include "base/time/time.h"
#include "content/browser/service_worker/service_worker_info.h"
#include "content/browser/service_worker/service_worker_version.h"
+#include "content/public/browser/global_routing_id.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_container_type.mojom.h"
#include "url/gurl.h"
@@ -71,13 +72,15 @@ class ServiceWorkerContextCoreObserver {
virtual void OnReportConsoleMessage(int64_t version_id,
const ConsoleMessage& message) {}
virtual void OnControlleeAdded(int64_t version_id,
- const GURL& scope,
const std::string& uuid,
const ServiceWorkerClientInfo& info) {}
virtual void OnControlleeRemoved(int64_t version_id,
- const GURL& scope,
const std::string& uuid) {}
virtual void OnNoControllees(int64_t version_id, const GURL& scope) {}
+ virtual void OnControlleeNavigationCommitted(
+ int64_t version_id,
+ const std::string& uuid,
+ GlobalFrameRoutingId render_frame_host_id) {}
// Called when the ServiceWorkerContainer.register() promise is resolved.
//
// This is called before the service worker registration is persisted to
@@ -92,9 +95,23 @@ class ServiceWorkerContextCoreObserver {
// add user data to the registration.
virtual void OnRegistrationStored(int64_t registration_id,
const GURL& scope) {}
+
+ // Called after a task has been posted to delete a registration from storage.
+ // This is roughly equivalent to the same time that the promise for
+ // unregister() would be resolved. This means the live
+ // ServiceWorkerRegistration may still exist, and the deletion operator may
+ // not yet have finished.
virtual void OnRegistrationDeleted(int64_t registration_id,
const GURL& scope) {}
+ // Called after all registrations for |origin| are deleted from storage. There
+ // may still be live registrations for this origin in the kUninstalling or
+ // kUninstalled state.
+ //
+ // This is called after OnRegistrationDeleted(). It is called once
+ // ServiceWorkerRegistry gets confirmation that the delete operation finished.
+ virtual void OnAllRegistrationsDeletedForOrigin(const url::Origin& origin) {}
+
// Notified when the storage corruption recovery is completed and all stored
// data is wiped out.
virtual void OnStorageWiped() {}
diff --git a/chromium/content/browser/service_worker/service_worker_context_core_unittest.cc b/chromium/content/browser/service_worker/service_worker_context_core_unittest.cc
index f403b351fb0..21f7bbc753a 100644
--- a/chromium/content/browser/service_worker/service_worker_context_core_unittest.cc
+++ b/chromium/content/browser/service_worker/service_worker_context_core_unittest.cc
@@ -152,7 +152,7 @@ class ServiceWorkerContextCoreTest : public testing::Test,
private:
BrowserTaskEnvironment task_environment_;
std::unique_ptr<EmbeddedWorkerTestHelper> helper_;
- std::vector<ServiceWorkerRemoteProviderEndpoint> remote_endpoints_;
+ std::vector<ServiceWorkerRemoteContainerEndpoint> remote_endpoints_;
GURL scope_for_wait_for_activated_;
base::OnceClosure quit_closure_for_wait_for_activated_;
bool is_observing_context_ = false;
diff --git a/chromium/content/browser/service_worker/service_worker_context_unittest.cc b/chromium/content/browser/service_worker/service_worker_context_unittest.cc
index 448978641cf..163d627c95c 100644
--- a/chromium/content/browser/service_worker/service_worker_context_unittest.cc
+++ b/chromium/content/browser/service_worker/service_worker_context_unittest.cc
@@ -17,8 +17,8 @@
#include "content/browser/service_worker/service_worker_context_core.h"
#include "content/browser/service_worker/service_worker_context_core_observer.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
+#include "content/browser/service_worker/service_worker_host.h"
#include "content/browser/service_worker/service_worker_metrics.h"
-#include "content/browser/service_worker/service_worker_provider_host.h"
#include "content/browser/service_worker/service_worker_registration.h"
#include "content/browser/service_worker/service_worker_storage.h"
#include "content/browser/service_worker/service_worker_test_utils.h"
@@ -266,7 +266,10 @@ class TestServiceWorkerContextObserver : public ServiceWorkerContextObserver {
RegistrationStored,
VersionActivated,
VersionRedundant,
+ ControlleeAdded,
+ ControlleeRemoved,
NoControllees,
+ ControlleeNavigationCommitted,
VersionStartedRunning,
VersionStoppedRunning,
Destruct
@@ -318,6 +321,23 @@ class TestServiceWorkerContextObserver : public ServiceWorkerContextObserver {
events_.push_back(log);
}
+ void OnControlleeAdded(int64_t version_id,
+ const std::string& client_uuid,
+ const ServiceWorkerClientInfo& client_info) override {
+ EventLog log;
+ log.type = EventType::ControlleeAdded;
+ log.version_id = version_id;
+ events_.push_back(log);
+ }
+
+ void OnControlleeRemoved(int64_t version_id,
+ const std::string& client_uuid) override {
+ EventLog log;
+ log.type = EventType::ControlleeRemoved;
+ log.version_id = version_id;
+ events_.push_back(log);
+ }
+
void OnNoControllees(int64_t version_id, const GURL& scope) override {
EventLog log;
log.type = EventType::NoControllees;
@@ -326,6 +346,16 @@ class TestServiceWorkerContextObserver : public ServiceWorkerContextObserver {
events_.push_back(log);
}
+ void OnControlleeNavigationCommitted(
+ int64_t version_id,
+ const std::string& client_uuid,
+ GlobalFrameRoutingId render_frame_host_id) override {
+ EventLog log;
+ log.type = EventType::ControlleeNavigationCommitted;
+ log.version_id = version_id;
+ events_.push_back(log);
+ }
+
void OnVersionStartedRunning(
int64_t version_id,
const ServiceWorkerRunningInfo& running_info) override {
@@ -403,8 +433,9 @@ TEST_F(ServiceWorkerContextTest, RegistrationCompletedObserver) {
EXPECT_EQ(scope, events[2].url);
}
-// Make sure OnNoControllees is called on observer.
-TEST_F(ServiceWorkerContextTest, NoControlleesObserver) {
+// Make sure OnControlleeAdded, OnControlleeRemoved and OnNoControllees are
+// called on observer.
+TEST_F(ServiceWorkerContextTest, Observer_ControlleeEvents) {
GURL scope("https://www.example.com/");
GURL script_url("https://www.example.com/service_worker.js");
blink::mojom::ServiceWorkerRegistrationOptions options;
@@ -420,24 +451,38 @@ TEST_F(ServiceWorkerContextTest, NoControlleesObserver) {
ServiceWorkerVersion::FetchHandlerExistence::EXISTS);
version->SetStatus(ServiceWorkerVersion::ACTIVATED);
- ServiceWorkerRemoteProviderEndpoint endpoint;
+ ServiceWorkerRemoteContainerEndpoint endpoint;
base::WeakPtr<ServiceWorkerContainerHost> container_host =
CreateContainerHostForWindow(helper_->mock_render_process_id(), true,
context()->AsWeakPtr(), &endpoint);
+ TestServiceWorkerContextObserver observer(context_wrapper());
+
version->AddControllee(container_host.get());
base::RunLoop().RunUntilIdle();
- TestServiceWorkerContextObserver observer(context_wrapper());
+ ASSERT_EQ(1u, observer.events().size());
+ EXPECT_EQ(TestServiceWorkerContextObserver::EventType::ControlleeAdded,
+ observer.events()[0].type);
+
+ version->OnControlleeNavigationCommitted(container_host->client_uuid(),
+ container_host->process_id(),
+ container_host->frame_id());
+ base::RunLoop().RunUntilIdle();
+
+ ASSERT_EQ(2u, observer.events().size());
+ EXPECT_EQ(TestServiceWorkerContextObserver::EventType::
+ ControlleeNavigationCommitted,
+ observer.events()[1].type);
version->RemoveControllee(container_host->client_uuid());
base::RunLoop().RunUntilIdle();
- ASSERT_EQ(1u, observer.events().size());
+ ASSERT_EQ(4u, observer.events().size());
+ EXPECT_EQ(TestServiceWorkerContextObserver::EventType::ControlleeRemoved,
+ observer.events()[2].type);
EXPECT_EQ(TestServiceWorkerContextObserver::EventType::NoControllees,
- observer.events()[0].type);
- EXPECT_EQ(scope, observer.events()[0].url);
- EXPECT_EQ(2l, observer.events()[0].version_id);
+ observer.events()[3].type);
}
// Make sure OnVersionActivated is called on observer.
@@ -977,7 +1022,7 @@ TEST_F(ServiceWorkerContextTest, ContainerHostIterator) {
const int kRenderProcessId2 = 2;
const GURL kOrigin1 = GURL("https://www.example.com/");
const GURL kOrigin2 = GURL("https://another-origin.example.net/");
- std::vector<ServiceWorkerRemoteProviderEndpoint> remote_endpoints;
+ std::vector<ServiceWorkerRemoteContainerEndpoint> remote_endpoints;
// Host1 : process_id=1, origin1.
remote_endpoints.emplace_back();
@@ -1020,17 +1065,16 @@ TEST_F(ServiceWorkerContextTest, ContainerHostIterator) {
blink::mojom::ScriptType::kClassic, 1L /* version_id */,
helper_->context()->AsWeakPtr());
remote_endpoints.emplace_back();
- // ServiceWorkrProviderHost creates ServiceWorkerContainerHost for a service
- // worker execution context.
- std::unique_ptr<ServiceWorkerProviderHost> provider_host4 =
- CreateProviderHostForServiceWorkerContext(
- kRenderProcessId2, true /* is_parent_frame_secure */, version.get(),
- context()->AsWeakPtr(), &remote_endpoints.back());
+ // ServiceWorkerHost creates ServiceWorkerContainerHost for a service worker
+ // execution context.
+ std::unique_ptr<ServiceWorkerHost> worker_host4 = CreateServiceWorkerHost(
+ kRenderProcessId2, true /* is_parent_frame_secure */, version.get(),
+ context()->AsWeakPtr(), &remote_endpoints.back());
ASSERT_TRUE(container_host1);
ASSERT_TRUE(container_host2);
ASSERT_TRUE(container_host3);
- ASSERT_TRUE(provider_host4->container_host());
+ ASSERT_TRUE(worker_host4->container_host());
// Iterate over the client container hosts that belong to kOrigin1.
std::set<ServiceWorkerContainerHost*> results;
@@ -1045,7 +1089,7 @@ TEST_F(ServiceWorkerContextTest, ContainerHostIterator) {
EXPECT_TRUE(base::Contains(results, container_host3.get()));
// Iterate over the container hosts that belong to kOrigin2. This should not
- // include provider_host4->container_host() as it's not for controllee.
+ // include worker_host4->container_host() as it's not for controllee.
results.clear();
for (auto it = context()->GetClientContainerHostIterator(
kOrigin2, true /* include_reserved_clients */,
diff --git a/chromium/content/browser/service_worker/service_worker_context_watcher.cc b/chromium/content/browser/service_worker/service_worker_context_watcher.cc
index 12c7fb7b89d..f179bc8687d 100644
--- a/chromium/content/browser/service_worker/service_worker_context_watcher.cc
+++ b/chromium/content/browser/service_worker/service_worker_context_watcher.cc
@@ -8,7 +8,6 @@
#include "base/bind.h"
#include "base/stl_util.h"
-#include "base/task/post_task.h"
#include "content/browser/service_worker/embedded_worker_status.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
#include "content/browser/service_worker/service_worker_version.h"
@@ -103,13 +102,13 @@ void ServiceWorkerContextWatcher::OnStoredRegistrationsOnCoreThread(
++version_it;
}
- base::PostTask(
- FROM_HERE, {BrowserThread::UI},
+ GetUIThreadTaskRunner({})->PostTask(
+ FROM_HERE,
base::BindOnce(
&ServiceWorkerContextWatcher::RunWorkerRegistrationUpdatedCallback,
this, std::move(registrations)));
- base::PostTask(
- FROM_HERE, {BrowserThread::UI},
+ GetUIThreadTaskRunner({})->PostTask(
+ FROM_HERE,
base::BindOnce(
&ServiceWorkerContextWatcher::RunWorkerVersionUpdatedCallback, this,
std::move(versions)));
@@ -163,8 +162,8 @@ void ServiceWorkerContextWatcher::SendRegistrationInfo(
registrations->push_back(
ServiceWorkerRegistrationInfo(scope, registration_id, delete_flag));
}
- base::PostTask(
- FROM_HERE, {BrowserThread::UI},
+ GetUIThreadTaskRunner({})->PostTask(
+ FROM_HERE,
base::BindOnce(
&ServiceWorkerContextWatcher::RunWorkerRegistrationUpdatedCallback,
this, std::move(registrations)));
@@ -176,8 +175,8 @@ void ServiceWorkerContextWatcher::SendVersionInfo(
std::unique_ptr<std::vector<ServiceWorkerVersionInfo>> versions =
std::make_unique<std::vector<ServiceWorkerVersionInfo>>();
versions->push_back(version_info);
- base::PostTask(
- FROM_HERE, {BrowserThread::UI},
+ GetUIThreadTaskRunner({})->PostTask(
+ FROM_HERE,
base::BindOnce(
&ServiceWorkerContextWatcher::RunWorkerVersionUpdatedCallback, this,
std::move(versions)));
@@ -311,8 +310,8 @@ void ServiceWorkerContextWatcher::OnErrorReported(int64_t version_id,
auto it = version_info_map_.find(version_id);
if (it != version_info_map_.end())
registration_id = it->second->registration_id;
- base::PostTask(
- FROM_HERE, {BrowserThread::UI},
+ GetUIThreadTaskRunner({})->PostTask(
+ FROM_HERE,
base::BindOnce(
&ServiceWorkerContextWatcher::RunWorkerErrorReportedCallback, this,
registration_id, version_id, std::make_unique<ErrorInfo>(info)));
@@ -329,8 +328,8 @@ void ServiceWorkerContextWatcher::OnReportConsoleMessage(
if (it != version_info_map_.end())
registration_id = it->second->registration_id;
- base::PostTask(
- FROM_HERE, {BrowserThread::UI},
+ GetUIThreadTaskRunner({})->PostTask(
+ FROM_HERE,
base::BindOnce(
&ServiceWorkerContextWatcher::RunWorkerErrorReportedCallback, this,
registration_id, version_id,
@@ -340,7 +339,6 @@ void ServiceWorkerContextWatcher::OnReportConsoleMessage(
void ServiceWorkerContextWatcher::OnControlleeAdded(
int64_t version_id,
- const GURL& scope,
const std::string& uuid,
const ServiceWorkerClientInfo& info) {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
@@ -355,7 +353,6 @@ void ServiceWorkerContextWatcher::OnControlleeAdded(
}
void ServiceWorkerContextWatcher::OnControlleeRemoved(int64_t version_id,
- const GURL& scope,
const std::string& uuid) {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
auto it = version_info_map_.find(version_id);
diff --git a/chromium/content/browser/service_worker/service_worker_context_watcher.h b/chromium/content/browser/service_worker/service_worker_context_watcher.h
index a2f529f5974..41097058874 100644
--- a/chromium/content/browser/service_worker/service_worker_context_watcher.h
+++ b/chromium/content/browser/service_worker/service_worker_context_watcher.h
@@ -105,11 +105,9 @@ class CONTENT_EXPORT ServiceWorkerContextWatcher
void OnReportConsoleMessage(int64_t version_id,
const ConsoleMessage& message) override;
void OnControlleeAdded(int64_t version_id,
- const GURL& scope,
const std::string& uuid,
const ServiceWorkerClientInfo& info) override;
void OnControlleeRemoved(int64_t version_id,
- const GURL& scope,
const std::string& uuid) override;
void OnRegistrationCompleted(int64_t registration_id,
const GURL& scope) override;
diff --git a/chromium/content/browser/service_worker/service_worker_context_wrapper.cc b/chromium/content/browser/service_worker/service_worker_context_wrapper.cc
index 5deb12403ec..9573ca1bd9f 100644
--- a/chromium/content/browser/service_worker/service_worker_context_wrapper.cc
+++ b/chromium/content/browser/service_worker/service_worker_context_wrapper.cc
@@ -27,10 +27,10 @@
#include "content/browser/loader/navigation_url_loader_impl.h"
#include "content/browser/service_worker/embedded_worker_status.h"
#include "content/browser/service_worker/service_worker_container_host.h"
-#include "content/browser/service_worker/service_worker_context_watcher.h"
+#include "content/browser/service_worker/service_worker_host.h"
+#include "content/browser/service_worker/service_worker_metrics.h"
#include "content/browser/service_worker/service_worker_object_host.h"
#include "content/browser/service_worker/service_worker_process_manager.h"
-#include "content/browser/service_worker/service_worker_provider_host.h"
#include "content/browser/service_worker/service_worker_quota_client.h"
#include "content/browser/service_worker/service_worker_version.h"
#include "content/browser/storage_partition_impl.h"
@@ -45,6 +45,7 @@
#include "content/public/common/content_features.h"
#include "mojo/public/cpp/bindings/self_owned_receiver.h"
#include "net/base/url_util.h"
+#include "storage/browser/quota/quota_client_type.h"
#include "storage/browser/quota/quota_manager_proxy.h"
#include "storage/browser/quota/special_storage_policy.h"
#include "third_party/blink/public/common/service_worker/service_worker_status_code.h"
@@ -58,8 +59,8 @@ namespace {
void WorkerStarted(ServiceWorkerContextWrapper::StatusCallback callback,
blink::ServiceWorkerStatusCode status) {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
- base::PostTask(FROM_HERE, {BrowserThread::UI},
- base::BindOnce(std::move(callback), status));
+ GetUIThreadTaskRunner({})->PostTask(
+ FROM_HERE, base::BindOnce(std::move(callback), status));
}
void StartActiveWorkerOnCoreThread(
@@ -76,8 +77,8 @@ void StartActiveWorkerOnCoreThread(
base::BindOnce(WorkerStarted, std::move(callback)));
return;
}
- base::PostTask(
- FROM_HERE, {BrowserThread::UI},
+ GetUIThreadTaskRunner({})->PostTask(
+ FROM_HERE,
base::BindOnce(std::move(callback),
blink::ServiceWorkerStatusCode::kErrorNotFound));
}
@@ -155,8 +156,8 @@ void FinishRegistrationOnCoreThread(
const std::string& status_message,
int64_t registration_id) {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
- base::PostTask(FROM_HERE, {BrowserThread::UI},
- base::BindOnce(std::move(callback),
+ GetUIThreadTaskRunner({})->PostTask(
+ FROM_HERE, base::BindOnce(std::move(callback),
status == blink::ServiceWorkerStatusCode::kOk));
}
@@ -164,8 +165,8 @@ void FinishUnregistrationOnCoreThread(
ServiceWorkerContext::ResultCallback callback,
blink::ServiceWorkerStatusCode status) {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
- base::PostTask(FROM_HERE, {BrowserThread::UI},
- base::BindOnce(std::move(callback),
+ GetUIThreadTaskRunner({})->PostTask(
+ FROM_HERE, base::BindOnce(std::move(callback),
status == blink::ServiceWorkerStatusCode::kOk));
}
@@ -223,12 +224,6 @@ ServiceWorkerContextWrapper::ServiceWorkerContextWrapper(
// Add this object as an observer of the wrapped |context_core_|. This lets us
// forward observer methods to observers outside of content.
core_observer_list_->AddObserver(this);
-
- watcher_ = base::MakeRefCounted<ServiceWorkerContextWatcher>(
- this,
- base::BindRepeating(&ServiceWorkerContextWrapper::OnRegistrationUpdated,
- base::Unretained(this)),
- base::DoNothing(), base::DoNothing());
}
void ServiceWorkerContextWrapper::Init(
@@ -268,11 +263,6 @@ void ServiceWorkerContextWrapper::Init(
base::RetainedRef(loader_factory_getter),
std::move(
non_network_pending_loader_factory_bundle_for_update_check)));
-
- // The watcher also runs or posts a core thread task which must run after
- // InitOnCoreThread(), so start it after posting that task above.
- if (watcher_)
- watcher_->Start();
}
void ServiceWorkerContextWrapper::Shutdown() {
@@ -280,10 +270,6 @@ void ServiceWorkerContextWrapper::Shutdown() {
storage_partition_ = nullptr;
process_manager_->Shutdown();
- if (watcher_) {
- watcher_->Stop();
- watcher_ = nullptr;
- }
// Use explicit feature check here instead of RunOrPostTaskOnThread(), since
// the feature may be disabled but in unit tests we are considered both on the
@@ -292,8 +278,8 @@ void ServiceWorkerContextWrapper::Shutdown() {
if (ServiceWorkerContext::IsServiceWorkerOnUIEnabled()) {
ShutdownOnCoreThread();
} else {
- base::PostTask(
- FROM_HERE, {BrowserThread::IO},
+ GetIOThreadTaskRunner({})->PostTask(
+ FROM_HERE,
base::BindOnce(&ServiceWorkerContextWrapper::ShutdownOnCoreThread,
this));
}
@@ -364,10 +350,18 @@ void ServiceWorkerContextWrapper::OnRegistrationStored(int64_t registration_id,
const GURL& scope) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ registered_origins_.insert(url::Origin::Create(scope.GetOrigin()));
+
for (auto& observer : observer_list_)
observer.OnRegistrationStored(registration_id, scope);
}
+void ServiceWorkerContextWrapper::OnAllRegistrationsDeletedForOrigin(
+ const url::Origin& origin) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ registered_origins_.erase(origin);
+}
+
void ServiceWorkerContextWrapper::OnReportConsoleMessage(
int64_t version_id,
const ConsoleMessage& message) {
@@ -377,6 +371,25 @@ void ServiceWorkerContextWrapper::OnReportConsoleMessage(
observer.OnReportConsoleMessage(version_id, message);
}
+void ServiceWorkerContextWrapper::OnControlleeAdded(
+ int64_t version_id,
+ const std::string& client_uuid,
+ const ServiceWorkerClientInfo& client_info) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ for (auto& observer : observer_list_)
+ observer.OnControlleeAdded(version_id, client_uuid, client_info);
+}
+
+void ServiceWorkerContextWrapper::OnControlleeRemoved(
+ int64_t version_id,
+ const std::string& client_uuid) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ for (auto& observer : observer_list_)
+ observer.OnControlleeRemoved(version_id, client_uuid);
+}
+
void ServiceWorkerContextWrapper::OnNoControllees(int64_t version_id,
const GURL& scope) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
@@ -385,6 +398,17 @@ void ServiceWorkerContextWrapper::OnNoControllees(int64_t version_id,
observer.OnNoControllees(version_id, scope);
}
+void ServiceWorkerContextWrapper::OnControlleeNavigationCommitted(
+ int64_t version_id,
+ const std::string& uuid,
+ GlobalFrameRoutingId render_frame_host_id) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
+ for (auto& observer : observer_list_)
+ observer.OnControlleeNavigationCommitted(version_id, uuid,
+ render_frame_host_id);
+}
+
void ServiceWorkerContextWrapper::OnStarted(int64_t version_id,
const GURL& scope,
int process_id,
@@ -463,8 +487,8 @@ void ServiceWorkerContextWrapper::RegisterServiceWorker(
return;
}
if (!context_core_) {
- base::PostTask(FROM_HERE, {BrowserThread::UI},
- base::BindOnce(std::move(callback), false));
+ GetUIThreadTaskRunner({})->PostTask(
+ FROM_HERE, base::BindOnce(std::move(callback), false));
return;
}
blink::mojom::ServiceWorkerRegistrationOptions options_to_pass(
@@ -492,8 +516,8 @@ void ServiceWorkerContextWrapper::UnregisterServiceWorker(
return;
}
if (!context_core_) {
- base::PostTask(FROM_HERE, {BrowserThread::UI},
- base::BindOnce(std::move(callback), false));
+ GetUIThreadTaskRunner({})->PostTask(
+ FROM_HERE, base::BindOnce(std::move(callback), false));
return;
}
@@ -540,6 +564,32 @@ void ServiceWorkerContextWrapper::CountExternalRequestsForTest(
origin, std::move(callback)));
}
+bool ServiceWorkerContextWrapper::MaybeHasRegistrationForOrigin(
+ const url::Origin& origin) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ if (!registrations_initialized_) {
+ return true;
+ }
+ if (registered_origins_.find(origin) != registered_origins_.end()) {
+ return true;
+ }
+ return false;
+}
+
+void ServiceWorkerContextWrapper::WaitForRegistrationsInitializedForTest() {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ if (registrations_initialized_)
+ return;
+ base::RunLoop loop;
+ on_registrations_initialized_ = loop.QuitClosure();
+ loop.Run();
+}
+
+void ServiceWorkerContextWrapper::AddRegistrationToRegisteredOriginsForTest(
+ const url::Origin& origin) {
+ registered_origins_.insert(origin);
+}
+
void ServiceWorkerContextWrapper::GetAllOriginsInfo(
GetUsageInfoCallback callback) {
RunOrPostTaskOnCoreThread(
@@ -560,7 +610,8 @@ void ServiceWorkerContextWrapper::GetAllOriginsInfoOnCoreThread(
}
context()->registry()->GetAllRegistrationsInfos(base::BindOnce(
&ServiceWorkerContextWrapper::DidGetAllRegistrationsForGetAllOrigins,
- this, std::move(callback), std::move(callback_runner)));
+ this, base::TimeTicks::Now(), std::move(callback),
+ std::move(callback_runner)));
}
void ServiceWorkerContextWrapper::DeleteForOrigin(const GURL& origin,
@@ -631,8 +682,8 @@ void ServiceWorkerContextWrapper::CheckHasServiceWorker(
return;
}
if (!context_core_) {
- base::PostTask(FROM_HERE, {BrowserThread::UI},
- base::BindOnce(std::move(callback),
+ GetUIThreadTaskRunner({})->PostTask(
+ FROM_HERE, base::BindOnce(std::move(callback),
ServiceWorkerCapability::NO_SERVICE_WORKER));
return;
}
@@ -653,8 +704,8 @@ void ServiceWorkerContextWrapper::CheckOfflineCapability(
return;
}
if (!context_core_) {
- base::PostTask(
- FROM_HERE, {BrowserThread::UI},
+ GetUIThreadTaskRunner({})->PostTask(
+ FROM_HERE,
base::BindOnce(std::move(callback), OfflineCapability::kUnsupported));
return;
}
@@ -676,7 +727,7 @@ void ServiceWorkerContextWrapper::ClearAllServiceWorkersForTest(
}
if (!context_core_) {
- base::PostTask(FROM_HERE, {BrowserThread::UI}, std::move(callback));
+ GetUIThreadTaskRunner({})->PostTask(FROM_HERE, std::move(callback));
return;
}
context_core_->ClearAllServiceWorkersForTest(std::move(callback));
@@ -777,7 +828,7 @@ void ServiceWorkerContextWrapper::DidStartServiceWorkerForMessageDispatch(
event->message = std::move(message);
event->source_origin = url::Origin::Create(source_origin);
event->source_info_for_service_worker =
- version->provider_host()
+ version->worker_host()
->container_host()
->GetOrCreateServiceWorkerObjectHost(version)
->CreateCompleteObjectInfoToSend();
@@ -1075,6 +1126,66 @@ void ServiceWorkerContextWrapper::GetAllRegistrationsOnCoreThread(
context_core_->registry()->GetAllRegistrationsInfos(std::move(callback));
}
+void ServiceWorkerContextWrapper::GetInstalledRegistrationOrigins(
+ base::Optional<std::string> host_filter,
+ GetInstalledRegistrationOriginsCallback callback) {
+ RunOrPostTaskOnCoreThread(
+ FROM_HERE, base::BindOnce(&ServiceWorkerContextWrapper::
+ GetInstalledRegistrationOriginsOnCoreThread,
+ this, host_filter, std::move(callback),
+ base::ThreadTaskRunnerHandle::Get()));
+}
+
+void ServiceWorkerContextWrapper::GetInstalledRegistrationOriginsOnCoreThread(
+ base::Optional<std::string> host_filter,
+ GetInstalledRegistrationOriginsCallback callback,
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner_for_callback) {
+ DCHECK_CURRENTLY_ON(GetCoreThreadId());
+
+ if (!context_core_) {
+ task_runner_for_callback->PostTask(
+ FROM_HERE,
+ base::BindOnce(std::move(callback), std::set<url::Origin>()));
+ return;
+ }
+
+ context()->registry()->storage()->GetRegisteredOrigins(base::BindOnce(
+ &ServiceWorkerContextWrapper::
+ DidGetRegisteredOriginsForGetInstalledRegistrationOrigins,
+ host_filter, std::move(callback), task_runner_for_callback));
+}
+
+void ServiceWorkerContextWrapper::GetStorageUsageForOrigin(
+ const url::Origin& origin,
+ GetStorageUsageForOriginCallback callback) {
+ RunOrPostTaskOnCoreThread(
+ FROM_HERE,
+ base::BindOnce(
+ &ServiceWorkerContextWrapper::GetStorageUsageForOriginOnCoreThread,
+ this, origin,
+ base::BindOnce(
+ [](GetStorageUsageForOriginCallback callback,
+ scoped_refptr<base::TaskRunner> callback_runner,
+ blink::ServiceWorkerStatusCode status, int64_t usage) {
+ callback_runner->PostTask(
+ FROM_HERE,
+ base::BindOnce(std::move(callback), status, usage));
+ },
+ std::move(callback), base::ThreadTaskRunnerHandle::Get())));
+}
+
+void ServiceWorkerContextWrapper::GetStorageUsageForOriginOnCoreThread(
+ const url::Origin& origin,
+ GetStorageUsageForOriginCallback callback) {
+ DCHECK_CURRENTLY_ON(GetCoreThreadId());
+ if (!context_core_) {
+ std::move(callback).Run(blink::ServiceWorkerStatusCode::kErrorAbort, 0);
+ return;
+ }
+ context_core_->registry()->GetStorageUsageForOrigin(origin,
+ std::move(callback));
+}
+
void ServiceWorkerContextWrapper::GetRegistrationsForOrigin(
const url::Origin& origin,
GetRegistrationsCallback callback) {
@@ -1176,11 +1287,11 @@ void ServiceWorkerContextWrapper::GetRegistrationUserKeysAndDataByKeyPrefix(
base::BindOnce(
[](GetUserKeysAndDataCallback callback,
scoped_refptr<base::TaskRunner> callback_runner,
- const base::flat_map<std::string, std::string>& data_map,
- blink::ServiceWorkerStatusCode status) {
+ blink::ServiceWorkerStatusCode status,
+ const base::flat_map<std::string, std::string>& data_map) {
callback_runner->PostTask(
FROM_HERE,
- base::BindOnce(std::move(callback), data_map, status));
+ base::BindOnce(std::move(callback), status, data_map));
},
std::move(callback), base::ThreadTaskRunnerHandle::Get())));
}
@@ -1192,8 +1303,8 @@ void ServiceWorkerContextWrapper::
GetUserKeysAndDataCallback callback) {
DCHECK_CURRENTLY_ON(GetCoreThreadId());
if (!context_core_) {
- std::move(callback).Run(base::flat_map<std::string, std::string>(),
- blink::ServiceWorkerStatusCode::kErrorAbort);
+ std::move(callback).Run(blink::ServiceWorkerStatusCode::kErrorAbort,
+ base::flat_map<std::string, std::string>());
return;
}
context_core_->registry()->GetUserKeysAndDataByKeyPrefix(
@@ -1412,8 +1523,8 @@ void ServiceWorkerContextWrapper::StartServiceWorker(const GURL& scope,
return;
}
if (!context_core_) {
- base::PostTask(FROM_HERE, {BrowserThread::UI},
- base::BindOnce(std::move(callback),
+ GetUIThreadTaskRunner({})->PostTask(
+ FROM_HERE, base::BindOnce(std::move(callback),
blink::ServiceWorkerStatusCode::kErrorAbort));
return;
}
@@ -1504,7 +1615,9 @@ void ServiceWorkerContextWrapper::InitOnCoreThread(
if (quota_manager_proxy) {
quota_manager_proxy->RegisterClient(
- base::MakeRefCounted<ServiceWorkerQuotaClient>(this));
+ base::MakeRefCounted<ServiceWorkerQuotaClient>(this),
+ storage::QuotaClientType::kServiceWorker,
+ {blink::mojom::StorageType::kTemporary});
}
context_core_ = std::make_unique<ServiceWorkerContextCore>(
@@ -1512,6 +1625,11 @@ void ServiceWorkerContextWrapper::InitOnCoreThread(
special_storage_policy, loader_factory_getter,
std::move(non_network_pending_loader_factory_bundle_for_update_check),
core_observer_list_.get(), this);
+
+ if (storage_partition_) {
+ context()->registry()->storage()->GetRegisteredOrigins(base::BindOnce(
+ &ServiceWorkerContextWrapper::DidGetRegisteredOrigins, this));
+ }
}
void ServiceWorkerContextWrapper::FindRegistrationForScopeOnCoreThread(
@@ -1639,6 +1757,7 @@ void ServiceWorkerContextWrapper::DidDeleteAndStartOver(
}
void ServiceWorkerContextWrapper::DidGetAllRegistrationsForGetAllOrigins(
+ base::TimeTicks start_time,
GetUsageInfoCallback callback,
scoped_refptr<base::TaskRunner> callback_runner,
blink::ServiceWorkerStatusCode status,
@@ -1664,6 +1783,10 @@ void ServiceWorkerContextWrapper::DidGetAllRegistrationsForGetAllOrigins(
for (const auto& origin_info_pair : origins) {
usage_infos.push_back(origin_info_pair.second);
}
+
+ ServiceWorkerMetrics::RecordGetAllOriginsInfoTime(base::TimeTicks::Now() -
+ start_time);
+
callback_runner->PostTask(FROM_HERE,
base::BindOnce(std::move(callback), usage_infos));
}
@@ -1673,16 +1796,16 @@ void ServiceWorkerContextWrapper::DidCheckHasServiceWorker(
ServiceWorkerCapability capability) {
DCHECK_CURRENTLY_ON(GetCoreThreadId());
- base::PostTask(FROM_HERE, {BrowserThread::UI},
- base::BindOnce(std::move(callback), capability));
+ GetUIThreadTaskRunner({})->PostTask(
+ FROM_HERE, base::BindOnce(std::move(callback), capability));
}
void ServiceWorkerContextWrapper::DidCheckOfflineCapability(
CheckOfflineCapabilityCallback callback,
OfflineCapability capability) {
DCHECK_CURRENTLY_ON(GetCoreThreadId());
- base::PostTask(FROM_HERE, {BrowserThread::UI},
- base::BindOnce(std::move(callback), capability));
+ GetUIThreadTaskRunner({})->PostTask(
+ FROM_HERE, base::BindOnce(std::move(callback), capability));
}
void ServiceWorkerContextWrapper::DidFindRegistrationForUpdate(
@@ -1721,8 +1844,8 @@ void ServiceWorkerContextWrapper::CountExternalRequests(
}
}
- base::PostTask(
- FROM_HERE, {BrowserThread::UI},
+ GetUIThreadTaskRunner({})->PostTask(
+ FROM_HERE,
base::BindOnce(std::move(callback), pending_external_request_count));
}
@@ -1802,8 +1925,8 @@ void ServiceWorkerContextWrapper::
StartServiceWorkerForNavigationHintResult result) {
DCHECK_CURRENTLY_ON(GetCoreThreadId());
ServiceWorkerMetrics::RecordStartServiceWorkerForNavigationHintResult(result);
- base::PostTask(FROM_HERE, {BrowserThread::UI},
- base::BindOnce(std::move(callback), result));
+ GetUIThreadTaskRunner({})->PostTask(
+ FROM_HERE, base::BindOnce(std::move(callback), result));
}
void ServiceWorkerContextWrapper::StopAllServiceWorkersOnCoreThread(
@@ -1966,44 +2089,41 @@ void ServiceWorkerContextWrapper::DidSetUpLoaderFactoryForUpdateCheck(
std::move(callback).Run(std::move(loader_factory));
}
-bool ServiceWorkerContextWrapper::HasRegistrationForOrigin(
- const GURL& origin) const {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- return !registrations_initialized_ ||
- registrations_for_origin_.find(origin) !=
- registrations_for_origin_.end();
-}
-
-void ServiceWorkerContextWrapper::WaitForRegistrationsInitializedForTest() {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- if (registrations_initialized_)
- return;
- base::RunLoop loop;
- on_registrations_initialized_ = loop.QuitClosure();
- loop.Run();
+void ServiceWorkerContextWrapper::DidGetRegisteredOrigins(
+ std::vector<url::Origin> origins) {
+ DCHECK_CURRENTLY_ON(GetCoreThreadId());
+ GetUIThreadTaskRunner({})->PostTask(
+ FROM_HERE,
+ base::BindOnce(
+ &ServiceWorkerContextWrapper::InitializeRegisteredOriginsOnUI, this,
+ std::move(origins)));
}
-void ServiceWorkerContextWrapper::OnRegistrationUpdated(
- const std::vector<ServiceWorkerRegistrationInfo>& registrations) {
+void ServiceWorkerContextWrapper::InitializeRegisteredOriginsOnUI(
+ std::vector<url::Origin> origins) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- // The first call will initialize stored registrations.
+ registered_origins_.insert(origins.begin(), origins.end());
registrations_initialized_ = true;
-
- for (const auto& registration : registrations) {
- GURL origin = registration.scope.GetOrigin();
- int64_t registration_id = registration.registration_id;
- if (registration.delete_flag == ServiceWorkerRegistrationInfo::IS_DELETED) {
- auto& registration_ids = registrations_for_origin_[origin];
- registration_ids.erase(registration_id);
- if (registration_ids.empty())
- registrations_for_origin_.erase(origin);
- } else {
- registrations_for_origin_[origin].insert(registration_id);
- }
- }
-
if (on_registrations_initialized_)
std::move(on_registrations_initialized_).Run();
}
+// static
+void ServiceWorkerContextWrapper::
+ DidGetRegisteredOriginsForGetInstalledRegistrationOrigins(
+ base::Optional<std::string> host_filter,
+ GetInstalledRegistrationOriginsCallback callback,
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner_for_callback,
+ std::vector<url::Origin> origins) {
+ std::set<url::Origin> filtered_origins;
+ for (const auto& origin : origins) {
+ if (host_filter.has_value() && host_filter.value() != origin.host())
+ continue;
+ filtered_origins.insert(origin);
+ }
+ task_runner_for_callback->PostTask(
+ FROM_HERE,
+ base::BindOnce(std::move(callback), std::move(filtered_origins)));
+}
+
} // namespace content
diff --git a/chromium/content/browser/service_worker/service_worker_context_wrapper.h b/chromium/content/browser/service_worker/service_worker_context_wrapper.h
index 2b55f068327..d654ff5ac3d 100644
--- a/chromium/content/browser/service_worker/service_worker_context_wrapper.h
+++ b/chromium/content/browser/service_worker/service_worker_context_wrapper.h
@@ -47,7 +47,6 @@ class BrowserContext;
class ChromeBlobStorageContext;
class ResourceContext;
class ServiceWorkerContextObserver;
-class ServiceWorkerContextWatcher;
class StoragePartitionImpl;
class URLLoaderFactoryGetter;
@@ -76,6 +75,10 @@ class CONTENT_EXPORT ServiceWorkerContextWrapper
ServiceWorkerRegistry::GetUserKeysAndDataCallback;
using GetUserDataForAllRegistrationsCallback =
ServiceWorkerRegistry::GetUserDataForAllRegistrationsCallback;
+ using GetInstalledRegistrationOriginsCallback =
+ base::OnceCallback<void(const std::set<url::Origin>& origins)>;
+ using GetStorageUsageForOriginCallback =
+ ServiceWorkerRegistry::GetStorageUsageForOriginCallback;
explicit ServiceWorkerContextWrapper(BrowserContext* browser_context);
@@ -123,9 +126,19 @@ class CONTENT_EXPORT ServiceWorkerContextWrapper
const GURL& scope) override;
void OnRegistrationStored(int64_t registration_id,
const GURL& scope) override;
+ void OnAllRegistrationsDeletedForOrigin(const url::Origin& origin) override;
void OnReportConsoleMessage(int64_t version_id,
const ConsoleMessage& message) override;
+ void OnControlleeAdded(int64_t version_id,
+ const std::string& uuid,
+ const ServiceWorkerClientInfo& info) override;
+ void OnControlleeRemoved(int64_t version_id,
+ const std::string& uuid) override;
void OnNoControllees(int64_t version_id, const GURL& scope) override;
+ void OnControlleeNavigationCommitted(
+ int64_t version_id,
+ const std::string& uuid,
+ GlobalFrameRoutingId render_frame_host_id) override;
void OnStarted(int64_t version_id,
const GURL& scope,
int process_id,
@@ -154,6 +167,10 @@ class CONTENT_EXPORT ServiceWorkerContextWrapper
void CountExternalRequestsForTest(
const GURL& url,
CountExternalRequestsCallback callback) override;
+ bool MaybeHasRegistrationForOrigin(const url::Origin& origin) override;
+ void WaitForRegistrationsInitializedForTest() override;
+ void AddRegistrationToRegisteredOriginsForTest(
+ const url::Origin& origin) override;
void GetAllOriginsInfo(GetUsageInfoCallback callback) override;
void DeleteForOrigin(const GURL& origin, ResultCallback callback) override;
void PerformStorageCleanup(base::OnceClosure callback) override;
@@ -295,6 +312,24 @@ class CONTENT_EXPORT ServiceWorkerContextWrapper
const std::string& key_prefix,
StatusCallback callback);
+ // Returns a set of origins which have at least one stored registration.
+ // The set doesn't include installing/uninstalling/uninstalled registrations.
+ // When |host_filter| is specified the set only includes origins whose host
+ // matches |host_filter|.
+ // This function can be called from any thread and the callback is called on
+ // that thread.
+ void GetInstalledRegistrationOrigins(
+ base::Optional<std::string> host_filter,
+ GetInstalledRegistrationOriginsCallback callback);
+
+ // Returns total resource size stored in the storage for |origin|.
+ // This can be called from any thread and the callback is called on that
+ // thread.
+ void GetStorageUsageForOrigin(const url::Origin& origin,
+ GetStorageUsageForOriginCallback callback);
+
+ // Returns a list of ServiceWorkerRegistration for |origin|. The list includes
+ // stored registrations and installing (not stored yet) registrations.
// Must be called on the core thread, and the callback is called on that
// thread. This restriction is because the callback gets pointers to live
// registrations, which live on the core thread.
@@ -321,10 +356,6 @@ class CONTENT_EXPORT ServiceWorkerContextWrapper
// DeleteAndStartOver fails.
ServiceWorkerContextCore* context();
- // Whether |origin| has any registrations. Must be called on UI thread.
- bool HasRegistrationForOrigin(const GURL& origin) const;
- void WaitForRegistrationsInitializedForTest();
-
// This must be called on the core thread, and the |callback| also runs on
// the core thread which can be called with nullptr on failure.
void GetLoaderFactoryForUpdateCheck(
@@ -384,6 +415,7 @@ class CONTENT_EXPORT ServiceWorkerContextWrapper
void DidDeleteAndStartOver(blink::ServiceWorkerStatusCode status);
void DidGetAllRegistrationsForGetAllOrigins(
+ base::TimeTicks start_time,
GetUsageInfoCallback callback,
scoped_refptr<base::TaskRunner> callback_runner,
blink::ServiceWorkerStatusCode status,
@@ -452,10 +484,17 @@ class CONTENT_EXPORT ServiceWorkerContextWrapper
base::OnceCallback<void(scoped_refptr<network::SharedURLLoaderFactory>)>
callback);
- // Called when the stored registrations are loaded, and each time a new
- // service worker is registered.
- void OnRegistrationUpdated(
- const std::vector<ServiceWorkerRegistrationInfo>& registrations);
+ // These methods are used as a callback for GetRegisteredOrigins when
+ // initialising on the core thread, so registered origins can be tracked
+ // on the UI thread as well.
+ void DidGetRegisteredOrigins(std::vector<url::Origin> origins);
+ void InitializeRegisteredOriginsOnUI(std::vector<url::Origin> origins);
+
+ static void DidGetRegisteredOriginsForGetInstalledRegistrationOrigins(
+ base::Optional<std::string> host_filter,
+ GetInstalledRegistrationOriginsCallback callback,
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner_for_callback,
+ std::vector<url::Origin> origins);
// Temporary for crbug.com/824858.
void GetAllOriginsInfoOnCoreThread(
@@ -535,6 +574,13 @@ class CONTENT_EXPORT ServiceWorkerContextWrapper
void StopAllServiceWorkersOnCoreThread(
base::OnceClosure callback,
scoped_refptr<base::SingleThreadTaskRunner> task_runner_for_callback);
+ void GetInstalledRegistrationOriginsOnCoreThread(
+ base::Optional<std::string> host_filter,
+ GetInstalledRegistrationOriginsCallback callback,
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner_for_callback);
+ void GetStorageUsageForOriginOnCoreThread(
+ const url::Origin& origin,
+ GetStorageUsageForOriginCallback callback);
// Observers of |context_core_| which live within content's implementation
// boundary. Shared with |context_core_|.
@@ -566,16 +612,14 @@ class CONTENT_EXPORT ServiceWorkerContextWrapper
base::flat_map<int64_t /* version_id */, ServiceWorkerRunningInfo>
running_service_workers_;
- // Maps the origin to a set of registration ids for that origin. Must be
- // accessed on UI thread.
+ // A set of origins that have at least one registration. See
+ // HasRegistrationForOrigin() for details. Must be accessed on the UI thread.
// TODO(http://crbug.com/824858): This can be removed when service workers are
// fully converted to running on the UI thread.
- base::flat_map<GURL, base::flat_set<int64_t>> registrations_for_origin_;
+ std::set<url::Origin> registered_origins_;
bool registrations_initialized_ = false;
base::OnceClosure on_registrations_initialized_;
- scoped_refptr<ServiceWorkerContextWatcher> watcher_;
-
// Temporary for moving context core to the UI thread.
scoped_refptr<base::TaskRunner> core_thread_task_runner_;
diff --git a/chromium/content/browser/service_worker/service_worker_context_wrapper_unittest.cc b/chromium/content/browser/service_worker/service_worker_context_wrapper_unittest.cc
index 10624f2b307..5551d917b76 100644
--- a/chromium/content/browser/service_worker/service_worker_context_wrapper_unittest.cc
+++ b/chromium/content/browser/service_worker/service_worker_context_wrapper_unittest.cc
@@ -62,6 +62,48 @@ class ServiceWorkerContextWrapperTest : public testing::Test {
ServiceWorkerRegistry* registry() { return context()->registry(); }
ServiceWorkerStorage* storage() { return context()->storage(); }
+ blink::ServiceWorkerStatusCode StoreRegistration(
+ scoped_refptr<ServiceWorkerRegistration> registration) {
+ blink::ServiceWorkerStatusCode result;
+ base::RunLoop loop;
+ registry()->StoreRegistration(
+ registration.get(), registration->waiting_version(),
+ base::BindLambdaForTesting([&](blink::ServiceWorkerStatusCode status) {
+ result = status;
+ loop.Quit();
+ }));
+ loop.Run();
+ return result;
+ }
+
+ blink::ServiceWorkerStatusCode DeleteRegistration(
+ scoped_refptr<ServiceWorkerRegistration> registration) {
+ blink::ServiceWorkerStatusCode result;
+ base::RunLoop loop;
+ registry()->DeleteRegistration(
+ registration, registration->scope().GetOrigin(),
+ base::BindLambdaForTesting([&](blink::ServiceWorkerStatusCode status) {
+ result = status;
+ loop.Quit();
+ }));
+ loop.Run();
+ return result;
+ }
+
+ std::set<url::Origin> GetInstalledRegistrationOrigins(
+ base::Optional<std::string> host_filter) {
+ std::set<url::Origin> result;
+ base::RunLoop loop;
+ wrapper_->GetInstalledRegistrationOrigins(
+ host_filter,
+ base::BindLambdaForTesting([&](const std::set<url::Origin>& origins) {
+ result = origins;
+ loop.Quit();
+ }));
+ loop.Run();
+ return result;
+ }
+
protected:
BrowserTaskEnvironment task_environment_{BrowserTaskEnvironment::IO_MAINLOOP};
base::ScopedTempDir user_data_directory_;
@@ -102,8 +144,279 @@ TEST_F(ServiceWorkerContextWrapperTest, HasRegistration) {
// Now test that registrations are recognized.
wrapper_->WaitForRegistrationsInitializedForTest();
- EXPECT_TRUE(wrapper_->HasRegistrationForOrigin(GURL("https://example.com")));
- EXPECT_FALSE(wrapper_->HasRegistrationForOrigin(GURL("https://example.org")));
+ EXPECT_TRUE(wrapper_->MaybeHasRegistrationForOrigin(
+ url::Origin::Create(GURL("https://example.com"))));
+ EXPECT_FALSE(wrapper_->MaybeHasRegistrationForOrigin(
+ url::Origin::Create(GURL("https://example.org"))));
+}
+
+// This test involves storing two registrations for the same origin to storage
+// and deleting one of them to check that MaybeHasRegistrationForOrigin still
+// correctly returns TRUE since there is still one registration for the origin,
+// and should only return FALSE when ALL registrations for that origin have been
+// deleted from storage.
+TEST_F(ServiceWorkerContextWrapperTest, DeleteRegistrationsForSameOrigin) {
+ wrapper_->WaitForRegistrationsInitializedForTest();
+
+ // Make two registrations for same origin.
+ GURL scope1("https://example1.com/abc/");
+ GURL script1("https://example1.com/abc/sw.js");
+ scoped_refptr<ServiceWorkerRegistration> registration1 =
+ CreateServiceWorkerRegistrationAndVersion(context(), scope1, script1,
+ /*resource_id=*/1);
+ GURL scope2("https://example1.com/xyz/");
+ GURL script2("https://example1.com/xyz/sw.js");
+ scoped_refptr<ServiceWorkerRegistration> registration2 =
+ CreateServiceWorkerRegistrationAndVersion(context(), scope2, script2, 1);
+
+ // Store both registrations.
+ ASSERT_EQ(StoreRegistration(registration1),
+ blink::ServiceWorkerStatusCode::kOk);
+ ASSERT_EQ(StoreRegistration(registration2),
+ blink::ServiceWorkerStatusCode::kOk);
+
+ // Delete one of the registrations.
+ ASSERT_EQ(DeleteRegistration(registration1),
+ blink::ServiceWorkerStatusCode::kOk);
+
+ // Run loop until idle to wait for
+ // ServiceWorkerRegistry::DidDeleteRegistration() to be executed, and make
+ // sure that NotifyAllRegistrationsDeletedForOrigin() is not called.
+ base::RunLoop().RunUntilIdle();
+
+ // Now test that a registration for an origin is still recognized.
+ EXPECT_TRUE(wrapper_->MaybeHasRegistrationForOrigin(
+ url::Origin::Create(GURL("https://example1.com"))));
+
+ // Remove second registration.
+ ASSERT_EQ(DeleteRegistration(registration2),
+ blink::ServiceWorkerStatusCode::kOk);
+
+ // Run loop until idle to wait for
+ // ServiceWorkerRegistry::DidDeleteRegistration() to be executed, and make
+ // sure that this time NotifyAllRegistrationsDeletedForOrigin() is called.
+ base::RunLoop().RunUntilIdle();
+
+ // Now test that origin does not have any registrations.
+ EXPECT_FALSE(wrapper_->MaybeHasRegistrationForOrigin(
+ url::Origin::Create(GURL("https://example1.com"))));
+}
+
+// This tests deleting registrations from storage and checking that even if live
+// registrations may exist, MaybeHasRegistrationForOrigin correctly returns
+// FALSE since the registrations do not exist in storage.
+TEST_F(ServiceWorkerContextWrapperTest, DeleteRegistration) {
+ wrapper_->WaitForRegistrationsInitializedForTest();
+
+ // Make registration.
+ GURL scope1("https://example2.com/");
+ GURL script1("https://example2.com/");
+ scoped_refptr<ServiceWorkerRegistration> registration =
+ CreateServiceWorkerRegistrationAndVersion(context(), scope1, script1,
+ /*resource_id=*/1);
+
+ // Store registration.
+ ASSERT_EQ(StoreRegistration(registration),
+ blink::ServiceWorkerStatusCode::kOk);
+
+ wrapper_->OnRegistrationCompleted(registration->id(), registration->scope());
+ base::RunLoop().RunUntilIdle();
+
+ // Now test that a registration is recognized.
+ EXPECT_TRUE(wrapper_->MaybeHasRegistrationForOrigin(
+ url::Origin::Create(GURL("https://example2.com"))));
+
+ // Delete registration from storage.
+ ASSERT_EQ(DeleteRegistration(registration),
+ blink::ServiceWorkerStatusCode::kOk);
+
+ // Finish deleting registration from storage.
+ base::RunLoop().RunUntilIdle();
+
+ // Now test that origin does not have any registrations. This should return
+ // FALSE even when live registrations may exist, as the registrations have
+ // been deleted from storage.
+ EXPECT_FALSE(wrapper_->MaybeHasRegistrationForOrigin(
+ url::Origin::Create(GURL("https://example2.com"))));
+}
+
+// GetInstalledRegistrationOrigins tests:
+
+// No registration.
+TEST_F(ServiceWorkerContextWrapperTest, GetInstalledRegistrationOrigins_Empty) {
+ wrapper_->WaitForRegistrationsInitializedForTest();
+
+ // No registration stored yet.
+ std::set<url::Origin> registered_origins =
+ GetInstalledRegistrationOrigins(base::nullopt);
+ EXPECT_EQ(registered_origins.size(), 0UL);
+}
+
+// On registration.
+TEST_F(ServiceWorkerContextWrapperTest, GetInstalledRegistrationOrigins_One) {
+ const GURL scope("https://example.com/");
+ const GURL script("https://example.com/sw.js");
+ const url::Origin origin = url::Origin::Create(scope.GetOrigin());
+
+ wrapper_->WaitForRegistrationsInitializedForTest();
+ scoped_refptr<ServiceWorkerRegistration> registration =
+ CreateServiceWorkerRegistrationAndVersion(context(), scope, script,
+ /*resource_id=*/1);
+ ASSERT_EQ(StoreRegistration(registration),
+ blink::ServiceWorkerStatusCode::kOk);
+ base::RunLoop().RunUntilIdle();
+
+ std::set<url::Origin> installed_origins =
+ GetInstalledRegistrationOrigins(base::nullopt);
+ ASSERT_EQ(installed_origins.size(), 1UL);
+ EXPECT_EQ(*installed_origins.begin(), origin);
+}
+
+// Two registrations from the same origin.
+TEST_F(ServiceWorkerContextWrapperTest,
+ GetInstalledRegistrationOrigins_SameOrigin) {
+ const GURL scope1("https://example.com/foo");
+ const GURL script1("https://example.com/foo/sw.js");
+ const url::Origin origin = url::Origin::Create(scope1.GetOrigin());
+ const GURL scope2("https://example.com/bar");
+ const GURL script2("https://example.com/bar/sw.js");
+
+ wrapper_->WaitForRegistrationsInitializedForTest();
+
+ scoped_refptr<ServiceWorkerRegistration> registration1 =
+ CreateServiceWorkerRegistrationAndVersion(context(), scope1, script1,
+ /*resource_id=*/1);
+ ASSERT_EQ(StoreRegistration(registration1),
+ blink::ServiceWorkerStatusCode::kOk);
+ scoped_refptr<ServiceWorkerRegistration> registration2 =
+ CreateServiceWorkerRegistrationAndVersion(context(), scope2, script2,
+ /*resource_id=*/2);
+ ASSERT_EQ(StoreRegistration(registration2),
+ blink::ServiceWorkerStatusCode::kOk);
+ base::RunLoop().RunUntilIdle();
+
+ std::set<url::Origin> installed_origins =
+ GetInstalledRegistrationOrigins(base::nullopt);
+ ASSERT_EQ(installed_origins.size(), 1UL);
+ EXPECT_EQ(*installed_origins.begin(), origin);
+}
+
+// Two registrations from different origins.
+TEST_F(ServiceWorkerContextWrapperTest,
+ GetInstalledRegistrationOrigins_DifferentOrigin) {
+ const GURL scope1("https://example1.com/foo");
+ const GURL script1("https://example1.com/foo/sw.js");
+ const url::Origin origin1 = url::Origin::Create(scope1.GetOrigin());
+ const GURL scope2("https://example2.com/bar");
+ const GURL script2("https://example2.com/bar/sw.js");
+ const url::Origin origin2 = url::Origin::Create(scope2.GetOrigin());
+
+ wrapper_->WaitForRegistrationsInitializedForTest();
+
+ scoped_refptr<ServiceWorkerRegistration> registration1 =
+ CreateServiceWorkerRegistrationAndVersion(context(), scope1, script1,
+ /*resource_id=*/1);
+ ASSERT_EQ(StoreRegistration(registration1),
+ blink::ServiceWorkerStatusCode::kOk);
+ scoped_refptr<ServiceWorkerRegistration> registration2 =
+ CreateServiceWorkerRegistrationAndVersion(context(), scope2, script2,
+ /*resource_id=*/2);
+ ASSERT_EQ(StoreRegistration(registration2),
+ blink::ServiceWorkerStatusCode::kOk);
+ base::RunLoop().RunUntilIdle();
+
+ std::set<url::Origin> installed_origins =
+ GetInstalledRegistrationOrigins(base::nullopt);
+ ASSERT_EQ(installed_origins.size(), 2UL);
+ EXPECT_TRUE(base::Contains(installed_origins, origin1));
+ EXPECT_TRUE(base::Contains(installed_origins, origin2));
+}
+
+// One registration, host filter matches it.
+TEST_F(ServiceWorkerContextWrapperTest,
+ GetInstalledRegistrationOrigins_HostFilterMatch) {
+ const GURL scope("https://example.com/");
+ const GURL script("https://example.com/sw.js");
+ const url::Origin origin = url::Origin::Create(scope.GetOrigin());
+
+ wrapper_->WaitForRegistrationsInitializedForTest();
+ scoped_refptr<ServiceWorkerRegistration> registration =
+ CreateServiceWorkerRegistrationAndVersion(context(), scope, script,
+ /*resource_id=*/1);
+ ASSERT_EQ(StoreRegistration(registration),
+ blink::ServiceWorkerStatusCode::kOk);
+ base::RunLoop().RunUntilIdle();
+
+ std::set<url::Origin> installed_origins =
+ GetInstalledRegistrationOrigins("example.com");
+ ASSERT_EQ(installed_origins.size(), 1UL);
+ EXPECT_EQ(*installed_origins.begin(), origin);
+}
+
+// One registration, host filter does not match it.
+TEST_F(ServiceWorkerContextWrapperTest,
+ GetInstalledRegistrationOrigins_HostFilterNoMatch) {
+ const GURL scope("https://example.com/");
+ const GURL script("https://example.com/sw.js");
+ const url::Origin origin = url::Origin::Create(scope.GetOrigin());
+
+ wrapper_->WaitForRegistrationsInitializedForTest();
+ scoped_refptr<ServiceWorkerRegistration> registration =
+ CreateServiceWorkerRegistrationAndVersion(context(), scope, script,
+ /*resource_id=*/1);
+ ASSERT_EQ(StoreRegistration(registration),
+ blink::ServiceWorkerStatusCode::kOk);
+ base::RunLoop().RunUntilIdle();
+
+ std::set<url::Origin> installed_origins =
+ GetInstalledRegistrationOrigins("example.test");
+ EXPECT_EQ(installed_origins.size(), 0UL);
+}
+
+// Two registrations, one is deleted, only the other one is returned.
+TEST_F(ServiceWorkerContextWrapperTest,
+ GetInstalledRegistrationOrigins_DeletedRegistration) {
+ const GURL scope1("https://example1.com/foo");
+ const GURL script1("https://example1.com/foo/sw.js");
+ const url::Origin origin1 = url::Origin::Create(scope1.GetOrigin());
+ const GURL scope2("https://example2.com/bar");
+ const GURL script2("https://example2.com/bar/sw.js");
+ const url::Origin origin2 = url::Origin::Create(scope2.GetOrigin());
+
+ wrapper_->WaitForRegistrationsInitializedForTest();
+
+ scoped_refptr<ServiceWorkerRegistration> registration1 =
+ CreateServiceWorkerRegistrationAndVersion(context(), scope1, script1,
+ /*resource_id=*/1);
+ ASSERT_EQ(StoreRegistration(registration1),
+ blink::ServiceWorkerStatusCode::kOk);
+ scoped_refptr<ServiceWorkerRegistration> registration2 =
+ CreateServiceWorkerRegistrationAndVersion(context(), scope2, script2,
+ /*resource_id=*/2);
+ ASSERT_EQ(StoreRegistration(registration2),
+ blink::ServiceWorkerStatusCode::kOk);
+ base::RunLoop().RunUntilIdle();
+
+ {
+ std::set<url::Origin> installed_origins =
+ GetInstalledRegistrationOrigins(base::nullopt);
+ ASSERT_EQ(installed_origins.size(), 2UL);
+ EXPECT_TRUE(base::Contains(installed_origins, origin1));
+ EXPECT_TRUE(base::Contains(installed_origins, origin2));
+ }
+
+ // Delete |registration2|.
+ ASSERT_EQ(DeleteRegistration(registration2),
+ blink::ServiceWorkerStatusCode::kOk);
+ base::RunLoop().RunUntilIdle();
+
+ // After |registration2| is deleted, only |origin1| should be returned.
+ {
+ std::set<url::Origin> installed_origins =
+ GetInstalledRegistrationOrigins(base::nullopt);
+ ASSERT_EQ(installed_origins.size(), 1UL);
+ EXPECT_EQ(*installed_origins.begin(), origin1);
+ }
}
} // namespace content
diff --git a/chromium/content/browser/service_worker/service_worker_controllee_request_handler.cc b/chromium/content/browser/service_worker/service_worker_controllee_request_handler.cc
index 679d926f14e..e2c6c9759ee 100644
--- a/chromium/content/browser/service_worker/service_worker_controllee_request_handler.cc
+++ b/chromium/content/browser/service_worker/service_worker_controllee_request_handler.cc
@@ -16,8 +16,8 @@
#include "content/browser/service_worker/service_worker_container_host.h"
#include "content/browser/service_worker/service_worker_context_core.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
+#include "content/browser/service_worker/service_worker_main_resource_loader.h"
#include "content/browser/service_worker/service_worker_metrics.h"
-#include "content/browser/service_worker/service_worker_navigation_loader.h"
#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"
@@ -471,9 +471,9 @@ void ServiceWorkerControlleeRequestHandler::ContinueWithActivatedVersion(
}
// Finally, we want to forward to the service worker! Make a
- // ServiceWorkerNavigationLoader which does that work.
- loader_wrapper_ = std::make_unique<ServiceWorkerNavigationLoaderWrapper>(
- std::make_unique<ServiceWorkerNavigationLoader>(
+ // ServiceWorkerMainResourceLoader which does that work.
+ loader_wrapper_ = std::make_unique<ServiceWorkerMainResourceLoaderWrapper>(
+ std::make_unique<ServiceWorkerMainResourceLoader>(
std::move(fallback_callback_), container_host_,
base::WrapRefCounted(context_->loader_factory_getter())));
@@ -484,7 +484,7 @@ void ServiceWorkerControlleeRequestHandler::ContinueWithActivatedVersion(
TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "Info",
"Forwarded to the ServiceWorker");
std::move(loader_callback_)
- .Run(base::BindOnce(&ServiceWorkerNavigationLoader::StartRequest,
+ .Run(base::BindOnce(&ServiceWorkerMainResourceLoader::StartRequest,
loader_wrapper_->get()->AsWeakPtr()));
}
diff --git a/chromium/content/browser/service_worker/service_worker_controllee_request_handler.h b/chromium/content/browser/service_worker/service_worker_controllee_request_handler.h
index fe3b8be1ddd..bb32752f5bf 100644
--- a/chromium/content/browser/service_worker/service_worker_controllee_request_handler.h
+++ b/chromium/content/browser/service_worker/service_worker_controllee_request_handler.h
@@ -17,7 +17,7 @@
#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/browser/service_worker/service_worker_main_resource_loader.h"
#include "content/common/content_export.h"
#include "services/network/public/cpp/resource_request.h"
#include "services/network/public/mojom/fetch_api.mojom.h"
@@ -36,7 +36,7 @@ class ServiceWorkerVersion;
// Handles main resource requests for service worker clients (documents and
// shared workers).
//
-// TODO(crbug.com/824858): Merge into ServiceWorkerNavigationLoaderInterceptor
+// TODO(crbug.com/824858): Merge into ServiceWorkerMainResourceLoaderInterceptor
// after the service worker core thread changes to the UI thread.
class CONTENT_EXPORT ServiceWorkerControlleeRequestHandler final {
public:
@@ -71,7 +71,7 @@ class CONTENT_EXPORT ServiceWorkerControlleeRequestHandler final {
const network::ResourceRequest& tentative_request);
// Exposed for testing.
- ServiceWorkerNavigationLoader* loader() {
+ ServiceWorkerMainResourceLoader* loader() {
return loader_wrapper_ ? loader_wrapper_->get() : nullptr;
}
@@ -113,7 +113,7 @@ class CONTENT_EXPORT ServiceWorkerControlleeRequestHandler final {
// If true, service workers are bypassed for request interception.
const bool skip_service_worker_;
- std::unique_ptr<ServiceWorkerNavigationLoaderWrapper> loader_wrapper_;
+ std::unique_ptr<ServiceWorkerMainResourceLoaderWrapper> loader_wrapper_;
BrowserContext* browser_context_;
ResourceContext* resource_context_;
GURL stripped_url_;
diff --git a/chromium/content/browser/service_worker/service_worker_controllee_request_handler_unittest.cc b/chromium/content/browser/service_worker/service_worker_controllee_request_handler_unittest.cc
index bd1151b1658..1c70031bb17 100644
--- a/chromium/content/browser/service_worker/service_worker_controllee_request_handler_unittest.cc
+++ b/chromium/content/browser/service_worker/service_worker_controllee_request_handler_unittest.cc
@@ -19,7 +19,7 @@
#include "content/browser/service_worker/service_worker_container_host.h"
#include "content/browser/service_worker/service_worker_context_core.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
-#include "content/browser/service_worker/service_worker_provider_host.h"
+#include "content/browser/service_worker/service_worker_host.h"
#include "content/browser/service_worker/service_worker_registration.h"
#include "content/browser/service_worker/service_worker_test_utils.h"
#include "content/public/browser/resource_context.h"
@@ -70,7 +70,7 @@ class ServiceWorkerControlleeRequestHandlerTest : public testing::Test {
base::DoNothing(), base::DoNothing());
}
- ServiceWorkerNavigationLoader* loader() { return handler_->loader(); }
+ ServiceWorkerMainResourceLoader* loader() { return handler_->loader(); }
void SetHandler(
std::unique_ptr<ServiceWorkerControlleeRequestHandler> handler) {
@@ -145,7 +145,7 @@ class ServiceWorkerControlleeRequestHandlerTest : public testing::Test {
net::TestDelegate url_request_delegate_;
GURL scope_;
GURL script_url_;
- std::vector<ServiceWorkerRemoteProviderEndpoint> remote_endpoints_;
+ std::vector<ServiceWorkerRemoteContainerEndpoint> remote_endpoints_;
};
class ServiceWorkerTestContentBrowserClient : public TestContentBrowserClient {
diff --git a/chromium/content/browser/service_worker/service_worker_database.cc b/chromium/content/browser/service_worker/service_worker_database.cc
index 54323ba4897..19f04328c7e 100644
--- a/chromium/content/browser/service_worker/service_worker_database.cc
+++ b/chromium/content/browser/service_worker/service_worker_database.cc
@@ -5,6 +5,7 @@
#include "content/browser/service_worker/service_worker_database.h"
#include "base/command_line.h"
+#include "base/debug/crash_logging.h"
#include "base/files/file_util.h"
#include "base/location.h"
#include "base/logging.h"
@@ -448,9 +449,58 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::GetRegistrationsForOrigin(
return status;
}
+ServiceWorkerDatabase::Status ServiceWorkerDatabase::GetUsageForOrigin(
+ const url::Origin& origin,
+ int64_t& out_usage) {
+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+ out_usage = 0;
+
+ Status status = LazyOpen(false);
+ if (IsNewOrNonexistentDatabase(status))
+ return Status::kOk;
+ if (status != Status::kOk)
+ return status;
+
+ std::string prefix = CreateRegistrationKeyPrefix(origin.GetURL());
+
+ // Read all registrations.
+ {
+ std::unique_ptr<leveldb::Iterator> itr(
+ db_->NewIterator(leveldb::ReadOptions()));
+ for (itr->Seek(prefix); itr->Valid(); itr->Next()) {
+ status = LevelDBStatusToServiceWorkerDBStatus(itr->status());
+ if (status != Status::kOk)
+ break;
+
+ if (!RemovePrefix(itr->key().ToString(), prefix, nullptr))
+ break;
+
+ storage::mojom::ServiceWorkerRegistrationDataPtr registration;
+ status = ParseRegistrationData(itr->value().ToString(), &registration);
+ if (status != Status::kOk)
+ break;
+ out_usage += registration->resources_total_size_bytes;
+ }
+ }
+
+ // Count reading all registrations as one "read operation" for UMA
+ // purposes.
+ HandleReadResult(FROM_HERE, status);
+ if (status != Status::kOk) {
+ out_usage = 0;
+ }
+
+ return status;
+}
+
ServiceWorkerDatabase::Status ServiceWorkerDatabase::GetAllRegistrations(
std::vector<storage::mojom::ServiceWorkerRegistrationDataPtr>*
registrations) {
+ static base::debug::CrashKeyString* crash_key =
+ base::debug::AllocateCrashKeyString("num_registrations",
+ base::debug::CrashKeySize::Size32);
+
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(registrations->empty());
@@ -465,6 +515,9 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::GetAllRegistrations(
db_->NewIterator(leveldb::ReadOptions()));
for (itr->Seek(service_worker_internals::kRegKeyPrefix); itr->Valid();
itr->Next()) {
+ base::debug::ScopedCrashKeyString num_registrations_crash(
+ crash_key, base::NumberToString(registrations->size()));
+
status = LevelDBStatusToServiceWorkerDBStatus(itr->status());
if (status != Status::kOk) {
registrations->clear();
@@ -484,7 +537,8 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::GetAllRegistrations(
registrations->push_back(std::move(registration));
}
}
-
+ UMA_HISTOGRAM_COUNTS_10000("ServiceWorker.RegistrationCount",
+ registrations->size());
HandleReadResult(FROM_HERE, status);
return status;
}
@@ -1221,7 +1275,7 @@ ServiceWorkerDatabase::DeleteUserDataForAllRegistrationsByKeyPrefix(
}
ServiceWorkerDatabase::Status ServiceWorkerDatabase::GetUncommittedResourceIds(
- std::set<int64_t>* ids) {
+ std::vector<int64_t>* ids) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
return ReadResourceIds(service_worker_internals::kUncommittedResIdKeyPrefix,
ids);
@@ -1229,7 +1283,7 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::GetUncommittedResourceIds(
ServiceWorkerDatabase::Status
ServiceWorkerDatabase::WriteUncommittedResourceIds(
- const std::set<int64_t>& ids) {
+ const std::vector<int64_t>& ids) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
leveldb::WriteBatch batch;
Status status = WriteResourceIdsInBatch(
@@ -1240,14 +1294,14 @@ ServiceWorkerDatabase::WriteUncommittedResourceIds(
}
ServiceWorkerDatabase::Status ServiceWorkerDatabase::GetPurgeableResourceIds(
- std::set<int64_t>* ids) {
+ std::vector<int64_t>* ids) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
return ReadResourceIds(service_worker_internals::kPurgeableResIdKeyPrefix,
ids);
}
ServiceWorkerDatabase::Status ServiceWorkerDatabase::ClearPurgeableResourceIds(
- const std::set<int64_t>& ids) {
+ const std::vector<int64_t>& ids) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
Status status = LazyOpen(false);
if (IsNewOrNonexistentDatabase(status))
@@ -1263,7 +1317,7 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::ClearPurgeableResourceIds(
ServiceWorkerDatabase::Status
ServiceWorkerDatabase::PurgeUncommittedResourceIds(
- const std::set<int64_t>& ids) {
+ const std::vector<int64_t>& ids) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
Status status = LazyOpen(false);
if (IsNewOrNonexistentDatabase(status))
@@ -1815,7 +1869,7 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::DeleteResourceRecords(
ServiceWorkerDatabase::Status ServiceWorkerDatabase::ReadResourceIds(
const char* id_key_prefix,
- std::set<int64_t>* ids) {
+ std::vector<int64_t>* ids) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(id_key_prefix);
DCHECK(ids->empty());
@@ -1827,12 +1881,13 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::ReadResourceIds(
return status;
{
+ std::set<int64_t> unique_ids;
std::unique_ptr<leveldb::Iterator> itr(
db_->NewIterator(leveldb::ReadOptions()));
for (itr->Seek(id_key_prefix); itr->Valid(); itr->Next()) {
status = LevelDBStatusToServiceWorkerDBStatus(itr->status());
if (status != Status::kOk) {
- ids->clear();
+ unique_ids.clear();
break;
}
@@ -1843,11 +1898,12 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::ReadResourceIds(
int64_t resource_id;
status = ParseId(unprefixed, &resource_id);
if (status != Status::kOk) {
- ids->clear();
+ unique_ids.clear();
break;
}
- ids->insert(resource_id);
+ unique_ids.insert(resource_id);
}
+ *ids = std::vector<int64_t>(unique_ids.begin(), unique_ids.end());
}
HandleReadResult(FROM_HERE, status);
@@ -1856,7 +1912,7 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::ReadResourceIds(
ServiceWorkerDatabase::Status ServiceWorkerDatabase::WriteResourceIdsInBatch(
const char* id_key_prefix,
- const std::set<int64_t>& ids,
+ const std::vector<int64_t>& ids,
leveldb::WriteBatch* batch) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(id_key_prefix);
@@ -1878,7 +1934,7 @@ ServiceWorkerDatabase::Status ServiceWorkerDatabase::WriteResourceIdsInBatch(
ServiceWorkerDatabase::Status ServiceWorkerDatabase::DeleteResourceIdsInBatch(
const char* id_key_prefix,
- const std::set<int64_t>& ids,
+ const std::vector<int64_t>& ids,
leveldb::WriteBatch* batch) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(id_key_prefix);
diff --git a/chromium/content/browser/service_worker/service_worker_database.h b/chromium/content/browser/service_worker/service_worker_database.h
index 286a4286f7a..dd3058fbcfd 100644
--- a/chromium/content/browser/service_worker/service_worker_database.h
+++ b/chromium/content/browser/service_worker/service_worker_database.h
@@ -96,6 +96,9 @@ class CONTENT_EXPORT ServiceWorkerDatabase {
std::vector<std::vector<storage::mojom::ServiceWorkerResourceRecordPtr>>*
opt_resources_list);
+ // Reads the total resource size stored in the database for |origin|.
+ Status GetUsageForOrigin(const url::Origin& origin, int64_t& out_usage);
+
// Reads all registrations from the database. Returns OK if successfully read
// or not found. Otherwise, returns an error.
Status GetAllRegistrations(
@@ -240,24 +243,24 @@ class CONTENT_EXPORT ServiceWorkerDatabase {
// Reads resource ids from the uncommitted list. Returns OK on success.
// Otherwise clears |ids| and returns an error.
- Status GetUncommittedResourceIds(std::set<int64_t>* ids);
+ Status GetUncommittedResourceIds(std::vector<int64_t>* ids);
// Writes resource ids into the uncommitted list. Returns OK on success.
// Otherwise writes nothing and returns an error.
- Status WriteUncommittedResourceIds(const std::set<int64_t>& ids);
+ Status WriteUncommittedResourceIds(const std::vector<int64_t>& ids);
// Reads resource ids from the purgeable list. Returns OK on success.
// Otherwise clears |ids| and returns an error.
- Status GetPurgeableResourceIds(std::set<int64_t>* ids);
+ Status GetPurgeableResourceIds(std::vector<int64_t>* ids);
// Deletes resource ids from the purgeable list. Returns OK on success.
// Otherwise deletes nothing and returns an error.
- Status ClearPurgeableResourceIds(const std::set<int64_t>& ids);
+ Status ClearPurgeableResourceIds(const std::vector<int64_t>& ids);
// Writes resource ids into the purgeable list and removes them from the
// uncommitted list. Returns OK on success. Otherwise writes nothing and
// returns an error.
- Status PurgeUncommittedResourceIds(const std::set<int64_t>& ids);
+ Status PurgeUncommittedResourceIds(const std::vector<int64_t>& ids);
// Deletes all data for |origins|, namely, unique origin, registrations and
// resource records. Resources are moved to the purgeable list. Returns OK if
@@ -333,19 +336,19 @@ class CONTENT_EXPORT ServiceWorkerDatabase {
// Reads resource ids for |id_key_prefix| from the database. Returns OK if
// it's successfully read or not found in the database. Otherwise, returns an
// error.
- Status ReadResourceIds(const char* id_key_prefix, std::set<int64_t>* ids);
+ Status ReadResourceIds(const char* id_key_prefix, std::vector<int64_t>* ids);
// Write resource ids for |id_key_prefix| into the database. Returns OK on
// success. Otherwise, returns writes nothing and returns an error.
Status WriteResourceIdsInBatch(const char* id_key_prefix,
- const std::set<int64_t>& ids,
+ const std::vector<int64_t>& ids,
leveldb::WriteBatch* batch);
// Deletes resource ids for |id_key_prefix| from the database. Returns OK if
// it's successfully deleted or not found in the database. Otherwise, returns
// an error.
Status DeleteResourceIdsInBatch(const char* id_key_prefix,
- const std::set<int64_t>& ids,
+ const std::vector<int64_t>& ids,
leveldb::WriteBatch* batch);
// Deletes all user data for |registration_id| from the database. Returns OK
diff --git a/chromium/content/browser/service_worker/service_worker_database_unittest.cc b/chromium/content/browser/service_worker/service_worker_database_unittest.cc
index 2595362644b..7f5c03feeae 100644
--- a/chromium/content/browser/service_worker/service_worker_database_unittest.cc
+++ b/chromium/content/browser/service_worker/service_worker_database_unittest.cc
@@ -276,11 +276,9 @@ TEST(ServiceWorkerDatabaseTest, GetNextAvailableIds) {
EXPECT_EQ(0, ids.res_id);
// Writing uncommitted resources bumps the next available resource id.
- const int64_t kUncommittedIds[] = {0, 1, 3, 5, 6, 10};
- EXPECT_EQ(
- ServiceWorkerDatabase::Status::kOk,
- database->WriteUncommittedResourceIds(std::set<int64_t>(
- kUncommittedIds, kUncommittedIds + base::size(kUncommittedIds))));
+ const std::vector<int64_t> kUncommittedIds = {0, 1, 3, 5, 6, 10};
+ EXPECT_EQ(ServiceWorkerDatabase::Status::kOk,
+ database->WriteUncommittedResourceIds(kUncommittedIds));
EXPECT_EQ(
ServiceWorkerDatabase::Status::kOk,
database->GetNextAvailableIds(&ids.reg_id, &ids.ver_id, &ids.res_id));
@@ -289,10 +287,9 @@ TEST(ServiceWorkerDatabaseTest, GetNextAvailableIds) {
EXPECT_EQ(11, ids.res_id);
// Writing purgeable resources bumps the next available id.
- const int64_t kPurgeableIds[] = {4, 12, 16, 17, 20};
+ const std::vector<int64_t> kPurgeableIds = {4, 12, 16, 17, 20};
EXPECT_EQ(ServiceWorkerDatabase::Status::kOk,
- database->WriteUncommittedResourceIds(std::set<int64_t>(
- kPurgeableIds, kPurgeableIds + base::size(kPurgeableIds))));
+ database->WriteUncommittedResourceIds(kPurgeableIds));
EXPECT_EQ(
ServiceWorkerDatabase::Status::kOk,
database->GetNextAvailableIds(&ids.reg_id, &ids.ver_id, &ids.res_id));
@@ -336,9 +333,9 @@ TEST(ServiceWorkerDatabaseTest, GetNextAvailableIds) {
// Same with resources.
int64_t kLowResourceId = 15;
+ std::vector<int64_t> resource_ids = {kLowResourceId};
EXPECT_EQ(ServiceWorkerDatabase::Status::kOk,
- database->WriteUncommittedResourceIds(
- std::set<int64_t>(&kLowResourceId, &kLowResourceId + 1)));
+ database->WriteUncommittedResourceIds(resource_ids));
// Close and reopen the database to verify the stored values.
database.reset(CreateDatabase(database_dir.GetPath()));
@@ -651,11 +648,11 @@ TEST(ServiceWorkerDatabaseTest, Registration_Basic) {
// Write a resource to the uncommitted list to make sure that writing
// registration removes resource ids associated with the registration from
// the uncommitted list.
- std::set<int64_t> uncommitted_ids;
- uncommitted_ids.insert(resources[0]->resource_id);
+ std::vector<int64_t> uncommitted_ids;
+ uncommitted_ids.push_back(resources[0]->resource_id);
EXPECT_EQ(ServiceWorkerDatabase::Status::kOk,
database->WriteUncommittedResourceIds(uncommitted_ids));
- std::set<int64_t> uncommitted_ids_out;
+ std::vector<int64_t> uncommitted_ids_out;
EXPECT_EQ(ServiceWorkerDatabase::Status::kOk,
database->GetUncommittedResourceIds(&uncommitted_ids_out));
EXPECT_EQ(uncommitted_ids, uncommitted_ids_out);
@@ -709,7 +706,7 @@ TEST(ServiceWorkerDatabaseTest, Registration_Basic) {
database->ReadRegistrationOrigin(data.registration_id, &origin_out));
// Resources should be purgeable because these are no longer referred.
- std::set<int64_t> purgeable_ids_out;
+ std::vector<int64_t> purgeable_ids_out;
EXPECT_EQ(ServiceWorkerDatabase::Status::kOk,
database->GetPurgeableResourceIds(&purgeable_ids_out));
EXPECT_EQ(2u, purgeable_ids_out.size());
@@ -836,7 +833,7 @@ TEST(ServiceWorkerDatabaseTest, Registration_Overwrite) {
VerifyRegistrationData(*updated_data, *data_out);
VerifyResourceRecords(resources2, resources_out);
- std::set<int64_t> purgeable_ids_out;
+ std::vector<int64_t> purgeable_ids_out;
EXPECT_EQ(ServiceWorkerDatabase::Status::kOk,
database->GetPurgeableResourceIds(&purgeable_ids_out));
EXPECT_EQ(2u, purgeable_ids_out.size());
@@ -904,7 +901,7 @@ TEST(ServiceWorkerDatabaseTest, Registration_Multiple) {
database->ReadRegistrationOrigin(data2.registration_id, &origin_out));
EXPECT_EQ(origin, origin_out);
- std::set<int64_t> purgeable_ids_out;
+ std::vector<int64_t> purgeable_ids_out;
EXPECT_EQ(ServiceWorkerDatabase::Status::kOk,
database->GetPurgeableResourceIds(&purgeable_ids_out));
EXPECT_TRUE(purgeable_ids_out.empty());
@@ -1863,29 +1860,24 @@ TEST(ServiceWorkerDatabaseTest, UncommittedAndPurgeableResourceIds) {
std::unique_ptr<ServiceWorkerDatabase> database(CreateDatabaseInMemory());
// Write {1, 2, 3} into the uncommitted list.
- std::set<int64_t> ids1;
- ids1.insert(1);
- ids1.insert(2);
- ids1.insert(3);
+ std::vector<int64_t> ids1 = {1, 2, 3};
EXPECT_EQ(ServiceWorkerDatabase::Status::kOk,
database->WriteUncommittedResourceIds(ids1));
- std::set<int64_t> ids_out;
+ std::vector<int64_t> ids_out;
EXPECT_EQ(ServiceWorkerDatabase::Status::kOk,
database->GetUncommittedResourceIds(&ids_out));
EXPECT_EQ(ids1, ids_out);
// Write {2, 4} into the uncommitted list.
- std::set<int64_t> ids2;
- ids2.insert(2);
- ids2.insert(4);
+ std::vector<int64_t> ids2 = {2, 4};
EXPECT_EQ(ServiceWorkerDatabase::Status::kOk,
database->WriteUncommittedResourceIds(ids2));
ids_out.clear();
EXPECT_EQ(ServiceWorkerDatabase::Status::kOk,
database->GetUncommittedResourceIds(&ids_out));
- std::set<int64_t> expected = base::STLSetUnion<std::set<int64_t>>(ids1, ids2);
+ std::vector<int64_t> expected = {1, 2, 3, 4};
EXPECT_EQ(expected, ids_out);
// Move {2, 4} from the uncommitted list to the purgeable list.
@@ -1908,7 +1900,7 @@ TEST(ServiceWorkerDatabaseTest, UncommittedAndPurgeableResourceIds) {
ids_out.clear();
EXPECT_EQ(ServiceWorkerDatabase::Status::kOk,
database->GetUncommittedResourceIds(&ids_out));
- expected = base::STLSetDifference<std::set<int64_t>>(ids1, ids2);
+ expected = {1, 3};
EXPECT_EQ(expected, ids_out);
}
@@ -2018,7 +2010,7 @@ TEST(ServiceWorkerDatabaseTest, DeleteAllDataForOrigin) {
EXPECT_EQ(origin2, origin_out);
// The resources associated with |origin1| should be purgeable.
- std::set<int64_t> purgeable_ids_out;
+ std::vector<int64_t> purgeable_ids_out;
EXPECT_EQ(ServiceWorkerDatabase::Status::kOk,
database->GetPurgeableResourceIds(&purgeable_ids_out));
EXPECT_EQ(4u, purgeable_ids_out.size());
diff --git a/chromium/content/browser/service_worker/service_worker_fetch_dispatcher.cc b/chromium/content/browser/service_worker/service_worker_fetch_dispatcher.cc
index ae523422b85..4dd9f0f70af 100644
--- a/chromium/content/browser/service_worker/service_worker_fetch_dispatcher.cc
+++ b/chromium/content/browser/service_worker/service_worker_fetch_dispatcher.cc
@@ -12,7 +12,6 @@
#include "base/bind_helpers.h"
#include "base/containers/queue.h"
#include "base/feature_list.h"
-#include "base/task/post_task.h"
#include "base/time/time.h"
#include "base/trace_event/trace_event.h"
#include "content/browser/child_process_security_policy_impl.h"
@@ -32,6 +31,7 @@
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
+#include "content/public/browser/global_request_id.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/common/content_client.h"
#include "content/public/common/navigation_policy.h"
@@ -45,7 +45,6 @@
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "net/url_request/url_request.h"
#include "services/network/public/cpp/wrapper_shared_url_loader_factory.h"
-#include "services/network/throttling/throttling_controller.h"
#include "third_party/blink/public/common/service_worker/service_worker_status_code.h"
namespace content {
@@ -192,8 +191,8 @@ class DelegatingURLLoaderClient final : public network::mojom::URLLoaderClient {
if (!worker_id_ || !devtools_enabled_)
return;
while (!devtools_callbacks.empty()) {
- base::PostTask(FROM_HERE, {BrowserThread::UI},
- base::BindOnce(std::move(devtools_callbacks.front()),
+ GetUIThreadTaskRunner({})->PostTask(
+ FROM_HERE, base::BindOnce(std::move(devtools_callbacks.front()),
*worker_id_, devtools_request_id_));
devtools_callbacks.pop();
}
@@ -534,6 +533,13 @@ void ServiceWorkerFetchDispatcher::StartWorker() {
GetEventType(),
base::BindOnce(&ServiceWorkerFetchDispatcher::DidStartWorker,
weak_factory_.GetWeakPtr()));
+
+ if (ServiceWorkerContext::IsServiceWorkerOnUIEnabled() &&
+ version_->is_endpoint_ready()) {
+ // For an active service worker, the endpoint becomes ready synchronously
+ // with StartWorker(). In that case, we can dispatch FetchEvent immediately.
+ DispatchFetchEvent();
+ }
}
void ServiceWorkerFetchDispatcher::DidStartWorker(
@@ -547,17 +553,19 @@ void ServiceWorkerFetchDispatcher::DidStartWorker(
DidFail(status);
return;
}
- DispatchFetchEvent();
+ if (!IsEventDispatched()) {
+ DispatchFetchEvent();
+ }
}
void ServiceWorkerFetchDispatcher::DispatchFetchEvent() {
- DCHECK_EQ(EmbeddedWorkerStatus::RUNNING, version_->running_status())
+ DCHECK(EmbeddedWorkerStatus::STARTING == version_->running_status() ||
+ EmbeddedWorkerStatus::RUNNING == version_->running_status())
<< "Worker stopped too soon after it was started.";
TRACE_EVENT_WITH_FLOW0("ServiceWorker",
"ServiceWorkerFetchDispatcher::DispatchFetchEvent",
TRACE_ID_LOCAL(this),
TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
-
// Grant the service worker's process access to files in the request body.
if (request_->body) {
GrantFileAccessToProcess(version_->embedded_worker()->process_id(),
@@ -598,16 +606,7 @@ void ServiceWorkerFetchDispatcher::DispatchFetchEvent() {
auto params = blink::mojom::DispatchFetchEventParams::New();
params->request = std::move(request_);
params->client_id = client_id_;
- if (is_offline_capability_check_) {
- // TODO(crbug.com/1031950): We have to set up |preload_handle_| correctly so
- // that event.preloadResponse is valid one if navigation preload is enabled.
-
- // At present, an offline-capability-check fetch event is not calling
- // MayStartNavigationPreload() so |preload_handle_| is null here.
- DCHECK(!preload_handle_);
- } else {
- params->preload_handle = std::move(preload_handle_);
- }
+ params->preload_handle = std::move(preload_handle_);
params->is_offline_capability_check = is_offline_capability_check_;
// TODO(https://crbug.com/900700): Make the remote connected to a receiver
@@ -637,9 +636,9 @@ void ServiceWorkerFetchDispatcher::DidFail(
"ServiceWorker", "ServiceWorkerFetchDispatcher::DidFail",
TRACE_ID_LOCAL(this),
TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "status", status);
- Complete(status, FetchEventResult::kShouldFallback,
- blink::mojom::FetchAPIResponse::New(), nullptr /* body_as_stream */,
- nullptr /* timing */);
+ RunCallback(status, FetchEventResult::kShouldFallback,
+ blink::mojom::FetchAPIResponse::New(),
+ nullptr /* body_as_stream */, nullptr /* timing */);
}
void ServiceWorkerFetchDispatcher::DidFinish(
@@ -652,17 +651,21 @@ void ServiceWorkerFetchDispatcher::DidFinish(
"ServiceWorkerFetchDispatcher::DidFinish",
TRACE_ID_LOCAL(this),
TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
- Complete(blink::ServiceWorkerStatusCode::kOk, fetch_result,
- std::move(response), std::move(body_as_stream), std::move(timing));
+ RunCallback(blink::ServiceWorkerStatusCode::kOk, fetch_result,
+ std::move(response), std::move(body_as_stream),
+ std::move(timing));
}
-void ServiceWorkerFetchDispatcher::Complete(
+void ServiceWorkerFetchDispatcher::RunCallback(
blink::ServiceWorkerStatusCode status,
FetchEventResult fetch_result,
blink::mojom::FetchAPIResponsePtr response,
blink::mojom::ServiceWorkerStreamHandlePtr body_as_stream,
blink::mojom::ServiceWorkerFetchEventTimingPtr timing) {
- DCHECK(fetch_callback_);
+ // Fetch dispatcher can be completed at this point due to a failure of
+ // starting up a worker. In that case, let's simply ignore it.
+ if (!fetch_callback_)
+ return;
std::move(fetch_callback_)
.Run(status, fetch_result, std::move(response), std::move(body_as_stream),
@@ -684,6 +687,23 @@ bool ServiceWorkerFetchDispatcher::MaybeStartNavigationPreload(
if (request_->body)
return false;
+ // When the fetch event is for an offline capability check, respond to the
+ // navigation preload with a network disconnected error, to simulate offline.
+ if (is_offline_capability_check_) {
+ mojo::PendingRemote<network::mojom::URLLoader> url_loader_to_pass;
+ mojo::Remote<network::mojom::URLLoaderClient> url_loader_client;
+ auto dummy_receiver = url_loader_to_pass.InitWithNewPipeAndPassReceiver();
+
+ preload_handle_ = blink::mojom::FetchEventPreloadHandle::New();
+ preload_handle_->url_loader = std::move(url_loader_to_pass);
+ preload_handle_->url_loader_client_receiver =
+ url_loader_client.BindNewPipeAndPassReceiver();
+
+ url_loader_client->OnComplete(
+ network::URLLoaderCompletionStatus(net::ERR_INTERNET_DISCONNECTED));
+ return true;
+ }
+
network::ResourceRequest resource_request(original_request);
if (resource_type_ == blink::mojom::ResourceType::kMainFrame) {
resource_request.resource_type = static_cast<int>(
@@ -699,8 +719,6 @@ bool ServiceWorkerFetchDispatcher::MaybeStartNavigationPreload(
DCHECK(net::HttpUtil::IsValidHeaderValue(
version_->navigation_preload_state().header));
- ServiceWorkerMetrics::RecordNavigationPreloadRequestHeaderSize(
- version_->navigation_preload_state().header.length());
resource_request.headers.SetHeader(
"Service-Worker-Navigation-Preload",
version_->navigation_preload_state().header);
@@ -709,8 +727,8 @@ bool ServiceWorkerFetchDispatcher::MaybeStartNavigationPreload(
scoped_refptr<network::SharedURLLoaderFactory> factory;
mojo::PendingRemote<network::mojom::URLLoaderFactory> network_factory;
- base::PostTask(
- FROM_HERE, {BrowserThread::UI},
+ GetUIThreadTaskRunner({})->PostTask(
+ FROM_HERE,
base::BindOnce(&CreateNetworkFactoryForNavigationPreloadOnUI,
frame_tree_node_id, std::move(context_wrapper),
network_factory.InitWithNewPipeAndPassReceiver()));
@@ -727,10 +745,6 @@ bool ServiceWorkerFetchDispatcher::MaybeStartNavigationPreload(
auto url_loader_client = std::make_unique<DelegatingURLLoaderClient>(
std::move(inner_url_loader_client), resource_request);
- // Get a unique request id across browser-initiated navigations and navigation
- // preloads.
- int request_id = GlobalRequestID::MakeBrowserInitiated().request_id;
-
// Start the network request for the URL using the network factory.
// TODO(falken): What to do about routing_id.
mojo::PendingRemote<network::mojom::URLLoaderClient>
@@ -740,7 +754,8 @@ bool ServiceWorkerFetchDispatcher::MaybeStartNavigationPreload(
factory->CreateLoaderAndStart(
url_loader.InitWithNewPipeAndPassReceiver(), -1 /* routing_id? */,
- request_id, network::mojom::kURLLoadOptionNone, resource_request,
+ GlobalRequestID::MakeBrowserInitiated().request_id,
+ network::mojom::kURLLoadOptionNone, resource_request,
std::move(url_loader_client_to_pass),
net::MutableNetworkTrafficAnnotationTag(
kNavigationPreloadTrafficAnnotation));
@@ -758,6 +773,10 @@ ServiceWorkerMetrics::EventType ServiceWorkerFetchDispatcher::GetEventType()
return ResourceTypeToEventType(resource_type_);
}
+bool ServiceWorkerFetchDispatcher::IsEventDispatched() const {
+ return request_.is_null();
+}
+
// static
void ServiceWorkerFetchDispatcher::OnFetchEventFinished(
ServiceWorkerVersion* version,
diff --git a/chromium/content/browser/service_worker/service_worker_fetch_dispatcher.h b/chromium/content/browser/service_worker/service_worker_fetch_dispatcher.h
index c24c6308b43..b7756b77122 100644
--- a/chromium/content/browser/service_worker/service_worker_fetch_dispatcher.h
+++ b/chromium/content/browser/service_worker/service_worker_fetch_dispatcher.h
@@ -91,11 +91,11 @@ class CONTENT_EXPORT ServiceWorkerFetchDispatcher {
blink::mojom::FetchAPIResponsePtr response,
blink::mojom::ServiceWorkerStreamHandlePtr body_as_stream,
blink::mojom::ServiceWorkerFetchEventTimingPtr timing);
- void Complete(blink::ServiceWorkerStatusCode status,
- FetchEventResult fetch_result,
- blink::mojom::FetchAPIResponsePtr response,
- blink::mojom::ServiceWorkerStreamHandlePtr body_as_stream,
- blink::mojom::ServiceWorkerFetchEventTimingPtr timing);
+ void RunCallback(blink::ServiceWorkerStatusCode status,
+ FetchEventResult fetch_result,
+ blink::mojom::FetchAPIResponsePtr response,
+ blink::mojom::ServiceWorkerStreamHandlePtr body_as_stream,
+ blink::mojom::ServiceWorkerFetchEventTimingPtr timing);
// The fetch event stays open until all respondWith() and waitUntil() promises
// are settled. This function is called once the renderer signals that
@@ -109,6 +109,8 @@ class CONTENT_EXPORT ServiceWorkerFetchDispatcher {
ServiceWorkerMetrics::EventType GetEventType() const;
+ bool IsEventDispatched() const;
+
blink::mojom::FetchAPIRequestPtr request_;
std::string client_id_;
scoped_refptr<ServiceWorkerVersion> version_;
diff --git a/chromium/content/browser/service_worker/service_worker_provider_host.cc b/chromium/content/browser/service_worker/service_worker_host.cc
index 18ca2aeffce..136443f9328 100644
--- a/chromium/content/browser/service_worker/service_worker_provider_host.cc
+++ b/chromium/content/browser/service_worker/service_worker_host.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/browser/service_worker/service_worker_provider_host.h"
+#include "content/browser/service_worker/service_worker_host.h"
#include <utility>
@@ -48,26 +48,26 @@ void CreateQuicTransportConnectorImpl(
} // anonymous namespace
-ServiceWorkerProviderHost::ServiceWorkerProviderHost(
+ServiceWorkerHost::ServiceWorkerHost(
mojo::PendingAssociatedReceiver<blink::mojom::ServiceWorkerContainerHost>
host_receiver,
- ServiceWorkerVersion* running_hosted_version,
+ ServiceWorkerVersion* version,
base::WeakPtr<ServiceWorkerContextCore> context)
- : running_hosted_version_(running_hosted_version),
+ : version_(version),
container_host_(std::make_unique<content::ServiceWorkerContainerHost>(
std::move(context))),
host_receiver_(container_host_.get(), std::move(host_receiver)) {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
- DCHECK(running_hosted_version_);
+ DCHECK(version_);
container_host_->set_service_worker_host(this);
container_host_->UpdateUrls(
- running_hosted_version_->script_url(),
- net::SiteForCookies::FromUrl(running_hosted_version_->script_url()),
- running_hosted_version_->script_origin());
+ version_->script_url(),
+ net::SiteForCookies::FromUrl(version_->script_url()),
+ version_->script_origin());
}
-ServiceWorkerProviderHost::~ServiceWorkerProviderHost() {
+ServiceWorkerHost::~ServiceWorkerHost() {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
// Explicitly destroy the ServiceWorkerContainerHost to release
@@ -75,12 +75,12 @@ ServiceWorkerProviderHost::~ServiceWorkerProviderHost() {
// that. Otherwise, this destructor can trigger their Mojo connection error
// handlers, which would call back into halfway destroyed |this|. This is
// because they are associated with the ServiceWorker interface, which can be
- // destroyed while in this destructor (|running_hosted_version_|'s
- // |event_dispatcher_|). See https://crbug.com/854993.
+ // destroyed while in this destructor (|version_|'s |event_dispatcher_|).
+ // See https://crbug.com/854993.
container_host_.reset();
}
-void ServiceWorkerProviderHost::CompleteStartWorkerPreparation(
+void ServiceWorkerHost::CompleteStartWorkerPreparation(
int process_id,
mojo::PendingReceiver<blink::mojom::BrowserInterfaceBroker>
broker_receiver) {
@@ -91,33 +91,29 @@ void ServiceWorkerProviderHost::CompleteStartWorkerPreparation(
broker_receiver_.Bind(std::move(broker_receiver));
}
-void ServiceWorkerProviderHost::CreateQuicTransportConnector(
+void ServiceWorkerHost::CreateQuicTransportConnector(
mojo::PendingReceiver<blink::mojom::QuicTransportConnector> receiver) {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
RunOrPostTaskOnThread(
FROM_HERE, BrowserThread::UI,
base::BindOnce(&CreateQuicTransportConnectorImpl, worker_process_id_,
- running_hosted_version_->script_origin(),
- std::move(receiver)));
+ version_->script_origin(), std::move(receiver)));
}
-void ServiceWorkerProviderHost::BindCacheStorage(
+void ServiceWorkerHost::BindCacheStorage(
mojo::PendingReceiver<blink::mojom::CacheStorage> receiver) {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
DCHECK(!base::FeatureList::IsEnabled(
blink::features::kEagerCacheStorageSetupForServiceWorkers));
- running_hosted_version_->embedded_worker()->BindCacheStorage(
- std::move(receiver));
+ version_->embedded_worker()->BindCacheStorage(std::move(receiver));
}
-base::WeakPtr<ServiceWorkerProviderHost>
-ServiceWorkerProviderHost::GetWeakPtr() {
+base::WeakPtr<ServiceWorkerHost> ServiceWorkerHost::GetWeakPtr() {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
return weak_factory_.GetWeakPtr();
}
-void ServiceWorkerProviderHost::ReportNoBinderForInterface(
- const std::string& error) {
+void ServiceWorkerHost::ReportNoBinderForInterface(const std::string& error) {
broker_receiver_.ReportBadMessage(error + " for the service worker scope");
}
diff --git a/chromium/content/browser/service_worker/service_worker_provider_host.h b/chromium/content/browser/service_worker/service_worker_host.h
index d8afd0194ee..e9daa763c9e 100644
--- a/chromium/content/browser/service_worker/service_worker_provider_host.h
+++ b/chromium/content/browser/service_worker/service_worker_host.h
@@ -2,8 +2,8 @@
// 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_PROVIDER_HOST_H_
-#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_PROVIDER_HOST_H_
+#ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_HOST_H_
+#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_HOST_H_
#include <memory>
#include <string>
@@ -37,28 +37,23 @@ namespace content {
class ServiceWorkerContextCore;
class ServiceWorkerVersion;
-// ServiceWorkerProviderHost is the host of a service worker execution context
-// in the renderer process. One ServiceWorkerProviderHost instance hosts one
-// service worker execution context instance.
+// ServiceWorkerHost is the host of a service worker execution context in the
+// renderer process. One ServiceWorkerHost instance hosts one service worker
+// execution context instance.
//
-// ServiceWorkerProviderHost lives on the service worker core thread, since all
-// nearly all browser process service worker machinery lives on the service
-// worker core thread.
-//
-// TODO(https://crbug.com/931087): Rename this to ServiceWorkerHost.
-class CONTENT_EXPORT ServiceWorkerProviderHost {
+// ServiceWorkerHost lives on the service worker core thread, since all nearly
+// all browser process service worker machinery lives on the service worker core
+// thread.
+class CONTENT_EXPORT ServiceWorkerHost {
public:
- ServiceWorkerProviderHost(
- mojo::PendingAssociatedReceiver<blink::mojom::ServiceWorkerContainerHost>
- host_receiver,
- ServiceWorkerVersion* running_hosted_version,
- base::WeakPtr<ServiceWorkerContextCore> context);
- ~ServiceWorkerProviderHost();
+ ServiceWorkerHost(mojo::PendingAssociatedReceiver<
+ blink::mojom::ServiceWorkerContainerHost> host_receiver,
+ ServiceWorkerVersion* version,
+ base::WeakPtr<ServiceWorkerContextCore> context);
+ ~ServiceWorkerHost();
int worker_process_id() const { return worker_process_id_; }
- ServiceWorkerVersion* running_hosted_version() const {
- return running_hosted_version_;
- }
+ ServiceWorkerVersion* version() const { return version_; }
// Completes initialization of this provider host. It is called once a
// renderer process has been found to host the worker.
@@ -77,19 +72,18 @@ class CONTENT_EXPORT ServiceWorkerProviderHost {
return container_host_.get();
}
- base::WeakPtr<ServiceWorkerProviderHost> GetWeakPtr();
+ base::WeakPtr<ServiceWorkerHost> GetWeakPtr();
void ReportNoBinderForInterface(const std::string& error);
private:
int worker_process_id_ = ChildProcessHost::kInvalidUniqueID;
- // The instance of service worker this provider hosts.
- // Raw pointer is safe because the version owns |this|.
- ServiceWorkerVersion* const running_hosted_version_;
+ // The service worker being hosted. Raw pointer is safe because the version
+ // owns |this|.
+ ServiceWorkerVersion* const version_;
- BrowserInterfaceBrokerImpl<ServiceWorkerProviderHost,
- const ServiceWorkerVersionInfo&>
+ BrowserInterfaceBrokerImpl<ServiceWorkerHost, const ServiceWorkerVersionInfo&>
broker_{this};
mojo::Receiver<blink::mojom::BrowserInterfaceBroker> broker_receiver_{
&broker_};
@@ -99,11 +93,11 @@ class CONTENT_EXPORT ServiceWorkerProviderHost {
mojo::AssociatedReceiver<blink::mojom::ServiceWorkerContainerHost>
host_receiver_;
- base::WeakPtrFactory<ServiceWorkerProviderHost> weak_factory_{this};
+ base::WeakPtrFactory<ServiceWorkerHost> weak_factory_{this};
- DISALLOW_COPY_AND_ASSIGN(ServiceWorkerProviderHost);
+ DISALLOW_COPY_AND_ASSIGN(ServiceWorkerHost);
};
} // namespace content
-#endif // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_PROVIDER_HOST_H_
+#endif // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_HOST_H_
diff --git a/chromium/content/browser/service_worker/service_worker_info.h b/chromium/content/browser/service_worker/service_worker_info.h
index 76b2e6514f0..78af74044c3 100644
--- a/chromium/content/browser/service_worker/service_worker_info.h
+++ b/chromium/content/browser/service_worker/service_worker_info.h
@@ -20,8 +20,8 @@
namespace content {
+class ServiceWorkerClientInfo;
enum class EmbeddedWorkerStatus;
-struct ServiceWorkerClientInfo;
struct CONTENT_EXPORT ServiceWorkerVersionInfo {
public:
diff --git a/chromium/content/browser/service_worker/service_worker_installed_scripts_sender_unittest.cc b/chromium/content/browser/service_worker/service_worker_installed_scripts_sender_unittest.cc
index 3107253371c..855ef9e27de 100644
--- a/chromium/content/browser/service_worker/service_worker_installed_scripts_sender_unittest.cc
+++ b/chromium/content/browser/service_worker/service_worker_installed_scripts_sender_unittest.cc
@@ -21,6 +21,7 @@
#include "net/base/io_buffer.h"
#include "net/base/test_completion_callback.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/common/blob/blob_utils.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom.h"
namespace content {
@@ -300,7 +301,7 @@ TEST_F(ServiceWorkerInstalledScriptsSenderTest, FailedToSendBody) {
TEST_F(ServiceWorkerInstalledScriptsSenderTest, FailedToSendMetaData) {
const GURL kMainScriptURL = version()->script_url();
std::string long_meta_data = "I'm the meta data!";
- long_meta_data.resize(3E6, '!');
+ long_meta_data.resize(blink::BlobUtils::GetDataPipeCapacity(3E6) + 1, '!');
std::map<GURL, ExpectedScriptInfo> kExpectedScriptInfoMap = {
{kMainScriptURL,
{1,
diff --git a/chromium/content/browser/service_worker/service_worker_internals_ui.cc b/chromium/content/browser/service_worker/service_worker_internals_ui.cc
index fada516d742..1d86f96b8fd 100644
--- a/chromium/content/browser/service_worker/service_worker_internals_ui.cc
+++ b/chromium/content/browser/service_worker/service_worker_internals_ui.cc
@@ -36,6 +36,7 @@
#include "content/public/browser/web_ui_data_source.h"
#include "content/public/common/child_process_host.h"
#include "content/public/common/url_constants.h"
+#include "services/network/public/mojom/content_security_policy.mojom.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_object.mojom.h"
using base::DictionaryValue;
@@ -56,8 +57,8 @@ void OperationCompleteCallback(WeakPtr<ServiceWorkerInternalsUI> internals,
int callback_id,
blink::ServiceWorkerStatusCode status) {
if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
- base::PostTask(FROM_HERE, {BrowserThread::UI},
- base::BindOnce(OperationCompleteCallback, internals,
+ GetUIThreadTaskRunner({})->PostTask(
+ FROM_HERE, base::BindOnce(OperationCompleteCallback, internals,
callback_id, status));
return;
}
@@ -159,9 +160,9 @@ void UpdateVersionInfo(const ServiceWorkerVersionInfo& version,
for (auto& it : version.clients) {
auto client = DictionaryValue();
client.SetStringPath("client_id", it.first);
- if (it.second.type == blink::mojom::ServiceWorkerClientType::kWindow) {
+ if (it.second.type() == blink::mojom::ServiceWorkerClientType::kWindow) {
WebContents* web_contents =
- WebContents::FromFrameTreeNodeId(it.second.frame_tree_node_id);
+ WebContents::FromFrameTreeNodeId(it.second.GetFrameTreeNodeId());
if (web_contents)
client.SetStringPath("url", web_contents->GetURL().spec());
}
@@ -221,8 +222,8 @@ void DidGetStoredRegistrationsOnCoreThread(
blink::ServiceWorkerStatusCode status,
const std::vector<ServiceWorkerRegistrationInfo>& stored_registrations) {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
- base::PostTask(
- FROM_HERE, {BrowserThread::UI},
+ GetUIThreadTaskRunner({})->PostTask(
+ FROM_HERE,
base::BindOnce(std::move(callback), context->GetAllLiveRegistrationInfo(),
context->GetAllLiveVersionInfo(), stored_registrations));
}
@@ -349,7 +350,8 @@ ServiceWorkerInternalsUI::ServiceWorkerInternalsUI(WebUI* web_ui)
: WebUIController(web_ui), next_partition_id_(0) {
WebUIDataSource* source =
WebUIDataSource::Create(kChromeUIServiceWorkerInternalsHost);
- source->OverrideContentSecurityPolicyScriptSrc(
+ source->OverrideContentSecurityPolicy(
+ network::mojom::CSPDirectiveName::ScriptSrc,
"script-src chrome://resources 'self' 'unsafe-eval';");
source->UseStringsJs();
source->AddResourcePath("serviceworker_internals.js",
diff --git a/chromium/content/browser/service_worker/service_worker_job_unittest.cc b/chromium/content/browser/service_worker/service_worker_job_unittest.cc
index d51ddca1d09..646f0e40095 100644
--- a/chromium/content/browser/service_worker/service_worker_job_unittest.cc
+++ b/chromium/content/browser/service_worker/service_worker_job_unittest.cc
@@ -203,7 +203,7 @@ class ServiceWorkerJobTest : public testing::Test {
BrowserTaskEnvironment task_environment_;
std::unique_ptr<EmbeddedWorkerTestHelper> helper_;
- std::vector<ServiceWorkerRemoteProviderEndpoint> remote_endpoints_;
+ std::vector<ServiceWorkerRemoteContainerEndpoint> remote_endpoints_;
};
scoped_refptr<ServiceWorkerRegistration> ServiceWorkerJobTest::RunRegisterJob(
@@ -432,10 +432,10 @@ TEST_F(ServiceWorkerJobTest, Unregister) {
observer.RunUntilActivated(registration->installing_version(), runner);
scoped_refptr<ServiceWorkerVersion> version = registration->active_version();
- ServiceWorkerProviderHost* provider_host =
- registration->active_version()->provider_host();
- ASSERT_NE(nullptr, provider_host);
- ServiceWorkerContainerHost* container_host = provider_host->container_host();
+ ServiceWorkerHost* worker_host =
+ registration->active_version()->worker_host();
+ ASSERT_NE(nullptr, worker_host);
+ ServiceWorkerContainerHost* container_host = worker_host->container_host();
// One ServiceWorkerRegistrationObjectHost should have been created for the
// new registration.
EXPECT_EQ(1UL, container_host->registration_object_hosts_.size());
@@ -448,7 +448,7 @@ TEST_F(ServiceWorkerJobTest, Unregister) {
WaitForVersionRunningStatus(version, EmbeddedWorkerStatus::STOPPED);
// The service worker registration object host and service worker object host
- // have been destroyed together with |provider_host| by the above
+ // have been destroyed together with |worker_host| by the above
// unregistration. Then |registration| and |version| should be the last one
// reference to the corresponding instance.
EXPECT_TRUE(registration->HasOneRef());
@@ -534,11 +534,11 @@ TEST_F(ServiceWorkerJobTest, RegisterDuplicateScript) {
// During the above registration, a service worker registration object host
// for ServiceWorkerGlobalScope#registration has been created/added into
- // |provider_host|.
- ServiceWorkerProviderHost* provider_host =
- old_registration->active_version()->provider_host();
- ASSERT_NE(nullptr, provider_host);
- ServiceWorkerContainerHost* container_host = provider_host->container_host();
+ // |worker_host|.
+ ServiceWorkerHost* worker_host =
+ old_registration->active_version()->worker_host();
+ ASSERT_NE(nullptr, worker_host);
+ ServiceWorkerContainerHost* container_host = worker_host->container_host();
// Clear all service worker object hosts.
container_host->service_worker_object_hosts_.clear();
@@ -1122,7 +1122,7 @@ TEST_F(ServiceWorkerJobTest, HasFetchHandler) {
// Test that clients are alerted of new registrations if they are
// in-scope, so that Clients.claim() or ServiceWorkerContainer.ready work
// correctly.
-TEST_F(ServiceWorkerJobTest, AddRegistrationToMatchingProviderHosts) {
+TEST_F(ServiceWorkerJobTest, AddRegistrationToMatchingerHosts) {
GURL scope("https://www.example.com/scope/");
GURL in_scope("https://www.example.com/scope/page");
GURL out_scope("https://www.example.com/page");
@@ -1441,11 +1441,11 @@ TEST_F(ServiceWorkerUpdateJobTest, RegisterWithDifferentUpdateViaCache) {
// During the above registration, a service worker registration object host
// for ServiceWorkerGlobalScope#registration has been created/added into
- // |provider_host|.
- ServiceWorkerProviderHost* provider_host =
- old_registration->active_version()->provider_host();
- ASSERT_TRUE(provider_host);
- ServiceWorkerContainerHost* container_host = provider_host->container_host();
+ // |worker_host|.
+ ServiceWorkerHost* worker_host =
+ old_registration->active_version()->worker_host();
+ ASSERT_TRUE(worker_host);
+ ServiceWorkerContainerHost* container_host = worker_host->container_host();
// Remove references to |old_registration| so that |old_registration| is the
// only reference to the registration.
diff --git a/chromium/content/browser/service_worker/service_worker_main_resource_handle.cc b/chromium/content/browser/service_worker/service_worker_main_resource_handle.cc
index 3fd46f7d7fe..43565c71451 100644
--- a/chromium/content/browser/service_worker/service_worker_main_resource_handle.cc
+++ b/chromium/content/browser/service_worker/service_worker_main_resource_handle.cc
@@ -34,13 +34,13 @@ ServiceWorkerMainResourceHandle::~ServiceWorkerMainResourceHandle() {
core_);
}
-void ServiceWorkerMainResourceHandle::OnCreatedProviderHost(
- blink::mojom::ServiceWorkerProviderInfoForClientPtr provider_info) {
+void ServiceWorkerMainResourceHandle::OnCreatedContainerHost(
+ blink::mojom::ServiceWorkerContainerInfoForClientPtr container_info) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- DCHECK(provider_info->host_remote.is_valid() &&
- provider_info->client_receiver.is_valid());
+ DCHECK(container_info->host_remote.is_valid() &&
+ container_info->client_receiver.is_valid());
- provider_info_ = std::move(provider_info);
+ container_info_ = std::move(container_info);
}
void ServiceWorkerMainResourceHandle::OnBeginNavigationCommit(
@@ -49,10 +49,10 @@ void ServiceWorkerMainResourceHandle::OnBeginNavigationCommit(
const network::CrossOriginEmbedderPolicy& cross_origin_embedder_policy,
mojo::PendingRemote<network::mojom::CrossOriginEmbedderPolicyReporter>
coep_reporter,
- blink::mojom::ServiceWorkerProviderInfoForClientPtr* out_provider_info) {
+ blink::mojom::ServiceWorkerContainerInfoForClientPtr* out_container_info) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- // We may have failed to pre-create the provider host.
- if (!provider_info_)
+ // We may have failed to pre-create the container host.
+ if (!container_info_)
return;
ServiceWorkerContextWrapper::RunOrPostTaskOnCoreThread(
FROM_HERE,
@@ -60,7 +60,16 @@ void ServiceWorkerMainResourceHandle::OnBeginNavigationCommit(
&ServiceWorkerMainResourceHandleCore::OnBeginNavigationCommit,
base::Unretained(core_), render_process_id, render_frame_id,
cross_origin_embedder_policy, std::move(coep_reporter)));
- *out_provider_info = std::move(provider_info_);
+ *out_container_info = std::move(container_info_);
+}
+
+void ServiceWorkerMainResourceHandle::OnEndNavigationCommit() {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ ServiceWorkerContextWrapper::RunOrPostTaskOnCoreThread(
+ FROM_HERE,
+ base::BindOnce(
+ &ServiceWorkerMainResourceHandleCore::OnEndNavigationCommit,
+ base::Unretained(core_)));
}
void ServiceWorkerMainResourceHandle::OnBeginWorkerCommit(
diff --git a/chromium/content/browser/service_worker/service_worker_main_resource_handle.h b/chromium/content/browser/service_worker/service_worker_main_resource_handle.h
index c7786a29008..13caaaa9cc8 100644
--- a/chromium/content/browser/service_worker/service_worker_main_resource_handle.h
+++ b/chromium/content/browser/service_worker/service_worker_main_resource_handle.h
@@ -26,37 +26,38 @@ namespace content {
class ServiceWorkerContextWrapper;
class ServiceWorkerMainResourceHandleCore;
-// This class is used to manage the lifetime of ServiceWorkerProviderHosts
+// This class is used to manage the lifetime of ServiceWorkerContainerHosts
// created for main resource requests (navigations and web workers). This is a
// UI thread class, with a pendant class on the core thread, the
// ServiceWorkerMainResourceHandleCore.
//
// The lifetime of the ServiceWorkerMainResourceHandle, the
-// ServiceWorkerMainResourceHandleCore and the ServiceWorkerProviderHost are the
-// following:
+// ServiceWorkerMainResourceHandleCore and the ServiceWorkerContainerHost are
+// the following:
// 1) We create a ServiceWorkerMainResourceHandle on the UI thread without
-// populating the member service worker provider info. This also leads to the
+// populating the member service worker container info. This also leads to the
// creation of a ServiceWorkerMainResourceHandleCore.
//
// 2) When the navigation request is sent to the core thread, we include a
// pointer to the ServiceWorkerMainResourceHandleCore.
//
-// 3) If we pre-create a ServiceWorkerProviderHost for this navigation, it
-// is added to ServiceWorkerContextCore and its provider info is passed to
+// 3) If we pre-create a ServiceWorkerContainerHost for this navigation, it
+// is added to ServiceWorkerContextCore and its container info is passed to
// ServiceWorkerMainResourceHandle on the UI thread via
// ServiceWorkerMainResourceHandleCore. See
-// ServiceWorkerMainResourceHandleCore::OnCreatedProviderHost() and
-// ServiceWorkerMainResourceHandle::OnCreatedProviderHost() for details.
+// ServiceWorkerMainResourceHandleCore::OnCreatedContainerHost() and
+// ServiceWorkerMainResourceHandle::OnCreatedContainerHost() for details.
//
// 4) When the navigation is ready to commit, the NavigationRequest will
// call ServiceWorkerMainResourceHandle::OnBeginNavigationCommit() to
-// - complete the initialization for the ServiceWorkerProviderHost.
-// - take out the provider info to be sent as part of navigation commit IPC.
+// - complete the initialization for the ServiceWorkerContainerHost.
+// - take out the container info to be sent as part of navigation commit
+// IPC.
//
// 5) When the navigation finishes, the ServiceWorkerMainResourceHandle is
// destroyed. The destructor of the ServiceWorkerMainResourceHandle destroys
-// the provider info which in turn leads to the destruction of an unclaimed
-// ServiceWorkerProviderHost, and posts a task to destroy the
+// the container info which in turn leads to the destruction of an unclaimed
+// ServiceWorkerContainerHost, and posts a task to destroy the
// ServiceWorkerMainResourceHandleCore on the core thread.
class CONTENT_EXPORT ServiceWorkerMainResourceHandle {
public:
@@ -65,42 +66,46 @@ class CONTENT_EXPORT ServiceWorkerMainResourceHandle {
ServiceWorkerAccessedCallback on_service_worker_accessed);
~ServiceWorkerMainResourceHandle();
- // Called after a ServiceWorkerProviderHost tied with |provider_info|
- // was pre-created for the navigation.
- void OnCreatedProviderHost(
- blink::mojom::ServiceWorkerProviderInfoForClientPtr provider_info);
+ // Called after a ServiceWorkerContainerHost tied with |container_info| was
+ // pre-created for the navigation.
+ void OnCreatedContainerHost(
+ blink::mojom::ServiceWorkerContainerInfoForClientPtr container_info);
// Called when the navigation is ready to commit.
// Provides |render_process_id|, |render_frame_id|, and
- // |cross_origin_embedder_policy| to the pre-created provider host. Fills in
- // |out_provider_info| so the caller can send it to the renderer process as
+ // |cross_origin_embedder_policy| to the pre-created container host. Fills in
+ // |out_container_info| so the caller can send it to the renderer process as
// part of the navigation commit IPC.
- // |out_provider_info| can be filled as null if we failed to pre-create the
- // provider host for some security reasons.
+ // |out_container_info| can be filled as null if we failed to pre-create the
+ // container host for some security reasons.
void OnBeginNavigationCommit(
int render_process_id,
int render_frame_id,
const network::CrossOriginEmbedderPolicy& cross_origin_embedder_policy,
mojo::PendingRemote<network::mojom::CrossOriginEmbedderPolicyReporter>
coep_reporter,
- blink::mojom::ServiceWorkerProviderInfoForClientPtr* out_provider_info);
+ blink::mojom::ServiceWorkerContainerInfoForClientPtr* out_container_info);
+
+ // Called after the renderer reports back that the navigation has been
+ // committed.
+ void OnEndNavigationCommit();
// Similar to OnBeginNavigationCommit() for shared workers (and dedicated
// workers when PlzDedicatedWorker is on).
- // |cross_origin_embedder_policy| is passed to the pre-created provider
+ // |cross_origin_embedder_policy| is passed to the pre-created container
// host.
void OnBeginWorkerCommit(
const network::CrossOriginEmbedderPolicy& cross_origin_embedder_policy);
- blink::mojom::ServiceWorkerProviderInfoForClientPtr TakeProviderInfo() {
- return std::move(provider_info_);
+ blink::mojom::ServiceWorkerContainerInfoForClientPtr TakeContainerInfo() {
+ return std::move(container_info_);
}
- bool has_provider_info() const { return !!provider_info_; }
+ bool has_container_info() const { return !!container_info_; }
ServiceWorkerMainResourceHandleCore* core() { return core_; }
- const ServiceWorkerContextWrapper* context_wrapper() const {
+ ServiceWorkerContextWrapper* context_wrapper() {
return context_wrapper_.get();
}
@@ -109,7 +114,7 @@ class CONTENT_EXPORT ServiceWorkerMainResourceHandle {
}
private:
- blink::mojom::ServiceWorkerProviderInfoForClientPtr provider_info_;
+ blink::mojom::ServiceWorkerContainerInfoForClientPtr container_info_;
ServiceWorkerMainResourceHandleCore* core_;
scoped_refptr<ServiceWorkerContextWrapper> context_wrapper_;
diff --git a/chromium/content/browser/service_worker/service_worker_main_resource_handle_core.cc b/chromium/content/browser/service_worker/service_worker_main_resource_handle_core.cc
index 7cd6d9022ee..62766a45e8b 100644
--- a/chromium/content/browser/service_worker/service_worker_main_resource_handle_core.cc
+++ b/chromium/content/browser/service_worker/service_worker_main_resource_handle_core.cc
@@ -40,6 +40,11 @@ void ServiceWorkerMainResourceHandleCore::OnBeginNavigationCommit(
std::move(coep_reporter));
}
}
+void ServiceWorkerMainResourceHandleCore::OnEndNavigationCommit() {
+ DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
+ if (container_host_)
+ container_host_->OnEndNavigationCommit();
+}
void ServiceWorkerMainResourceHandleCore::OnBeginWorkerCommit(
const network::CrossOriginEmbedderPolicy& cross_origin_embedder_policy) {
diff --git a/chromium/content/browser/service_worker/service_worker_main_resource_handle_core.h b/chromium/content/browser/service_worker/service_worker_main_resource_handle_core.h
index aac0082f657..5397df2c8da 100644
--- a/chromium/content/browser/service_worker/service_worker_main_resource_handle_core.h
+++ b/chromium/content/browser/service_worker/service_worker_main_resource_handle_core.h
@@ -49,6 +49,7 @@ class CONTENT_EXPORT ServiceWorkerMainResourceHandleCore {
const network::CrossOriginEmbedderPolicy& cross_origin_embedder_policy,
mojo::PendingRemote<network::mojom::CrossOriginEmbedderPolicyReporter>
coep_reporter);
+ void OnEndNavigationCommit();
void OnBeginWorkerCommit(
const network::CrossOriginEmbedderPolicy& cross_origin_embedder_policy);
diff --git a/chromium/content/browser/service_worker/service_worker_navigation_loader.cc b/chromium/content/browser/service_worker/service_worker_main_resource_loader.cc
index 07b61ef023b..a54ddc9d48f 100644
--- a/chromium/content/browser/service_worker/service_worker_navigation_loader.cc
+++ b/chromium/content/browser/service_worker/service_worker_main_resource_loader.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/browser/service_worker/service_worker_navigation_loader.h"
+#include "content/browser/service_worker/service_worker_main_resource_loader.h"
#include <sstream>
#include <string>
@@ -45,12 +45,12 @@ std::string ComposeFetchEventResultString(
} // namespace
// This class waits for completion of a stream response from the service worker.
-// It calls ServiceWorkerNavigationLoader::CommitCompleted() upon completion of
-// the response.
-class ServiceWorkerNavigationLoader::StreamWaiter
+// It calls ServiceWorkerMainResourceLoader::CommitCompleted() upon completion
+// of the response.
+class ServiceWorkerMainResourceLoader::StreamWaiter
: public blink::mojom::ServiceWorkerStreamCallback {
public:
- StreamWaiter(ServiceWorkerNavigationLoader* owner,
+ StreamWaiter(ServiceWorkerMainResourceLoader* owner,
mojo::PendingReceiver<blink::mojom::ServiceWorkerStreamCallback>
callback_receiver)
: owner_(owner), receiver_(this, std::move(callback_receiver)) {
@@ -69,13 +69,13 @@ class ServiceWorkerNavigationLoader::StreamWaiter
}
private:
- ServiceWorkerNavigationLoader* owner_;
+ ServiceWorkerMainResourceLoader* owner_;
mojo::Receiver<blink::mojom::ServiceWorkerStreamCallback> receiver_;
DISALLOW_COPY_AND_ASSIGN(StreamWaiter);
};
-ServiceWorkerNavigationLoader::ServiceWorkerNavigationLoader(
+ServiceWorkerMainResourceLoader::ServiceWorkerMainResourceLoader(
NavigationLoaderInterceptor::FallbackCallback fallback_callback,
base::WeakPtr<ServiceWorkerContainerHost> container_host,
scoped_refptr<URLLoaderFactoryGetter> url_loader_factory_getter)
@@ -84,21 +84,21 @@ ServiceWorkerNavigationLoader::ServiceWorkerNavigationLoader(
url_loader_factory_getter_(std::move(url_loader_factory_getter)) {
TRACE_EVENT_WITH_FLOW0(
"ServiceWorker",
- "ServiceWorkerNavigationLoader::ServiceWorkerNavigationLoader", this,
+ "ServiceWorkerMainResourceLoader::ServiceWorkerMainResourceLoader", this,
TRACE_EVENT_FLAG_FLOW_OUT);
response_head_->load_timing.request_start = base::TimeTicks::Now();
response_head_->load_timing.request_start_time = base::Time::Now();
}
-ServiceWorkerNavigationLoader::~ServiceWorkerNavigationLoader() {
+ServiceWorkerMainResourceLoader::~ServiceWorkerMainResourceLoader() {
TRACE_EVENT_WITH_FLOW0(
"ServiceWorker",
- "ServiceWorkerNavigationLoader::~ServiceWorkerNavigationloader", this,
+ "ServiceWorkerMainResourceLoader::~ServiceWorkerNavigationloader", this,
TRACE_EVENT_FLAG_FLOW_IN);
}
-void ServiceWorkerNavigationLoader::DetachedFromRequest() {
+void ServiceWorkerMainResourceLoader::DetachedFromRequest() {
is_detached_ = true;
// Clear |fallback_callback_| since it's no longer safe to invoke it because
// the bound object has been destroyed.
@@ -106,21 +106,21 @@ void ServiceWorkerNavigationLoader::DetachedFromRequest() {
DeleteIfNeeded();
}
-base::WeakPtr<ServiceWorkerNavigationLoader>
-ServiceWorkerNavigationLoader::AsWeakPtr() {
+base::WeakPtr<ServiceWorkerMainResourceLoader>
+ServiceWorkerMainResourceLoader::AsWeakPtr() {
return weak_factory_.GetWeakPtr();
}
-void ServiceWorkerNavigationLoader::StartRequest(
+void ServiceWorkerMainResourceLoader::StartRequest(
const network::ResourceRequest& resource_request,
mojo::PendingReceiver<network::mojom::URLLoader> receiver,
mojo::PendingRemote<network::mojom::URLLoaderClient> client) {
TRACE_EVENT_WITH_FLOW1("ServiceWorker",
- "ServiceWorkerNavigationLoader::StartRequest", this,
+ "ServiceWorkerMainResourceLoader::StartRequest", this,
TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT,
"url", resource_request.url.spec());
- DCHECK(ServiceWorkerUtils::IsMainResourceType(
- static_cast<blink::mojom::ResourceType>(resource_request.resource_type)));
+ DCHECK(ServiceWorkerUtils::IsMainRequestDestination(
+ resource_request.destination));
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
resource_request_ = resource_request;
@@ -133,7 +133,7 @@ void ServiceWorkerNavigationLoader::StartRequest(
DCHECK(!url_loader_client_.is_bound());
receiver_.Bind(std::move(receiver));
receiver_.set_disconnect_handler(
- base::BindOnce(&ServiceWorkerNavigationLoader::OnConnectionClosed,
+ base::BindOnce(&ServiceWorkerMainResourceLoader::OnConnectionClosed,
base::Unretained(this)));
url_loader_client_.Bind(std::move(client));
@@ -166,15 +166,18 @@ void ServiceWorkerNavigationLoader::StartRequest(
blink::mojom::FetchAPIRequest::From(resource_request_),
static_cast<blink::mojom::ResourceType>(resource_request_.resource_type),
container_host_->client_uuid(), active_worker,
- base::BindOnce(&ServiceWorkerNavigationLoader::DidPrepareFetchEvent,
+ base::BindOnce(&ServiceWorkerMainResourceLoader::DidPrepareFetchEvent,
weak_factory_.GetWeakPtr(), active_worker,
active_worker->running_status()),
- base::BindOnce(&ServiceWorkerNavigationLoader::DidDispatchFetchEvent,
+ base::BindOnce(&ServiceWorkerMainResourceLoader::DidDispatchFetchEvent,
weak_factory_.GetWeakPtr()),
/*is_offline_capability_check=*/false);
- did_navigation_preload_ = fetch_dispatcher_->MaybeStartNavigationPreload(
- resource_request_, url_loader_factory_getter_.get(), std::move(context),
- container_host_->frame_tree_node_id());
+
+ if (container_host_->IsContainerForWindowClient()) {
+ did_navigation_preload_ = fetch_dispatcher_->MaybeStartNavigationPreload(
+ resource_request_, url_loader_factory_getter_.get(), std::move(context),
+ container_host_->frame_tree_node_id());
+ }
// Record worker start time here as |fetch_dispatcher_| will start a service
// worker if there is no running service worker.
@@ -183,10 +186,10 @@ void ServiceWorkerNavigationLoader::StartRequest(
fetch_dispatcher_->Run();
}
-void ServiceWorkerNavigationLoader::CommitResponseHeaders() {
+void ServiceWorkerMainResourceLoader::CommitResponseHeaders() {
DCHECK(url_loader_client_.is_bound());
TRACE_EVENT_WITH_FLOW2(
- "ServiceWorker", "ServiceWorkerNavigationLoader::CommitResponseHeaders",
+ "ServiceWorker", "ServiceWorkerMainResourceLoader::CommitResponseHeaders",
this, TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT,
"response_code", response_head_->headers->response_code(), "status_text",
response_head_->headers->GetStatusText());
@@ -194,13 +197,13 @@ void ServiceWorkerNavigationLoader::CommitResponseHeaders() {
url_loader_client_->OnReceiveResponse(response_head_.Clone());
}
-void ServiceWorkerNavigationLoader::CommitResponseBody(
+void ServiceWorkerMainResourceLoader::CommitResponseBody(
mojo::ScopedDataPipeConsumerHandle response_body) {
TransitionToStatus(Status::kSentBody);
url_loader_client_->OnStartLoadingResponseBody(std::move(response_body));
}
-void ServiceWorkerNavigationLoader::CommitEmptyResponseAndComplete() {
+void ServiceWorkerMainResourceLoader::CommitEmptyResponseAndComplete() {
mojo::ScopedDataPipeProducerHandle producer_handle;
mojo::ScopedDataPipeConsumerHandle consumer_handle;
if (CreateDataPipe(nullptr, &producer_handle, &consumer_handle) !=
@@ -215,10 +218,10 @@ void ServiceWorkerNavigationLoader::CommitEmptyResponseAndComplete() {
CommitCompleted(net::OK, "No body exists.");
}
-void ServiceWorkerNavigationLoader::CommitCompleted(int error_code,
- const char* reason) {
+void ServiceWorkerMainResourceLoader::CommitCompleted(int error_code,
+ const char* reason) {
TRACE_EVENT_WITH_FLOW2(
- "ServiceWorker", "ServiceWorkerNavigationLoader::CommitCompleted", this,
+ "ServiceWorker", "ServiceWorkerMainResourceLoader::CommitCompleted", this,
TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "error_code",
net::ErrorToString(error_code), "reason", TRACE_STR_COPY(reason));
@@ -234,11 +237,11 @@ void ServiceWorkerNavigationLoader::CommitCompleted(int error_code,
network::URLLoaderCompletionStatus(error_code));
}
-void ServiceWorkerNavigationLoader::DidPrepareFetchEvent(
+void ServiceWorkerMainResourceLoader::DidPrepareFetchEvent(
scoped_refptr<ServiceWorkerVersion> version,
EmbeddedWorkerStatus initial_worker_status) {
TRACE_EVENT_WITH_FLOW1(
- "ServiceWorker", "ServiceWorkerNavigationLoader::DidPrepareFetchEvent",
+ "ServiceWorker", "ServiceWorkerMainResourceLoader::DidPrepareFetchEvent",
this, TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT,
"initial_worker_status",
EmbeddedWorkerInstance::StatusToString(initial_worker_status));
@@ -253,7 +256,7 @@ void ServiceWorkerNavigationLoader::DidPrepareFetchEvent(
devtools_attached_ = version->embedded_worker()->devtools_attached();
}
-void ServiceWorkerNavigationLoader::DidDispatchFetchEvent(
+void ServiceWorkerMainResourceLoader::DidDispatchFetchEvent(
blink::ServiceWorkerStatusCode status,
ServiceWorkerFetchDispatcher::FetchEventResult fetch_result,
blink::mojom::FetchAPIResponsePtr response,
@@ -264,7 +267,7 @@ void ServiceWorkerNavigationLoader::DidDispatchFetchEvent(
DCHECK_EQ(status_, Status::kStarted);
TRACE_EVENT_WITH_FLOW2(
- "ServiceWorker", "ServiceWorkerNavigationLoader::DidDispatchFetchEvent",
+ "ServiceWorker", "ServiceWorkerMainResourceLoader::DidDispatchFetchEvent",
this, TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "status",
blink::ServiceWorkerStatusToString(status), "result",
ComposeFetchEventResultString(fetch_result, *response));
@@ -321,7 +324,7 @@ void ServiceWorkerNavigationLoader::DidDispatchFetchEvent(
std::move(body_as_stream));
}
-void ServiceWorkerNavigationLoader::StartResponse(
+void ServiceWorkerMainResourceLoader::StartResponse(
blink::mojom::FetchAPIResponsePtr response,
scoped_refptr<ServiceWorkerVersion> version,
blink::mojom::ServiceWorkerStreamHandlePtr body_as_stream) {
@@ -339,6 +342,10 @@ void ServiceWorkerNavigationLoader::StartResponse(
response_head_->load_timing.receive_headers_end =
response_head_->load_timing.receive_headers_start;
response_source_ = response->response_source;
+ response_head_->load_timing.service_worker_fetch_start =
+ fetch_event_timing_->dispatch_event_time;
+ response_head_->load_timing.service_worker_respond_with_settled =
+ fetch_event_timing_->respond_with_settled_time;
// Make the navigated page inherit the SSLInfo from its controller service
// worker's script. This affects the HTTPS padlock, etc, shown by the
@@ -355,7 +362,7 @@ void ServiceWorkerNavigationLoader::StartResponse(
*response_head_);
if (redirect_info) {
TRACE_EVENT_WITH_FLOW2(
- "ServiceWorker", "ServiceWorkerNavigationLoader::StartResponse", this,
+ "ServiceWorker", "ServiceWorkerMainResourceLoader::StartResponse", this,
TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "result",
"redirect", "redirect url", redirect_info->new_url.spec());
@@ -373,10 +380,10 @@ void ServiceWorkerNavigationLoader::StartResponse(
// Handle a stream response body.
if (!body_as_stream.is_null() && body_as_stream->stream.is_valid()) {
- TRACE_EVENT_WITH_FLOW1("ServiceWorker",
- "ServiceWorkerNavigationLoader::StartResponse", this,
- TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT,
- "result", "stream response");
+ TRACE_EVENT_WITH_FLOW1(
+ "ServiceWorker", "ServiceWorkerMainResourceLoader::StartResponse", this,
+ TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "result",
+ "stream response");
stream_waiter_ = std::make_unique<StreamWaiter>(
this, std::move(body_as_stream->callback_receiver));
CommitResponseBody(std::move(body_as_stream->stream));
@@ -391,17 +398,17 @@ void ServiceWorkerNavigationLoader::StartResponse(
mojo::ScopedDataPipeConsumerHandle data_pipe;
int error = ServiceWorkerLoaderHelpers::ReadBlobResponseBody(
&body_as_blob_, response->blob->size,
- base::BindOnce(&ServiceWorkerNavigationLoader::OnBlobReadingComplete,
+ base::BindOnce(&ServiceWorkerMainResourceLoader::OnBlobReadingComplete,
weak_factory_.GetWeakPtr()),
&data_pipe);
if (error != net::OK) {
CommitCompleted(error, "Failed to read blob body");
return;
}
- TRACE_EVENT_WITH_FLOW1("ServiceWorker",
- "ServiceWorkerNavigationLoader::StartResponse", this,
- TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT,
- "result", "blob response");
+ TRACE_EVENT_WITH_FLOW1(
+ "ServiceWorker", "ServiceWorkerMainResourceLoader::StartResponse", this,
+ TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "result",
+ "blob response");
CommitResponseBody(std::move(data_pipe));
// We continue in OnBlobReadingComplete().
@@ -409,7 +416,7 @@ void ServiceWorkerNavigationLoader::StartResponse(
}
TRACE_EVENT_WITH_FLOW1("ServiceWorker",
- "ServiceWorkerNavigationLoader::StartResponse", this,
+ "ServiceWorkerMainResourceLoader::StartResponse", this,
TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT,
"result", "no body");
@@ -418,7 +425,7 @@ void ServiceWorkerNavigationLoader::StartResponse(
// URLLoader implementation----------------------------------------
-void ServiceWorkerNavigationLoader::FollowRedirect(
+void ServiceWorkerMainResourceLoader::FollowRedirect(
const std::vector<std::string>& removed_headers,
const net::HttpRequestHeaders& modified_headers,
const net::HttpRequestHeaders& modified_cors_exempt_headers,
@@ -426,23 +433,24 @@ void ServiceWorkerNavigationLoader::FollowRedirect(
NOTIMPLEMENTED();
}
-void ServiceWorkerNavigationLoader::SetPriority(net::RequestPriority priority,
- int32_t intra_priority_value) {
+void ServiceWorkerMainResourceLoader::SetPriority(
+ net::RequestPriority priority,
+ int32_t intra_priority_value) {
NOTIMPLEMENTED();
}
-void ServiceWorkerNavigationLoader::PauseReadingBodyFromNet() {}
+void ServiceWorkerMainResourceLoader::PauseReadingBodyFromNet() {}
-void ServiceWorkerNavigationLoader::ResumeReadingBodyFromNet() {}
+void ServiceWorkerMainResourceLoader::ResumeReadingBodyFromNet() {}
-void ServiceWorkerNavigationLoader::OnBlobReadingComplete(int net_error) {
+void ServiceWorkerMainResourceLoader::OnBlobReadingComplete(int net_error) {
CommitCompleted(net_error, "Blob has been read.");
body_as_blob_.reset();
}
-void ServiceWorkerNavigationLoader::OnConnectionClosed() {
+void ServiceWorkerMainResourceLoader::OnConnectionClosed() {
TRACE_EVENT_WITH_FLOW0(
- "ServiceWorker", "ServiceWorkerNavigationLoader::OnConnectionClosed",
+ "ServiceWorker", "ServiceWorkerMainResourceLoader::OnConnectionClosed",
this, TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT);
// The fetch dispatcher or stream waiter may still be running. Don't let them
@@ -462,12 +470,12 @@ void ServiceWorkerNavigationLoader::OnConnectionClosed() {
DeleteIfNeeded();
}
-void ServiceWorkerNavigationLoader::DeleteIfNeeded() {
+void ServiceWorkerMainResourceLoader::DeleteIfNeeded() {
if (!receiver_.is_bound() && is_detached_)
delete this;
}
-void ServiceWorkerNavigationLoader::RecordTimingMetrics(bool handled) {
+void ServiceWorkerMainResourceLoader::RecordTimingMetrics(bool handled) {
DCHECK(fetch_event_timing_);
DCHECK(!completion_time_.is_null());
@@ -543,7 +551,7 @@ void ServiceWorkerNavigationLoader::RecordTimingMetrics(bool handled) {
}
}
-void ServiceWorkerNavigationLoader::TransitionToStatus(Status new_status) {
+void ServiceWorkerMainResourceLoader::TransitionToStatus(Status new_status) {
#if DCHECK_IS_ON()
switch (new_status) {
case Status::kNotStarted:
@@ -577,11 +585,12 @@ void ServiceWorkerNavigationLoader::TransitionToStatus(Status new_status) {
completion_time_ = base::TimeTicks::Now();
}
-ServiceWorkerNavigationLoaderWrapper::ServiceWorkerNavigationLoaderWrapper(
- std::unique_ptr<ServiceWorkerNavigationLoader> loader)
+ServiceWorkerMainResourceLoaderWrapper::ServiceWorkerMainResourceLoaderWrapper(
+ std::unique_ptr<ServiceWorkerMainResourceLoader> loader)
: loader_(std::move(loader)) {}
-ServiceWorkerNavigationLoaderWrapper::~ServiceWorkerNavigationLoaderWrapper() {
+ServiceWorkerMainResourceLoaderWrapper::
+ ~ServiceWorkerMainResourceLoaderWrapper() {
if (loader_)
loader_.release()->DetachedFromRequest();
}
diff --git a/chromium/content/browser/service_worker/service_worker_navigation_loader.h b/chromium/content/browser/service_worker/service_worker_main_resource_loader.h
index 76796bb0b98..48ebd466b30 100644
--- a/chromium/content/browser/service_worker/service_worker_navigation_loader.h
+++ b/chromium/content/browser/service_worker/service_worker_main_resource_loader.h
@@ -2,8 +2,8 @@
// 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_NAVIGATION_LOADER_H_
-#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_NAVIGATION_LOADER_H_
+#ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_MAIN_RESOURCE_LOADER_H_
+#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_MAIN_RESOURCE_LOADER_H_
#include <memory>
#include <string>
@@ -32,7 +32,7 @@ namespace content {
class ServiceWorkerContainerHost;
class ServiceWorkerVersion;
-// ServiceWorkerNavigationLoader is the URLLoader used for main resource
+// ServiceWorkerMainResourceLoader is the URLLoader used for main resource
// requests (i.e., navigation and shared worker requests) that go through a
// service worker. This loader is only used for the main resource request; once
// the response is delivered, the resulting client loads subresources via
@@ -41,7 +41,7 @@ class ServiceWorkerVersion;
// This class is owned by ServiceWorkerControlleeRequestHandler until it is
// bound to a URLLoader request. After it is bound |this| is kept alive until
// the Mojo connection to this URLLoader is dropped.
-class CONTENT_EXPORT ServiceWorkerNavigationLoader
+class CONTENT_EXPORT ServiceWorkerMainResourceLoader
: public network::mojom::URLLoader {
public:
// Created by ServiceWorkerControlleeRequestHandler
@@ -49,7 +49,7 @@ class CONTENT_EXPORT ServiceWorkerNavigationLoader
//
// For the navigation case, this job typically works in the following order:
// 1. ServiceWorkerControlleeRequestHandler::MaybeCreateLoader() creates the
- // ServiceWorkerNavigationLoader, passing StartRequest() as the
+ // ServiceWorkerMainResourceLoader, passing StartRequest() as the
// RequestHandler.
// 2. At this point, the NavigationURLLoaderImpl can throttle the request,
// and invoke the RequestHandler later with a possibly modified request.
@@ -65,12 +65,12 @@ class CONTENT_EXPORT ServiceWorkerNavigationLoader
//
// Loads for shared workers work similarly, except SharedWorkerScriptLoader
// is used instead of NavigationURLLoaderImpl.
- ServiceWorkerNavigationLoader(
+ ServiceWorkerMainResourceLoader(
NavigationLoaderInterceptor::FallbackCallback fallback_callback,
base::WeakPtr<ServiceWorkerContainerHost> container_host,
scoped_refptr<URLLoaderFactoryGetter> url_loader_factory_getter);
- ~ServiceWorkerNavigationLoader() override;
+ ~ServiceWorkerMainResourceLoader() override;
// Passed as the RequestHandler for
// NavigationLoaderInterceptor::MaybeCreateLoader.
@@ -86,7 +86,7 @@ class CONTENT_EXPORT ServiceWorkerNavigationLoader
// endpoint is held by the client.
void DetachedFromRequest();
- base::WeakPtr<ServiceWorkerNavigationLoader> AsWeakPtr();
+ base::WeakPtr<ServiceWorkerMainResourceLoader> AsWeakPtr();
private:
class StreamWaiter;
@@ -186,26 +186,26 @@ class CONTENT_EXPORT ServiceWorkerNavigationLoader
Status status_ = Status::kNotStarted;
bool is_detached_ = false;
- base::WeakPtrFactory<ServiceWorkerNavigationLoader> weak_factory_{this};
+ base::WeakPtrFactory<ServiceWorkerMainResourceLoader> weak_factory_{this};
- DISALLOW_COPY_AND_ASSIGN(ServiceWorkerNavigationLoader);
+ DISALLOW_COPY_AND_ASSIGN(ServiceWorkerMainResourceLoader);
};
// Owns a loader and calls DetachedFromRequest() to release it.
-class ServiceWorkerNavigationLoaderWrapper {
+class ServiceWorkerMainResourceLoaderWrapper {
public:
- explicit ServiceWorkerNavigationLoaderWrapper(
- std::unique_ptr<ServiceWorkerNavigationLoader> loader);
- ~ServiceWorkerNavigationLoaderWrapper();
+ explicit ServiceWorkerMainResourceLoaderWrapper(
+ std::unique_ptr<ServiceWorkerMainResourceLoader> loader);
+ ~ServiceWorkerMainResourceLoaderWrapper();
- ServiceWorkerNavigationLoader* get() { return loader_.get(); }
+ ServiceWorkerMainResourceLoader* get() { return loader_.get(); }
private:
- std::unique_ptr<ServiceWorkerNavigationLoader> loader_;
+ std::unique_ptr<ServiceWorkerMainResourceLoader> loader_;
- DISALLOW_COPY_AND_ASSIGN(ServiceWorkerNavigationLoaderWrapper);
+ DISALLOW_COPY_AND_ASSIGN(ServiceWorkerMainResourceLoaderWrapper);
};
} // namespace content
-#endif // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_NAVIGATION_LOADER_H_
+#endif // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_MAIN_RESOURCE_LOADER_H_
diff --git a/chromium/content/browser/service_worker/service_worker_navigation_loader_interceptor.cc b/chromium/content/browser/service_worker/service_worker_main_resource_loader_interceptor.cc
index 23166ec06e5..701b8f9d0ec 100644
--- a/chromium/content/browser/service_worker/service_worker_navigation_loader_interceptor.cc
+++ b/chromium/content/browser/service_worker/service_worker_main_resource_loader_interceptor.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/browser/service_worker/service_worker_navigation_loader_interceptor.h"
+#include "content/browser/service_worker/service_worker_main_resource_loader_interceptor.h"
#include <memory>
#include <utility>
@@ -17,7 +17,6 @@
#include "content/browser/service_worker/service_worker_controllee_request_handler.h"
#include "content/browser/service_worker/service_worker_main_resource_handle.h"
#include "content/browser/service_worker/service_worker_main_resource_handle_core.h"
-#include "content/browser/service_worker/service_worker_provider_host.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/common/origin_util.h"
#include "content/public/common/url_constants.h"
@@ -33,7 +32,7 @@ namespace {
void LoaderCallbackWrapperOnCoreThread(
ServiceWorkerMainResourceHandleCore* handle_core,
- base::WeakPtr<ServiceWorkerNavigationLoaderInterceptor> interceptor_on_ui,
+ base::WeakPtr<ServiceWorkerMainResourceLoaderInterceptor> interceptor_on_ui,
NavigationLoaderInterceptor::LoaderCallback loader_callback,
SingleRequestURLLoaderFactory::RequestHandler handler) {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
@@ -47,13 +46,13 @@ void LoaderCallbackWrapperOnCoreThread(
RunOrPostTaskOnThread(
FROM_HERE, BrowserThread::UI,
base::BindOnce(
- &ServiceWorkerNavigationLoaderInterceptor::LoaderCallbackWrapper,
+ &ServiceWorkerMainResourceLoaderInterceptor::LoaderCallbackWrapper,
interceptor_on_ui, std::move(subresource_loader_params),
std::move(loader_callback), std::move(handler)));
}
void FallbackCallbackWrapperOnCoreThread(
- base::WeakPtr<ServiceWorkerNavigationLoaderInterceptor> interceptor_on_ui,
+ base::WeakPtr<ServiceWorkerMainResourceLoaderInterceptor> interceptor_on_ui,
NavigationLoaderInterceptor::FallbackCallback fallback_callback,
bool reset_subresource_loader_params) {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
@@ -61,7 +60,7 @@ void FallbackCallbackWrapperOnCoreThread(
RunOrPostTaskOnThread(
FROM_HERE, BrowserThread::UI,
base::BindOnce(
- &ServiceWorkerNavigationLoaderInterceptor::FallbackCallbackWrapper,
+ &ServiceWorkerMainResourceLoaderInterceptor::FallbackCallbackWrapper,
interceptor_on_ui, std::move(fallback_callback),
reset_subresource_loader_params));
}
@@ -79,7 +78,7 @@ void InvokeRequestHandlerOnCoreThread(
// Does setup on the the core thread and calls back to
// |interceptor_on_ui->LoaderCallbackWrapper()| on the UI thread.
void MaybeCreateLoaderOnCoreThread(
- base::WeakPtr<ServiceWorkerNavigationLoaderInterceptor> interceptor_on_ui,
+ base::WeakPtr<ServiceWorkerMainResourceLoaderInterceptor> interceptor_on_ui,
ServiceWorkerMainResourceHandleCore* handle_core,
blink::mojom::ResourceType resource_type,
bool skip_service_worker,
@@ -114,7 +113,7 @@ void MaybeCreateLoaderOnCoreThread(
if (!handle_core->container_host()) {
// This is the initial request before redirects, so make the container host.
- // Its lifetime is tied to the |provider_info| in the
+ // Its lifetime is tied to the |container_info| in the
// ServiceWorkerMainResourceHandle on the UI thread and which will be passed
// to the renderer when the navigation commits.
DCHECK(host_receiver);
@@ -129,13 +128,15 @@ void MaybeCreateLoaderOnCoreThread(
} else {
DCHECK(resource_type == blink::mojom::ResourceType::kWorker ||
resource_type == blink::mojom::ResourceType::kSharedWorker);
- auto client_type =
+
+ ServiceWorkerClientInfo client_info =
resource_type == blink::mojom::ResourceType::kWorker
- ? blink::mojom::ServiceWorkerClientType::kDedicatedWorker
- : blink::mojom::ServiceWorkerClientType::kSharedWorker;
+ ? ServiceWorkerClientInfo(dedicated_worker_id)
+ : ServiceWorkerClientInfo(shared_worker_id);
+
container_host = context_core->CreateContainerHostForWorker(
std::move(host_receiver), process_id, std::move(client_remote),
- client_type, dedicated_worker_id, shared_worker_id);
+ client_info);
}
DCHECK(container_host);
handle_core->set_container_host(container_host);
@@ -182,8 +183,8 @@ bool SchemeMaySupportRedirectingToHTTPS(const GURL& url) {
#endif // OS_CHROMEOS
}
-// Returns true if a ServiceWorkerNavigationLoaderInterceptor should be created
-// for a worker with this |url|.
+// Returns true if a ServiceWorkerMainResourceLoaderInterceptor should be
+// created for a worker with this |url|.
bool ShouldCreateForWorker(const GURL& url) {
// Create the handler even for insecure HTTP since it's used in the
// case of redirect to HTTPS.
@@ -195,28 +196,29 @@ bool ShouldCreateForWorker(const GURL& url) {
} // namespace
std::unique_ptr<NavigationLoaderInterceptor>
-ServiceWorkerNavigationLoaderInterceptor::CreateForNavigation(
+ServiceWorkerMainResourceLoaderInterceptor::CreateForNavigation(
const GURL& url,
base::WeakPtr<ServiceWorkerMainResourceHandle> navigation_handle,
const NavigationRequestInfo& request_info) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- if (!ShouldCreateForNavigation(url))
+ if (!ShouldCreateForNavigation(
+ url, request_info.begin_params->request_destination)) {
return nullptr;
+ }
- return std::unique_ptr<ServiceWorkerNavigationLoaderInterceptor>(
- new ServiceWorkerNavigationLoaderInterceptor(
- std::move(navigation_handle),
- request_info.is_main_frame ? blink::mojom::ResourceType::kMainFrame
- : blink::mojom::ResourceType::kSubFrame,
- request_info.begin_params->skip_service_worker,
- request_info.are_ancestors_secure, request_info.frame_tree_node_id,
- ChildProcessHost::kInvalidUniqueID, DedicatedWorkerId(),
- SharedWorkerId()));
+ return base::WrapUnique(new ServiceWorkerMainResourceLoaderInterceptor(
+ std::move(navigation_handle),
+ request_info.is_main_frame ? blink::mojom::ResourceType::kMainFrame
+ : blink::mojom::ResourceType::kSubFrame,
+ request_info.begin_params->skip_service_worker,
+ request_info.are_ancestors_secure, request_info.frame_tree_node_id,
+ ChildProcessHost::kInvalidUniqueID, DedicatedWorkerId(),
+ SharedWorkerId()));
}
std::unique_ptr<NavigationLoaderInterceptor>
-ServiceWorkerNavigationLoaderInterceptor::CreateForWorker(
+ServiceWorkerMainResourceLoaderInterceptor::CreateForWorker(
const network::ResourceRequest& resource_request,
int process_id,
DedicatedWorkerId dedicated_worker_id,
@@ -235,20 +237,19 @@ ServiceWorkerNavigationLoaderInterceptor::CreateForWorker(
if (!ShouldCreateForWorker(resource_request.url))
return nullptr;
- return std::unique_ptr<ServiceWorkerNavigationLoaderInterceptor>(
- new ServiceWorkerNavigationLoaderInterceptor(
- std::move(navigation_handle), resource_type,
- resource_request.skip_service_worker, /*are_ancestors_secure=*/false,
- FrameTreeNode::kFrameTreeNodeInvalidId, process_id,
- dedicated_worker_id, shared_worker_id));
+ return base::WrapUnique(new ServiceWorkerMainResourceLoaderInterceptor(
+ std::move(navigation_handle), resource_type,
+ resource_request.skip_service_worker, /*are_ancestors_secure=*/false,
+ FrameTreeNode::kFrameTreeNodeInvalidId, process_id, dedicated_worker_id,
+ shared_worker_id));
}
-ServiceWorkerNavigationLoaderInterceptor::
- ~ServiceWorkerNavigationLoaderInterceptor() {
+ServiceWorkerMainResourceLoaderInterceptor::
+ ~ServiceWorkerMainResourceLoaderInterceptor() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
}
-void ServiceWorkerNavigationLoaderInterceptor::MaybeCreateLoader(
+void ServiceWorkerMainResourceLoaderInterceptor::MaybeCreateLoader(
const network::ResourceRequest& tentative_resource_request,
BrowserContext* browser_context,
LoaderCallback loader_callback,
@@ -261,23 +262,23 @@ void ServiceWorkerNavigationLoaderInterceptor::MaybeCreateLoader(
mojo::PendingAssociatedRemote<blink::mojom::ServiceWorkerContainer>
client_remote;
- // If this is the first request before redirects, a provider info has not yet
+ // If this is the first request before redirects, a container info has not yet
// been created.
- if (!handle_->has_provider_info()) {
- auto provider_info =
- blink::mojom::ServiceWorkerProviderInfoForClient::New();
+ if (!handle_->has_container_info()) {
+ auto container_info =
+ blink::mojom::ServiceWorkerContainerInfoForClient::New();
host_receiver =
- provider_info->host_remote.InitWithNewEndpointAndPassReceiver();
- provider_info->client_receiver =
+ container_info->host_remote.InitWithNewEndpointAndPassReceiver();
+ container_info->client_receiver =
client_remote.InitWithNewEndpointAndPassReceiver();
- handle_->OnCreatedProviderHost(std::move(provider_info));
+ handle_->OnCreatedContainerHost(std::move(container_info));
}
bool initialize_container_host_only = false;
LoaderCallback original_callback;
if (!ServiceWorkerContext::IsServiceWorkerOnUIEnabled() &&
- !handle_->context_wrapper()->HasRegistrationForOrigin(
- tentative_resource_request.url.GetOrigin())) {
+ !handle_->context_wrapper()->MaybeHasRegistrationForOrigin(
+ url::Origin::Create(tentative_resource_request.url))) {
// We have no registrations, so it's safe to continue the request now
// without blocking on the IO thread. Give a dummy callback to the
// IO thread interceptor, and we'll run the original callback immediately
@@ -306,12 +307,13 @@ void ServiceWorkerNavigationLoaderInterceptor::MaybeCreateLoader(
}
base::Optional<SubresourceLoaderParams>
-ServiceWorkerNavigationLoaderInterceptor::MaybeCreateSubresourceLoaderParams() {
+ServiceWorkerMainResourceLoaderInterceptor::
+ MaybeCreateSubresourceLoaderParams() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
return std::move(subresource_loader_params_);
}
-void ServiceWorkerNavigationLoaderInterceptor::LoaderCallbackWrapper(
+void ServiceWorkerMainResourceLoaderInterceptor::LoaderCallbackWrapper(
base::Optional<SubresourceLoaderParams> subresource_loader_params,
LoaderCallback loader_callback,
SingleRequestURLLoaderFactory::RequestHandler handler_on_core_thread) {
@@ -339,25 +341,25 @@ void ServiceWorkerNavigationLoaderInterceptor::LoaderCallbackWrapper(
// wrapper to the loader callback.
std::move(loader_callback)
.Run(base::MakeRefCounted<SingleRequestURLLoaderFactory>(base::BindOnce(
- &ServiceWorkerNavigationLoaderInterceptor::RequestHandlerWrapper,
+ &ServiceWorkerMainResourceLoaderInterceptor::RequestHandlerWrapper,
GetWeakPtr(), std::move(handler_on_core_thread))));
}
-void ServiceWorkerNavigationLoaderInterceptor::FallbackCallbackWrapper(
+void ServiceWorkerMainResourceLoaderInterceptor::FallbackCallbackWrapper(
FallbackCallback fallback_callback,
bool reset_subresource_loader_params) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
std::move(fallback_callback).Run(reset_subresource_loader_params);
}
-base::WeakPtr<ServiceWorkerNavigationLoaderInterceptor>
-ServiceWorkerNavigationLoaderInterceptor::GetWeakPtr() {
+base::WeakPtr<ServiceWorkerMainResourceLoaderInterceptor>
+ServiceWorkerMainResourceLoaderInterceptor::GetWeakPtr() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
return weak_factory_.GetWeakPtr();
}
-ServiceWorkerNavigationLoaderInterceptor::
- ServiceWorkerNavigationLoaderInterceptor(
+ServiceWorkerMainResourceLoaderInterceptor::
+ ServiceWorkerMainResourceLoaderInterceptor(
base::WeakPtr<ServiceWorkerMainResourceHandle> handle,
blink::mojom::ResourceType resource_type,
bool skip_service_worker,
@@ -379,15 +381,23 @@ ServiceWorkerNavigationLoaderInterceptor::
}
// static
-bool ServiceWorkerNavigationLoaderInterceptor::ShouldCreateForNavigation(
- const GURL& url) {
+bool ServiceWorkerMainResourceLoaderInterceptor::ShouldCreateForNavigation(
+ const GURL& url,
+ network::mojom::RequestDestination request_destination) {
+ // <embed> and <object> navigations must bypass the service worker, per the
+ // discussion in https://w3c.github.io/ServiceWorker/#implementer-concerns.
+ if (request_destination == network::mojom::RequestDestination::kEmbed ||
+ request_destination == network::mojom::RequestDestination::kObject) {
+ return false;
+ }
+
// Create the handler even for insecure HTTP since it's used in the
// case of redirect to HTTPS.
return url.SchemeIsHTTPOrHTTPS() || OriginCanAccessServiceWorkers(url) ||
SchemeMaySupportRedirectingToHTTPS(url);
}
-void ServiceWorkerNavigationLoaderInterceptor::RequestHandlerWrapper(
+void ServiceWorkerMainResourceLoaderInterceptor::RequestHandlerWrapper(
SingleRequestURLLoaderFactory::RequestHandler handler_on_core_thread,
const network::ResourceRequest& resource_request,
mojo::PendingReceiver<network::mojom::URLLoader> receiver,
diff --git a/chromium/content/browser/service_worker/service_worker_navigation_loader_interceptor.h b/chromium/content/browser/service_worker/service_worker_main_resource_loader_interceptor.h
index f6afa906886..692ce5a5495 100644
--- a/chromium/content/browser/service_worker/service_worker_navigation_loader_interceptor.h
+++ b/chromium/content/browser/service_worker/service_worker_main_resource_loader_interceptor.h
@@ -2,8 +2,8 @@
// 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_NAVIGATION_LOADER_INTERCEPTOR_H_
-#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_NAVIGATION_LOADER_INTERCEPTOR_H_
+#ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_MAIN_RESOURCE_LOADER_INTERCEPTOR_H_
+#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_MAIN_RESOURCE_LOADER_INTERCEPTOR_H_
#include <memory>
@@ -33,17 +33,17 @@ struct NavigationRequestInfo;
// The corresponding legacy class is ServiceWorkerControlleeRequestHandler which
// lives on the service worker context core thread. Currently, this class just
// delegates to the legacy class by posting tasks to it on the core thread.
-class CONTENT_EXPORT ServiceWorkerNavigationLoaderInterceptor final
+class CONTENT_EXPORT ServiceWorkerMainResourceLoaderInterceptor final
: public NavigationLoaderInterceptor {
public:
- // Creates a ServiceWorkerNavigationLoaderInterceptor for a navigation.
+ // Creates a ServiceWorkerMainResourceLoaderInterceptor for a navigation.
// Returns nullptr if the interceptor could not be created for this |url|.
static std::unique_ptr<NavigationLoaderInterceptor> CreateForNavigation(
const GURL& url,
base::WeakPtr<ServiceWorkerMainResourceHandle> navigation_handle,
const NavigationRequestInfo& request_info);
- // Creates a ServiceWorkerNavigationLoaderInterceptor for a worker.
+ // Creates a ServiceWorkerMainResourceLoaderInterceptor for a worker.
// Returns nullptr if the interceptor could not be created for the URL of the
// worker.
static std::unique_ptr<NavigationLoaderInterceptor> CreateForWorker(
@@ -53,7 +53,7 @@ class CONTENT_EXPORT ServiceWorkerNavigationLoaderInterceptor final
SharedWorkerId shared_worker_id,
base::WeakPtr<ServiceWorkerMainResourceHandle> navigation_handle);
- ~ServiceWorkerNavigationLoaderInterceptor() override;
+ ~ServiceWorkerMainResourceLoaderInterceptor() override;
// NavigationLoaderInterceptor overrides:
@@ -78,12 +78,12 @@ class CONTENT_EXPORT ServiceWorkerNavigationLoaderInterceptor final
void FallbackCallbackWrapper(FallbackCallback fallback_callback,
bool reset_subresource_loader_params);
- base::WeakPtr<ServiceWorkerNavigationLoaderInterceptor> GetWeakPtr();
+ base::WeakPtr<ServiceWorkerMainResourceLoaderInterceptor> GetWeakPtr();
private:
- friend class ServiceWorkerNavigationLoaderInterceptorTest;
+ friend class ServiceWorkerMainResourceLoaderInterceptorTest;
- ServiceWorkerNavigationLoaderInterceptor(
+ ServiceWorkerMainResourceLoaderInterceptor(
base::WeakPtr<ServiceWorkerMainResourceHandle> handle,
blink::mojom::ResourceType resource_type,
bool skip_service_worker,
@@ -93,9 +93,11 @@ class CONTENT_EXPORT ServiceWorkerNavigationLoaderInterceptor final
DedicatedWorkerId dedicated_worker_id,
SharedWorkerId shared_worker_id);
- // Returns true if a ServiceWorkerNavigationLoaderInterceptor should be
+ // Returns true if a ServiceWorkerMainResourceLoaderInterceptor should be
// created for a navigation to |url|.
- static bool ShouldCreateForNavigation(const GURL& url);
+ static bool ShouldCreateForNavigation(
+ const GURL& url,
+ network::mojom::RequestDestination request_destination);
// Given as a callback to NavigationURLLoaderImpl.
void RequestHandlerWrapper(
@@ -129,12 +131,12 @@ class CONTENT_EXPORT ServiceWorkerNavigationLoaderInterceptor final
base::Optional<SubresourceLoaderParams> subresource_loader_params_;
- base::WeakPtrFactory<ServiceWorkerNavigationLoaderInterceptor> weak_factory_{
- this};
+ base::WeakPtrFactory<ServiceWorkerMainResourceLoaderInterceptor>
+ weak_factory_{this};
- DISALLOW_COPY_AND_ASSIGN(ServiceWorkerNavigationLoaderInterceptor);
+ DISALLOW_COPY_AND_ASSIGN(ServiceWorkerMainResourceLoaderInterceptor);
};
} // namespace content
-#endif // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_NAVIGATION_LOADER_INTERCEPTOR_H_
+#endif // CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_MAIN_RESOURCE_LOADER_INTERCEPTOR_H_
diff --git a/chromium/content/browser/service_worker/service_worker_main_resource_loader_interceptor_unittest.cc b/chromium/content/browser/service_worker/service_worker_main_resource_loader_interceptor_unittest.cc
new file mode 100644
index 00000000000..d76725acb7d
--- /dev/null
+++ b/chromium/content/browser/service_worker/service_worker_main_resource_loader_interceptor_unittest.cc
@@ -0,0 +1,79 @@
+// 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/browser/service_worker/service_worker_main_resource_loader_interceptor.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
+
+namespace content {
+
+class ServiceWorkerMainResourceLoaderInterceptorTest : public testing::Test {
+ public:
+ bool ShouldCreateForNavigation(
+ const GURL& url,
+ network::mojom::RequestDestination request_destination) {
+ return ServiceWorkerMainResourceLoaderInterceptor::
+ ShouldCreateForNavigation(url, request_destination);
+ }
+};
+
+TEST_F(ServiceWorkerMainResourceLoaderInterceptorTest,
+ ShouldCreateForNavigation_HTTP) {
+ EXPECT_TRUE(
+ ShouldCreateForNavigation(GURL("http://host/scope/doc"),
+ network::mojom::RequestDestination::kDocument));
+ EXPECT_FALSE(
+ ShouldCreateForNavigation(GURL("http://host/scope/doc"),
+ network::mojom::RequestDestination::kEmbed));
+ EXPECT_FALSE(
+ ShouldCreateForNavigation(GURL("http://host/scope/doc"),
+ network::mojom::RequestDestination::kObject));
+}
+
+TEST_F(ServiceWorkerMainResourceLoaderInterceptorTest,
+ ShouldCreateForNavigation_HTTPS) {
+ EXPECT_TRUE(
+ ShouldCreateForNavigation(GURL("https://host/scope/doc"),
+ network::mojom::RequestDestination::kDocument));
+ EXPECT_FALSE(
+ ShouldCreateForNavigation(GURL("https://host/scope/doc"),
+ network::mojom::RequestDestination::kEmbed));
+ EXPECT_FALSE(
+ ShouldCreateForNavigation(GURL("https://host/scope/doc"),
+ network::mojom::RequestDestination::kObject));
+}
+
+TEST_F(ServiceWorkerMainResourceLoaderInterceptorTest,
+ ShouldCreateForNavigation_FTP) {
+ EXPECT_FALSE(
+ ShouldCreateForNavigation(GURL("ftp://host/scope/doc"),
+ network::mojom::RequestDestination::kDocument));
+ EXPECT_FALSE(
+ ShouldCreateForNavigation(GURL("ftp://host/scope/doc"),
+ network::mojom::RequestDestination::kEmbed));
+ EXPECT_FALSE(
+ ShouldCreateForNavigation(GURL("ftp://host/scope/doc"),
+ network::mojom::RequestDestination::kObject));
+}
+
+TEST_F(ServiceWorkerMainResourceLoaderInterceptorTest,
+ ShouldCreateForNavigation_ExternalFileScheme) {
+ bool expected_handler_created = false;
+#if defined(OS_CHROMEOS)
+ expected_handler_created = true;
+#endif // OS_CHROMEOS
+ EXPECT_EQ(
+ expected_handler_created,
+ ShouldCreateForNavigation(GURL("externalfile:drive/doc"),
+ network::mojom::RequestDestination::kDocument));
+ EXPECT_FALSE(
+ ShouldCreateForNavigation(GURL("externalfile:drive/doc"),
+ network::mojom::RequestDestination::kEmbed));
+ EXPECT_FALSE(
+ ShouldCreateForNavigation(GURL("externalfile:drive/doc"),
+ network::mojom::RequestDestination::kObject));
+}
+
+} // namespace content
diff --git a/chromium/content/browser/service_worker/service_worker_navigation_loader_unittest.cc b/chromium/content/browser/service_worker/service_worker_main_resource_loader_unittest.cc
index a8b46fb282f..7c54afa69ab 100644
--- a/chromium/content/browser/service_worker/service_worker_navigation_loader_unittest.cc
+++ b/chromium/content/browser/service_worker/service_worker_main_resource_loader_unittest.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "content/browser/service_worker/service_worker_navigation_loader.h"
+#include "content/browser/service_worker/service_worker_main_resource_loader.h"
#include <string>
#include <utility>
@@ -44,7 +44,7 @@
#include "third_party/blink/public/mojom/service_worker/service_worker_registration.mojom.h"
namespace content {
-namespace service_worker_navigation_loader_unittest {
+namespace service_worker_main_resource_loader_unittest {
void ReceiveRequestHandler(
SingleRequestURLLoaderFactory::RequestHandler* out_handler,
@@ -53,11 +53,17 @@ void ReceiveRequestHandler(
}
blink::mojom::FetchAPIResponsePtr OkResponse(
- blink::mojom::SerializedBlobPtr blob_body) {
+ blink::mojom::SerializedBlobPtr blob_body,
+ network::mojom::FetchResponseSource response_source,
+ base::Time response_time,
+ std::string cache_storage_cache_name) {
auto response = blink::mojom::FetchAPIResponse::New();
response->status_code = 200;
response->status_text = "OK";
response->response_type = network::mojom::FetchResponseType::kDefault;
+ response->response_source = response_source;
+ response->response_time = response_time;
+ response->cache_storage_cache_name = cache_storage_cache_name;
response->blob = std::move(blob_body);
if (response->blob) {
response->headers.emplace("Content-Length",
@@ -169,7 +175,8 @@ class FetchEventServiceWorker : public FakeServiceWorker {
void DeferResponse() { response_mode_ = ResponseMode::kDeferredResponse; }
void FinishRespondWith() {
response_callback_->OnResponse(
- OkResponse(nullptr /* blob_body */),
+ OkResponse(nullptr /* blob_body */, response_source_, response_time_,
+ cache_storage_cache_name_),
blink::mojom::ServiceWorkerFetchEventTiming::New());
response_callback_.FlushForTesting();
std::move(finish_callback_)
@@ -195,6 +202,16 @@ class FetchEventServiceWorker : public FakeServiceWorker {
run_loop.Run();
}
+ void SetResponseSource(network::mojom::FetchResponseSource source) {
+ response_source_ = source;
+ }
+
+ void SetCacheStorageCacheName(std::string cache_name) {
+ cache_storage_cache_name_ = cache_name;
+ }
+
+ void SetResponseTime(base::Time time) { response_time_ = time; }
+
protected:
void DispatchFetchEventForMainResource(
blink::mojom::DispatchFetchEventParamsPtr params,
@@ -209,6 +226,11 @@ class FetchEventServiceWorker : public FakeServiceWorker {
if (params->request->body)
request_body_ = params->request->body;
+ auto timing = blink::mojom::ServiceWorkerFetchEventTiming::New();
+ auto now = base::TimeTicks::Now();
+ timing->dispatch_event_time = now;
+ timing->respond_with_settled_time = now;
+
mojo::Remote<blink::mojom::ServiceWorkerFetchResponseCallback>
response_callback(std::move(pending_response_callback));
switch (response_mode_) {
@@ -219,35 +241,35 @@ class FetchEventServiceWorker : public FakeServiceWorker {
break;
case ResponseMode::kBlob:
response_callback->OnResponse(
- OkResponse(std::move(blob_body_)),
- blink::mojom::ServiceWorkerFetchEventTiming::New());
+ OkResponse(std::move(blob_body_), response_source_, response_time_,
+ cache_storage_cache_name_),
+ std::move(timing));
std::move(finish_callback)
.Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED);
break;
case ResponseMode::kStream:
response_callback->OnResponseStream(
- OkResponse(nullptr /* blob_body */), std::move(stream_handle_),
- blink::mojom::ServiceWorkerFetchEventTiming::New());
+ OkResponse(nullptr /* blob_body */, response_source_,
+ response_time_, cache_storage_cache_name_),
+ std::move(stream_handle_), std::move(timing));
+
std::move(finish_callback)
.Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED);
break;
case ResponseMode::kFallbackResponse:
- response_callback->OnFallback(
- blink::mojom::ServiceWorkerFetchEventTiming::New());
+ response_callback->OnFallback(std::move(timing));
std::move(finish_callback)
.Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED);
break;
case ResponseMode::kErrorResponse:
- response_callback->OnResponse(
- ErrorResponse(),
- blink::mojom::ServiceWorkerFetchEventTiming::New());
+ response_callback->OnResponse(ErrorResponse(), std::move(timing));
std::move(finish_callback)
.Run(blink::mojom::ServiceWorkerEventStatus::REJECTED);
break;
case ResponseMode::kFailFetchEventDispatch:
// Simulate failure by stopping the worker before the event finishes.
// This causes ServiceWorkerVersion::StartRequest() to call its error
- // callback, which triggers ServiceWorkerNavigationLoader's dispatch
+ // callback, which triggers ServiceWorkerMainResourceLoader's dispatch
// failed behavior.
embedded_worker_instance_client_->host()->OnStopped();
@@ -268,21 +290,20 @@ class FetchEventServiceWorker : public FakeServiceWorker {
case ResponseMode::kEarlyResponse:
finish_callback_ = std::move(finish_callback);
response_callback->OnResponse(
- OkResponse(nullptr /* blob_body */),
- blink::mojom::ServiceWorkerFetchEventTiming::New());
+ OkResponse(nullptr /* blob_body */, response_source_,
+ response_time_, cache_storage_cache_name_),
+ std::move(timing));
// Now the caller must call FinishWaitUntil() to finish the event.
break;
case ResponseMode::kRedirect:
- response_callback->OnResponse(
- RedirectResponse(redirected_url_.spec()),
- blink::mojom::ServiceWorkerFetchEventTiming::New());
+ response_callback->OnResponse(RedirectResponse(redirected_url_.spec()),
+ std::move(timing));
std::move(finish_callback)
.Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED);
break;
case ResponseMode::kHeaders:
- response_callback->OnResponse(
- HeadersResponse(headers_),
- blink::mojom::ServiceWorkerFetchEventTiming::New());
+ response_callback->OnResponse(HeadersResponse(headers_),
+ std::move(timing));
std::move(finish_callback)
.Run(blink::mojom::ServiceWorkerEventStatus::COMPLETED);
break;
@@ -332,6 +353,12 @@ class FetchEventServiceWorker : public FakeServiceWorker {
FakeEmbeddedWorkerInstanceClient* const embedded_worker_instance_client_;
+ network::mojom::FetchResponseSource response_source_ =
+ network::mojom::FetchResponseSource::kUnspecified;
+
+ std::string cache_storage_cache_name_;
+ base::Time response_time_;
+
DISALLOW_COPY_AND_ASSIGN(FetchEventServiceWorker);
};
@@ -343,7 +370,6 @@ network::mojom::URLResponseHeadPtr CreateResponseInfoFromServiceWorker() {
head->was_fallback_required_by_service_worker = false;
head->url_list_via_service_worker = std::vector<GURL>();
head->response_type = network::mojom::FetchResponseType::kDefault;
- head->is_in_cache_storage = false;
head->cache_storage_cache_name = std::string();
head->did_service_worker_navigation_preload = false;
return head;
@@ -352,17 +378,17 @@ network::mojom::URLResponseHeadPtr CreateResponseInfoFromServiceWorker() {
const char kHistogramMainResourceFetchEvent[] =
"ServiceWorker.FetchEvent.MainResource.Status";
-// ServiceWorkerNavigationLoaderTest is for testing the handling of requests
-// by a service worker via ServiceWorkerNavigationLoader.
+// ServiceWorkerMainResourceLoaderTest is for testing the handling of requests
+// by a service worker via ServiceWorkerMainResourceLoader.
//
// Of course, no actual service worker runs in the unit test, it is simulated
// via EmbeddedWorkerTestHelper receiving IPC messages from the browser and
// responding as if a service worker is running in the renderer.
-class ServiceWorkerNavigationLoaderTest : public testing::Test {
+class ServiceWorkerMainResourceLoaderTest : public testing::Test {
public:
- ServiceWorkerNavigationLoaderTest()
+ ServiceWorkerMainResourceLoaderTest()
: task_environment_(BrowserTaskEnvironment::IO_MAINLOOP) {}
- ~ServiceWorkerNavigationLoaderTest() override = default;
+ ~ServiceWorkerMainResourceLoaderTest() override = default;
void SetUp() override {
helper_ = std::make_unique<EmbeddedWorkerTestHelper>(base::FilePath());
@@ -420,7 +446,7 @@ class ServiceWorkerNavigationLoaderTest : public testing::Test {
container_host_ = CreateContainerHostForWindow(
helper_->mock_render_process_id(),
/*is_parent_frame_secure=*/true, helper_->context()->AsWeakPtr(),
- &provider_endpoints_);
+ &container_endpoints_);
container_host_->UpdateUrls(request->url,
net::SiteForCookies::FromUrl(request->url),
url::Origin::Create(request->url));
@@ -429,9 +455,9 @@ class ServiceWorkerNavigationLoaderTest : public testing::Test {
registration_, /*notify_controllerchange=*/false);
}
- // Create a ServiceWorkerNavigationLoader.
- loader_ = std::make_unique<ServiceWorkerNavigationLoader>(
- base::BindOnce(&ServiceWorkerNavigationLoaderTest::Fallback,
+ // Create a ServiceWorkerMainResourceLoader.
+ loader_ = std::make_unique<ServiceWorkerMainResourceLoader>(
+ base::BindOnce(&ServiceWorkerMainResourceLoaderTest::Fallback,
base::Unretained(this)),
container_host_,
base::WrapRefCounted<URLLoaderFactoryGetter>(
@@ -442,7 +468,7 @@ class ServiceWorkerNavigationLoaderTest : public testing::Test {
client_.CreateRemote());
}
- // The |fallback_callback| passed to the ServiceWorkerNavigationLoader in
+ // The |fallback_callback| passed to the ServiceWorkerMainResourceLoader in
// StartRequest().
void Fallback(bool reset_subresource_loader_params) {
did_call_fallback_callback_ = true;
@@ -451,7 +477,7 @@ class ServiceWorkerNavigationLoaderTest : public testing::Test {
std::move(quit_closure_for_fallback_callback_).Run();
}
- // Runs until the ServiceWorkerNavigationLoader created in StartRequest()
+ // Runs until the ServiceWorkerMainResourceLoader created in StartRequest()
// calls the |fallback_callback| given to it. The argument passed to
// |fallback_callback| is saved in |reset_subresurce_loader_params_|.
void RunUntilFallbackCallback() {
@@ -472,11 +498,20 @@ class ServiceWorkerNavigationLoaderTest : public testing::Test {
EXPECT_EQ(expected_info.url_list_via_service_worker,
info.url_list_via_service_worker);
EXPECT_EQ(expected_info.response_type, info.response_type);
+ EXPECT_EQ(expected_info.response_time, info.response_time);
EXPECT_FALSE(info.load_timing.service_worker_start_time.is_null());
EXPECT_FALSE(info.load_timing.service_worker_ready_time.is_null());
+ EXPECT_FALSE(info.load_timing.service_worker_fetch_start.is_null());
+ EXPECT_FALSE(
+ info.load_timing.service_worker_respond_with_settled.is_null());
EXPECT_LT(info.load_timing.service_worker_start_time,
info.load_timing.service_worker_ready_time);
- EXPECT_EQ(expected_info.is_in_cache_storage, info.is_in_cache_storage);
+ EXPECT_LE(info.load_timing.service_worker_ready_time,
+ info.load_timing.service_worker_fetch_start);
+ EXPECT_LE(info.load_timing.service_worker_fetch_start,
+ info.load_timing.service_worker_respond_with_settled);
+ EXPECT_EQ(expected_info.service_worker_response_source,
+ info.service_worker_response_source);
EXPECT_EQ(expected_info.cache_storage_cache_name,
info.cache_storage_cache_name);
EXPECT_EQ(expected_info.did_service_worker_navigation_preload,
@@ -491,6 +526,7 @@ class ServiceWorkerNavigationLoaderTest : public testing::Test {
request->mode = network::mojom::RequestMode::kNavigate;
request->credentials_mode = network::mojom::CredentialsMode::kInclude;
request->redirect_mode = network::mojom::RedirectMode::kManual;
+ request->destination = network::mojom::RequestDestination::kDocument;
return request;
}
@@ -506,17 +542,17 @@ class ServiceWorkerNavigationLoaderTest : public testing::Test {
FetchEventServiceWorker* service_worker_;
storage::BlobStorageContext blob_context_;
network::TestURLLoaderClient client_;
- std::unique_ptr<ServiceWorkerNavigationLoader> loader_;
+ std::unique_ptr<ServiceWorkerMainResourceLoader> loader_;
mojo::Remote<network::mojom::URLLoader> loader_remote_;
base::WeakPtr<ServiceWorkerContainerHost> container_host_;
- ServiceWorkerRemoteProviderEndpoint provider_endpoints_;
+ ServiceWorkerRemoteContainerEndpoint container_endpoints_;
bool did_call_fallback_callback_ = false;
bool reset_subresource_loader_params_ = false;
base::OnceClosure quit_closure_for_fallback_callback_;
};
-TEST_F(ServiceWorkerNavigationLoaderTest, Basic) {
+TEST_F(ServiceWorkerMainResourceLoaderTest, Basic) {
base::HistogramTester histogram_tester;
// Perform the request.
@@ -540,13 +576,13 @@ TEST_F(ServiceWorkerNavigationLoaderTest, Basic) {
1);
}
-TEST_F(ServiceWorkerNavigationLoaderTest, NoActiveWorker) {
+TEST_F(ServiceWorkerMainResourceLoaderTest, NoActiveWorker) {
base::HistogramTester histogram_tester;
// Make a container host without a controller.
container_host_ = CreateContainerHostForWindow(
helper_->mock_render_process_id(), /*is_parent_frame_secure=*/true,
- helper_->context()->AsWeakPtr(), &provider_endpoints_);
+ helper_->context()->AsWeakPtr(), &container_endpoints_);
container_host_->UpdateUrls(
GURL("https://example.com/"),
net::SiteForCookies::FromUrl(GURL("https://example.com/")),
@@ -566,7 +602,7 @@ TEST_F(ServiceWorkerNavigationLoaderTest, NoActiveWorker) {
}
// Test that the request body is passed to the fetch event.
-TEST_F(ServiceWorkerNavigationLoaderTest, RequestBody) {
+TEST_F(ServiceWorkerMainResourceLoaderTest, RequestBody) {
const std::string kData = "hi this is the request body";
// Create a request with a body.
@@ -587,7 +623,7 @@ TEST_F(ServiceWorkerNavigationLoaderTest, RequestBody) {
EXPECT_EQ(kData, body);
}
-TEST_F(ServiceWorkerNavigationLoaderTest, BlobResponse) {
+TEST_F(ServiceWorkerMainResourceLoaderTest, BlobResponse) {
base::HistogramTester histogram_tester;
// Construct the blob to respond with.
@@ -603,6 +639,12 @@ TEST_F(ServiceWorkerNavigationLoaderTest, BlobResponse) {
storage::BlobImpl::Create(std::move(blob_handle),
blob->blob.InitWithNewPipeAndPassReceiver());
service_worker_->RespondWithBlob(std::move(blob));
+ service_worker_->SetResponseSource(
+ network::mojom::FetchResponseSource::kCacheStorage);
+ std::string cache_name = "v1";
+ service_worker_->SetCacheStorageCacheName(cache_name);
+ base::Time response_time = base::Time::Now();
+ service_worker_->SetResponseTime(response_time);
// Perform the request.
StartRequest(CreateRequest());
@@ -610,7 +652,12 @@ TEST_F(ServiceWorkerNavigationLoaderTest, BlobResponse) {
auto& info = client_.response_head();
EXPECT_EQ(200, info->headers->response_code());
- ExpectResponseInfo(*info, *CreateResponseInfoFromServiceWorker());
+ auto expected_info = CreateResponseInfoFromServiceWorker();
+ expected_info->response_time = response_time;
+ expected_info->cache_storage_cache_name = cache_name;
+ expected_info->service_worker_response_source =
+ network::mojom::FetchResponseSource::kCacheStorage;
+ ExpectResponseInfo(*info, *expected_info);
EXPECT_EQ(33, info->content_length);
// Test the body.
@@ -629,7 +676,7 @@ TEST_F(ServiceWorkerNavigationLoaderTest, BlobResponse) {
}
// Tell the helper to respond with a non-existent Blob.
-TEST_F(ServiceWorkerNavigationLoaderTest, BrokenBlobResponse) {
+TEST_F(ServiceWorkerMainResourceLoaderTest, BrokenBlobResponse) {
base::HistogramTester histogram_tester;
const std::string kBrokenUUID = "broken_uuid";
@@ -669,7 +716,7 @@ TEST_F(ServiceWorkerNavigationLoaderTest, BrokenBlobResponse) {
0);
}
-TEST_F(ServiceWorkerNavigationLoaderTest, StreamResponse) {
+TEST_F(ServiceWorkerMainResourceLoaderTest, StreamResponse) {
base::HistogramTester histogram_tester;
// Construct the Stream to respond with.
@@ -717,7 +764,7 @@ TEST_F(ServiceWorkerNavigationLoaderTest, StreamResponse) {
}
// Test when a stream response body is aborted.
-TEST_F(ServiceWorkerNavigationLoaderTest, StreamResponse_Abort) {
+TEST_F(ServiceWorkerMainResourceLoaderTest, StreamResponse_Abort) {
base::HistogramTester histogram_tester;
// Construct the Stream to respond with.
@@ -767,7 +814,7 @@ TEST_F(ServiceWorkerNavigationLoaderTest, StreamResponse_Abort) {
}
// Test when the loader is cancelled while a stream response is being written.
-TEST_F(ServiceWorkerNavigationLoaderTest, StreamResponseAndCancel) {
+TEST_F(ServiceWorkerMainResourceLoaderTest, StreamResponseAndCancel) {
base::HistogramTester histogram_tester;
// Construct the Stream to respond with.
@@ -797,7 +844,7 @@ TEST_F(ServiceWorkerNavigationLoaderTest, StreamResponseAndCancel) {
loader_remote_.reset();
base::RunLoop().RunUntilIdle();
- // Although ServiceWorkerNavigationLoader resets its URLLoaderClient pointer
+ // Although ServiceWorkerMainResourceLoader resets its URLLoaderClient pointer
// on connection error, the URLLoaderClient still exists. In this test, it is
// |client_| which owns the data pipe, so it's still valid to write data to
// it.
@@ -823,7 +870,7 @@ TEST_F(ServiceWorkerNavigationLoaderTest, StreamResponseAndCancel) {
// Test when the service worker responds with network fallback.
// i.e., does not call respondWith().
-TEST_F(ServiceWorkerNavigationLoaderTest, FallbackResponse) {
+TEST_F(ServiceWorkerMainResourceLoaderTest, FallbackResponse) {
base::HistogramTester histogram_tester;
service_worker_->RespondWithFallback();
@@ -848,7 +895,7 @@ TEST_F(ServiceWorkerNavigationLoaderTest, FallbackResponse) {
}
// Test when the service worker rejects the FetchEvent.
-TEST_F(ServiceWorkerNavigationLoaderTest, ErrorResponse) {
+TEST_F(ServiceWorkerMainResourceLoaderTest, ErrorResponse) {
base::HistogramTester histogram_tester;
service_worker_->RespondWithError();
@@ -868,7 +915,7 @@ TEST_F(ServiceWorkerNavigationLoaderTest, ErrorResponse) {
}
// Test when dispatching the fetch event to the service worker failed.
-TEST_F(ServiceWorkerNavigationLoaderTest, FailFetchDispatch) {
+TEST_F(ServiceWorkerMainResourceLoaderTest, FailFetchDispatch) {
base::HistogramTester histogram_tester;
service_worker_->FailToDispatchFetchEvent();
@@ -892,7 +939,7 @@ TEST_F(ServiceWorkerNavigationLoaderTest, FailFetchDispatch) {
// Test when the respondWith() promise resolves before the waitUntil() promise
// resolves. The response should be received before the event finishes.
-TEST_F(ServiceWorkerNavigationLoaderTest, EarlyResponse) {
+TEST_F(ServiceWorkerMainResourceLoaderTest, EarlyResponse) {
service_worker_->RespondEarly();
// Perform the request.
@@ -911,7 +958,7 @@ TEST_F(ServiceWorkerNavigationLoaderTest, EarlyResponse) {
}
// Test responding to the fetch event with a redirect response.
-TEST_F(ServiceWorkerNavigationLoaderTest, Redirect) {
+TEST_F(ServiceWorkerMainResourceLoaderTest, Redirect) {
base::HistogramTester histogram_tester;
GURL new_url("https://example.com/redirected");
service_worker_->RespondWithRedirectResponse(new_url);
@@ -933,9 +980,9 @@ TEST_F(ServiceWorkerNavigationLoaderTest, Redirect) {
blink::ServiceWorkerStatusCode::kOk, 1);
}
-TEST_F(ServiceWorkerNavigationLoaderTest, Lifetime) {
+TEST_F(ServiceWorkerMainResourceLoaderTest, Lifetime) {
StartRequest(CreateRequest());
- base::WeakPtr<ServiceWorkerNavigationLoader> loader = loader_->AsWeakPtr();
+ base::WeakPtr<ServiceWorkerMainResourceLoader> loader = loader_->AsWeakPtr();
ASSERT_TRUE(loader);
client_.RunUntilComplete();
@@ -955,7 +1002,7 @@ TEST_F(ServiceWorkerNavigationLoaderTest, Lifetime) {
// |loader_| is deleted here. LSan test will alert if it leaks.
}
-TEST_F(ServiceWorkerNavigationLoaderTest, ConnectionErrorDuringFetchEvent) {
+TEST_F(ServiceWorkerMainResourceLoaderTest, ConnectionErrorDuringFetchEvent) {
service_worker_->DeferResponse();
StartRequest(CreateRequest());
@@ -976,12 +1023,12 @@ TEST_F(ServiceWorkerNavigationLoaderTest, ConnectionErrorDuringFetchEvent) {
base::RunLoop().RunUntilIdle();
}
-TEST_F(ServiceWorkerNavigationLoaderTest, CancelNavigationDuringFetchEvent) {
+TEST_F(ServiceWorkerMainResourceLoaderTest, CancelNavigationDuringFetchEvent) {
StartRequest(CreateRequest());
// Delete the container host during the request. The load should abort without
// crashing.
- provider_endpoints_.host_remote()->reset();
+ container_endpoints_.host_remote()->reset();
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(container_host_);
@@ -989,5 +1036,5 @@ TEST_F(ServiceWorkerNavigationLoaderTest, CancelNavigationDuringFetchEvent) {
EXPECT_EQ(net::ERR_ABORTED, client_.completion_status().error_code);
}
-} // namespace service_worker_navigation_loader_unittest
+} // namespace service_worker_main_resource_loader_unittest
} // namespace content
diff --git a/chromium/content/browser/service_worker/service_worker_metrics.cc b/chromium/content/browser/service_worker/service_worker_metrics.cc
index 57b27dd84c8..33b37fbf430 100644
--- a/chromium/content/browser/service_worker/service_worker_metrics.cc
+++ b/chromium/content/browser/service_worker/service_worker_metrics.cc
@@ -438,11 +438,6 @@ void ServiceWorkerMetrics::RecordFetchEventStatus(
}
}
-void ServiceWorkerMetrics::RecordProcessCreated(bool is_new_process) {
- UMA_HISTOGRAM_BOOLEAN("EmbeddedWorkerInstance.ProcessCreated",
- is_new_process);
-}
-
void ServiceWorkerMetrics::RecordStartWorkerTiming(const StartTimes& times,
StartSituation situation) {
if (!ServiceWorkerContext::IsServiceWorkerOnUIEnabled()) {
@@ -543,12 +538,6 @@ void ServiceWorkerMetrics::RecordStartStatusAfterFailure(
}
}
-void ServiceWorkerMetrics::RecordNavigationPreloadRequestHeaderSize(
- size_t size) {
- UMA_HISTOGRAM_COUNTS_100000("ServiceWorker.NavigationPreload.HeaderSize",
- size);
-}
-
void ServiceWorkerMetrics::RecordRuntime(base::TimeDelta time) {
// Start at 1 second since we expect service worker to last at least this
// long: the update timer and idle timeout timer run on the order of seconds.
@@ -601,4 +590,8 @@ void ServiceWorkerMetrics::RecordByteForByteUpdateCheckStatus(
}
}
+void ServiceWorkerMetrics::RecordGetAllOriginsInfoTime(base::TimeDelta time) {
+ base::UmaHistogramMediumTimes("ServiceWorker.GetAllOriginsInfoTime", time);
+}
+
} // namespace content
diff --git a/chromium/content/browser/service_worker/service_worker_metrics.h b/chromium/content/browser/service_worker/service_worker_metrics.h
index 5abbd860241..22eb3f27d9d 100644
--- a/chromium/content/browser/service_worker/service_worker_metrics.h
+++ b/chromium/content/browser/service_worker/service_worker_metrics.h
@@ -224,8 +224,6 @@ class ServiceWorkerMetrics {
static void RecordFetchEventStatus(bool is_main_resource,
blink::ServiceWorkerStatusCode status);
- static void RecordProcessCreated(bool is_new_process);
-
CONTENT_EXPORT static void RecordStartWorkerTiming(const StartTimes& times,
StartSituation situation);
static void RecordStartWorkerTimingClockConsistency(
@@ -267,6 +265,8 @@ class ServiceWorkerMetrics {
blink::ServiceWorkerStatusCode status,
bool has_found_update);
+ static void RecordGetAllOriginsInfoTime(base::TimeDelta time);
+
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(ServiceWorkerMetrics);
};
diff --git a/chromium/content/browser/service_worker/service_worker_navigation_loader_interceptor_unittest.cc b/chromium/content/browser/service_worker/service_worker_navigation_loader_interceptor_unittest.cc
deleted file mode 100644
index c19d457b71a..00000000000
--- a/chromium/content/browser/service_worker/service_worker_navigation_loader_interceptor_unittest.cc
+++ /dev/null
@@ -1,45 +0,0 @@
-// 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/browser/service_worker/service_worker_navigation_loader_interceptor.h"
-
-#include "testing/gtest/include/gtest/gtest.h"
-#include "url/gurl.h"
-
-namespace content {
-
-class ServiceWorkerNavigationLoaderInterceptorTest : public testing::Test {
- public:
- bool ShouldCreateForNavigation(const GURL& url) {
- return ServiceWorkerNavigationLoaderInterceptor::ShouldCreateForNavigation(
- url);
- }
-};
-
-TEST_F(ServiceWorkerNavigationLoaderInterceptorTest,
- ShouldCreateForNavigation_HTTP) {
- EXPECT_TRUE(ShouldCreateForNavigation(GURL("http://host/scope/doc")));
-}
-
-TEST_F(ServiceWorkerNavigationLoaderInterceptorTest,
- ShouldCreateForNavigation_HTTPS) {
- EXPECT_TRUE(ShouldCreateForNavigation(GURL("https://host/scope/doc")));
-}
-
-TEST_F(ServiceWorkerNavigationLoaderInterceptorTest,
- ShouldCreateForNavigation_FTP) {
- EXPECT_FALSE(ShouldCreateForNavigation(GURL("ftp://host/scope/doc")));
-}
-
-TEST_F(ServiceWorkerNavigationLoaderInterceptorTest,
- ShouldCreateForNavigation_ExternalFileScheme) {
- bool expected_handler_created = false;
-#if defined(OS_CHROMEOS)
- expected_handler_created = true;
-#endif // OS_CHROMEOS
- EXPECT_EQ(expected_handler_created,
- ShouldCreateForNavigation(GURL("externalfile:drive/doc")));
-}
-
-} // namespace content
diff --git a/chromium/content/browser/service_worker/service_worker_new_script_loader.cc b/chromium/content/browser/service_worker/service_worker_new_script_loader.cc
index 5ce7b1c5c80..f3fa77e0b2e 100644
--- a/chromium/content/browser/service_worker/service_worker_new_script_loader.cc
+++ b/chromium/content/browser/service_worker/service_worker_new_script_loader.cc
@@ -102,7 +102,7 @@ ServiceWorkerNewScriptLoader::ServiceWorkerNewScriptLoader(
network::mojom::RequestDestination::kServiceWorker);
if (is_main_script) {
// Request SSLInfo. It will be persisted in service worker storage and
- // may be used by ServiceWorkerNavigationLoader for navigations handled
+ // may be used by ServiceWorkerMainResourceLoader for navigations handled
// by this service worker.
options |= network::mojom::kURLLoadOptionSendSSLInfoWithResponse;
diff --git a/chromium/content/browser/service_worker/service_worker_object_host.cc b/chromium/content/browser/service_worker/service_worker_object_host.cc
index 8e8565665e0..8de61b59e6f 100644
--- a/chromium/content/browser/service_worker/service_worker_object_host.cc
+++ b/chromium/content/browser/service_worker/service_worker_object_host.cc
@@ -10,7 +10,7 @@
#include "content/browser/service_worker/service_worker_container_host.h"
#include "content/browser/service_worker/service_worker_context_core.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
-#include "content/browser/service_worker/service_worker_provider_host.h"
+#include "content/browser/service_worker/service_worker_host.h"
#include "content/browser/service_worker/service_worker_registration.h"
#include "content/browser/service_worker/service_worker_type_converters.h"
#include "content/common/service_worker/service_worker_utils.h"
@@ -128,11 +128,10 @@ bool PrepareExtendableMessageEventFromServiceWorker(
DCHECK(source_container_host->IsContainerForServiceWorker());
blink::mojom::ServiceWorkerObjectInfoPtr source_worker_info;
base::WeakPtr<ServiceWorkerObjectHost> service_worker_object_host =
- worker->provider_host()
+ worker->worker_host()
->container_host()
->GetOrCreateServiceWorkerObjectHost(
- source_container_host->service_worker_host()
- ->running_hosted_version());
+ source_container_host->service_worker_host()->version());
if (service_worker_object_host) {
// CreateCompleteObjectInfoToSend() is safe because |source_worker_info|
// will be sent immediately by the caller of this function.
@@ -289,9 +288,8 @@ void ServiceWorkerObjectHost::DispatchExtendableMessageEvent(
if (container_host_->IsContainerForServiceWorker()) {
// Clamp timeout to the sending worker's remaining timeout, to prevent
// postMessage from keeping workers alive forever.
- base::TimeDelta timeout = container_host_->service_worker_host()
- ->running_hosted_version()
- ->remaining_timeout();
+ base::TimeDelta timeout =
+ container_host_->service_worker_host()->version()->remaining_timeout();
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE,
diff --git a/chromium/content/browser/service_worker/service_worker_object_host_unittest.cc b/chromium/content/browser/service_worker/service_worker_object_host_unittest.cc
index 6eab59040ab..800a1ac5f4e 100644
--- a/chromium/content/browser/service_worker/service_worker_object_host_unittest.cc
+++ b/chromium/content/browser/service_worker/service_worker_object_host_unittest.cc
@@ -229,7 +229,7 @@ TEST_F(ServiceWorkerObjectHostTest, OnVersionStateChanged) {
SetUpRegistration(scope, script_url);
registration_->SetInstallingVersion(version_);
- ServiceWorkerRemoteProviderEndpoint remote_endpoint;
+ ServiceWorkerRemoteContainerEndpoint remote_endpoint;
base::WeakPtr<ServiceWorkerContainerHost> container_host =
CreateContainerHostForWindow(
helper_->mock_render_process_id(), true /* is_parent_frame_secure */,
@@ -282,7 +282,7 @@ TEST_F(ServiceWorkerObjectHostTest,
// execution context (e.g., self.registration.active inside the active
// worker and self.serviceWorker).
ServiceWorkerContainerHost* container_host =
- version_->provider_host()->container_host();
+ version_->worker_host()->container_host();
blink::mojom::ServiceWorkerObjectInfoPtr info =
container_host->GetOrCreateServiceWorkerObjectHost(version_)
->CreateCompleteObjectInfoToSend();
@@ -379,7 +379,7 @@ TEST_F(ServiceWorkerObjectHostTest, DispatchExtendableMessageEvent_FromClient) {
WebContentsTester::CreateTestWebContents(helper_->browser_context(),
nullptr));
RenderFrameHost* frame_host = web_contents->GetMainFrame();
- ServiceWorkerRemoteProviderEndpoint remote_endpoint;
+ ServiceWorkerRemoteContainerEndpoint remote_endpoint;
base::WeakPtr<ServiceWorkerContainerHost> container_host =
CreateContainerHostForWindow(
frame_host->GetProcess()->GetID(), true /* is_parent_frame_secure */,
@@ -436,7 +436,7 @@ TEST_F(ServiceWorkerObjectHostTest, OnConnectionError) {
// Set up the case where the last reference to the version is owned by the
// service worker object host.
ServiceWorkerContainerHost* container_host =
- version_->provider_host()->container_host();
+ version_->worker_host()->container_host();
ServiceWorkerVersion* version_rawptr = version_.get();
version_ = nullptr;
ASSERT_TRUE(version_rawptr->HasOneRef());
diff --git a/chromium/content/browser/service_worker/service_worker_offline_capability_check_browsertest.cc b/chromium/content/browser/service_worker/service_worker_offline_capability_check_browsertest.cc
index 9b3688bca19..47a47339315 100644
--- a/chromium/content/browser/service_worker/service_worker_offline_capability_check_browsertest.cc
+++ b/chromium/content/browser/service_worker/service_worker_offline_capability_check_browsertest.cc
@@ -689,4 +689,24 @@ IN_PROC_BROWSER_TEST_F(ServiceWorkerOfflineCapabilityCheckBrowserTest,
CheckOfflineCapability("/service_worker/empty.html?offline"));
}
+// Sites with a service worker that enable navigation preload are identified
+// as supporting offline capability only when they return a valid response in
+// offline mode.
+IN_PROC_BROWSER_TEST_F(ServiceWorkerOfflineCapabilityCheckBrowserTest,
+ CheckOfflineCapabilityForNavigationPreload) {
+ EXPECT_TRUE(NavigateToURL(shell(),
+ embedded_test_server()->GetURL(
+ "/service_worker/create_service_worker.html")));
+ EXPECT_EQ("DONE", EvalJs(shell(),
+ "register('navigation_preload_worker.js')"));
+
+ EXPECT_EQ(OfflineCapability::kUnsupported,
+ CheckOfflineCapability("/service_worker/empty.html"));
+
+ EXPECT_EQ(
+ OfflineCapability::kSupported,
+ CheckOfflineCapability(
+ "/service_worker/empty.html?navpreload_or_offline"));
+}
+
} // namespace content
diff --git a/chromium/content/browser/service_worker/service_worker_offline_capability_checker.cc b/chromium/content/browser/service_worker/service_worker_offline_capability_checker.cc
index 4a216827f97..52304d4fad2 100644
--- a/chromium/content/browser/service_worker/service_worker_offline_capability_checker.cc
+++ b/chromium/content/browser/service_worker/service_worker_offline_capability_checker.cc
@@ -11,6 +11,7 @@
#include "content/browser/service_worker/service_worker_registration.h"
#include "content/browser/service_worker/service_worker_version.h"
#include "content/browser/storage_partition_impl.h"
+#include "content/common/fetch/fetch_request_type_converters.h"
#include "url/gurl.h"
namespace content {
@@ -82,18 +83,35 @@ void ServiceWorkerOfflineCapabilityChecker::DidFindRegistration(
return;
}
- auto request = blink::mojom::FetchAPIRequest::New();
- request->url = url_;
- request->method = "GET";
- request->is_main_resource_load = true;
+ network::ResourceRequest resource_request;
+ resource_request.url = url_;
+ resource_request.method = "GET";
+ resource_request.mode = network::mojom::RequestMode::kNavigate;
+ resource_request.resource_type =
+ static_cast<int>(blink::mojom::ResourceType::kMainFrame);
+
+ // Store the weak reference to ServiceWorkerContextCore before
+ // |preferred_version| moves.
+ base::WeakPtr<ServiceWorkerContextCore> context =
+ preferred_version->context();
+ if (!context) {
+ std::move(callback_).Run(OfflineCapability::kUnsupported);
+ return;
+ }
fetch_dispatcher_ = std::make_unique<ServiceWorkerFetchDispatcher>(
- std::move(request), blink::mojom::ResourceType::kMainFrame,
+ blink::mojom::FetchAPIRequest::From(resource_request),
+ static_cast<blink::mojom::ResourceType>(resource_request.resource_type),
base::GenerateGUID() /* client_id */, std::move(preferred_version),
base::DoNothing() /* prepare callback */,
base::BindOnce(&ServiceWorkerOfflineCapabilityChecker::OnFetchResult,
base::Unretained(this)),
/*is_offline_capability_check=*/true);
+
+ fetch_dispatcher_->MaybeStartNavigationPreload(
+ resource_request, context->loader_factory_getter(),
+ context->wrapper(), /*frame_tree_node_id=*/-1);
+
fetch_dispatcher_->Run();
}
diff --git a/chromium/content/browser/service_worker/service_worker_process_manager.cc b/chromium/content/browser/service_worker/service_worker_process_manager.cc
index cca04c6aeda..f145516871b 100644
--- a/chromium/content/browser/service_worker/service_worker_process_manager.cc
+++ b/chromium/content/browser/service_worker/service_worker_process_manager.cc
@@ -9,7 +9,6 @@
#include <algorithm>
#include <utility>
-#include "base/task/post_task.h"
#include "content/browser/renderer_host/render_process_host_impl.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
#include "content/browser/site_instance_impl.h"
@@ -202,6 +201,6 @@ namespace std {
// thread.
void default_delete<content::ServiceWorkerProcessManager>::operator()(
content::ServiceWorkerProcessManager* ptr) const {
- base::DeleteSoon(FROM_HERE, {content::BrowserThread::UI}, ptr);
+ content::GetUIThreadTaskRunner({})->DeleteSoon(FROM_HERE, ptr);
}
} // namespace std
diff --git a/chromium/content/browser/service_worker/service_worker_process_manager_unittest.cc b/chromium/content/browser/service_worker/service_worker_process_manager_unittest.cc
index 67d7c2a114b..d089d7a1e41 100644
--- a/chromium/content/browser/service_worker/service_worker_process_manager_unittest.cc
+++ b/chromium/content/browser/service_worker/service_worker_process_manager_unittest.cc
@@ -109,7 +109,7 @@ TEST_F(ServiceWorkerProcessManagerTest,
std::unique_ptr<MockRenderProcessHost> host(CreateRenderProcessHost());
host->Init();
RenderProcessHostImpl::AddFrameWithSite(browser_context_.get(), host.get(),
- kSiteUrl);
+ SiteInfo(kSiteUrl));
const std::map<int, scoped_refptr<SiteInstance>>& processes =
worker_process_map();
@@ -139,7 +139,7 @@ TEST_F(ServiceWorkerProcessManagerTest,
EXPECT_TRUE(processes.empty());
RenderProcessHostImpl::RemoveFrameWithSite(browser_context_.get(), host.get(),
- kSiteUrl);
+ SiteInfo(kSiteUrl));
}
TEST_F(ServiceWorkerProcessManagerTest,
@@ -150,7 +150,7 @@ TEST_F(ServiceWorkerProcessManagerTest,
// Create a process that is hosting a frame with kSiteUrl.
std::unique_ptr<MockRenderProcessHost> host(CreateRenderProcessHost());
RenderProcessHostImpl::AddFrameWithSite(browser_context_.get(), host.get(),
- kSiteUrl);
+ SiteInfo(kSiteUrl));
const std::map<int, scoped_refptr<SiteInstance>>& processes =
worker_process_map();
@@ -179,7 +179,7 @@ TEST_F(ServiceWorkerProcessManagerTest,
EXPECT_TRUE(processes.empty());
RenderProcessHostImpl::RemoveFrameWithSite(browser_context_.get(), host.get(),
- kSiteUrl);
+ SiteInfo(kSiteUrl));
}
TEST_F(ServiceWorkerProcessManagerTest, AllocateWorkerProcess_InShutdown) {
diff --git a/chromium/content/browser/service_worker/service_worker_quota_client.cc b/chromium/content/browser/service_worker/service_worker_quota_client.cc
index 7cb9b81224c..31b9ec70f27 100644
--- a/chromium/content/browser/service_worker/service_worker_quota_client.cc
+++ b/chromium/content/browser/service_worker/service_worker_quota_client.cc
@@ -1,47 +1,36 @@
// Copyright 2014 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/browser/service_worker/service_worker_quota_client.h"
+#include <string>
+#include <utility>
+#include <vector>
+
#include "base/bind.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/storage_usage_info.h"
+#include "third_party/blink/public/mojom/quota/quota_types.mojom-shared.h"
+#include "third_party/blink/public/mojom/quota/quota_types.mojom.h"
+#include "url/gurl.h"
+#include "url/origin.h"
using blink::mojom::StorageType;
using storage::QuotaClient;
namespace content {
namespace {
-void ReportOrigins(QuotaClient::GetOriginsCallback callback,
- bool restrict_on_host,
- const std::string host,
- const std::vector<StorageUsageInfo>& usage_info) {
- std::set<url::Origin> origins;
- for (const StorageUsageInfo& info : usage_info) {
- if (restrict_on_host && info.origin.host() != host) {
- continue;
- }
- origins.insert(info.origin);
- }
- std::move(callback).Run(origins);
-}
-
void ReportToQuotaStatus(QuotaClient::DeletionCallback callback, bool status) {
std::move(callback).Run(status ? blink::mojom::QuotaStatusCode::kOk
: blink::mojom::QuotaStatusCode::kUnknown);
}
void FindUsageForOrigin(QuotaClient::GetUsageCallback callback,
- const GURL& origin,
- const std::vector<StorageUsageInfo>& usage_info) {
- for (const auto& info : usage_info) {
- if (info.origin.GetURL() == origin) {
- std::move(callback).Run(info.total_size_bytes);
- return;
- }
- }
- std::move(callback).Run(0);
+ blink::ServiceWorkerStatusCode status,
+ int64_t usage) {
+ std::move(callback).Run(usage);
}
} // namespace
@@ -53,49 +42,31 @@ ServiceWorkerQuotaClient::ServiceWorkerQuotaClient(
ServiceWorkerQuotaClient::~ServiceWorkerQuotaClient() {
}
-storage::QuotaClientType ServiceWorkerQuotaClient::type() const {
- return storage::QuotaClientType::kServiceWorker;
-}
-
void ServiceWorkerQuotaClient::GetOriginUsage(const url::Origin& origin,
StorageType type,
GetUsageCallback callback) {
- if (type != StorageType::kTemporary) {
- std::move(callback).Run(0);
- return;
- }
- context_->GetAllOriginsInfo(base::BindOnce(
- &FindUsageForOrigin, std::move(callback), origin.GetURL()));
+ DCHECK_EQ(type, StorageType::kTemporary);
+ context_->GetStorageUsageForOrigin(
+ origin, base::BindOnce(&FindUsageForOrigin, std::move(callback)));
}
void ServiceWorkerQuotaClient::GetOriginsForType(StorageType type,
GetOriginsCallback callback) {
- if (type != StorageType::kTemporary) {
- std::move(callback).Run(std::set<url::Origin>());
- return;
- }
- context_->GetAllOriginsInfo(
- base::BindOnce(&ReportOrigins, std::move(callback), false, ""));
+ DCHECK_EQ(type, StorageType::kTemporary);
+ context_->GetInstalledRegistrationOrigins(base::nullopt, std::move(callback));
}
void ServiceWorkerQuotaClient::GetOriginsForHost(StorageType type,
const std::string& host,
GetOriginsCallback callback) {
- if (type != StorageType::kTemporary) {
- std::move(callback).Run(std::set<url::Origin>());
- return;
- }
- context_->GetAllOriginsInfo(
- base::BindOnce(&ReportOrigins, std::move(callback), true, host));
+ DCHECK_EQ(type, StorageType::kTemporary);
+ context_->GetInstalledRegistrationOrigins(host, std::move(callback));
}
void ServiceWorkerQuotaClient::DeleteOriginData(const url::Origin& origin,
StorageType type,
DeletionCallback callback) {
- if (type != StorageType::kTemporary) {
- std::move(callback).Run(blink::mojom::QuotaStatusCode::kOk);
- return;
- }
+ DCHECK_EQ(type, StorageType::kTemporary);
context_->DeleteForOrigin(
origin.GetURL(),
base::BindOnce(&ReportToQuotaStatus, std::move(callback)));
@@ -104,15 +75,8 @@ void ServiceWorkerQuotaClient::DeleteOriginData(const url::Origin& origin,
void ServiceWorkerQuotaClient::PerformStorageCleanup(
blink::mojom::StorageType type,
base::OnceClosure callback) {
- if (type != StorageType::kTemporary) {
- std::move(callback).Run();
- return;
- }
+ DCHECK_EQ(type, StorageType::kTemporary);
context_->PerformStorageCleanup(std::move(callback));
}
-bool ServiceWorkerQuotaClient::DoesSupport(StorageType type) const {
- return type == StorageType::kTemporary;
-}
-
} // namespace content
diff --git a/chromium/content/browser/service_worker/service_worker_quota_client.h b/chromium/content/browser/service_worker/service_worker_quota_client.h
index 3e4d51c20b8..885e5988d03 100644
--- a/chromium/content/browser/service_worker/service_worker_quota_client.h
+++ b/chromium/content/browser/service_worker/service_worker_quota_client.h
@@ -5,13 +5,17 @@
#ifndef CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_QUOTA_CLIENT_H_
#define CONTENT_BROWSER_SERVICE_WORKER_SERVICE_WORKER_QUOTA_CLIENT_H_
+#include "base/callback_forward.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "content/common/content_export.h"
#include "storage/browser/quota/quota_client.h"
#include "storage/browser/quota/quota_client_type.h"
#include "third_party/blink/public/mojom/quota/quota_types.mojom.h"
-#include "url/origin.h"
+
+namespace url {
+class Origin;
+} // namespace url
namespace content {
class ServiceWorkerContextWrapper;
@@ -22,7 +26,6 @@ class ServiceWorkerQuotaClient : public storage::QuotaClient {
ServiceWorkerContextWrapper* context);
// QuotaClient method overrides
- storage::QuotaClientType type() const override;
void OnQuotaManagerDestroyed() override {}
void GetOriginUsage(const url::Origin& origin,
blink::mojom::StorageType type,
@@ -37,7 +40,9 @@ class ServiceWorkerQuotaClient : public storage::QuotaClient {
DeletionCallback callback) override;
void PerformStorageCleanup(blink::mojom::StorageType type,
base::OnceClosure callback) override;
- bool DoesSupport(blink::mojom::StorageType type) const override;
+
+ static constexpr storage::QuotaClientType kType =
+ storage::QuotaClientType::kServiceWorker;
private:
friend class ServiceWorkerContextWrapper;
diff --git a/chromium/content/browser/service_worker/service_worker_register_job.cc b/chromium/content/browser/service_worker/service_worker_register_job.cc
index 06effef92e9..c7586d5ee6d 100644
--- a/chromium/content/browser/service_worker/service_worker_register_job.cc
+++ b/chromium/content/browser/service_worker/service_worker_register_job.cc
@@ -30,7 +30,6 @@
#include "content/common/service_worker/service_worker_utils.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
-#include "mojo/public/cpp/bindings/associated_binding.h"
#include "net/base/net_errors.h"
#include "third_party/blink/public/common/service_worker/service_worker_type_converters.h"
#include "third_party/blink/public/common/service_worker/service_worker_utils.h"
diff --git a/chromium/content/browser/service_worker/service_worker_registration.cc b/chromium/content/browser/service_worker/service_worker_registration.cc
index 5375e02473d..4673d32e1ac 100644
--- a/chromium/content/browser/service_worker/service_worker_registration.cc
+++ b/chromium/content/browser/service_worker/service_worker_registration.cc
@@ -8,6 +8,7 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
+#include "base/metrics/histogram_macros.h"
#include "base/threading/thread_task_runner_handle.h"
#include "content/browser/service_worker/embedded_worker_status.h"
#include "content/browser/service_worker/service_worker_container_host.h"
@@ -138,6 +139,9 @@ void ServiceWorkerRegistration::NotifyVersionAttributesChanged(
ServiceWorkerRegistrationInfo ServiceWorkerRegistration::GetInfo() {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
+ UMA_HISTOGRAM_COUNTS_10000("ServiceWorker.RegistrationInfo.ScopeLength",
+ scope().spec().length());
+
return ServiceWorkerRegistrationInfo(
scope(), update_via_cache(), registration_id_,
is_deleted() ? ServiceWorkerRegistrationInfo::IS_DELETED
diff --git a/chromium/content/browser/service_worker/service_worker_registration.h b/chromium/content/browser/service_worker/service_worker_registration.h
index 6a504b87657..c59f1fe3cfa 100644
--- a/chromium/content/browser/service_worker/service_worker_registration.h
+++ b/chromium/content/browser/service_worker/service_worker_registration.h
@@ -11,7 +11,6 @@
#include <string>
#include <vector>
-#include "base/logging.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/single_thread_task_runner.h"
diff --git a/chromium/content/browser/service_worker/service_worker_registration_object_host.cc b/chromium/content/browser/service_worker/service_worker_registration_object_host.cc
index 0d61c5f7dcf..b930d95bafc 100644
--- a/chromium/content/browser/service_worker/service_worker_registration_object_host.cc
+++ b/chromium/content/browser/service_worker/service_worker_registration_object_host.cc
@@ -12,8 +12,8 @@
#include "content/browser/service_worker/service_worker_container_host.h"
#include "content/browser/service_worker/service_worker_context_core.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
+#include "content/browser/service_worker/service_worker_host.h"
#include "content/browser/service_worker/service_worker_object_host.h"
-#include "content/browser/service_worker/service_worker_provider_host.h"
#include "content/common/service_worker/service_worker_utils.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
@@ -187,7 +187,7 @@ void ServiceWorkerRegistrationObjectHost::Update(
// with an "InvalidStateError" DOMException and abort these steps.
ServiceWorkerVersion* version = nullptr;
if (container_host_->IsContainerForServiceWorker()) {
- version = container_host_->service_worker_host()->running_hosted_version();
+ version = container_host_->service_worker_host()->version();
DCHECK(version);
if (ServiceWorkerVersion::Status::INSTALLING == version->status()) {
// This can happen if update() is called during execution of the
diff --git a/chromium/content/browser/service_worker/service_worker_registration_unittest.cc b/chromium/content/browser/service_worker/service_worker_registration_unittest.cc
index ea7b997d4ae..c71ed3a6148 100644
--- a/chromium/content/browser/service_worker/service_worker_registration_unittest.cc
+++ b/chromium/content/browser/service_worker/service_worker_registration_unittest.cc
@@ -31,7 +31,7 @@
#include "content/browser/service_worker/service_worker_context_core.h"
#include "content/browser/service_worker/service_worker_context_core_observer.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
-#include "content/browser/service_worker/service_worker_provider_host.h"
+#include "content/browser/service_worker/service_worker_host.h"
#include "content/browser/service_worker/service_worker_register_job.h"
#include "content/browser/service_worker/service_worker_registration_object_host.h"
#include "content/browser/service_worker/service_worker_test_utils.h"
@@ -44,9 +44,9 @@
#include "content/public/test/url_loader_interceptor.h"
#include "content/test/fake_network.h"
#include "content/test/test_content_browser_client.h"
-#include "mojo/core/embedder/embedder.h"
#include "mojo/public/cpp/bindings/associated_receiver.h"
#include "mojo/public/cpp/bindings/pending_associated_receiver.h"
+#include "mojo/public/cpp/system/functions.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_object.mojom.h"
@@ -315,7 +315,7 @@ TEST_F(ServiceWorkerRegistrationTest, FailedRegistrationNoCrash) {
auto registration = base::MakeRefCounted<ServiceWorkerRegistration>(
options, kRegistrationId, context()->AsWeakPtr());
// Prepare a ServiceWorkerContainerHost.
- ServiceWorkerRemoteProviderEndpoint remote_endpoint;
+ ServiceWorkerRemoteContainerEndpoint remote_endpoint;
base::WeakPtr<ServiceWorkerContainerHost> container_host =
CreateContainerHostForWindow(helper_->mock_render_process_id(),
true /* is_parent_frame_secure */,
@@ -553,7 +553,7 @@ class ServiceWorkerActivationTest : public ServiceWorkerRegistrationTest,
FakeServiceWorker* version_2_service_worker_ = nullptr;
base::WeakPtr<ServiceWorkerContainerHost> container_host_;
- ServiceWorkerRemoteProviderEndpoint remote_endpoint_;
+ ServiceWorkerRemoteContainerEndpoint remote_endpoint_;
int inflight_request_id_ = -1;
DISALLOW_COPY_AND_ASSIGN(ServiceWorkerActivationTest);
@@ -790,14 +790,13 @@ class ServiceWorkerRegistrationObjectHostTest
protected:
void SetUp() override {
ServiceWorkerRegistrationTest::SetUp();
- mojo::core::SetDefaultProcessErrorCallback(base::AdaptCallbackForRepeating(
+ mojo::SetDefaultProcessErrorHandler(base::AdaptCallbackForRepeating(
base::BindOnce(&ServiceWorkerRegistrationObjectHostTest::OnMojoError,
base::Unretained(this))));
}
void TearDown() override {
- mojo::core::SetDefaultProcessErrorCallback(
- mojo::core::ProcessErrorCallback());
+ mojo::SetDefaultProcessErrorHandler(base::NullCallback());
ServiceWorkerRegistrationTest::TearDown();
}
@@ -925,10 +924,10 @@ class ServiceWorkerRegistrationObjectHostTest
return registration->id();
}
- ServiceWorkerRemoteProviderEndpoint PrepareContainerHost(
+ ServiceWorkerRemoteContainerEndpoint PrepareContainerHost(
const GURL& document_url,
base::WeakPtr<ServiceWorkerContainerHost>* out_container_host) {
- ServiceWorkerRemoteProviderEndpoint remote_endpoint;
+ ServiceWorkerRemoteContainerEndpoint remote_endpoint;
base::WeakPtr<ServiceWorkerContainerHost> container_host =
CreateContainerHostForWindow(helper_->mock_render_process_id(),
true /* is_parent_frame_secure */,
@@ -989,7 +988,7 @@ TEST_F(ServiceWorkerRegistrationObjectHostTest, BreakConnection_Destroy) {
const GURL kScope("https://www.example.com/");
const GURL kScriptUrl("https://www.example.com/sw.js");
int64_t registration_id = SetUpRegistration(kScope, kScriptUrl);
- ServiceWorkerRemoteProviderEndpoint remote_endpoint =
+ ServiceWorkerRemoteContainerEndpoint remote_endpoint =
PrepareContainerHost(kScope, nullptr /* out_container_host */);
blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info =
GetRegistrationFromRemote(remote_endpoint.host_remote()->get(), kScope);
@@ -1007,7 +1006,7 @@ TEST_P(ServiceWorkerRegistrationObjectHostUpdateTest, Update_Success) {
const GURL kScope("https://www.example.com/");
const GURL kScriptUrl("https://www.example.com/sw.js");
SetUpRegistration(kScope, kScriptUrl);
- ServiceWorkerRemoteProviderEndpoint remote_endpoint =
+ ServiceWorkerRemoteContainerEndpoint remote_endpoint =
PrepareContainerHost(kScope, nullptr /* out_container_host */);
mojo::AssociatedRemote<blink::mojom::ServiceWorkerRegistrationObjectHost>
registration_host;
@@ -1029,7 +1028,7 @@ TEST_P(ServiceWorkerRegistrationObjectHostUpdateTest,
const GURL kScriptUrl("https://www.example.com/sw.js");
SetUpRegistration(kScope, kScriptUrl);
base::WeakPtr<ServiceWorkerContainerHost> container_host;
- ServiceWorkerRemoteProviderEndpoint remote_endpoint =
+ ServiceWorkerRemoteContainerEndpoint remote_endpoint =
PrepareContainerHost(kScope, &container_host);
blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info =
GetRegistrationFromRemote(remote_endpoint.host_remote()->get(), kScope);
@@ -1050,7 +1049,7 @@ TEST_P(ServiceWorkerRegistrationObjectHostUpdateTest,
const GURL kScope("https://www.example.com/");
const GURL kScriptUrl("https://www.example.com/sw.js");
SetUpRegistration(kScope, kScriptUrl);
- ServiceWorkerRemoteProviderEndpoint remote_endpoint =
+ ServiceWorkerRemoteContainerEndpoint remote_endpoint =
PrepareContainerHost(kScope, nullptr /* out_container_host */);
blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info =
GetRegistrationFromRemote(remote_endpoint.host_remote()->get(), kScope);
@@ -1077,7 +1076,7 @@ TEST_P(ServiceWorkerRegistrationObjectHostUpdateTest,
const GURL kScope("https://www.example.com/");
const GURL kScriptUrl("https://www.example.com/sw.js");
int64_t registration_id = SetUpRegistration(kScope, kScriptUrl);
- ServiceWorkerRemoteProviderEndpoint remote_endpoint =
+ ServiceWorkerRemoteContainerEndpoint remote_endpoint =
PrepareContainerHost(kScope, nullptr /* out_container_host */);
mojo::AssociatedRemote<blink::mojom::ServiceWorkerRegistrationObjectHost>
registration_host;
@@ -1144,7 +1143,7 @@ TEST_P(ServiceWorkerRegistrationObjectHostUpdateTest,
CreateVersion(registration.get(), kScriptUrl);
version->SetStatus(ServiceWorkerVersion::ACTIVATED);
- ServiceWorkerRemoteProviderEndpoint remote_endpoint;
+ ServiceWorkerRemoteContainerEndpoint remote_endpoint;
base::WeakPtr<ServiceWorkerContainerHost> container_host =
CreateContainerHostForWindow(helper_->mock_render_process_id(),
true /* is_parent_frame_secure */,
@@ -1175,7 +1174,7 @@ TEST_F(ServiceWorkerRegistrationObjectHostTest, Unregister_Success) {
const GURL kScope("https://www.example.com/");
const GURL kScriptUrl("https://www.example.com/sw.js");
int64_t registration_id = SetUpRegistration(kScope, kScriptUrl);
- ServiceWorkerRemoteProviderEndpoint remote_endpoint =
+ ServiceWorkerRemoteContainerEndpoint remote_endpoint =
PrepareContainerHost(kScope, nullptr /* out_container_host */);
mojo::AssociatedRemote<blink::mojom::ServiceWorkerRegistrationObjectHost>
registration_host;
@@ -1205,7 +1204,7 @@ TEST_F(ServiceWorkerRegistrationObjectHostTest,
const GURL kScriptUrl("https://www.example.com/sw.js");
SetUpRegistration(kScope, kScriptUrl);
base::WeakPtr<ServiceWorkerContainerHost> container_host;
- ServiceWorkerRemoteProviderEndpoint remote_endpoint =
+ ServiceWorkerRemoteContainerEndpoint remote_endpoint =
PrepareContainerHost(kScope, &container_host);
blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info =
GetRegistrationFromRemote(remote_endpoint.host_remote()->get(), kScope);
@@ -1227,7 +1226,7 @@ TEST_F(ServiceWorkerRegistrationObjectHostTest,
const GURL kScope("https://www.example.com/");
const GURL kScriptUrl("https://www.example.com/sw.js");
SetUpRegistration(kScope, kScriptUrl);
- ServiceWorkerRemoteProviderEndpoint remote_endpoint =
+ ServiceWorkerRemoteContainerEndpoint remote_endpoint =
PrepareContainerHost(kScope, nullptr /* out_container_host */);
blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info =
GetRegistrationFromRemote(remote_endpoint.host_remote()->get(), kScope);
@@ -1247,7 +1246,7 @@ TEST_F(ServiceWorkerRegistrationObjectHostTest, SetVersionAttributes) {
const GURL kScope("https://www.example.com/");
const GURL kScriptUrl("https://www.example.com/sw.js");
int64_t registration_id = SetUpRegistration(kScope, kScriptUrl);
- ServiceWorkerRemoteProviderEndpoint remote_endpoint =
+ ServiceWorkerRemoteContainerEndpoint remote_endpoint =
PrepareContainerHost(kScope, nullptr /* out_container_host */);
blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info =
GetRegistrationFromRemote(remote_endpoint.host_remote()->get(), kScope);
@@ -1331,7 +1330,7 @@ TEST_F(ServiceWorkerRegistrationObjectHostTest, SetUpdateViaCache) {
const GURL kScope("https://www.example.com/");
const GURL kScriptUrl("https://www.example.com/sw.js");
int64_t registration_id = SetUpRegistration(kScope, kScriptUrl);
- ServiceWorkerRemoteProviderEndpoint remote_endpoint =
+ ServiceWorkerRemoteContainerEndpoint remote_endpoint =
PrepareContainerHost(kScope, nullptr /* out_container_host */);
blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info =
GetRegistrationFromRemote(remote_endpoint.host_remote()->get(), kScope);
@@ -1382,7 +1381,7 @@ TEST_P(ServiceWorkerRegistrationObjectHostUpdateTest, UpdateFound) {
const GURL kScope("https://www.example.com/");
const GURL kScriptUrl("https://www.example.com/sw.js");
int64_t registration_id = SetUpRegistration(kScope, kScriptUrl);
- ServiceWorkerRemoteProviderEndpoint remote_endpoint =
+ ServiceWorkerRemoteContainerEndpoint remote_endpoint =
PrepareContainerHost(kScope, nullptr /* out_container_host */);
blink::mojom::ServiceWorkerRegistrationObjectInfoPtr info =
GetRegistrationFromRemote(remote_endpoint.host_remote()->get(), kScope);
diff --git a/chromium/content/browser/service_worker/service_worker_registry.cc b/chromium/content/browser/service_worker/service_worker_registry.cc
index 363274a46d6..edd43add84f 100644
--- a/chromium/content/browser/service_worker/service_worker_registry.cc
+++ b/chromium/content/browser/service_worker/service_worker_registry.cc
@@ -16,6 +16,7 @@
#include "content/browser/service_worker/service_worker_context_wrapper.h"
#include "content/browser/service_worker/service_worker_info.h"
#include "content/browser/service_worker/service_worker_registration.h"
+#include "content/browser/service_worker/service_worker_storage_control_impl.h"
#include "content/browser/service_worker/service_worker_version.h"
#include "content/common/service_worker/service_worker_utils.h"
#include "content/public/browser/browser_task_traits.h"
@@ -121,9 +122,10 @@ ServiceWorkerRegistry::ServiceWorkerRegistry(
storage::QuotaManagerProxy* quota_manager_proxy,
storage::SpecialStoragePolicy* special_storage_policy)
: context_(context),
- storage_(ServiceWorkerStorage::Create(user_data_directory,
- std::move(database_task_runner),
- quota_manager_proxy)),
+ storage_control_(std::make_unique<ServiceWorkerStorageControlImpl>(
+ ServiceWorkerStorage::Create(user_data_directory,
+ std::move(database_task_runner),
+ quota_manager_proxy))),
special_storage_policy_(special_storage_policy) {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
DCHECK(context_);
@@ -134,7 +136,8 @@ ServiceWorkerRegistry::ServiceWorkerRegistry(
ServiceWorkerContextCore* context,
ServiceWorkerRegistry* old_registry)
: context_(context),
- storage_(ServiceWorkerStorage::Create(old_registry->storage())),
+ storage_control_(std::make_unique<ServiceWorkerStorageControlImpl>(
+ ServiceWorkerStorage::Create(old_registry->storage()))),
special_storage_policy_(old_registry->special_storage_policy_) {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
DCHECK(context_);
@@ -143,6 +146,10 @@ ServiceWorkerRegistry::ServiceWorkerRegistry(
ServiceWorkerRegistry::~ServiceWorkerRegistry() = default;
+ServiceWorkerStorage* ServiceWorkerRegistry::storage() const {
+ return storage_control_->storage();
+}
+
void ServiceWorkerRegistry::CreateNewRegistration(
blink::mojom::ServiceWorkerRegistrationOptions options,
NewRegistrationCallback callback) {
@@ -279,6 +286,23 @@ void ServiceWorkerRegistry::GetRegistrationsForOrigin(
weak_factory_.GetWeakPtr(), std::move(callback), origin));
}
+void ServiceWorkerRegistry::GetStorageUsageForOrigin(
+ const url::Origin& origin,
+ GetStorageUsageForOriginCallback callback) {
+ DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
+ storage()->GetUsageForOrigin(
+ origin,
+ base::BindOnce(
+ [](GetStorageUsageForOriginCallback callback,
+ storage::mojom::ServiceWorkerDatabaseStatus database_status,
+ int64_t usage) {
+ blink::ServiceWorkerStatusCode status =
+ DatabaseStatusToStatusCode(database_status);
+ std::move(callback).Run(status, usage);
+ },
+ std::move(callback)));
+}
+
void ServiceWorkerRegistry::GetAllRegistrationsInfos(
GetRegistrationsInfosCallback callback) {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
@@ -361,10 +385,10 @@ void ServiceWorkerRegistry::StoreRegistration(
version->cross_origin_embedder_policy().value();
}
- auto resources = std::make_unique<ResourceList>();
- version->script_cache_map()->GetResources(resources.get());
+ ResourceList resources;
+ version->script_cache_map()->GetResources(&resources);
- if (resources->empty()) {
+ if (resources.empty()) {
RunSoon(FROM_HERE,
base::BindOnce(std::move(callback),
blink::ServiceWorkerStatusCode::kErrorFailed));
@@ -372,7 +396,7 @@ void ServiceWorkerRegistry::StoreRegistration(
}
uint64_t resources_total_size_bytes = 0;
- for (const auto& resource : *resources) {
+ for (const auto& resource : resources) {
DCHECK_GE(resource->size_bytes, 0);
resources_total_size_bytes += resource->size_bytes;
}
@@ -430,9 +454,9 @@ void ServiceWorkerRegistry::NotifyDoneInstallingRegistration(
ResourceList resources;
version->script_cache_map()->GetResources(&resources);
- std::set<int64_t> resource_ids;
+ std::vector<int64_t> resource_ids;
for (const auto& resource : resources)
- resource_ids.insert(resource->resource_id);
+ resource_ids.push_back(resource->resource_id);
DoomUncommittedResources(resource_ids);
}
}
@@ -449,7 +473,7 @@ void ServiceWorkerRegistry::UpdateToActiveState(int64_t registration_id,
const GURL& origin,
StatusCallback callback) {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
- storage()->UpdateToActiveState(
+ GetRemoteStorageControl()->UpdateToActiveState(
registration_id, origin,
base::BindOnce(&ServiceWorkerRegistry::DidUpdateToActiveState,
weak_factory_.GetWeakPtr(), origin, std::move(callback)));
@@ -499,11 +523,12 @@ void ServiceWorkerRegistry::StoreUncommittedResourceId(int64_t resource_id,
void ServiceWorkerRegistry::DoomUncommittedResource(int64_t resource_id) {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
- DoomUncommittedResources(std::set<int64_t>(&resource_id, &resource_id + 1));
+ std::vector<int64_t> resource_ids = {resource_id};
+ DoomUncommittedResources(resource_ids);
}
void ServiceWorkerRegistry::DoomUncommittedResources(
- const std::set<int64_t>& resource_ids) {
+ const std::vector<int64_t>& resource_ids) {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
storage()->DoomUncommittedResources(
resource_ids,
@@ -565,8 +590,8 @@ void ServiceWorkerRegistry::GetUserKeysAndDataByKeyPrefix(
key_prefix.empty()) {
RunSoon(FROM_HERE,
base::BindOnce(std::move(callback),
- base::flat_map<std::string, std::string>(),
- blink::ServiceWorkerStatusCode::kErrorFailed));
+ blink::ServiceWorkerStatusCode::kErrorFailed,
+ base::flat_map<std::string, std::string>()));
return;
}
@@ -1194,9 +1219,12 @@ void ServiceWorkerRegistry::DidDeleteRegistration(
if (registration)
registration->UnsetStored();
- if (special_storage_policy_ &&
- origin_state == ServiceWorkerStorage::OriginState::kDelete) {
- tracked_origins_for_policy_update_.erase(url::Origin::Create(origin));
+ if (origin_state == ServiceWorkerStorage::OriginState::kDelete) {
+ context_->NotifyAllRegistrationsDeletedForOrigin(
+ url::Origin::Create(origin));
+ if (special_storage_policy_) {
+ tracked_origins_for_policy_update_.erase(url::Origin::Create(origin));
+ }
}
std::move(callback).Run(status);
@@ -1220,7 +1248,7 @@ void ServiceWorkerRegistry::DidWriteUncommittedResourceIds(
}
void ServiceWorkerRegistry::DidDoomUncommittedResourceIds(
- const std::set<int64_t>& resource_ids,
+ const std::vector<int64_t>& resource_ids,
storage::mojom::ServiceWorkerDatabaseStatus status) {
if (status != storage::mojom::ServiceWorkerDatabaseStatus::kOk) {
ScheduleDeleteAndStartOver();
@@ -1231,8 +1259,8 @@ void ServiceWorkerRegistry::DidDoomUncommittedResourceIds(
void ServiceWorkerRegistry::DidGetUserData(
GetUserDataCallback callback,
- const std::vector<std::string>& data,
- storage::mojom::ServiceWorkerDatabaseStatus status) {
+ storage::mojom::ServiceWorkerDatabaseStatus status,
+ const std::vector<std::string>& data) {
if (status != storage::mojom::ServiceWorkerDatabaseStatus::kOk &&
status != storage::mojom::ServiceWorkerDatabaseStatus::kErrorNotFound) {
ScheduleDeleteAndStartOver();
@@ -1242,14 +1270,14 @@ void ServiceWorkerRegistry::DidGetUserData(
void ServiceWorkerRegistry::DidGetUserKeysAndData(
GetUserKeysAndDataCallback callback,
- const base::flat_map<std::string, std::string>& data_map,
- storage::mojom::ServiceWorkerDatabaseStatus status) {
+ storage::mojom::ServiceWorkerDatabaseStatus status,
+ const base::flat_map<std::string, std::string>& data_map) {
DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
if (status != storage::mojom::ServiceWorkerDatabaseStatus::kOk &&
status != storage::mojom::ServiceWorkerDatabaseStatus::kErrorNotFound) {
ScheduleDeleteAndStartOver();
}
- std::move(callback).Run(data_map, DatabaseStatusToStatusCode(status));
+ std::move(callback).Run(DatabaseStatusToStatusCode(status), data_map);
}
void ServiceWorkerRegistry::DidStoreUserData(
@@ -1375,4 +1403,18 @@ bool ServiceWorkerRegistry::ShouldPurgeOnShutdown(const url::Origin& origin) {
!special_storage_policy_->IsStorageProtected(origin.GetURL());
}
+mojo::Remote<storage::mojom::ServiceWorkerStorageControl>&
+ServiceWorkerRegistry::GetRemoteStorageControl() {
+ DCHECK(!(remote_storage_control_.is_bound() &&
+ !remote_storage_control_.is_connected()))
+ << "Rebinding is not supported yet.";
+
+ if (!remote_storage_control_.is_bound()) {
+ storage_control_->Bind(
+ remote_storage_control_.BindNewPipeAndPassReceiver());
+ }
+
+ return remote_storage_control_;
+}
+
} // namespace content
diff --git a/chromium/content/browser/service_worker/service_worker_registry.h b/chromium/content/browser/service_worker/service_worker_registry.h
index aad45746807..2f475c6a338 100644
--- a/chromium/content/browser/service_worker/service_worker_registry.h
+++ b/chromium/content/browser/service_worker/service_worker_registry.h
@@ -13,6 +13,7 @@
#include "content/browser/service_worker/service_worker_registration.h"
#include "content/browser/service_worker/service_worker_storage.h"
#include "content/common/content_export.h"
+#include "mojo/public/cpp/bindings/remote.h"
namespace base {
class SequencedTaskRunner;
@@ -27,6 +28,7 @@ namespace content {
class ServiceWorkerContextCore;
class ServiceWorkerVersion;
+class ServiceWorkerStorageControlImpl;
class ServiceWorkerRegistryTest;
FORWARD_DECLARE_TEST(ServiceWorkerRegistryTest, StoragePolicyChange);
@@ -56,11 +58,14 @@ class CONTENT_EXPORT ServiceWorkerRegistry {
base::OnceCallback<void(const std::vector<std::string>& data,
blink::ServiceWorkerStatusCode status)>;
using GetUserKeysAndDataCallback = base::OnceCallback<void(
- const base::flat_map<std::string, std::string>& data_map,
- blink::ServiceWorkerStatusCode status)>;
+ blink::ServiceWorkerStatusCode status,
+ const base::flat_map<std::string, std::string>& data_map)>;
using GetUserDataForAllRegistrationsCallback = base::OnceCallback<void(
const std::vector<std::pair<int64_t, std::string>>& user_data,
blink::ServiceWorkerStatusCode status)>;
+ using GetStorageUsageForOriginCallback =
+ base::OnceCallback<void(blink::ServiceWorkerStatusCode status,
+ int64_t usage)>;
using StatusCallback =
base::OnceCallback<void(blink::ServiceWorkerStatusCode status)>;
@@ -78,7 +83,7 @@ class CONTENT_EXPORT ServiceWorkerRegistry {
~ServiceWorkerRegistry();
- ServiceWorkerStorage* storage() const { return storage_.get(); }
+ ServiceWorkerStorage* storage() const;
// Creates a new in-memory representation of registration. Can be null when
// storage is disabled. This method must be called after storage is
@@ -132,7 +137,13 @@ class CONTENT_EXPORT ServiceWorkerRegistry {
void GetRegistrationsForOrigin(const GURL& origin,
GetRegistrationsCallback callback);
+ // Reads the total resource size stored in the storage for a given origin.
+ void GetStorageUsageForOrigin(const url::Origin& origin,
+ GetStorageUsageForOriginCallback callback);
+
// Returns info about all stored and initially installing registrations.
+ // TODO(crbug.com/807440,1055677): Consider removing this method. Getting all
+ // registrations at once might not be a good idea.
void GetAllRegistrationsInfos(GetRegistrationsInfosCallback callback);
ServiceWorkerRegistration* GetUninstallingRegistration(const GURL& scope);
@@ -191,7 +202,7 @@ class CONTENT_EXPORT ServiceWorkerRegistry {
StatusCallback callback);
void StoreUncommittedResourceId(int64_t resource_id, const GURL& origin);
void DoomUncommittedResource(int64_t resource_id);
- void DoomUncommittedResources(const std::set<int64_t>& resource_ids);
+ void DoomUncommittedResources(const std::vector<int64_t>& resource_ids);
void GetUserData(int64_t registration_id,
const std::vector<std::string>& keys,
GetUserDataCallback callback);
@@ -308,15 +319,15 @@ class CONTENT_EXPORT ServiceWorkerRegistry {
void DidWriteUncommittedResourceIds(
storage::mojom::ServiceWorkerDatabaseStatus status);
void DidDoomUncommittedResourceIds(
- const std::set<int64_t>& resource_ids,
+ const std::vector<int64_t>& resource_ids,
storage::mojom::ServiceWorkerDatabaseStatus status);
void DidGetUserData(GetUserDataCallback callback,
- const std::vector<std::string>& data,
- storage::mojom::ServiceWorkerDatabaseStatus status);
+ storage::mojom::ServiceWorkerDatabaseStatus status,
+ const std::vector<std::string>& data);
void DidGetUserKeysAndData(
GetUserKeysAndDataCallback callback,
- const base::flat_map<std::string, std::string>& data_map,
- storage::mojom::ServiceWorkerDatabaseStatus status);
+ storage::mojom::ServiceWorkerDatabaseStatus status,
+ const base::flat_map<std::string, std::string>& data_map);
void DidStoreUserData(StatusCallback callback,
storage::mojom::ServiceWorkerDatabaseStatus status);
void DidClearUserData(StatusCallback callback,
@@ -345,10 +356,19 @@ class CONTENT_EXPORT ServiceWorkerRegistry {
void OnStoragePolicyChanged();
bool ShouldPurgeOnShutdown(const url::Origin& origin);
+ mojo::Remote<storage::mojom::ServiceWorkerStorageControl>&
+ GetRemoteStorageControl();
+
// The ServiceWorkerContextCore object must outlive this.
ServiceWorkerContextCore* const context_;
- std::unique_ptr<ServiceWorkerStorage> storage_;
+ mojo::Remote<storage::mojom::ServiceWorkerStorageControl>
+ remote_storage_control_;
+ // TODO(crbug.com/1055677): Remove this field after all storage operations are
+ // called via |remote_storage_control_|. An instance of this impl should live
+ // in the storage service.
+ std::unique_ptr<ServiceWorkerStorageControlImpl> storage_control_;
+
bool is_storage_disabled_ = false;
const scoped_refptr<storage::SpecialStoragePolicy> special_storage_policy_;
diff --git a/chromium/content/browser/service_worker/service_worker_registry_unittest.cc b/chromium/content/browser/service_worker/service_worker_registry_unittest.cc
index ec182e5ae24..66b8ea9c279 100644
--- a/chromium/content/browser/service_worker/service_worker_registry_unittest.cc
+++ b/chromium/content/browser/service_worker/service_worker_registry_unittest.cc
@@ -16,6 +16,20 @@
namespace content {
+namespace {
+
+void FindCallback(base::OnceClosure quit_closure,
+ base::Optional<blink::ServiceWorkerStatusCode>* result,
+ scoped_refptr<ServiceWorkerRegistration>* found,
+ blink::ServiceWorkerStatusCode status,
+ scoped_refptr<ServiceWorkerRegistration> registration) {
+ *result = status;
+ *found = std::move(registration);
+ std::move(quit_closure).Run();
+}
+
+} // namespace
+
class ServiceWorkerRegistryTest : public testing::Test {
public:
ServiceWorkerRegistryTest()
@@ -26,9 +40,8 @@ class ServiceWorkerRegistryTest : public testing::Test {
user_data_directory_path_ = user_data_directory_.GetPath();
special_storage_policy_ =
base::MakeRefCounted<storage::MockSpecialStoragePolicy>();
- helper_ = std::make_unique<EmbeddedWorkerTestHelper>(
- user_data_directory_path_, special_storage_policy_.get());
- registry()->storage()->LazyInitializeForTest();
+ InitializeTestHelper();
+ LazyInitialize();
}
void TearDown() override {
@@ -44,6 +57,35 @@ class ServiceWorkerRegistryTest : public testing::Test {
return special_storage_policy_.get();
}
+ void InitializeTestHelper() {
+ helper_ = std::make_unique<EmbeddedWorkerTestHelper>(
+ user_data_directory_path_, special_storage_policy_.get());
+ }
+
+ void LazyInitialize() { registry()->storage()->LazyInitializeForTest(); }
+
+ void SimulateRestart() {
+ // Need to reset |helper_| then wait for scheduled tasks to be finished
+ // because |helper_| has TestBrowserContext and the dtor schedules storage
+ // cleanup tasks.
+ helper_.reset();
+ base::RunLoop().RunUntilIdle();
+ InitializeTestHelper();
+ LazyInitialize();
+ }
+
+ blink::ServiceWorkerStatusCode FindRegistrationForClientUrl(
+ const GURL& document_url,
+ scoped_refptr<ServiceWorkerRegistration>* registration) {
+ base::Optional<blink::ServiceWorkerStatusCode> result;
+ base::RunLoop loop;
+ registry()->FindRegistrationForClientUrl(
+ document_url, base::BindOnce(&FindCallback, loop.QuitClosure(), &result,
+ registration));
+ loop.Run();
+ return result.value();
+ }
+
blink::ServiceWorkerStatusCode StoreRegistration(
scoped_refptr<ServiceWorkerRegistration> registration,
scoped_refptr<ServiceWorkerVersion> version) {
@@ -59,6 +101,22 @@ class ServiceWorkerRegistryTest : public testing::Test {
return result;
}
+ blink::ServiceWorkerStatusCode GetAllRegistrationsInfos(
+ std::vector<ServiceWorkerRegistrationInfo>* registrations) {
+ base::Optional<blink::ServiceWorkerStatusCode> result;
+ base::RunLoop loop;
+ registry()->GetAllRegistrationsInfos(base::BindLambdaForTesting(
+ [&](blink::ServiceWorkerStatusCode status,
+ const std::vector<ServiceWorkerRegistrationInfo>& infos) {
+ result = status;
+ *registrations = infos;
+ loop.Quit();
+ }));
+ EXPECT_FALSE(result.has_value()); // always async
+ loop.Run();
+ return result.value();
+ }
+
private:
// |user_data_directory_| must be declared first to preserve destructor order.
base::ScopedTempDir user_data_directory_;
@@ -69,6 +127,140 @@ class ServiceWorkerRegistryTest : public testing::Test {
std::unique_ptr<EmbeddedWorkerTestHelper> helper_;
};
+TEST_F(ServiceWorkerRegistryTest, FindRegistration_LongestScopeMatch) {
+ LazyInitialize();
+ const GURL kDocumentUrl("http://www.example.com/scope/foo");
+ scoped_refptr<ServiceWorkerRegistration> found_registration;
+
+ // Registration for "/scope/".
+ const GURL kScope1("http://www.example.com/scope/");
+ const GURL kScript1("http://www.example.com/script1.js");
+ scoped_refptr<ServiceWorkerRegistration> live_registration1 =
+ CreateServiceWorkerRegistrationAndVersion(context(), kScope1, kScript1,
+ /*resource_id=*/1);
+
+ // Registration for "/scope/foo".
+ const GURL kScope2("http://www.example.com/scope/foo");
+ const GURL kScript2("http://www.example.com/script2.js");
+ scoped_refptr<ServiceWorkerRegistration> live_registration2 =
+ CreateServiceWorkerRegistrationAndVersion(context(), kScope2, kScript2,
+ /*resource_id=*/2);
+
+ // Registration for "/scope/foobar".
+ const GURL kScope3("http://www.example.com/scope/foobar");
+ const GURL kScript3("http://www.example.com/script3.js");
+ scoped_refptr<ServiceWorkerRegistration> live_registration3 =
+ CreateServiceWorkerRegistrationAndVersion(context(), kScope3, kScript3,
+ /*resource_id=*/3);
+
+ // Notify storage of them being installed.
+ registry()->NotifyInstallingRegistration(live_registration1.get());
+ registry()->NotifyInstallingRegistration(live_registration2.get());
+ registry()->NotifyInstallingRegistration(live_registration3.get());
+
+ // Find a registration among installing ones.
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
+ FindRegistrationForClientUrl(kDocumentUrl, &found_registration));
+ EXPECT_EQ(live_registration2, found_registration);
+ found_registration = nullptr;
+
+ // Store registrations.
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
+ StoreRegistration(live_registration1,
+ live_registration1->waiting_version()));
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
+ StoreRegistration(live_registration2,
+ live_registration2->waiting_version()));
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
+ StoreRegistration(live_registration3,
+ live_registration3->waiting_version()));
+
+ // Notify storage of installations no longer happening.
+ registry()->NotifyDoneInstallingRegistration(
+ live_registration1.get(), nullptr, blink::ServiceWorkerStatusCode::kOk);
+ registry()->NotifyDoneInstallingRegistration(
+ live_registration2.get(), nullptr, blink::ServiceWorkerStatusCode::kOk);
+ registry()->NotifyDoneInstallingRegistration(
+ live_registration3.get(), nullptr, blink::ServiceWorkerStatusCode::kOk);
+
+ // Find a registration among installed ones.
+ EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
+ FindRegistrationForClientUrl(kDocumentUrl, &found_registration));
+ EXPECT_EQ(live_registration2, found_registration);
+}
+
+// Tests that fields of ServiceWorkerRegistrationInfo are filled correctly.
+TEST_F(ServiceWorkerRegistryTest, RegistrationInfoFields) {
+ const GURL kScope("http://www.example.com/scope/");
+ const GURL kScript("http://www.example.com/script1.js");
+ scoped_refptr<ServiceWorkerRegistration> registration =
+ CreateServiceWorkerRegistrationAndVersion(context(), kScope, kScript,
+ /*resource_id=*/1);
+
+ // Set some fields to check ServiceWorkerStorage serializes/deserializes
+ // these fields correctly.
+ registration->SetUpdateViaCache(
+ blink::mojom::ServiceWorkerUpdateViaCache::kImports);
+ registration->EnableNavigationPreload(true);
+ registration->SetNavigationPreloadHeader("header");
+
+ registry()->NotifyInstallingRegistration(registration.get());
+ ASSERT_EQ(StoreRegistration(registration, registration->waiting_version()),
+ blink::ServiceWorkerStatusCode::kOk);
+
+ std::vector<ServiceWorkerRegistrationInfo> all_registrations;
+ EXPECT_EQ(GetAllRegistrationsInfos(&all_registrations),
+ blink::ServiceWorkerStatusCode::kOk);
+ ASSERT_EQ(all_registrations.size(), 1UL);
+
+ ServiceWorkerRegistrationInfo info = all_registrations[0];
+ EXPECT_EQ(info.scope, registration->scope());
+ EXPECT_EQ(info.update_via_cache, registration->update_via_cache());
+ EXPECT_EQ(info.registration_id, registration->id());
+ EXPECT_EQ(info.navigation_preload_enabled,
+ registration->navigation_preload_state().enabled);
+ EXPECT_EQ(info.navigation_preload_header_length,
+ registration->navigation_preload_state().header.size());
+}
+
+// Tests loading a registration with an enabled navigation preload state, as
+// well as a custom header value.
+TEST_F(ServiceWorkerRegistryTest, EnabledNavigationPreloadState) {
+ const GURL kScope("https://valid.example.com/scope");
+ const GURL kScript("https://valid.example.com/script.js");
+ const std::string kHeaderValue("custom header value");
+
+ scoped_refptr<ServiceWorkerRegistration> registration =
+ CreateServiceWorkerRegistrationAndVersion(context(), kScope, kScript,
+ /*resource_id=*/1);
+ ServiceWorkerVersion* version = registration->waiting_version();
+ version->SetStatus(ServiceWorkerVersion::ACTIVATED);
+ registration->SetActiveVersion(version);
+ registration->EnableNavigationPreload(true);
+ registration->SetNavigationPreloadHeader(kHeaderValue);
+
+ ASSERT_EQ(StoreRegistration(registration, version),
+ blink::ServiceWorkerStatusCode::kOk);
+
+ // Simulate browser shutdown and restart.
+ registration = nullptr;
+ version = nullptr;
+ SimulateRestart();
+
+ scoped_refptr<ServiceWorkerRegistration> found_registration;
+ EXPECT_EQ(FindRegistrationForClientUrl(kScope, &found_registration),
+ blink::ServiceWorkerStatusCode::kOk);
+ const blink::mojom::NavigationPreloadState& registration_state =
+ found_registration->navigation_preload_state();
+ EXPECT_TRUE(registration_state.enabled);
+ EXPECT_EQ(registration_state.header, kHeaderValue);
+ ASSERT_TRUE(found_registration->active_version());
+ const blink::mojom::NavigationPreloadState& state =
+ found_registration->active_version()->navigation_preload_state();
+ EXPECT_TRUE(state.enabled);
+ EXPECT_EQ(state.header, kHeaderValue);
+}
+
// Tests that storage policy changes are observed.
TEST_F(ServiceWorkerRegistryTest, StoragePolicyChange) {
const GURL kScope("http://www.example.com/scope/");
diff --git a/chromium/content/browser/service_worker/service_worker_script_cache_map.h b/chromium/content/browser/service_worker/service_worker_script_cache_map.h
index ef8a55e24a0..affc4bcf4bc 100644
--- a/chromium/content/browser/service_worker/service_worker_script_cache_map.h
+++ b/chromium/content/browser/service_worker/service_worker_script_cache_map.h
@@ -73,6 +73,8 @@ class CONTENT_EXPORT ServiceWorkerScriptCacheMap {
friend class ServiceWorkerVersion;
friend class ServiceWorkerVersionBrowserTest;
FRIEND_TEST_ALL_PREFIXES(ServiceWorkerReadFromCacheJobTest, ResourceNotFound);
+ FRIEND_TEST_ALL_PREFIXES(ServiceWorkerBrowserTest,
+ DispatchFetchEventToBrokenWorker);
ServiceWorkerScriptCacheMap(
ServiceWorkerVersion* owner,
diff --git a/chromium/content/browser/service_worker/service_worker_script_loader_factory.cc b/chromium/content/browser/service_worker/service_worker_script_loader_factory.cc
index 57335f6ad2c..3a03b8c7a56 100644
--- a/chromium/content/browser/service_worker/service_worker_script_loader_factory.cc
+++ b/chromium/content/browser/service_worker/service_worker_script_loader_factory.cc
@@ -8,13 +8,13 @@
#include <string>
#include <utility>
-#include "base/debug/crash_logging.h"
+#include "base/strings/string_number_conversions.h"
#include "content/browser/service_worker/service_worker_cache_writer.h"
#include "content/browser/service_worker/service_worker_consts.h"
#include "content/browser/service_worker/service_worker_context_core.h"
+#include "content/browser/service_worker/service_worker_host.h"
#include "content/browser/service_worker/service_worker_installed_script_loader.h"
#include "content/browser/service_worker/service_worker_new_script_loader.h"
-#include "content/browser/service_worker/service_worker_provider_host.h"
#include "content/browser/service_worker/service_worker_updated_script_loader.h"
#include "content/browser/service_worker/service_worker_version.h"
#include "mojo/public/cpp/bindings/remote.h"
@@ -27,16 +27,15 @@ namespace content {
ServiceWorkerScriptLoaderFactory::ServiceWorkerScriptLoaderFactory(
base::WeakPtr<ServiceWorkerContextCore> context,
- base::WeakPtr<ServiceWorkerProviderHost> provider_host,
+ base::WeakPtr<ServiceWorkerHost> worker_host,
scoped_refptr<network::SharedURLLoaderFactory>
loader_factory_for_new_scripts)
: context_(context),
- provider_host_(provider_host),
+ worker_host_(worker_host),
loader_factory_for_new_scripts_(
std::move(loader_factory_for_new_scripts)) {
DCHECK(loader_factory_for_new_scripts_ ||
- ServiceWorkerVersion::IsInstalled(
- provider_host_->running_hosted_version()->status()));
+ ServiceWorkerVersion::IsInstalled(worker_host_->version()->status()));
}
ServiceWorkerScriptLoaderFactory::~ServiceWorkerScriptLoaderFactory() = default;
@@ -78,8 +77,7 @@ void ServiceWorkerScriptLoaderFactory::CreateLoaderAndStart(
// using ServiceWorkerNewScriptLoader.
// Case A and C:
- scoped_refptr<ServiceWorkerVersion> version =
- provider_host_->running_hosted_version();
+ scoped_refptr<ServiceWorkerVersion> version = worker_host_->version();
int64_t resource_id =
version->script_cache_map()->LookupResourceId(resource_request.url);
if (resource_id != blink::mojom::kInvalidServiceWorkerResourceId) {
@@ -156,11 +154,10 @@ void ServiceWorkerScriptLoaderFactory::Update(
bool ServiceWorkerScriptLoaderFactory::CheckIfScriptRequestIsValid(
const network::ResourceRequest& resource_request) {
- if (!context_ || !provider_host_)
+ if (!context_ || !worker_host_)
return false;
- scoped_refptr<ServiceWorkerVersion> version =
- provider_host_->running_hosted_version();
+ scoped_refptr<ServiceWorkerVersion> version = worker_host_->version();
if (!version)
return false;
@@ -205,8 +202,7 @@ void ServiceWorkerScriptLoaderFactory::CopyScript(
storage->CreateResponseReader(resource_id),
storage->CreateResponseWriter(new_resource_id));
- scoped_refptr<ServiceWorkerVersion> version =
- provider_host_->running_hosted_version();
+ scoped_refptr<ServiceWorkerVersion> version = worker_host_->version();
version->script_cache_map()->NotifyStartedCaching(url, new_resource_id);
net::Error error = cache_writer_->StartCopy(
@@ -228,8 +224,7 @@ void ServiceWorkerScriptLoaderFactory::OnCopyScriptFinished(
net::Error error) {
int64_t resource_size = cache_writer_->bytes_written();
cache_writer_.reset();
- scoped_refptr<ServiceWorkerVersion> version =
- provider_host_->running_hosted_version();
+ scoped_refptr<ServiceWorkerVersion> version = worker_host_->version();
if (error != net::OK) {
version->script_cache_map()->NotifyFinishedCaching(
@@ -273,8 +268,8 @@ void ServiceWorkerScriptLoaderFactory::OnResourceIdAssignedForNewScriptLoader(
mojo::MakeSelfOwnedReceiver(
ServiceWorkerNewScriptLoader::CreateAndStart(
routing_id, request_id, options, resource_request, std::move(client),
- provider_host_->running_hosted_version(),
- loader_factory_for_new_scripts_, traffic_annotation, resource_id),
+ worker_host_->version(), loader_factory_for_new_scripts_,
+ traffic_annotation, resource_id),
std::move(receiver));
}
diff --git a/chromium/content/browser/service_worker/service_worker_script_loader_factory.h b/chromium/content/browser/service_worker/service_worker_script_loader_factory.h
index 99867e40ebb..ccda38cf72b 100644
--- a/chromium/content/browser/service_worker/service_worker_script_loader_factory.h
+++ b/chromium/content/browser/service_worker/service_worker_script_loader_factory.h
@@ -22,7 +22,7 @@ namespace content {
class ServiceWorkerCacheWriter;
class ServiceWorkerContextCore;
-class ServiceWorkerProviderHost;
+class ServiceWorkerHost;
// Created per one running service worker for loading its scripts. This is kept
// alive while the WebServiceWorkerNetworkProvider in the renderer process is
@@ -50,7 +50,7 @@ class CONTENT_EXPORT ServiceWorkerScriptLoaderFactory
// error.
ServiceWorkerScriptLoaderFactory(
base::WeakPtr<ServiceWorkerContextCore> context,
- base::WeakPtr<ServiceWorkerProviderHost> provider_host,
+ base::WeakPtr<ServiceWorkerHost> worker_host,
scoped_refptr<network::SharedURLLoaderFactory>
loader_factory_for_new_scripts);
~ServiceWorkerScriptLoaderFactory() override;
@@ -108,7 +108,7 @@ class CONTENT_EXPORT ServiceWorkerScriptLoaderFactory
int64_t resource_id);
base::WeakPtr<ServiceWorkerContextCore> context_;
- base::WeakPtr<ServiceWorkerProviderHost> provider_host_;
+ base::WeakPtr<ServiceWorkerHost> worker_host_;
// Can be null if this factory is for an installed service worker.
scoped_refptr<network::SharedURLLoaderFactory>
loader_factory_for_new_scripts_;
diff --git a/chromium/content/browser/service_worker/service_worker_script_loader_factory_unittest.cc b/chromium/content/browser/service_worker/service_worker_script_loader_factory_unittest.cc
index 4a739dfa676..7030d15da9c 100644
--- a/chromium/content/browser/service_worker/service_worker_script_loader_factory_unittest.cc
+++ b/chromium/content/browser/service_worker/service_worker_script_loader_factory_unittest.cc
@@ -45,12 +45,12 @@ class ServiceWorkerScriptLoaderFactoryTest : public testing::Test {
context->registry(), registration_.get(), script_url_,
blink::mojom::ScriptType::kClassic);
- provider_host_ = CreateProviderHostForServiceWorkerContext(
+ worker_host_ = CreateServiceWorkerHost(
helper_->mock_render_process_id(), true /* is_parent_frame_secure */,
version_.get(), context->AsWeakPtr(), &remote_endpoint_);
factory_ = std::make_unique<ServiceWorkerScriptLoaderFactory>(
- helper_->context()->AsWeakPtr(), provider_host_->GetWeakPtr(),
+ helper_->context()->AsWeakPtr(), worker_host_->GetWeakPtr(),
helper_->url_loader_factory_getter()->GetNetworkFactory());
}
@@ -79,8 +79,8 @@ class ServiceWorkerScriptLoaderFactoryTest : public testing::Test {
GURL script_url_;
scoped_refptr<ServiceWorkerRegistration> registration_;
scoped_refptr<ServiceWorkerVersion> version_;
- std::unique_ptr<ServiceWorkerProviderHost> provider_host_;
- ServiceWorkerRemoteProviderEndpoint remote_endpoint_;
+ std::unique_ptr<ServiceWorkerHost> worker_host_;
+ ServiceWorkerRemoteContainerEndpoint remote_endpoint_;
std::unique_ptr<ServiceWorkerScriptLoaderFactory> factory_;
};
@@ -102,8 +102,8 @@ TEST_F(ServiceWorkerScriptLoaderFactoryTest, Redundant) {
EXPECT_EQ(net::ERR_ABORTED, client.completion_status().error_code);
}
-TEST_F(ServiceWorkerScriptLoaderFactoryTest, NoProviderHost) {
- provider_host_.reset();
+TEST_F(ServiceWorkerScriptLoaderFactoryTest, NoWorkerHost) {
+ worker_host_.reset();
network::TestURLLoaderClient client;
mojo::PendingRemote<network::mojom::URLLoader> loader =
diff --git a/chromium/content/browser/service_worker/service_worker_single_script_update_checker.cc b/chromium/content/browser/service_worker/service_worker_single_script_update_checker.cc
index f14d3f499f9..d2307f134cd 100644
--- a/chromium/content/browser/service_worker/service_worker_single_script_update_checker.cc
+++ b/chromium/content/browser/service_worker/service_worker_single_script_update_checker.cc
@@ -180,7 +180,7 @@ ServiceWorkerSingleScriptUpdateChecker::ServiceWorkerSingleScriptUpdateChecker(
static_cast<int>(blink::mojom::ResourceType::kServiceWorker);
// Request SSLInfo. It will be persisted in service worker storage and
- // may be used by ServiceWorkerNavigationLoader for navigations handled
+ // may be used by ServiceWorkerMainResourceLoader for navigations handled
// by this service worker.
options |= network::mojom::kURLLoadOptionSendSSLInfoWithResponse;
} else {
@@ -216,14 +216,11 @@ ServiceWorkerSingleScriptUpdateChecker::ServiceWorkerSingleScriptUpdateChecker(
std::move(compare_reader), std::move(copy_reader), std::move(writer),
/*pause_when_not_identical=*/true);
- // Get a unique request id across browser-initiated navigations and navigation
- // preloads.
- const int request_id = GlobalRequestID::MakeBrowserInitiated().request_id;
network_loader_ = ServiceWorkerUpdatedScriptLoader::
ThrottlingURLLoaderCoreWrapper::CreateLoaderAndStart(
loader_factory->Clone(), browser_context_getter, MSG_ROUTING_NONE,
- request_id, options, resource_request,
- network_client_receiver_.BindNewPipeAndPassRemote(),
+ GlobalRequestID::MakeBrowserInitiated().request_id, options,
+ resource_request, network_client_receiver_.BindNewPipeAndPassRemote(),
kUpdateCheckTrafficAnnotation);
DCHECK_EQ(network_loader_state_,
ServiceWorkerUpdatedScriptLoader::LoaderState::kNotStarted);
diff --git a/chromium/content/browser/service_worker/service_worker_single_script_update_checker_unittest.cc b/chromium/content/browser/service_worker/service_worker_single_script_update_checker_unittest.cc
index 63ec02749f1..26ed8c14481 100644
--- a/chromium/content/browser/service_worker/service_worker_single_script_update_checker_unittest.cc
+++ b/chromium/content/browser/service_worker/service_worker_single_script_update_checker_unittest.cc
@@ -174,19 +174,7 @@ class ServiceWorkerSingleScriptUpdateCheckerTest : public testing::Test {
DISALLOW_COPY_AND_ASSIGN(ServiceWorkerSingleScriptUpdateCheckerTest);
};
-class ServiceWorkerSingleScriptUpdateCheckerToggleAsyncTest
- : public ServiceWorkerSingleScriptUpdateCheckerTest,
- public testing::WithParamInterface<bool> {
- public:
- static bool IsAsync() { return GetParam(); }
-};
-
-INSTANTIATE_TEST_SUITE_P(ServiceWorkerSingleScriptUpdateCheckerToggleAsyncTestP,
- ServiceWorkerSingleScriptUpdateCheckerToggleAsyncTest,
- testing::Bool());
-
-TEST_P(ServiceWorkerSingleScriptUpdateCheckerToggleAsyncTest,
- Identical_SingleRead) {
+TEST_F(ServiceWorkerSingleScriptUpdateCheckerTest, Identical_SingleRead) {
// Response body from the network.
const std::string body_from_net("abcdef");
@@ -201,8 +189,8 @@ TEST_P(ServiceWorkerSingleScriptUpdateCheckerToggleAsyncTest,
auto copy_reader = std::make_unique<MockServiceWorkerResponseReader>();
auto writer = std::make_unique<MockServiceWorkerResponseWriter>();
MockServiceWorkerResponseReader* compare_reader_rawptr = compare_reader.get();
- compare_reader->ExpectReadOk(body_from_storage, TotalBytes(body_from_storage),
- IsAsync());
+ compare_reader->ExpectReadOk(body_from_storage,
+ TotalBytes(body_from_storage));
base::Optional<CheckResult> check_result;
std::unique_ptr<ServiceWorkerSingleScriptUpdateChecker> checker =
@@ -211,19 +199,17 @@ TEST_P(ServiceWorkerSingleScriptUpdateCheckerToggleAsyncTest,
std::move(copy_reader), std::move(writer), loader_factory.get(),
&check_result);
- if (IsAsync()) {
- // Blocked on reading the header.
- base::RunLoop().RunUntilIdle();
- EXPECT_FALSE(check_result.has_value());
+ // Blocked on reading the header.
+ base::RunLoop().RunUntilIdle();
+ EXPECT_FALSE(check_result.has_value());
- // Unblock the header, and then blocked on reading the body.
- compare_reader_rawptr->CompletePendingRead();
- base::RunLoop().RunUntilIdle();
- EXPECT_FALSE(check_result.has_value());
+ // Unblock the header, and then blocked on reading the body.
+ compare_reader_rawptr->CompletePendingRead();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_FALSE(check_result.has_value());
- // Unblock the body.
- compare_reader_rawptr->CompletePendingRead();
- }
+ // Unblock the body.
+ compare_reader_rawptr->CompletePendingRead();
// Complete the comparison of the body. It should be identical.
base::RunLoop().RunUntilIdle();
@@ -234,8 +220,7 @@ TEST_P(ServiceWorkerSingleScriptUpdateCheckerToggleAsyncTest,
EXPECT_TRUE(compare_reader_rawptr->AllExpectedReadsDone());
}
-TEST_P(ServiceWorkerSingleScriptUpdateCheckerToggleAsyncTest,
- Identical_MultipleRead) {
+TEST_F(ServiceWorkerSingleScriptUpdateCheckerTest, Identical_MultipleRead) {
// Response body from the network.
const std::string body_from_net("abcdef");
@@ -250,8 +235,8 @@ TEST_P(ServiceWorkerSingleScriptUpdateCheckerToggleAsyncTest,
auto copy_reader = std::make_unique<MockServiceWorkerResponseReader>();
auto writer = std::make_unique<MockServiceWorkerResponseWriter>();
MockServiceWorkerResponseReader* compare_reader_rawptr = compare_reader.get();
- compare_reader->ExpectReadOk(body_from_storage, TotalBytes(body_from_storage),
- IsAsync());
+ compare_reader->ExpectReadOk(body_from_storage,
+ TotalBytes(body_from_storage));
base::Optional<CheckResult> check_result;
std::unique_ptr<ServiceWorkerSingleScriptUpdateChecker> checker =
@@ -260,24 +245,22 @@ TEST_P(ServiceWorkerSingleScriptUpdateCheckerToggleAsyncTest,
std::move(copy_reader), std::move(writer), loader_factory.get(),
&check_result);
- if (IsAsync()) {
- // Blocked on reading the header.
- base::RunLoop().RunUntilIdle();
- EXPECT_FALSE(check_result.has_value());
+ // Blocked on reading the header.
+ base::RunLoop().RunUntilIdle();
+ EXPECT_FALSE(check_result.has_value());
- // Unblock the header, and then blocked on reading the body.
- compare_reader_rawptr->CompletePendingRead();
- base::RunLoop().RunUntilIdle();
- EXPECT_FALSE(check_result.has_value());
+ // Unblock the header, and then blocked on reading the body.
+ compare_reader_rawptr->CompletePendingRead();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_FALSE(check_result.has_value());
- // Unblock the body ("abc").
- compare_reader_rawptr->CompletePendingRead();
- base::RunLoop().RunUntilIdle();
- EXPECT_FALSE(check_result.has_value());
+ // Unblock the body ("abc").
+ compare_reader_rawptr->CompletePendingRead();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_FALSE(check_result.has_value());
- // Unblock the body ("def").
- compare_reader_rawptr->CompletePendingRead();
- }
+ // Unblock the body ("def").
+ compare_reader_rawptr->CompletePendingRead();
// Complete the comparison of the body. It should be identical.
base::RunLoop().RunUntilIdle();
@@ -288,7 +271,7 @@ TEST_P(ServiceWorkerSingleScriptUpdateCheckerToggleAsyncTest,
EXPECT_TRUE(compare_reader_rawptr->AllExpectedReadsDone());
}
-TEST_P(ServiceWorkerSingleScriptUpdateCheckerToggleAsyncTest, Identical_Empty) {
+TEST_F(ServiceWorkerSingleScriptUpdateCheckerTest, Identical_Empty) {
// Response body from the network, which is empty.
const std::string body_from_net("");
@@ -303,8 +286,8 @@ TEST_P(ServiceWorkerSingleScriptUpdateCheckerToggleAsyncTest, Identical_Empty) {
auto copy_reader = std::make_unique<MockServiceWorkerResponseReader>();
auto writer = std::make_unique<MockServiceWorkerResponseWriter>();
MockServiceWorkerResponseReader* compare_reader_rawptr = compare_reader.get();
- compare_reader->ExpectReadOk(body_from_storage, TotalBytes(body_from_storage),
- IsAsync());
+ compare_reader->ExpectReadOk(body_from_storage,
+ TotalBytes(body_from_storage));
base::Optional<CheckResult> check_result;
std::unique_ptr<ServiceWorkerSingleScriptUpdateChecker> checker =
@@ -313,16 +296,14 @@ TEST_P(ServiceWorkerSingleScriptUpdateCheckerToggleAsyncTest, Identical_Empty) {
std::move(copy_reader), std::move(writer), loader_factory.get(),
&check_result);
- if (IsAsync()) {
- // Blocked on reading the header.
- base::RunLoop().RunUntilIdle();
- EXPECT_FALSE(check_result.has_value());
+ // Blocked on reading the header.
+ base::RunLoop().RunUntilIdle();
+ EXPECT_FALSE(check_result.has_value());
- // Unblock the header. The initial block of the network body is empty, and
- // the empty body is passed to the cache writer. It will finish the
- // comparison immediately.
- compare_reader_rawptr->CompletePendingRead();
- }
+ // Unblock the header. The initial block of the network body is empty, and
+ // the empty body is passed to the cache writer. It will finish the
+ // comparison immediately.
+ compare_reader_rawptr->CompletePendingRead();
// Both network and storage are empty. The result should be kIdentical.
base::RunLoop().RunUntilIdle();
@@ -333,7 +314,7 @@ TEST_P(ServiceWorkerSingleScriptUpdateCheckerToggleAsyncTest, Identical_Empty) {
EXPECT_FALSE(check_result.value().paused_state);
}
-TEST_P(ServiceWorkerSingleScriptUpdateCheckerToggleAsyncTest,
+TEST_F(ServiceWorkerSingleScriptUpdateCheckerTest,
Different_SingleRead_NetworkIsLonger) {
// Response body from the network.
const std::string body_from_net = "abcdef";
@@ -349,8 +330,8 @@ TEST_P(ServiceWorkerSingleScriptUpdateCheckerToggleAsyncTest,
auto copy_reader = std::make_unique<MockServiceWorkerResponseReader>();
auto writer = std::make_unique<MockServiceWorkerResponseWriter>();
MockServiceWorkerResponseReader* compare_reader_rawptr = compare_reader.get();
- compare_reader->ExpectReadOk(body_from_storage, TotalBytes(body_from_storage),
- IsAsync());
+ compare_reader->ExpectReadOk(body_from_storage,
+ TotalBytes(body_from_storage));
base::Optional<CheckResult> check_result;
std::unique_ptr<ServiceWorkerSingleScriptUpdateChecker> checker =
@@ -359,25 +340,23 @@ TEST_P(ServiceWorkerSingleScriptUpdateCheckerToggleAsyncTest,
std::move(copy_reader), std::move(writer), loader_factory.get(),
&check_result);
- if (IsAsync()) {
- // Blocked on reading the header.
- base::RunLoop().RunUntilIdle();
- EXPECT_FALSE(check_result.has_value());
+ // Blocked on reading the header.
+ base::RunLoop().RunUntilIdle();
+ EXPECT_FALSE(check_result.has_value());
- // Unblock the header, and then blocked on reading the body.
- compare_reader_rawptr->CompletePendingRead();
- base::RunLoop().RunUntilIdle();
- EXPECT_FALSE(check_result.has_value());
+ // Unblock the header, and then blocked on reading the body.
+ compare_reader_rawptr->CompletePendingRead();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_FALSE(check_result.has_value());
- // Unblock the body ("abc").
- compare_reader_rawptr->CompletePendingRead();
- base::RunLoop().RunUntilIdle();
- EXPECT_FALSE(check_result.has_value());
+ // Unblock the body ("abc").
+ compare_reader_rawptr->CompletePendingRead();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_FALSE(check_result.has_value());
- // Unblock the body from storage (""). The cache writer detects the end of
- // the body from the disk cache.
- compare_reader_rawptr->CompletePendingRead();
- }
+ // Unblock the body from storage (""). The cache writer detects the end of
+ // the body from the disk cache.
+ compare_reader_rawptr->CompletePendingRead();
// Complete the comparison of the body. It should be different.
base::RunLoop().RunUntilIdle();
@@ -388,7 +367,7 @@ TEST_P(ServiceWorkerSingleScriptUpdateCheckerToggleAsyncTest,
EXPECT_TRUE(compare_reader_rawptr->AllExpectedReadsDone());
}
-TEST_P(ServiceWorkerSingleScriptUpdateCheckerToggleAsyncTest,
+TEST_F(ServiceWorkerSingleScriptUpdateCheckerTest,
Different_SingleRead_StorageIsLonger) {
// Response body from the network.
const std::string body_from_net = "abc";
@@ -404,8 +383,8 @@ TEST_P(ServiceWorkerSingleScriptUpdateCheckerToggleAsyncTest,
auto copy_reader = std::make_unique<MockServiceWorkerResponseReader>();
auto writer = std::make_unique<MockServiceWorkerResponseWriter>();
MockServiceWorkerResponseReader* compare_reader_rawptr = compare_reader.get();
- compare_reader->ExpectReadOk(body_from_storage, TotalBytes(body_from_storage),
- IsAsync());
+ compare_reader->ExpectReadOk(body_from_storage,
+ TotalBytes(body_from_storage));
base::Optional<CheckResult> check_result;
std::unique_ptr<ServiceWorkerSingleScriptUpdateChecker> checker =
@@ -414,20 +393,18 @@ TEST_P(ServiceWorkerSingleScriptUpdateCheckerToggleAsyncTest,
std::move(copy_reader), std::move(writer), loader_factory.get(),
&check_result);
- if (IsAsync()) {
- // Blocked on reading the header.
- base::RunLoop().RunUntilIdle();
- EXPECT_FALSE(check_result.has_value());
+ // Blocked on reading the header.
+ base::RunLoop().RunUntilIdle();
+ EXPECT_FALSE(check_result.has_value());
- // Unblock the header, and then blocked on reading the body.
- compare_reader_rawptr->CompletePendingRead();
- base::RunLoop().RunUntilIdle();
- EXPECT_FALSE(check_result.has_value());
+ // Unblock the header, and then blocked on reading the body.
+ compare_reader_rawptr->CompletePendingRead();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_FALSE(check_result.has_value());
- // Unblock the body ("abc"). At this point, data from the network reaches
- // the end.
- compare_reader_rawptr->CompletePendingRead();
- }
+ // Unblock the body ("abc"). At this point, data from the network reaches
+ // the end.
+ compare_reader_rawptr->CompletePendingRead();
// Complete the comparison of the body. It should be different.
base::RunLoop().RunUntilIdle();
@@ -444,7 +421,7 @@ TEST_P(ServiceWorkerSingleScriptUpdateCheckerToggleAsyncTest,
// Regression test for https://crbug.com/995146.
// It should detect the update appropriately even when OnComplete() arrives
// after the end of the body.
-TEST_P(ServiceWorkerSingleScriptUpdateCheckerToggleAsyncTest,
+TEST_F(ServiceWorkerSingleScriptUpdateCheckerTest,
Different_SingleRead_EndOfTheBodyFirst) {
// Response body from the network.
const std::string body_from_net = "abc";
@@ -456,8 +433,8 @@ TEST_P(ServiceWorkerSingleScriptUpdateCheckerToggleAsyncTest,
auto copy_reader = std::make_unique<MockServiceWorkerResponseReader>();
auto writer = std::make_unique<MockServiceWorkerResponseWriter>();
MockServiceWorkerResponseReader* compare_reader_rawptr = compare_reader.get();
- compare_reader->ExpectReadOk(body_from_storage, TotalBytes(body_from_storage),
- IsAsync());
+ compare_reader->ExpectReadOk(body_from_storage,
+ TotalBytes(body_from_storage));
auto loader_factory = std::make_unique<network::TestURLLoaderFactory>();
base::Optional<CheckResult> check_result;
@@ -497,20 +474,18 @@ TEST_P(ServiceWorkerSingleScriptUpdateCheckerToggleAsyncTest,
mojo::BlockingCopyFromString(body_from_net, body_producer);
body_producer.reset();
- if (IsAsync()) {
- // Blocked on reading the header.
- base::RunLoop().RunUntilIdle();
- EXPECT_FALSE(check_result.has_value());
+ // Blocked on reading the header.
+ base::RunLoop().RunUntilIdle();
+ EXPECT_FALSE(check_result.has_value());
- // Unblock the header, and then blocked on reading the body.
- compare_reader_rawptr->CompletePendingRead();
- base::RunLoop().RunUntilIdle();
- EXPECT_FALSE(check_result.has_value());
+ // Unblock the header, and then blocked on reading the body.
+ compare_reader_rawptr->CompletePendingRead();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_FALSE(check_result.has_value());
- // Unblock the body ("abc"). At this point, data from the network reaches
- // the end.
- compare_reader_rawptr->CompletePendingRead();
- }
+ // Unblock the body ("abc"). At this point, data from the network reaches
+ // the end.
+ compare_reader_rawptr->CompletePendingRead();
// Comparison should not finish until OnComplete() is called.
base::RunLoop().RunUntilIdle();
@@ -530,7 +505,7 @@ TEST_P(ServiceWorkerSingleScriptUpdateCheckerToggleAsyncTest,
EXPECT_FALSE(compare_reader_rawptr->AllExpectedReadsDone());
}
-TEST_P(ServiceWorkerSingleScriptUpdateCheckerToggleAsyncTest,
+TEST_F(ServiceWorkerSingleScriptUpdateCheckerTest,
Different_SingleRead_DifferentBody) {
// Response body from the network.
const std::string body_from_net = "abc";
@@ -546,8 +521,8 @@ TEST_P(ServiceWorkerSingleScriptUpdateCheckerToggleAsyncTest,
auto copy_reader = std::make_unique<MockServiceWorkerResponseReader>();
auto writer = std::make_unique<MockServiceWorkerResponseWriter>();
MockServiceWorkerResponseReader* compare_reader_rawptr = compare_reader.get();
- compare_reader->ExpectReadOk(body_from_storage, TotalBytes(body_from_storage),
- IsAsync());
+ compare_reader->ExpectReadOk(body_from_storage,
+ TotalBytes(body_from_storage));
base::Optional<CheckResult> check_result;
std::unique_ptr<ServiceWorkerSingleScriptUpdateChecker> checker =
@@ -556,19 +531,17 @@ TEST_P(ServiceWorkerSingleScriptUpdateCheckerToggleAsyncTest,
std::move(copy_reader), std::move(writer), loader_factory.get(),
&check_result);
- if (IsAsync()) {
- // Blocked on reading the header.
- base::RunLoop().RunUntilIdle();
- EXPECT_FALSE(check_result.has_value());
+ // Blocked on reading the header.
+ base::RunLoop().RunUntilIdle();
+ EXPECT_FALSE(check_result.has_value());
- // Unblock the header, and then blocked on reading the body.
- compare_reader_rawptr->CompletePendingRead();
- base::RunLoop().RunUntilIdle();
- EXPECT_FALSE(check_result.has_value());
+ // Unblock the header, and then blocked on reading the body.
+ compare_reader_rawptr->CompletePendingRead();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_FALSE(check_result.has_value());
- // Unblock the body ("abx").
- compare_reader_rawptr->CompletePendingRead();
- }
+ // Unblock the body ("abx").
+ compare_reader_rawptr->CompletePendingRead();
// Complete the comparison of the body. It should be different.
base::RunLoop().RunUntilIdle();
@@ -579,7 +552,7 @@ TEST_P(ServiceWorkerSingleScriptUpdateCheckerToggleAsyncTest,
EXPECT_TRUE(compare_reader_rawptr->AllExpectedReadsDone());
}
-TEST_P(ServiceWorkerSingleScriptUpdateCheckerToggleAsyncTest,
+TEST_F(ServiceWorkerSingleScriptUpdateCheckerTest,
Different_MultipleRead_NetworkIsLonger) {
// Response body from the network.
const std::string body_from_net = "abcdef";
@@ -595,8 +568,8 @@ TEST_P(ServiceWorkerSingleScriptUpdateCheckerToggleAsyncTest,
auto copy_reader = std::make_unique<MockServiceWorkerResponseReader>();
auto writer = std::make_unique<MockServiceWorkerResponseWriter>();
MockServiceWorkerResponseReader* compare_reader_rawptr = compare_reader.get();
- compare_reader->ExpectReadOk(body_from_storage, TotalBytes(body_from_storage),
- IsAsync());
+ compare_reader->ExpectReadOk(body_from_storage,
+ TotalBytes(body_from_storage));
base::Optional<CheckResult> check_result;
std::unique_ptr<ServiceWorkerSingleScriptUpdateChecker> checker =
@@ -605,32 +578,30 @@ TEST_P(ServiceWorkerSingleScriptUpdateCheckerToggleAsyncTest,
std::move(copy_reader), std::move(writer), loader_factory.get(),
&check_result);
- if (IsAsync()) {
- // Blocked on reading the header.
- base::RunLoop().RunUntilIdle();
- EXPECT_FALSE(check_result.has_value());
+ // Blocked on reading the header.
+ base::RunLoop().RunUntilIdle();
+ EXPECT_FALSE(check_result.has_value());
- // Unblock the header, and then blocked on reading the body.
- compare_reader_rawptr->CompletePendingRead();
- base::RunLoop().RunUntilIdle();
- EXPECT_FALSE(check_result.has_value());
+ // Unblock the header, and then blocked on reading the body.
+ compare_reader_rawptr->CompletePendingRead();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_FALSE(check_result.has_value());
- // Unblock the body from storage ("ab"), and then blocked on reading the
- // body again.
- compare_reader_rawptr->CompletePendingRead();
- base::RunLoop().RunUntilIdle();
- EXPECT_FALSE(check_result.has_value());
+ // Unblock the body from storage ("ab"), and then blocked on reading the
+ // body again.
+ compare_reader_rawptr->CompletePendingRead();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_FALSE(check_result.has_value());
- // Unblock the body from storage ("c"), and then blocked on reading the body
- // again.
- compare_reader_rawptr->CompletePendingRead();
- base::RunLoop().RunUntilIdle();
- EXPECT_FALSE(check_result.has_value());
+ // Unblock the body from storage ("c"), and then blocked on reading the body
+ // again.
+ compare_reader_rawptr->CompletePendingRead();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_FALSE(check_result.has_value());
- // Unblock the body from storage (""). The cache writer detects the end of
- // the body from the disk cache.
- compare_reader_rawptr->CompletePendingRead();
- }
+ // Unblock the body from storage (""). The cache writer detects the end of
+ // the body from the disk cache.
+ compare_reader_rawptr->CompletePendingRead();
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(check_result.has_value());
@@ -640,7 +611,7 @@ TEST_P(ServiceWorkerSingleScriptUpdateCheckerToggleAsyncTest,
EXPECT_TRUE(compare_reader_rawptr->AllExpectedReadsDone());
}
-TEST_P(ServiceWorkerSingleScriptUpdateCheckerToggleAsyncTest,
+TEST_F(ServiceWorkerSingleScriptUpdateCheckerTest,
Different_MultipleRead_StorageIsLonger) {
// Response body from the network.
const std::string body_from_net = "abc";
@@ -656,8 +627,8 @@ TEST_P(ServiceWorkerSingleScriptUpdateCheckerToggleAsyncTest,
auto copy_reader = std::make_unique<MockServiceWorkerResponseReader>();
auto writer = std::make_unique<MockServiceWorkerResponseWriter>();
MockServiceWorkerResponseReader* compare_reader_rawptr = compare_reader.get();
- compare_reader->ExpectReadOk(body_from_storage, TotalBytes(body_from_storage),
- IsAsync());
+ compare_reader->ExpectReadOk(body_from_storage,
+ TotalBytes(body_from_storage));
base::Optional<CheckResult> check_result;
std::unique_ptr<ServiceWorkerSingleScriptUpdateChecker> checker =
@@ -666,26 +637,24 @@ TEST_P(ServiceWorkerSingleScriptUpdateCheckerToggleAsyncTest,
std::move(copy_reader), std::move(writer), loader_factory.get(),
&check_result);
- if (IsAsync()) {
- // Blocked on reading the header.
- base::RunLoop().RunUntilIdle();
- EXPECT_FALSE(check_result.has_value());
+ // Blocked on reading the header.
+ base::RunLoop().RunUntilIdle();
+ EXPECT_FALSE(check_result.has_value());
- // Unblock the header, and then blocked on reading the body.
- compare_reader_rawptr->CompletePendingRead();
- base::RunLoop().RunUntilIdle();
- EXPECT_FALSE(check_result.has_value());
+ // Unblock the header, and then blocked on reading the body.
+ compare_reader_rawptr->CompletePendingRead();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_FALSE(check_result.has_value());
- // Unblock the body from storage ("ab"), and then blocked on reading the
- // body again.
- compare_reader_rawptr->CompletePendingRead();
- base::RunLoop().RunUntilIdle();
- EXPECT_FALSE(check_result.has_value());
+ // Unblock the body from storage ("ab"), and then blocked on reading the
+ // body again.
+ compare_reader_rawptr->CompletePendingRead();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_FALSE(check_result.has_value());
- // Unblock the body from storage ("c"). At this point, data from the network
- // reaches the end.
- compare_reader_rawptr->CompletePendingRead();
- }
+ // Unblock the body from storage ("c"). At this point, data from the network
+ // reaches the end.
+ compare_reader_rawptr->CompletePendingRead();
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(check_result.has_value());
@@ -698,7 +667,7 @@ TEST_P(ServiceWorkerSingleScriptUpdateCheckerToggleAsyncTest,
EXPECT_FALSE(compare_reader_rawptr->AllExpectedReadsDone());
}
-TEST_P(ServiceWorkerSingleScriptUpdateCheckerToggleAsyncTest,
+TEST_F(ServiceWorkerSingleScriptUpdateCheckerTest,
Different_MultipleRead_DifferentBody) {
// Response body from the network.
const std::string body_from_net = "abc";
@@ -714,8 +683,8 @@ TEST_P(ServiceWorkerSingleScriptUpdateCheckerToggleAsyncTest,
auto copy_reader = std::make_unique<MockServiceWorkerResponseReader>();
auto writer = std::make_unique<MockServiceWorkerResponseWriter>();
MockServiceWorkerResponseReader* compare_reader_rawptr = compare_reader.get();
- compare_reader->ExpectReadOk(body_from_storage, TotalBytes(body_from_storage),
- IsAsync());
+ compare_reader->ExpectReadOk(body_from_storage,
+ TotalBytes(body_from_storage));
base::Optional<CheckResult> check_result;
std::unique_ptr<ServiceWorkerSingleScriptUpdateChecker> checker =
@@ -724,26 +693,24 @@ TEST_P(ServiceWorkerSingleScriptUpdateCheckerToggleAsyncTest,
std::move(copy_reader), std::move(writer), loader_factory.get(),
&check_result);
- if (IsAsync()) {
- // Blocked on reading the header.
- base::RunLoop().RunUntilIdle();
- EXPECT_FALSE(check_result.has_value());
+ // Blocked on reading the header.
+ base::RunLoop().RunUntilIdle();
+ EXPECT_FALSE(check_result.has_value());
- // Unblock the header, and then blocked on reading the body.
- compare_reader_rawptr->CompletePendingRead();
- base::RunLoop().RunUntilIdle();
- EXPECT_FALSE(check_result.has_value());
+ // Unblock the header, and then blocked on reading the body.
+ compare_reader_rawptr->CompletePendingRead();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_FALSE(check_result.has_value());
- // Unblock the body from storage ("ab"), and then blocked on reading the
- // body again.
- compare_reader_rawptr->CompletePendingRead();
- base::RunLoop().RunUntilIdle();
- EXPECT_FALSE(check_result.has_value());
+ // Unblock the body from storage ("ab"), and then blocked on reading the
+ // body again.
+ compare_reader_rawptr->CompletePendingRead();
+ base::RunLoop().RunUntilIdle();
+ EXPECT_FALSE(check_result.has_value());
- // Unblock the body from storage ("x"), which is different from the body
- // from the network.
- compare_reader_rawptr->CompletePendingRead();
- }
+ // Unblock the body from storage ("x"), which is different from the body
+ // from the network.
+ compare_reader_rawptr->CompletePendingRead();
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(check_result.has_value());
@@ -766,8 +733,8 @@ TEST_F(ServiceWorkerSingleScriptUpdateCheckerTest,
auto copy_reader = std::make_unique<MockServiceWorkerResponseReader>();
auto writer = std::make_unique<MockServiceWorkerResponseWriter>();
MockServiceWorkerResponseReader* compare_reader_rawptr = compare_reader.get();
- compare_reader->ExpectReadOk(body_from_storage, TotalBytes(body_from_storage),
- /*async=*/true);
+ compare_reader->ExpectReadOk(body_from_storage,
+ TotalBytes(body_from_storage));
base::Optional<CheckResult> check_result;
std::unique_ptr<ServiceWorkerSingleScriptUpdateChecker> checker =
@@ -1101,8 +1068,8 @@ TEST_F(ServiceWorkerSingleScriptUpdateCheckerTest, PathRestrictionPass) {
auto copy_reader = std::make_unique<MockServiceWorkerResponseReader>();
auto writer = std::make_unique<MockServiceWorkerResponseWriter>();
MockServiceWorkerResponseReader* compare_reader_rawptr = compare_reader.get();
- compare_reader->ExpectReadOk(body_from_storage, TotalBytes(body_from_storage),
- false /* async */);
+ compare_reader->ExpectReadOk(body_from_storage,
+ TotalBytes(body_from_storage));
base::Optional<CheckResult> check_result;
std::unique_ptr<ServiceWorkerSingleScriptUpdateChecker> checker =
@@ -1112,6 +1079,16 @@ TEST_F(ServiceWorkerSingleScriptUpdateCheckerTest, PathRestrictionPass) {
blink::mojom::ServiceWorkerUpdateViaCache::kNone, base::TimeDelta(),
std::move(compare_reader), std::move(copy_reader), std::move(writer),
loader_factory.get(), &check_result);
+
+ // Blocked on reading the header.
+ base::RunLoop().RunUntilIdle();
+
+ // Unblock the header, and then blocked on reading the body.
+ compare_reader_rawptr->CompletePendingRead();
+ base::RunLoop().RunUntilIdle();
+
+ // Unblock the body from the storage ("abcdef"), and the comparison ends.
+ compare_reader_rawptr->CompletePendingRead();
base::RunLoop().RunUntilIdle();
EXPECT_TRUE(check_result.has_value());
diff --git a/chromium/content/browser/service_worker/service_worker_storage.cc b/chromium/content/browser/service_worker/service_worker_storage.cc
index 7d0f4facc2b..4d89284d004 100644
--- a/chromium/content/browser/service_worker/service_worker_storage.cc
+++ b/chromium/content/browser/service_worker/service_worker_storage.cc
@@ -295,6 +295,33 @@ void ServiceWorkerStorage::GetRegistrationsForOrigin(
std::move(registrations), std::move(resource_lists)));
}
+void ServiceWorkerStorage::GetUsageForOrigin(
+ const url::Origin& origin,
+ GetUsageForOriginCallback callback) {
+ switch (state_) {
+ case STORAGE_STATE_DISABLED:
+ RunSoon(FROM_HERE,
+ base::BindOnce(std::move(callback),
+ ServiceWorkerDatabase::Status::kErrorDisabled,
+ /*usage=*/0));
+ return;
+ case STORAGE_STATE_INITIALIZING: // Fall-through.
+ case STORAGE_STATE_UNINITIALIZED:
+ LazyInitialize(base::BindOnce(&ServiceWorkerStorage::GetUsageForOrigin,
+ weak_factory_.GetWeakPtr(), origin,
+ std::move(callback)));
+ return;
+ case STORAGE_STATE_INITIALIZED:
+ break;
+ }
+
+ database_task_runner_->PostTask(
+ FROM_HERE,
+ base::BindOnce(&ServiceWorkerStorage::GetUsageForOriginInDB,
+ database_.get(), base::ThreadTaskRunnerHandle::Get(),
+ origin, std::move(callback)));
+}
+
void ServiceWorkerStorage::GetAllRegistrations(
GetAllRegistrationsCallback callback) {
switch (state_) {
@@ -328,7 +355,7 @@ void ServiceWorkerStorage::GetAllRegistrations(
void ServiceWorkerStorage::StoreRegistrationData(
storage::mojom::ServiceWorkerRegistrationDataPtr registration_data,
- std::unique_ptr<ResourceList> resources,
+ ResourceList resources,
StoreRegistrationDataCallback callback) {
DCHECK_EQ(state_, STORAGE_STATE_INITIALIZED);
@@ -510,17 +537,17 @@ void ServiceWorkerStorage::StoreUncommittedResourceId(
if (!has_checked_for_stale_resources_)
DeleteStaleResources();
+ std::vector<int64_t> resource_ids = {resource_id};
base::PostTaskAndReplyWithResult(
database_task_runner_.get(), FROM_HERE,
base::BindOnce(&ServiceWorkerDatabase::WriteUncommittedResourceIds,
- base::Unretained(database_.get()),
- std::set<int64_t>(&resource_id, &resource_id + 1)),
+ base::Unretained(database_.get()), resource_ids),
base::BindOnce(&ServiceWorkerStorage::DidWriteUncommittedResourceIds,
weak_factory_.GetWeakPtr(), std::move(callback), origin));
}
void ServiceWorkerStorage::DoomUncommittedResources(
- const std::set<int64_t>& resource_ids,
+ const std::vector<int64_t>& resource_ids,
DatabaseStatusCallback callback) {
DCHECK(STORAGE_STATE_INITIALIZED == state_ ||
STORAGE_STATE_DISABLED == state_)
@@ -576,8 +603,9 @@ void ServiceWorkerStorage::GetUserData(int64_t registration_id,
switch (state_) {
case STORAGE_STATE_DISABLED:
RunSoon(FROM_HERE,
- base::BindOnce(std::move(callback), std::vector<std::string>(),
- ServiceWorkerDatabase::Status::kErrorDisabled));
+ base::BindOnce(std::move(callback),
+ ServiceWorkerDatabase::Status::kErrorDisabled,
+ std::vector<std::string>()));
return;
case STORAGE_STATE_INITIALIZING: // Fall-through.
case STORAGE_STATE_UNINITIALIZED:
@@ -608,8 +636,9 @@ void ServiceWorkerStorage::GetUserDataByKeyPrefix(
switch (state_) {
case STORAGE_STATE_DISABLED:
RunSoon(FROM_HERE,
- base::BindOnce(std::move(callback), std::vector<std::string>(),
- ServiceWorkerDatabase::Status::kErrorDisabled));
+ base::BindOnce(std::move(callback),
+ ServiceWorkerDatabase::Status::kErrorDisabled,
+ std::vector<std::string>()));
return;
case STORAGE_STATE_INITIALIZING: // Fall-through.
case STORAGE_STATE_UNINITIALIZED:
@@ -642,8 +671,8 @@ void ServiceWorkerStorage::GetUserKeysAndDataByKeyPrefix(
case STORAGE_STATE_DISABLED:
RunSoon(FROM_HERE,
base::BindOnce(std::move(callback),
- base::flat_map<std::string, std::string>(),
- ServiceWorkerDatabase::Status::kErrorDisabled));
+ ServiceWorkerDatabase::Status::kErrorDisabled,
+ base::flat_map<std::string, std::string>()));
return;
case STORAGE_STATE_INITIALIZING: // Fall-through.
case STORAGE_STATE_UNINITIALIZED:
@@ -886,13 +915,6 @@ void ServiceWorkerStorage::PurgeResources(
StartPurgingResources(resource_ids);
}
-void ServiceWorkerStorage::PurgeResources(
- const std::set<int64_t>& resource_ids) {
- if (!has_checked_for_stale_resources_)
- DeleteStaleResources();
- StartPurgingResources(resource_ids);
-}
-
void ServiceWorkerStorage::ApplyPolicyUpdates(
const std::vector<storage::mojom::LocalStoragePolicyUpdatePtr>&
policy_updates) {
@@ -1139,14 +1161,6 @@ void ServiceWorkerStorage::OnDiskCacheInitialized(int rv) {
}
void ServiceWorkerStorage::StartPurgingResources(
- const std::set<int64_t>& resource_ids) {
- DCHECK(has_checked_for_stale_resources_);
- for (int64_t resource_id : resource_ids)
- purgeable_resource_ids_.push_back(resource_id);
- ContinuePurgingResources();
-}
-
-void ServiceWorkerStorage::StartPurgingResources(
const std::vector<int64_t>& resource_ids) {
DCHECK(has_checked_for_stale_resources_);
for (int64_t resource_id : resource_ids)
@@ -1198,7 +1212,7 @@ void ServiceWorkerStorage::OnResourcePurged(int64_t id, int rv) {
// TODO(falken): Is it always OK to ClearPurgeableResourceIds if |rv| is
// failure? The disk cache entry might still remain and once we remove its
// purgeable id, we will never retry deleting it.
- std::set<int64_t> ids = {id};
+ std::vector<int64_t> ids = {id};
database_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(
@@ -1265,7 +1279,7 @@ void ServiceWorkerStorage::CollectStaleResourcesFromDB(
ServiceWorkerDatabase* database,
scoped_refptr<base::SequencedTaskRunner> original_task_runner,
GetResourcesCallback callback) {
- std::set<int64_t> ids;
+ std::vector<int64_t> ids;
ServiceWorkerDatabase::Status status =
database->GetUncommittedResourceIds(&ids);
if (status != ServiceWorkerDatabase::Status::kOk) {
@@ -1364,13 +1378,12 @@ void ServiceWorkerStorage::WriteRegistrationInDB(
ServiceWorkerDatabase* database,
scoped_refptr<base::SequencedTaskRunner> original_task_runner,
storage::mojom::ServiceWorkerRegistrationDataPtr registration,
- std::unique_ptr<ResourceList> resources,
+ ResourceList resources,
WriteRegistrationCallback callback) {
DCHECK(database);
- DCHECK(resources);
ServiceWorkerDatabase::DeletedVersion deleted_version;
ServiceWorkerDatabase::Status status =
- database->WriteRegistration(*registration, *resources, &deleted_version);
+ database->WriteRegistration(*registration, resources, &deleted_version);
original_task_runner->PostTask(
FROM_HERE,
base::BindOnce(std::move(callback), registration->script.GetOrigin(),
@@ -1484,6 +1497,19 @@ void ServiceWorkerStorage::FindForIdOnlyInDB(
std::move(callback));
}
+// static
+void ServiceWorkerStorage::GetUsageForOriginInDB(
+ ServiceWorkerDatabase* database,
+ scoped_refptr<base::SequencedTaskRunner> original_task_runner,
+ url::Origin origin,
+ GetUsageForOriginCallback callback) {
+ int64_t usage = 0;
+ ServiceWorkerDatabase::Status status =
+ database->GetUsageForOrigin(origin, usage);
+ original_task_runner->PostTask(
+ FROM_HERE, base::BindOnce(std::move(callback), status, usage));
+}
+
void ServiceWorkerStorage::GetUserDataInDB(
ServiceWorkerDatabase* database,
scoped_refptr<base::SequencedTaskRunner> original_task_runner,
@@ -1494,7 +1520,7 @@ void ServiceWorkerStorage::GetUserDataInDB(
ServiceWorkerDatabase::Status status =
database->ReadUserData(registration_id, keys, &values);
original_task_runner->PostTask(
- FROM_HERE, base::BindOnce(std::move(callback), values, status));
+ FROM_HERE, base::BindOnce(std::move(callback), status, values));
}
void ServiceWorkerStorage::GetUserDataByKeyPrefixInDB(
@@ -1507,7 +1533,7 @@ void ServiceWorkerStorage::GetUserDataByKeyPrefixInDB(
ServiceWorkerDatabase::Status status =
database->ReadUserDataByKeyPrefix(registration_id, key_prefix, &values);
original_task_runner->PostTask(
- FROM_HERE, base::BindOnce(std::move(callback), values, status));
+ FROM_HERE, base::BindOnce(std::move(callback), status, values));
}
void ServiceWorkerStorage::GetUserKeysAndDataByKeyPrefixInDB(
@@ -1521,7 +1547,7 @@ void ServiceWorkerStorage::GetUserKeysAndDataByKeyPrefixInDB(
database->ReadUserKeysAndDataByKeyPrefix(registration_id, key_prefix,
&data_map);
original_task_runner->PostTask(
- FROM_HERE, base::BindOnce(std::move(callback), data_map, status));
+ FROM_HERE, base::BindOnce(std::move(callback), status, data_map));
}
void ServiceWorkerStorage::GetUserDataForAllRegistrationsInDB(
diff --git a/chromium/content/browser/service_worker/service_worker_storage.h b/chromium/content/browser/service_worker/service_worker_storage.h
index 0e9f0dcd321..63e356b7d20 100644
--- a/chromium/content/browser/service_worker/service_worker_storage.h
+++ b/chromium/content/browser/service_worker/service_worker_storage.h
@@ -42,6 +42,7 @@ class ServiceWorkerDiskCache;
class ServiceWorkerResponseMetadataWriter;
class ServiceWorkerResponseReader;
class ServiceWorkerResponseWriter;
+class ServiceWorkerStorageControlImplTest;
namespace service_worker_storage_unittest {
class ServiceWorkerStorageTest;
@@ -79,6 +80,9 @@ class CONTENT_EXPORT ServiceWorkerStorage {
ServiceWorkerDatabase::Status status,
std::unique_ptr<RegistrationList> registrations,
std::unique_ptr<std::vector<ResourceList>> resource_lists)>;
+ using GetUsageForOriginCallback =
+ base::OnceCallback<void(ServiceWorkerDatabase::Status status,
+ int64_t usage)>;
using GetAllRegistrationsCallback =
base::OnceCallback<void(ServiceWorkerDatabase::Status status,
std::unique_ptr<RegistrationList> registrations)>;
@@ -99,11 +103,9 @@ class CONTENT_EXPORT ServiceWorkerStorage {
using DatabaseStatusCallback =
base::OnceCallback<void(ServiceWorkerDatabase::Status status)>;
using GetUserDataInDBCallback =
- base::OnceCallback<void(const std::vector<std::string>& data,
- ServiceWorkerDatabase::Status)>;
- using GetUserKeysAndDataInDBCallback = base::OnceCallback<void(
- const base::flat_map<std::string, std::string>& data_map,
- ServiceWorkerDatabase::Status)>;
+ storage::mojom::ServiceWorkerStorageControl::GetUserDataCallback;
+ using GetUserKeysAndDataInDBCallback = storage::mojom::
+ ServiceWorkerStorageControl::GetUserKeysAndDataByKeyPrefixCallback;
using GetUserDataForAllRegistrationsInDBCallback = base::OnceCallback<void(
const std::vector<std::pair<int64_t, std::string>>& user_data,
ServiceWorkerDatabase::Status)>;
@@ -141,13 +143,17 @@ class CONTENT_EXPORT ServiceWorkerStorage {
void GetRegistrationsForOrigin(const GURL& origin,
GetRegistrationsDataCallback callback);
+ // Reads the total resource size stored in the storage for a given origin.
+ void GetUsageForOrigin(const url::Origin& origin,
+ GetUsageForOriginCallback callback);
+
// Returns all stored registrations.
void GetAllRegistrations(GetAllRegistrationsCallback callback);
// Stores |registration_data| and |resources| on persistent storage.
void StoreRegistrationData(
storage::mojom::ServiceWorkerRegistrationDataPtr registration_data,
- std::unique_ptr<ResourceList> resources,
+ ResourceList resources,
StoreRegistrationDataCallback callback);
// Updates the state of the registration's stored version to active.
@@ -199,7 +205,7 @@ class CONTENT_EXPORT ServiceWorkerStorage {
// Removes resource ids from uncommitted list, adds them to the purgeable list
// and purges them.
- void DoomUncommittedResources(const std::set<int64_t>& resource_ids,
+ void DoomUncommittedResources(const std::vector<int64_t>& resource_ids,
DatabaseStatusCallback callback);
// Provide a storage mechanism to read/write arbitrary data associated with
@@ -291,7 +297,6 @@ class CONTENT_EXPORT ServiceWorkerStorage {
// the uncommitted resource keys.
void PurgeResources(const ResourceList& resources);
void PurgeResources(const std::vector<int64_t>& resource_ids);
- void PurgeResources(const std::set<int64_t>& resource_ids);
// Applies |policy_updates|.
void ApplyPolicyUpdates(
@@ -303,6 +308,7 @@ class CONTENT_EXPORT ServiceWorkerStorage {
void SetPurgingCompleteCallbackForTest(base::OnceClosure callback);
private:
+ friend class ServiceWorkerStorageControlImplTest;
friend class service_worker_storage_unittest::ServiceWorkerStorageTest;
friend class service_worker_storage_unittest::
ServiceWorkerResourceStorageTest;
@@ -409,7 +415,6 @@ class CONTENT_EXPORT ServiceWorkerStorage {
void InitializeDiskCache();
void OnDiskCacheInitialized(int rv);
- void StartPurgingResources(const std::set<int64_t>& resource_ids);
void StartPurgingResources(const std::vector<int64_t>& resource_ids);
void StartPurgingResources(const ResourceList& resources);
void ContinuePurgingResources();
@@ -450,7 +455,7 @@ class CONTENT_EXPORT ServiceWorkerStorage {
ServiceWorkerDatabase* database,
scoped_refptr<base::SequencedTaskRunner> original_task_runner,
storage::mojom::ServiceWorkerRegistrationDataPtr registration,
- std::unique_ptr<ResourceList> resources,
+ ResourceList resources,
WriteRegistrationCallback callback);
static void FindForClientUrlInDB(
ServiceWorkerDatabase* database,
@@ -473,6 +478,11 @@ class CONTENT_EXPORT ServiceWorkerStorage {
scoped_refptr<base::SequencedTaskRunner> original_task_runner,
int64_t registration_id,
FindInDBCallback callback);
+ static void GetUsageForOriginInDB(
+ ServiceWorkerDatabase* database,
+ scoped_refptr<base::SequencedTaskRunner> original_task_runner,
+ url::Origin origin,
+ GetUsageForOriginCallback callback);
static void GetUserDataInDB(
ServiceWorkerDatabase* database,
scoped_refptr<base::SequencedTaskRunner> original_task_runner,
diff --git a/chromium/content/browser/service_worker/service_worker_storage_control_impl.cc b/chromium/content/browser/service_worker/service_worker_storage_control_impl.cc
index b771697e424..3667bc14151 100644
--- a/chromium/content/browser/service_worker/service_worker_storage_control_impl.cc
+++ b/chromium/content/browser/service_worker/service_worker_storage_control_impl.cc
@@ -5,48 +5,14 @@
#include "content/browser/service_worker/service_worker_storage_control_impl.h"
#include "content/browser/service_worker/service_worker_resource_ops.h"
-#include "content/browser/service_worker/service_worker_storage.h"
+#include "mojo/public/cpp/bindings/pending_remote.h"
+#include "mojo/public/cpp/bindings/receiver_set.h"
#include "mojo/public/cpp/bindings/self_owned_receiver.h"
namespace content {
namespace {
-using ResourceList =
- std::vector<storage::mojom::ServiceWorkerResourceRecordPtr>;
-
-void DidFindRegistration(
- base::OnceCallback<
- void(storage::mojom::ServiceWorkerFindRegistrationResultPtr)> callback,
- storage::mojom::ServiceWorkerRegistrationDataPtr data,
- std::unique_ptr<ResourceList> resources,
- storage::mojom::ServiceWorkerDatabaseStatus status) {
- ResourceList resource_list =
- resources ? std::move(*resources) : ResourceList();
- std::move(callback).Run(
- storage::mojom::ServiceWorkerFindRegistrationResult::New(
- status, std::move(data), std::move(resource_list)));
-}
-
-void DidStoreRegistration(
- ServiceWorkerStorageControlImpl::StoreRegistrationCallback callback,
- storage::mojom::ServiceWorkerDatabaseStatus status,
- int64_t deleted_version_id,
- const std::vector<int64_t>& newly_purgeable_resources) {
- // TODO(bashi): Figure out how to purge resources.
- std::move(callback).Run(status);
-}
-
-void DidDeleteRegistration(
- ServiceWorkerStorageControlImpl::DeleteRegistrationCallback callback,
- storage::mojom::ServiceWorkerDatabaseStatus status,
- ServiceWorkerStorage::OriginState origin_state,
- int64_t deleted_version_id,
- const std::vector<int64_t>& newly_purgeable_resources) {
- // TODO(bashi): Figure out how to purge resources.
- std::move(callback).Run(status, origin_state);
-}
-
void DidGetRegistrationsForOrigin(
ServiceWorkerStorageControlImpl::GetRegistrationsForOriginCallback callback,
storage::mojom::ServiceWorkerDatabaseStatus status,
@@ -68,26 +34,6 @@ void DidGetRegistrationsForOrigin(
std::move(callback).Run(status, std::move(registrations));
}
-void DidGetUserData(
- ServiceWorkerStorageControlImpl::GetUserDataCallback callback,
- const std::vector<std::string>& values,
- storage::mojom::ServiceWorkerDatabaseStatus status) {
- // TODO(bashi): Change ServiceWorkerStorage::GetUserDataInDBCallback to remove
- // this indirection (the order of |values| and |status| is different).
- std::move(callback).Run(status, values);
-}
-
-void DidGetKeysAndUserData(
- ServiceWorkerStorageControlImpl::GetUserKeysAndDataByKeyPrefixCallback
- callback,
- const base::flat_map<std::string, std::string>& user_data,
- storage::mojom::ServiceWorkerDatabaseStatus status) {
- // TODO(bashi): Change ServiceWorkerStorage::GetUserKeysAndDataInDBCallback to
- // remove this indirection (the order of |user_data| and |status| is
- // different).
- std::move(callback).Run(status, user_data);
-}
-
void DidGetUserDataForAllRegistrations(
ServiceWorkerStorageControlImpl::GetUserDataForAllRegistrationsCallback
callback,
@@ -104,6 +50,46 @@ void DidGetUserDataForAllRegistrations(
} // namespace
+class ServiceWorkerLiveVersionRefImpl
+ : public storage::mojom::ServiceWorkerLiveVersionRef {
+ public:
+ ServiceWorkerLiveVersionRefImpl(
+ base::WeakPtr<ServiceWorkerStorageControlImpl> storage,
+ int64_t version_id)
+ : storage_(std::move(storage)), version_id_(version_id) {
+ DCHECK_NE(version_id_, blink::mojom::kInvalidServiceWorkerVersionId);
+ receivers_.set_disconnect_handler(
+ base::BindRepeating(&ServiceWorkerLiveVersionRefImpl::OnDisconnect,
+ base::Unretained(this)));
+ }
+ ~ServiceWorkerLiveVersionRefImpl() override = default;
+
+ void Add(mojo::PendingReceiver<storage::mojom::ServiceWorkerLiveVersionRef>
+ receiver) {
+ receivers_.Add(this, std::move(receiver));
+ }
+
+ void set_purgeable_resources(
+ const std::vector<int64_t>& purgeable_resources) {
+ DCHECK(purgeable_resources_.empty());
+ purgeable_resources_ = purgeable_resources;
+ }
+ const std::vector<int64_t>& purgeable_resources() const {
+ return purgeable_resources_;
+ }
+
+ private:
+ void OnDisconnect() {
+ if (storage_ && receivers_.empty())
+ storage_->OnNoLiveVersion(version_id_);
+ }
+
+ base::WeakPtr<ServiceWorkerStorageControlImpl> storage_;
+ const int64_t version_id_;
+ std::vector<int64_t /*resource_id*/> purgeable_resources_;
+ mojo::ReceiverSet<storage::mojom::ServiceWorkerLiveVersionRef> receivers_;
+};
+
ServiceWorkerStorageControlImpl::ServiceWorkerStorageControlImpl(
std::unique_ptr<ServiceWorkerStorage> storage)
: storage_(std::move(storage)) {
@@ -112,6 +98,24 @@ ServiceWorkerStorageControlImpl::ServiceWorkerStorageControlImpl(
ServiceWorkerStorageControlImpl::~ServiceWorkerStorageControlImpl() = default;
+void ServiceWorkerStorageControlImpl::Bind(
+ mojo::PendingReceiver<storage::mojom::ServiceWorkerStorageControl>
+ receiver) {
+ // There should be one connection at most for now because this class hasn't
+ // moved to the storage service yet.
+ DCHECK(receivers_.empty())
+ << "ServiceWorkerStorageControl doesn't support multiple connections yet";
+
+ receivers_.Add(this, std::move(receiver));
+}
+
+void ServiceWorkerStorageControlImpl::OnNoLiveVersion(int64_t version_id) {
+ auto it = live_versions_.find(version_id);
+ DCHECK(it != live_versions_.end());
+ storage_->PurgeResources(it->second->purgeable_resources());
+ live_versions_.erase(it);
+}
+
void ServiceWorkerStorageControlImpl::LazyInitializeForTest() {
storage_->LazyInitializeForTest();
}
@@ -120,14 +124,18 @@ void ServiceWorkerStorageControlImpl::FindRegistrationForClientUrl(
const GURL& client_url,
FindRegistrationForClientUrlCallback callback) {
storage_->FindRegistrationForClientUrl(
- client_url, base::BindOnce(&DidFindRegistration, std::move(callback)));
+ client_url,
+ base::BindOnce(&ServiceWorkerStorageControlImpl::DidFindRegistration,
+ weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
}
void ServiceWorkerStorageControlImpl::FindRegistrationForScope(
const GURL& scope,
FindRegistrationForClientUrlCallback callback) {
storage_->FindRegistrationForScope(
- scope, base::BindOnce(&DidFindRegistration, std::move(callback)));
+ scope,
+ base::BindOnce(&ServiceWorkerStorageControlImpl::DidFindRegistration,
+ weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
}
void ServiceWorkerStorageControlImpl::FindRegistrationForId(
@@ -136,7 +144,8 @@ void ServiceWorkerStorageControlImpl::FindRegistrationForId(
FindRegistrationForClientUrlCallback callback) {
storage_->FindRegistrationForId(
registration_id, origin,
- base::BindOnce(&DidFindRegistration, std::move(callback)));
+ base::BindOnce(&ServiceWorkerStorageControlImpl::DidFindRegistration,
+ weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
}
void ServiceWorkerStorageControlImpl::GetRegistrationsForOrigin(
@@ -151,13 +160,10 @@ void ServiceWorkerStorageControlImpl::StoreRegistration(
storage::mojom::ServiceWorkerRegistrationDataPtr registration,
std::vector<storage::mojom::ServiceWorkerResourceRecordPtr> resources,
StoreRegistrationCallback callback) {
- // TODO(bashi): Change the signature of
- // ServiceWorkerStorage::StoreRegistrationData() to take a const reference.
storage_->StoreRegistrationData(
- std::move(registration),
- std::make_unique<ServiceWorkerStorage::ResourceList>(
- std::move(resources)),
- base::BindOnce(&DidStoreRegistration, std::move(callback)));
+ std::move(registration), std::move(resources),
+ base::BindOnce(&ServiceWorkerStorageControlImpl::DidStoreRegistration,
+ weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
}
void ServiceWorkerStorageControlImpl::DeleteRegistration(
@@ -166,7 +172,8 @@ void ServiceWorkerStorageControlImpl::DeleteRegistration(
DeleteRegistrationCallback callback) {
storage_->DeleteRegistration(
registration_id, origin,
- base::BindOnce(&DidDeleteRegistration, std::move(callback)));
+ base::BindOnce(&ServiceWorkerStorageControlImpl::DidDeleteRegistration,
+ weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
}
void ServiceWorkerStorageControlImpl::UpdateToActiveState(
@@ -210,7 +217,9 @@ void ServiceWorkerStorageControlImpl::GetNewRegistrationId(
void ServiceWorkerStorageControlImpl::GetNewVersionId(
GetNewVersionIdCallback callback) {
- storage_->GetNewVersionId(std::move(callback));
+ storage_->GetNewVersionId(
+ base::BindOnce(&ServiceWorkerStorageControlImpl::DidGetNewVersionId,
+ weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
}
void ServiceWorkerStorageControlImpl::GetNewResourceId(
@@ -247,12 +256,25 @@ void ServiceWorkerStorageControlImpl::CreateResourceMetadataWriter(
std::move(writer));
}
+void ServiceWorkerStorageControlImpl::StoreUncommittedResourceId(
+ int64_t resource_id,
+ const GURL& origin,
+ StoreUncommittedResourceIdCallback callback) {
+ storage_->StoreUncommittedResourceId(resource_id, origin,
+ std::move(callback));
+}
+
+void ServiceWorkerStorageControlImpl::DoomUncommittedResources(
+ const std::vector<int64_t>& resource_ids,
+ DoomUncommittedResourcesCallback callback) {
+ storage_->DoomUncommittedResources(resource_ids, std::move(callback));
+}
+
void ServiceWorkerStorageControlImpl::GetUserData(
int64_t registration_id,
const std::vector<std::string>& keys,
GetUserDataCallback callback) {
- storage_->GetUserData(registration_id, keys,
- base::BindOnce(&DidGetUserData, std::move(callback)));
+ storage_->GetUserData(registration_id, keys, std::move(callback));
}
void ServiceWorkerStorageControlImpl::StoreUserData(
@@ -275,18 +297,16 @@ void ServiceWorkerStorageControlImpl::GetUserDataByKeyPrefix(
int64_t registration_id,
const std::string& key_prefix,
GetUserDataByKeyPrefixCallback callback) {
- storage_->GetUserDataByKeyPrefix(
- registration_id, key_prefix,
- base::BindOnce(&DidGetUserData, std::move(callback)));
+ storage_->GetUserDataByKeyPrefix(registration_id, key_prefix,
+ std::move(callback));
}
void ServiceWorkerStorageControlImpl::GetUserKeysAndDataByKeyPrefix(
int64_t registration_id,
const std::string& key_prefix,
GetUserKeysAndDataByKeyPrefixCallback callback) {
- storage_->GetUserKeysAndDataByKeyPrefix(
- registration_id, key_prefix,
- base::BindOnce(&DidGetKeysAndUserData, std::move(callback)));
+ storage_->GetUserKeysAndDataByKeyPrefix(registration_id, key_prefix,
+ std::move(callback));
}
void ServiceWorkerStorageControlImpl::ClearUserDataByKeyPrefixes(
@@ -327,4 +347,92 @@ void ServiceWorkerStorageControlImpl::ApplyPolicyUpdates(
storage_->ApplyPolicyUpdates(std::move(policy_updates));
}
+void ServiceWorkerStorageControlImpl::DidFindRegistration(
+ base::OnceCallback<
+ void(storage::mojom::ServiceWorkerFindRegistrationResultPtr)> callback,
+ storage::mojom::ServiceWorkerRegistrationDataPtr data,
+ std::unique_ptr<ResourceList> resources,
+ storage::mojom::ServiceWorkerDatabaseStatus status) {
+ ResourceList resource_list =
+ resources ? std::move(*resources) : ResourceList();
+
+ mojo::PendingRemote<storage::mojom::ServiceWorkerLiveVersionRef>
+ remote_reference;
+ if (data &&
+ data->version_id != blink::mojom::kInvalidServiceWorkerVersionId) {
+ DCHECK_EQ(status, storage::mojom::ServiceWorkerDatabaseStatus::kOk);
+ auto it = live_versions_.find(data->version_id);
+ if (it == live_versions_.end()) {
+ remote_reference = CreateLiveVersionReference(data->version_id);
+ } else {
+ it->second->Add(remote_reference.InitWithNewPipeAndPassReceiver());
+ }
+ }
+
+ std::move(callback).Run(
+ storage::mojom::ServiceWorkerFindRegistrationResult::New(
+ status, std::move(remote_reference), std::move(data),
+ std::move(resource_list)));
+}
+
+void ServiceWorkerStorageControlImpl::DidStoreRegistration(
+ StoreRegistrationCallback callback,
+ storage::mojom::ServiceWorkerDatabaseStatus status,
+ int64_t deleted_version_id,
+ const std::vector<int64_t>& newly_purgeable_resources) {
+ MaybePurgeResources(deleted_version_id, newly_purgeable_resources);
+ std::move(callback).Run(status);
+}
+
+void ServiceWorkerStorageControlImpl::DidDeleteRegistration(
+ DeleteRegistrationCallback callback,
+ storage::mojom::ServiceWorkerDatabaseStatus status,
+ ServiceWorkerStorage::OriginState origin_state,
+ int64_t deleted_version_id,
+ const std::vector<int64_t>& newly_purgeable_resources) {
+ MaybePurgeResources(deleted_version_id, newly_purgeable_resources);
+ std::move(callback).Run(status, origin_state);
+}
+
+void ServiceWorkerStorageControlImpl::DidGetNewVersionId(
+ GetNewVersionIdCallback callback,
+ int64_t version_id) {
+ mojo::PendingRemote<storage::mojom::ServiceWorkerLiveVersionRef>
+ remote_reference;
+ if (version_id != blink::mojom::kInvalidServiceWorkerVersionId) {
+ remote_reference = CreateLiveVersionReference(version_id);
+ }
+ std::move(callback).Run(version_id, std::move(remote_reference));
+}
+
+mojo::PendingRemote<storage::mojom::ServiceWorkerLiveVersionRef>
+ServiceWorkerStorageControlImpl::CreateLiveVersionReference(
+ int64_t version_id) {
+ DCHECK_NE(version_id, blink::mojom::kInvalidServiceWorkerVersionId);
+ DCHECK(!base::Contains(live_versions_, version_id));
+
+ mojo::PendingRemote<storage::mojom::ServiceWorkerLiveVersionRef>
+ remote_reference;
+ auto reference = std::make_unique<ServiceWorkerLiveVersionRefImpl>(
+ weak_ptr_factory_.GetWeakPtr(), version_id);
+ reference->Add(remote_reference.InitWithNewPipeAndPassReceiver());
+ live_versions_[version_id] = std::move(reference);
+ return remote_reference;
+}
+
+void ServiceWorkerStorageControlImpl::MaybePurgeResources(
+ int64_t version_id,
+ const std::vector<int64_t>& purgeable_resources) {
+ if (version_id == blink::mojom::kInvalidServiceWorkerVersionId ||
+ purgeable_resources.size() == 0)
+ return;
+
+ if (base::Contains(live_versions_, version_id)) {
+ live_versions_[version_id]->set_purgeable_resources(
+ std::move(purgeable_resources));
+ } else {
+ storage_->PurgeResources(std::move(purgeable_resources));
+ }
+}
+
} // namespace content
diff --git a/chromium/content/browser/service_worker/service_worker_storage_control_impl.h b/chromium/content/browser/service_worker/service_worker_storage_control_impl.h
index 63320c98b19..e76695eac81 100644
--- a/chromium/content/browser/service_worker/service_worker_storage_control_impl.h
+++ b/chromium/content/browser/service_worker/service_worker_storage_control_impl.h
@@ -7,13 +7,17 @@
#include <memory>
+#include "base/containers/flat_map.h"
+#include "base/memory/weak_ptr.h"
#include "components/services/storage/public/mojom/service_worker_storage_control.mojom.h"
+#include "content/browser/service_worker/service_worker_storage.h"
#include "content/common/content_export.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
+#include "mojo/public/cpp/bindings/receiver_set.h"
namespace content {
-class ServiceWorkerStorage;
+class ServiceWorkerLiveVersionRefImpl;
// This class wraps ServiceWorkerStorage to implement mojo interface defined by
// the storage service, i.e., ServiceWorkerStorageControl.
@@ -32,6 +36,15 @@ class CONTENT_EXPORT ServiceWorkerStorageControlImpl
~ServiceWorkerStorageControlImpl() override;
+ // TODO(crbug.com/1055677): Remove this accessor after all
+ // ServiceWorkerStorage method calls are replaced with mojo methods.
+ ServiceWorkerStorage* storage() const { return storage_.get(); }
+
+ void Bind(mojo::PendingReceiver<storage::mojom::ServiceWorkerStorageControl>
+ receiver);
+
+ void OnNoLiveVersion(int64_t version_id);
+
void LazyInitializeForTest();
private:
@@ -88,6 +101,13 @@ class CONTENT_EXPORT ServiceWorkerStorageControlImpl
int64_t resource_id,
mojo::PendingReceiver<storage::mojom::ServiceWorkerResourceMetadataWriter>
writer) override;
+ void StoreUncommittedResourceId(
+ int64_t resource_id,
+ const GURL& origin,
+ StoreUncommittedResourceIdCallback callback) override;
+ void DoomUncommittedResources(
+ const std::vector<int64_t>& resource_ids,
+ DoomUncommittedResourcesCallback callback) override;
void GetUserData(int64_t registration_id,
const std::vector<std::string>& keys,
GetUserDataCallback callback) override;
@@ -123,7 +143,44 @@ class CONTENT_EXPORT ServiceWorkerStorageControlImpl
const std::vector<storage::mojom::LocalStoragePolicyUpdatePtr>
policy_updates) override;
+ using ResourceList =
+ std::vector<storage::mojom::ServiceWorkerResourceRecordPtr>;
+
+ // Callbacks for ServiceWorkerStorage methods.
+ void DidFindRegistration(
+ base::OnceCallback<void(
+ storage::mojom::ServiceWorkerFindRegistrationResultPtr)> callback,
+ storage::mojom::ServiceWorkerRegistrationDataPtr data,
+ std::unique_ptr<ResourceList> resources,
+ storage::mojom::ServiceWorkerDatabaseStatus status);
+ void DidStoreRegistration(
+ StoreRegistrationCallback callback,
+ storage::mojom::ServiceWorkerDatabaseStatus status,
+ int64_t deleted_version_id,
+ const std::vector<int64_t>& newly_purgeable_resources);
+ void DidDeleteRegistration(
+ DeleteRegistrationCallback callback,
+ storage::mojom::ServiceWorkerDatabaseStatus status,
+ ServiceWorkerStorage::OriginState origin_state,
+ int64_t deleted_version_id,
+ const std::vector<int64_t>& newly_purgeable_resources);
+ void DidGetNewVersionId(GetNewVersionIdCallback callback, int64_t version_id);
+
+ mojo::PendingRemote<storage::mojom::ServiceWorkerLiveVersionRef>
+ CreateLiveVersionReference(int64_t version_id);
+
+ void MaybePurgeResources(int64_t version_id,
+ const std::vector<int64_t>& purgeable_resources);
+
const std::unique_ptr<ServiceWorkerStorage> storage_;
+
+ mojo::ReceiverSet<storage::mojom::ServiceWorkerStorageControl> receivers_;
+
+ base::flat_map<int64_t /*version_id*/,
+ std::unique_ptr<ServiceWorkerLiveVersionRefImpl>>
+ live_versions_;
+
+ base::WeakPtrFactory<ServiceWorkerStorageControlImpl> weak_ptr_factory_{this};
};
} // namespace content
diff --git a/chromium/content/browser/service_worker/service_worker_storage_control_impl_unittest.cc b/chromium/content/browser/service_worker/service_worker_storage_control_impl_unittest.cc
index f6b40a65171..c87699128f5 100644
--- a/chromium/content/browser/service_worker/service_worker_storage_control_impl_unittest.cc
+++ b/chromium/content/browser/service_worker/service_worker_storage_control_impl_unittest.cc
@@ -30,6 +30,8 @@
namespace content {
using DatabaseStatus = storage::mojom::ServiceWorkerDatabaseStatus;
+using RegistrationData = storage::mojom::ServiceWorkerRegistrationDataPtr;
+using ResourceRecord = storage::mojom::ServiceWorkerResourceRecordPtr;
using FindRegistrationResult =
storage::mojom::ServiceWorkerFindRegistrationResultPtr;
@@ -52,6 +54,11 @@ struct DeleteRegistrationResult {
storage::mojom::ServiceWorkerStorageOriginState origin_state;
};
+struct GetNewVersionIdResult {
+ int64_t version_id;
+ mojo::PendingRemote<storage::mojom::ServiceWorkerLiveVersionRef> reference;
+};
+
struct GetUserDataResult {
DatabaseStatus status;
std::vector<std::string> values;
@@ -190,7 +197,7 @@ class ServiceWorkerStorageControlImplTest : public testing::Test {
storage()->FindRegistrationForClientUrl(
client_url,
base::BindLambdaForTesting([&](FindRegistrationResult result) {
- return_value = result.Clone();
+ return_value = std::move(result);
loop.Quit();
}));
loop.Run();
@@ -202,7 +209,7 @@ class ServiceWorkerStorageControlImplTest : public testing::Test {
base::RunLoop loop;
storage()->FindRegistrationForScope(
scope, base::BindLambdaForTesting([&](FindRegistrationResult result) {
- return_value = result.Clone();
+ return_value = std::move(result);
loop.Quit();
}));
loop.Run();
@@ -216,7 +223,7 @@ class ServiceWorkerStorageControlImplTest : public testing::Test {
storage()->FindRegistrationForId(
registration_id, origin,
base::BindLambdaForTesting([&](FindRegistrationResult result) {
- return_value = result.Clone();
+ return_value = std::move(result);
loop.Quit();
}));
loop.Run();
@@ -243,7 +250,7 @@ class ServiceWorkerStorageControlImplTest : public testing::Test {
}
DatabaseStatus StoreRegistration(
- storage::mojom::ServiceWorkerRegistrationDataPtr registration,
+ RegistrationData registration,
std::vector<storage::mojom::ServiceWorkerResourceRecordPtr> resources) {
DatabaseStatus out_status;
base::RunLoop loop;
@@ -345,16 +352,19 @@ class ServiceWorkerStorageControlImplTest : public testing::Test {
return return_value;
}
- int64_t GetNewVersionId() {
- int64_t return_value;
+ GetNewVersionIdResult GetNewVersionId() {
+ GetNewVersionIdResult result;
base::RunLoop loop;
- storage()->GetNewVersionId(
- base::BindLambdaForTesting([&](int64_t version_id) {
- return_value = version_id;
+ storage()->GetNewVersionId(base::BindLambdaForTesting(
+ [&](int64_t version_id,
+ mojo::PendingRemote<storage::mojom::ServiceWorkerLiveVersionRef>
+ reference) {
+ result.version_id = version_id;
+ result.reference = std::move(reference);
loop.Quit();
}));
loop.Run();
- return return_value;
+ return result;
}
int64_t GetNewResourceId() {
@@ -369,6 +379,33 @@ class ServiceWorkerStorageControlImplTest : public testing::Test {
return return_value;
}
+ DatabaseStatus StoreUncommittedResourceId(int64_t resource_id,
+ const GURL& origin) {
+ DatabaseStatus return_value;
+ base::RunLoop loop;
+ storage()->StoreUncommittedResourceId(
+ resource_id, origin,
+ base::BindLambdaForTesting([&](DatabaseStatus status) {
+ return_value = status;
+ loop.Quit();
+ }));
+ loop.Run();
+ return return_value;
+ }
+
+ DatabaseStatus DoomUncommittedResources(
+ const std::vector<int64_t> resource_ids) {
+ DatabaseStatus return_value;
+ base::RunLoop loop;
+ storage()->DoomUncommittedResources(
+ resource_ids, base::BindLambdaForTesting([&](DatabaseStatus status) {
+ return_value = status;
+ loop.Quit();
+ }));
+ loop.Run();
+ return return_value;
+ }
+
GetUserDataResult GetUserData(int64_t registration_id,
const std::vector<std::string>& keys) {
GetUserDataResult result;
@@ -511,17 +548,14 @@ class ServiceWorkerStorageControlImplTest : public testing::Test {
return return_value;
}
- // Create a registration with a single resource and stores the registration.
- DatabaseStatus CreateAndStoreRegistration(int64_t registration_id,
- int64_t version_id,
- int64_t resource_id,
- const GURL& scope,
- const GURL& script_url,
- int64_t script_size) {
- std::vector<storage::mojom::ServiceWorkerResourceRecordPtr> resources;
- resources.push_back(storage::mojom::ServiceWorkerResourceRecord::New(
- resource_id, script_url, script_size));
-
+ // Creates a registration with the given resource records.
+ RegistrationData CreateRegistrationData(
+ int64_t registration_id,
+ int64_t version_id,
+ const GURL& scope,
+ const GURL& script_url,
+ const std::vector<storage::mojom::ServiceWorkerResourceRecordPtr>&
+ resources) {
auto data = storage::mojom::ServiceWorkerRegistrationData::New();
data->registration_id = registration_id;
data->version_id = version_id;
@@ -536,11 +570,53 @@ class ServiceWorkerStorageControlImplTest : public testing::Test {
}
data->resources_total_size_bytes = resources_total_size_bytes;
+ return data;
+ }
+
+ // Creates a registration with a single resource and stores the registration.
+ DatabaseStatus CreateAndStoreRegistration(int64_t registration_id,
+ int64_t version_id,
+ int64_t resource_id,
+ const GURL& scope,
+ const GURL& script_url,
+ int64_t script_size) {
+ std::vector<storage::mojom::ServiceWorkerResourceRecordPtr> resources;
+ resources.push_back(storage::mojom::ServiceWorkerResourceRecord::New(
+ resource_id, script_url, script_size));
+
+ RegistrationData data = CreateRegistrationData(
+ registration_id, version_id, scope, script_url, resources);
+
DatabaseStatus status =
StoreRegistration(std::move(data), std::move(resources));
return status;
}
+ int WriteResource(int64_t resource_id, const std::string& data) {
+ auto response_head = network::mojom::URLResponseHead::New();
+ response_head->headers = base::MakeRefCounted<net::HttpResponseHeaders>(
+ net::HttpUtil::AssembleRawHeaders(
+ "HTTP/1.1 200 OK\n"
+ "Content-Type: application/javascript\n"));
+ response_head->headers->GetMimeType(&response_head->mime_type);
+
+ mojo::Remote<storage::mojom::ServiceWorkerResourceWriter> writer =
+ CreateResourceWriter(resource_id);
+ int result = WriteResponseHead(writer.get(), std::move(response_head));
+ if (result < 0)
+ return result;
+
+ mojo_base::BigBuffer buffer(base::as_bytes(base::make_span(data)));
+ result = WriteResponseData(writer.get(), std::move(buffer));
+ return result;
+ }
+
+ std::string ReadResource(int64_t resource_id, int data_size) {
+ mojo::Remote<storage::mojom::ServiceWorkerResourceReader> reader =
+ CreateResourceReader(resource_id);
+ return ReadResponseData(reader.get(), data_size);
+ }
+
mojo::Remote<storage::mojom::ServiceWorkerResourceReader>
CreateResourceReader(int64_t resource_id) {
mojo::Remote<storage::mojom::ServiceWorkerResourceReader> reader;
@@ -565,6 +641,22 @@ class ServiceWorkerStorageControlImplTest : public testing::Test {
return writer;
}
+ // Helper function that reads uncommitted resource ids from database.
+ std::vector<int64_t> GetUncommittedResourceIds() {
+ std::vector<int64_t> ids;
+ base::RunLoop loop;
+ ServiceWorkerStorage* internal_storage = storage_impl_->storage();
+ ServiceWorkerDatabase* database_raw = internal_storage->database_.get();
+ internal_storage->database_task_runner_->PostTask(
+ FROM_HERE, base::BindLambdaForTesting([&]() {
+ EXPECT_EQ(ServiceWorkerDatabase::Status::kOk,
+ database_raw->GetUncommittedResourceIds(&ids));
+ loop.Quit();
+ }));
+ loop.Run();
+ return ids;
+ }
+
private:
base::ScopedTempDir user_data_directory_;
BrowserTaskEnvironment task_environment_;
@@ -607,7 +699,7 @@ TEST_F(ServiceWorkerStorageControlImplTest, StoreAndDeleteRegistration) {
LazyInitializeForTest();
const int64_t kRegistrationId = GetNewResourceId();
- const int64_t kVersionId = GetNewVersionId();
+ const int64_t kVersionId = GetNewVersionId().version_id;
// Create a registration data with a single resource.
std::vector<storage::mojom::ServiceWorkerResourceRecordPtr> resources;
@@ -682,7 +774,7 @@ TEST_F(ServiceWorkerStorageControlImplTest, UpdateToActiveState) {
// Preparation: Store a registration.
const int64_t registration_id = GetNewRegistrationId();
- const int64_t version_id = GetNewVersionId();
+ const int64_t version_id = GetNewVersionId().version_id;
const int64_t resource_id = GetNewResourceId();
DatabaseStatus status =
CreateAndStoreRegistration(registration_id, version_id, resource_id,
@@ -719,7 +811,7 @@ TEST_F(ServiceWorkerStorageControlImplTest, UpdateLastUpdateCheckTime) {
// Preparation: Store a registration.
const int64_t registration_id = GetNewRegistrationId();
- const int64_t version_id = GetNewVersionId();
+ const int64_t version_id = GetNewVersionId().version_id;
const int64_t resource_id = GetNewResourceId();
DatabaseStatus status =
CreateAndStoreRegistration(registration_id, version_id, resource_id,
@@ -757,7 +849,7 @@ TEST_F(ServiceWorkerStorageControlImplTest, Update) {
// Preparation: Store a registration.
const int64_t registration_id = GetNewRegistrationId();
- const int64_t version_id = GetNewVersionId();
+ const int64_t version_id = GetNewVersionId().version_id;
const int64_t resource_id = GetNewResourceId();
DatabaseStatus status =
CreateAndStoreRegistration(registration_id, version_id, resource_id,
@@ -806,14 +898,14 @@ TEST_F(ServiceWorkerStorageControlImplTest, GetRegistrationsForOrigin) {
// Store two registrations which have the same origin.
DatabaseStatus status;
const int64_t registration_id1 = GetNewRegistrationId();
- const int64_t version_id1 = GetNewVersionId();
+ const int64_t version_id1 = GetNewVersionId().version_id;
const int64_t resource_id1 = GetNewResourceId();
status =
CreateAndStoreRegistration(registration_id1, version_id1, resource_id1,
kScope1, kScriptUrl1, kScriptSize);
ASSERT_EQ(status, DatabaseStatus::kOk);
const int64_t registration_id2 = GetNewRegistrationId();
- const int64_t version_id2 = GetNewVersionId();
+ const int64_t version_id2 = GetNewVersionId().version_id;
const int64_t resource_id2 = GetNewResourceId();
status =
CreateAndStoreRegistration(registration_id2, version_id2, resource_id2,
@@ -933,6 +1025,83 @@ TEST_F(ServiceWorkerStorageControlImplTest, WriteAndReadResource) {
}
}
+// Tests that uncommitted resources can be listed on storage and these resources
+// will be committed when a registration is stored with these resources.
+TEST_F(ServiceWorkerStorageControlImplTest, UncommittedResources) {
+ const GURL kScope("https://www.example.com/");
+ const GURL kScriptUrl("https://www.example.com/sw.js");
+ const GURL kImportedScriptUrl("https://www.example.com/imported.js");
+
+ LazyInitializeForTest();
+
+ // Preparation: Create a registration with two resources. These aren't written
+ // to storage yet.
+ std::vector<ResourceRecord> resources;
+ const int64_t resource_id1 = GetNewResourceId();
+ const std::string resource_data1 = "main script data";
+ resources.push_back(storage::mojom::ServiceWorkerResourceRecord::New(
+ resource_id1, kScriptUrl, resource_data1.size()));
+
+ const int64_t resource_id2 = GetNewResourceId();
+ const std::string resource_data2 = "imported script data";
+ resources.push_back(storage::mojom::ServiceWorkerResourceRecord::New(
+ resource_id2, kImportedScriptUrl, resource_data2.size()));
+
+ const int64_t registration_id = GetNewRegistrationId();
+ const int64_t version_id = GetNewVersionId().version_id;
+ RegistrationData registration_data = CreateRegistrationData(
+ registration_id, version_id, kScope, kScriptUrl, resources);
+
+ // Put these resources ids on the uncommitted list in storage.
+ DatabaseStatus status;
+ status = StoreUncommittedResourceId(resource_id1, kScope.GetOrigin());
+ ASSERT_EQ(status, DatabaseStatus::kOk);
+ status = StoreUncommittedResourceId(resource_id2, kScope.GetOrigin());
+ ASSERT_EQ(status, DatabaseStatus::kOk);
+
+ std::vector<int64_t> uncommitted_ids = GetUncommittedResourceIds();
+ EXPECT_EQ(uncommitted_ids.size(), 2UL);
+
+ // Write responses and the registration data.
+ int result;
+ result = WriteResource(resource_id1, resource_data1);
+ ASSERT_GT(result, 0);
+ result = WriteResource(resource_id2, resource_data2);
+ ASSERT_GT(result, 0);
+ status =
+ StoreRegistration(std::move(registration_data), std::move(resources));
+ ASSERT_EQ(status, DatabaseStatus::kOk);
+
+ // Storing registration should take the resource ids out of the uncommitted
+ // list.
+ uncommitted_ids = GetUncommittedResourceIds();
+ EXPECT_TRUE(uncommitted_ids.empty());
+}
+
+// Tests that uncommitted resource ids are purged by DoomUncommittedResources.
+TEST_F(ServiceWorkerStorageControlImplTest, DoomUncommittedResources) {
+ const GURL kScope("https://www.example.com/");
+
+ LazyInitializeForTest();
+
+ const int64_t resource_id1 = GetNewResourceId();
+ const int64_t resource_id2 = GetNewResourceId();
+
+ DatabaseStatus status;
+ status = StoreUncommittedResourceId(resource_id1, kScope.GetOrigin());
+ ASSERT_EQ(status, DatabaseStatus::kOk);
+ status = StoreUncommittedResourceId(resource_id2, kScope.GetOrigin());
+ ASSERT_EQ(status, DatabaseStatus::kOk);
+
+ std::vector<int64_t> uncommitted_ids = GetUncommittedResourceIds();
+ EXPECT_EQ(uncommitted_ids.size(), 2UL);
+
+ status = DoomUncommittedResources({resource_id1, resource_id2});
+ ASSERT_EQ(status, DatabaseStatus::kOk);
+ uncommitted_ids = GetUncommittedResourceIds();
+ EXPECT_TRUE(uncommitted_ids.empty());
+}
+
// Tests that storing/getting user data for a registration work.
TEST_F(ServiceWorkerStorageControlImplTest, StoreAndGetUserData) {
const GURL kScope("https://www.example.com/");
@@ -942,7 +1111,7 @@ TEST_F(ServiceWorkerStorageControlImplTest, StoreAndGetUserData) {
LazyInitializeForTest();
const int64_t registration_id = GetNewRegistrationId();
- const int64_t version_id = GetNewVersionId();
+ const int64_t version_id = GetNewVersionId().version_id;
const int64_t resource_id = GetNewResourceId();
DatabaseStatus status;
status = CreateAndStoreRegistration(registration_id, version_id, resource_id,
@@ -1002,7 +1171,7 @@ TEST_F(ServiceWorkerStorageControlImplTest, StoreAndGetUserData) {
// Delete the registration and store a new registration for the same
// scope.
const int64_t new_registration_id = GetNewRegistrationId();
- const int64_t new_version_id = GetNewVersionId();
+ const int64_t new_version_id = GetNewVersionId().version_id;
const int64_t new_resource_id = GetNewResourceId();
{
DeleteRegistrationResult result =
@@ -1033,7 +1202,7 @@ TEST_F(ServiceWorkerStorageControlImplTest, StoreAndGetUserDataByKeyPrefix) {
LazyInitializeForTest();
const int64_t registration_id = GetNewRegistrationId();
- const int64_t version_id = GetNewVersionId();
+ const int64_t version_id = GetNewVersionId().version_id;
const int64_t resource_id = GetNewResourceId();
DatabaseStatus status;
status = CreateAndStoreRegistration(registration_id, version_id, resource_id,
@@ -1111,14 +1280,14 @@ TEST_F(ServiceWorkerStorageControlImplTest,
// Preparation: Create and store two registrations.
DatabaseStatus status;
const int64_t registration_id1 = GetNewRegistrationId();
- const int64_t version_id1 = GetNewVersionId();
+ const int64_t version_id1 = GetNewVersionId().version_id;
const int64_t resource_id1 = GetNewResourceId();
status =
CreateAndStoreRegistration(registration_id1, version_id1, resource_id1,
kScope1, kScriptUrl1, kScriptSize);
ASSERT_EQ(status, DatabaseStatus::kOk);
const int64_t registration_id2 = GetNewRegistrationId();
- const int64_t version_id2 = GetNewVersionId();
+ const int64_t version_id2 = GetNewVersionId().version_id;
const int64_t resource_id2 = GetNewResourceId();
status =
CreateAndStoreRegistration(registration_id2, version_id2, resource_id2,
@@ -1215,14 +1384,14 @@ TEST_F(ServiceWorkerStorageControlImplTest, ApplyPolicyUpdates) {
// Preparation: Create and store two registrations.
DatabaseStatus status;
const int64_t registration_id1 = GetNewRegistrationId();
- const int64_t version_id1 = GetNewVersionId();
+ const int64_t version_id1 = GetNewVersionId().version_id;
const int64_t resource_id1 = GetNewResourceId();
status =
CreateAndStoreRegistration(registration_id1, version_id1, resource_id1,
kScope1, kScriptUrl1, kScriptSize);
ASSERT_EQ(status, DatabaseStatus::kOk);
const int64_t registration_id2 = GetNewRegistrationId();
- const int64_t version_id2 = GetNewVersionId();
+ const int64_t version_id2 = GetNewVersionId().version_id;
const int64_t resource_id2 = GetNewResourceId();
status =
CreateAndStoreRegistration(registration_id2, version_id2, resource_id2,
@@ -1248,4 +1417,92 @@ TEST_F(ServiceWorkerStorageControlImplTest, ApplyPolicyUpdates) {
}
}
+TEST_F(ServiceWorkerStorageControlImplTest, TrackRunningVersion) {
+ const GURL kScope("https://www.example.com/");
+ const GURL kScriptUrl("https://www.example.com/sw.js");
+ const GURL kImportedScriptUrl("https://www.example.com/imported.js");
+
+ LazyInitializeForTest();
+
+ // Preparation: Create a registration with two resources (The main script and
+ // an imported script).
+ int result;
+ std::vector<ResourceRecord> resources;
+ const int64_t resource_id1 = GetNewResourceId();
+ const std::string resource_data1 = "main script data";
+ result = WriteResource(resource_id1, resource_data1);
+ ASSERT_GT(result, 0);
+ resources.push_back(storage::mojom::ServiceWorkerResourceRecord::New(
+ resource_id1, kScriptUrl, resource_data1.size()));
+
+ const int64_t resource_id2 = GetNewResourceId();
+ const std::string resource_data2 = "imported script data";
+ result = WriteResource(resource_id2, resource_data2);
+ ASSERT_GT(result, 0);
+ resources.push_back(storage::mojom::ServiceWorkerResourceRecord::New(
+ resource_id2, kImportedScriptUrl, resource_data2.size()));
+
+ const int64_t registration_id = GetNewRegistrationId();
+ GetNewVersionIdResult new_version_id_result = GetNewVersionId();
+ ASSERT_NE(new_version_id_result.version_id,
+ blink::mojom::kInvalidServiceWorkerVersionId);
+ const int64_t version_id = new_version_id_result.version_id;
+ RegistrationData registration_data = CreateRegistrationData(
+ registration_id, version_id, kScope, kScriptUrl, resources);
+ DatabaseStatus status =
+ StoreRegistration(std::move(registration_data), std::move(resources));
+ ASSERT_EQ(status, DatabaseStatus::kOk);
+
+ // Create two references, one from GetNewVersionId() and the other from
+ // FindRegistrationForId().
+ mojo::Remote<storage::mojom::ServiceWorkerLiveVersionRef> reference1;
+ ASSERT_TRUE(new_version_id_result.reference);
+ reference1.Bind(std::move(new_version_id_result.reference));
+
+ mojo::Remote<storage::mojom::ServiceWorkerLiveVersionRef> reference2;
+ {
+ FindRegistrationResult result =
+ FindRegistrationForId(registration_id, kScope.GetOrigin());
+ ASSERT_EQ(result->status, DatabaseStatus::kOk);
+ ASSERT_TRUE(result->version_reference);
+ reference2.Bind(std::move(result->version_reference));
+ }
+
+ // Drop the first reference and delete the registration.
+ reference1.reset();
+ {
+ DeleteRegistrationResult result =
+ DeleteRegistration(registration_id, kScope.GetOrigin());
+ ASSERT_EQ(result.status, DatabaseStatus::kOk);
+ }
+
+ // Make sure all tasks are ran.
+ // TODO(bashi): Don't rely on RunAllTasksUntilIdle()?
+ content::RunAllTasksUntilIdle();
+
+ // Resources shouldn't be purged because there is an active reference.
+ {
+ std::string read_resource_data1 =
+ ReadResource(resource_id1, resource_data1.size());
+ ASSERT_EQ(read_resource_data1, resource_data1);
+ std::string read_resource_data2 =
+ ReadResource(resource_id2, resource_data2.size());
+ ASSERT_EQ(read_resource_data2, resource_data2);
+ }
+
+ // Drop the second reference.
+ reference2.reset();
+ content::RunAllTasksUntilIdle();
+
+ // Resources should have been purged.
+ {
+ std::string read_resource_data1 =
+ ReadResource(resource_id1, resource_data1.size());
+ ASSERT_EQ(read_resource_data1, "");
+ std::string read_resource_data2 =
+ ReadResource(resource_id2, resource_data2.size());
+ ASSERT_EQ(read_resource_data2, "");
+ }
+}
+
} // namespace content
diff --git a/chromium/content/browser/service_worker/service_worker_storage_unittest.cc b/chromium/content/browser/service_worker/service_worker_storage_unittest.cc
index 281985eedec..95b5bb61f54 100644
--- a/chromium/content/browser/service_worker/service_worker_storage_unittest.cc
+++ b/chromium/content/browser/service_worker/service_worker_storage_unittest.cc
@@ -333,6 +333,23 @@ class ServiceWorkerStorageTest : public testing::Test {
return result.value();
}
+ ServiceWorkerDatabase::Status DeleteRegistrationById(int64_t registration_id,
+ const GURL& origin) {
+ ServiceWorkerDatabase::Status result;
+ base::RunLoop loop;
+ storage()->DeleteRegistration(
+ registration_id, origin,
+ base::BindLambdaForTesting(
+ [&](ServiceWorkerDatabase::Status status,
+ ServiceWorkerStorage::OriginState, int64_t deleted_version,
+ const std::vector<int64_t>& newly_purgeable_resources) {
+ result = status;
+ loop.Quit();
+ }));
+ loop.Run();
+ return result;
+ }
+
blink::ServiceWorkerStatusCode GetAllRegistrationsInfos(
std::vector<ServiceWorkerRegistrationInfo>* registrations) {
base::Optional<blink::ServiceWorkerStatusCode> result;
@@ -349,6 +366,22 @@ class ServiceWorkerStorageTest : public testing::Test {
return result.value();
}
+ blink::ServiceWorkerStatusCode GetStorageUsageForOrigin(
+ const url::Origin& origin,
+ int64_t& out_usage) {
+ blink::ServiceWorkerStatusCode result;
+ base::RunLoop loop;
+ registry()->GetStorageUsageForOrigin(
+ origin, base::BindLambdaForTesting(
+ [&](blink::ServiceWorkerStatusCode status, int64_t usage) {
+ result = status;
+ out_usage = usage;
+ loop.Quit();
+ }));
+ loop.Run();
+ return result;
+ }
+
blink::ServiceWorkerStatusCode GetRegistrationsForOrigin(
const GURL& origin,
std::vector<scoped_refptr<ServiceWorkerRegistration>>* registrations) {
@@ -566,8 +599,8 @@ class ServiceWorkerStorageTest : public testing::Test {
loop.Run();
}
- std::set<int64_t> GetPurgeableResourceIdsFromDB() {
- std::set<int64_t> ids;
+ std::vector<int64_t> GetPurgeableResourceIdsFromDB() {
+ std::vector<int64_t> ids;
base::RunLoop loop;
ServiceWorkerDatabase* database_raw = database();
storage()->database_task_runner_->PostTask(
@@ -580,8 +613,8 @@ class ServiceWorkerStorageTest : public testing::Test {
return ids;
}
- std::set<int64_t> GetUncommittedResourceIdsFromDB() {
- std::set<int64_t> ids;
+ std::vector<int64_t> GetUncommittedResourceIdsFromDB() {
+ std::vector<int64_t> ids;
base::RunLoop loop;
ServiceWorkerDatabase* database_raw = database();
storage()->database_task_runner_->PostTask(
@@ -1219,39 +1252,6 @@ TEST_F(ServiceWorkerStorageTest,
EXPECT_TRUE(data_list_out.empty());
}
-TEST_F(ServiceWorkerStorageTest, GetAllRegistrationsInfosFields) {
- LazyInitialize();
- const GURL kScope("http://www.example.com/scope/");
- const GURL kScript("http://www.example.com/script1.js");
- scoped_refptr<ServiceWorkerRegistration> registration =
- CreateServiceWorkerRegistrationAndVersion(context(), kScope, kScript,
- /*resource_id=*/1);
-
- // Set some fields to check ServiceWorkerStorage serializes/deserializes
- // these fields correctly.
- registration->SetUpdateViaCache(
- blink::mojom::ServiceWorkerUpdateViaCache::kImports);
- registration->EnableNavigationPreload(true);
- registration->SetNavigationPreloadHeader("header");
-
- registry()->NotifyInstallingRegistration(registration.get());
- EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
- StoreRegistration(registration, registration->waiting_version()));
- std::vector<ServiceWorkerRegistrationInfo> all_registrations;
- EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
- GetAllRegistrationsInfos(&all_registrations));
- ASSERT_EQ(1u, all_registrations.size());
-
- ServiceWorkerRegistrationInfo info = all_registrations[0];
- EXPECT_EQ(registration->scope(), info.scope);
- EXPECT_EQ(registration->update_via_cache(), info.update_via_cache);
- EXPECT_EQ(registration->id(), info.registration_id);
- EXPECT_EQ(registration->navigation_preload_state().enabled,
- info.navigation_preload_enabled);
- EXPECT_EQ(registration->navigation_preload_state().header.size(),
- info.navigation_preload_header_length);
-}
-
class ServiceWorkerResourceStorageTest : public ServiceWorkerStorageTest {
public:
void SetUp() override {
@@ -1293,7 +1293,7 @@ class ServiceWorkerResourceStorageTest : public ServiceWorkerStorageTest {
registry()->StoreUncommittedResourceId(resource_id1_, scope_);
registry()->StoreUncommittedResourceId(resource_id2_, scope_);
- std::set<int64_t> verify_ids = GetUncommittedResourceIdsFromDB();
+ std::vector<int64_t> verify_ids = GetUncommittedResourceIdsFromDB();
EXPECT_EQ(2u, verify_ids.size());
// And dump something in the disk cache for them.
@@ -1440,7 +1440,7 @@ TEST_F(ServiceWorkerResourceStorageTest, DeleteRegistration_ActiveVersion) {
registry()->UpdateToActiveState(registration_->id(),
registration_->scope().GetOrigin(),
base::DoNothing());
- ServiceWorkerRemoteProviderEndpoint remote_endpoint;
+ ServiceWorkerRemoteContainerEndpoint remote_endpoint;
base::WeakPtr<ServiceWorkerContainerHost> container_host =
CreateContainerHostForWindow(33 /* dummy render process id */,
true /* is_parent_frame_secure */,
@@ -1477,7 +1477,7 @@ TEST_F(ServiceWorkerResourceStorageDiskTest, CleanupOnRestart) {
registry()->UpdateToActiveState(registration_->id(),
registration_->scope().GetOrigin(),
base::DoNothing());
- ServiceWorkerRemoteProviderEndpoint remote_endpoint;
+ ServiceWorkerRemoteContainerEndpoint remote_endpoint;
base::WeakPtr<ServiceWorkerContainerHost> container_host =
CreateContainerHostForWindow(33 /* dummy render process id */,
true /* is_parent_frame_secure */,
@@ -1488,7 +1488,7 @@ TEST_F(ServiceWorkerResourceStorageDiskTest, CleanupOnRestart) {
// but keep them available.
EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
DeleteRegistration(registration_, scope_.GetOrigin()));
- std::set<int64_t> verify_ids = GetPurgeableResourceIdsFromDB();
+ std::vector<int64_t> verify_ids = GetPurgeableResourceIdsFromDB();
EXPECT_EQ(2u, verify_ids.size());
EXPECT_TRUE(VerifyBasicResponse(storage(), resource_id1_, true));
@@ -1615,7 +1615,7 @@ TEST_F(ServiceWorkerResourceStorageTest, UpdateRegistration) {
registry()->UpdateToActiveState(registration_->id(),
registration_->scope().GetOrigin(),
base::DoNothing());
- ServiceWorkerRemoteProviderEndpoint remote_endpoint;
+ ServiceWorkerRemoteContainerEndpoint remote_endpoint;
base::WeakPtr<ServiceWorkerContainerHost> container_host =
CreateContainerHostForWindow(
33 /* dummy render process id */, true /* is_parent_frame_secure */,
@@ -1700,68 +1700,6 @@ TEST_F(ServiceWorkerResourceStorageTest, UpdateRegistration_NoLiveVersion) {
EXPECT_FALSE(VerifyBasicResponse(storage(), resource_id2_, false));
}
-TEST_F(ServiceWorkerStorageTest, FindRegistration_LongestScopeMatch) {
- LazyInitialize();
- const GURL kDocumentUrl("http://www.example.com/scope/foo");
- scoped_refptr<ServiceWorkerRegistration> found_registration;
-
- // Registration for "/scope/".
- const GURL kScope1("http://www.example.com/scope/");
- const GURL kScript1("http://www.example.com/script1.js");
- scoped_refptr<ServiceWorkerRegistration> live_registration1 =
- CreateServiceWorkerRegistrationAndVersion(context(), kScope1, kScript1,
- /*resource_id=*/1);
-
- // Registration for "/scope/foo".
- const GURL kScope2("http://www.example.com/scope/foo");
- const GURL kScript2("http://www.example.com/script2.js");
- scoped_refptr<ServiceWorkerRegistration> live_registration2 =
- CreateServiceWorkerRegistrationAndVersion(context(), kScope2, kScript2,
- /*resource_id=*/2);
-
- // Registration for "/scope/foobar".
- const GURL kScope3("http://www.example.com/scope/foobar");
- const GURL kScript3("http://www.example.com/script3.js");
- scoped_refptr<ServiceWorkerRegistration> live_registration3 =
- CreateServiceWorkerRegistrationAndVersion(context(), kScope3, kScript3,
- /*resource_id=*/3);
-
- // Notify storage of them being installed.
- registry()->NotifyInstallingRegistration(live_registration1.get());
- registry()->NotifyInstallingRegistration(live_registration2.get());
- registry()->NotifyInstallingRegistration(live_registration3.get());
-
- // Find a registration among installing ones.
- EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
- FindRegistrationForClientUrl(kDocumentUrl, &found_registration));
- EXPECT_EQ(live_registration2, found_registration);
- found_registration = nullptr;
-
- // Store registrations.
- EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
- StoreRegistration(live_registration1,
- live_registration1->waiting_version()));
- EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
- StoreRegistration(live_registration2,
- live_registration2->waiting_version()));
- EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
- StoreRegistration(live_registration3,
- live_registration3->waiting_version()));
-
- // Notify storage of installations no longer happening.
- registry()->NotifyDoneInstallingRegistration(
- live_registration1.get(), nullptr, blink::ServiceWorkerStatusCode::kOk);
- registry()->NotifyDoneInstallingRegistration(
- live_registration2.get(), nullptr, blink::ServiceWorkerStatusCode::kOk);
- registry()->NotifyDoneInstallingRegistration(
- live_registration3.get(), nullptr, blink::ServiceWorkerStatusCode::kOk);
-
- // Find a registration among installed ones.
- EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
- FindRegistrationForClientUrl(kDocumentUrl, &found_registration));
- EXPECT_EQ(live_registration2, found_registration);
-}
-
// Test fixture that uses disk storage, rather than memory. Useful for tests
// that test persistence by simulating browser shutdown and restart.
class ServiceWorkerStorageDiskTest : public ServiceWorkerStorageTest {
@@ -2090,6 +2028,68 @@ TEST_F(ServiceWorkerStorageDiskTest, RegisteredOriginCount) {
}
}
+// Tests reading storage usage from database.
+TEST_F(ServiceWorkerStorageTest, GetStorageUsageForOrigin) {
+ const GURL kScope1("https://www.example.com/foo/");
+ const GURL kScript1("https://www.example.com/foo/sw.js");
+ const GURL kScope2("https://www.example.com/bar/");
+ const GURL kScript2("https://www.example.com/bar/sw.js");
+ const GURL kScript3("https://www.example.com/bar/sub.js");
+
+ // Preparation: Store two registrations.
+ RegistrationData data1;
+ data1.registration_id = 1;
+ data1.scope = kScope1;
+ data1.script = kScript1;
+ data1.version_id = 1;
+ data1.is_active = true;
+ std::vector<ResourceRecord> resources1;
+ resources1.push_back(CreateResourceRecord(1, kScript1, 123));
+ data1.resources_total_size_bytes = 0;
+ for (auto& resource : resources1) {
+ data1.resources_total_size_bytes += resource->size_bytes;
+ }
+ WriteRegistrationToDB(data1, std::move(resources1));
+
+ RegistrationData data2;
+ data2.registration_id = 2;
+ data2.scope = kScope2;
+ data2.script = kScript2;
+ data2.version_id = 1;
+ data2.is_active = true;
+ std::vector<ResourceRecord> resources2;
+ resources2.push_back(CreateResourceRecord(2, kScript2, 456));
+ resources2.push_back(CreateResourceRecord(3, kScript3, 789));
+ data2.resources_total_size_bytes = 0;
+ for (auto& resource : resources2) {
+ data2.resources_total_size_bytes += resource->size_bytes;
+ }
+ WriteRegistrationToDB(data2, std::move(resources2));
+
+ // Storage usage should report total resource size from two registrations.
+ const url::Origin origin = url::Origin::Create(kScope1.GetOrigin());
+ int64_t usage;
+ EXPECT_EQ(GetStorageUsageForOrigin(origin, usage),
+ blink::ServiceWorkerStatusCode::kOk);
+ EXPECT_EQ(usage, data1.resources_total_size_bytes +
+ data2.resources_total_size_bytes);
+
+ // Delete the first registration. Storage usage should report only the second
+ // registration.
+ EXPECT_EQ(DeleteRegistrationById(data1.registration_id, origin.GetURL()),
+ ServiceWorkerDatabase::Status::kOk);
+ EXPECT_EQ(GetStorageUsageForOrigin(origin, usage),
+ blink::ServiceWorkerStatusCode::kOk);
+ EXPECT_EQ(usage, data2.resources_total_size_bytes);
+
+ // Delete the second registration. No storage usage should be reported.
+ EXPECT_EQ(DeleteRegistrationById(data2.registration_id, origin.GetURL()),
+ ServiceWorkerDatabase::Status::kOk);
+ EXPECT_EQ(GetStorageUsageForOrigin(origin, usage),
+ blink::ServiceWorkerStatusCode::kOk);
+ EXPECT_EQ(usage, 0);
+}
+
// Tests loading a registration with a disabled navigation preload
// state.
TEST_F(ServiceWorkerStorageDiskTest, DisabledNavigationPreloadState) {
@@ -2127,44 +2127,5 @@ TEST_F(ServiceWorkerStorageDiskTest, DisabledNavigationPreloadState) {
EXPECT_EQ("true", state.header);
}
-// Tests loading a registration with an enabled navigation preload state, as
-// well as a custom header value.
-TEST_F(ServiceWorkerStorageDiskTest, EnabledNavigationPreloadState) {
- LazyInitialize();
- const GURL kScope("https://valid.example.com/scope");
- const GURL kScript("https://valid.example.com/script.js");
- const std::string kHeaderValue("custom header value");
- scoped_refptr<ServiceWorkerRegistration> registration =
- CreateServiceWorkerRegistrationAndVersion(context(), kScope, kScript,
- /*resource_id=*/1);
- ServiceWorkerVersion* version = registration->waiting_version();
- version->SetStatus(ServiceWorkerVersion::ACTIVATED);
- registration->SetActiveVersion(version);
- registration->EnableNavigationPreload(true);
- registration->SetNavigationPreloadHeader(kHeaderValue);
-
- EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
- StoreRegistration(registration, version));
-
- // Simulate browser shutdown and restart.
- registration = nullptr;
- version = nullptr;
- InitializeTestHelper();
- LazyInitialize();
-
- scoped_refptr<ServiceWorkerRegistration> found_registration;
- EXPECT_EQ(blink::ServiceWorkerStatusCode::kOk,
- FindRegistrationForClientUrl(kScope, &found_registration));
- const blink::mojom::NavigationPreloadState& registration_state =
- found_registration->navigation_preload_state();
- EXPECT_TRUE(registration_state.enabled);
- EXPECT_EQ(kHeaderValue, registration_state.header);
- ASSERT_TRUE(found_registration->active_version());
- const blink::mojom::NavigationPreloadState& state =
- found_registration->active_version()->navigation_preload_state();
- EXPECT_TRUE(state.enabled);
- EXPECT_EQ(kHeaderValue, state.header);
-}
-
} // namespace service_worker_storage_unittest
} // namespace content
diff --git a/chromium/content/browser/service_worker/service_worker_test_utils.cc b/chromium/content/browser/service_worker/service_worker_test_utils.cc
index a99d755c05d..d073ab43966 100644
--- a/chromium/content/browser/service_worker/service_worker_test_utils.cc
+++ b/chromium/content/browser/service_worker/service_worker_test_utils.cc
@@ -22,7 +22,7 @@
#include "content/browser/service_worker/service_worker_context_core.h"
#include "content/browser/service_worker/service_worker_database.h"
#include "content/browser/service_worker/service_worker_disk_cache.h"
-#include "content/browser/service_worker/service_worker_provider_host.h"
+#include "content/browser/service_worker/service_worker_host.h"
#include "content/browser/service_worker/service_worker_registration.h"
#include "content/browser/service_worker/service_worker_storage.h"
#include "content/common/frame.mojom.h"
@@ -34,6 +34,8 @@
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/self_owned_receiver.h"
+#include "mojo/public/cpp/system/data_pipe.h"
+#include "mojo/public/cpp/system/data_pipe_utils.h"
#include "net/base/completion_once_callback.h"
#include "net/base/io_buffer.h"
#include "net/base/test_completion_callback.h"
@@ -104,7 +106,7 @@ class MockPendingSharedURLLoaderFactory final
class FakeNavigationClient : public mojom::NavigationClient {
public:
using ReceivedProviderInfoCallback = base::OnceCallback<void(
- blink::mojom::ServiceWorkerProviderInfoForClientPtr)>;
+ blink::mojom::ServiceWorkerContainerInfoForClientPtr)>;
explicit FakeNavigationClient(
ReceivedProviderInfoCallback on_received_callback)
@@ -125,12 +127,12 @@ class FakeNavigationClient : public mojom::NavigationClient {
subresource_overrides,
blink::mojom::ControllerServiceWorkerInfoPtr
controller_service_worker_info,
- blink::mojom::ServiceWorkerProviderInfoForClientPtr provider_info,
+ blink::mojom::ServiceWorkerContainerInfoForClientPtr container_info,
mojo::PendingRemote<network::mojom::URLLoaderFactory>
prefetch_loader_factory,
const base::UnguessableToken& devtools_navigation_token,
CommitNavigationCallback callback) override {
- std::move(on_received_callback_).Run(std::move(provider_info));
+ std::move(on_received_callback_).Run(std::move(container_info));
std::move(callback).Run(nullptr, nullptr);
}
void CommitFailedNavigation(
@@ -254,30 +256,32 @@ storage::mojom::ServiceWorkerResourceRecordPtr WriteToDiskCacheSyncInternal(
} // namespace
-ServiceWorkerRemoteProviderEndpoint::ServiceWorkerRemoteProviderEndpoint() {}
-ServiceWorkerRemoteProviderEndpoint::ServiceWorkerRemoteProviderEndpoint(
- ServiceWorkerRemoteProviderEndpoint&& other)
+ServiceWorkerRemoteContainerEndpoint::ServiceWorkerRemoteContainerEndpoint() =
+ default;
+ServiceWorkerRemoteContainerEndpoint::ServiceWorkerRemoteContainerEndpoint(
+ ServiceWorkerRemoteContainerEndpoint&& other)
: navigation_client_(std::move(other.navigation_client_)),
host_remote_(std::move(other.host_remote_)),
client_receiver_(std::move(other.client_receiver_)) {}
-ServiceWorkerRemoteProviderEndpoint::~ServiceWorkerRemoteProviderEndpoint() {}
+ServiceWorkerRemoteContainerEndpoint::~ServiceWorkerRemoteContainerEndpoint() =
+ default;
-void ServiceWorkerRemoteProviderEndpoint::BindForWindow(
- blink::mojom::ServiceWorkerProviderInfoForClientPtr info) {
+void ServiceWorkerRemoteContainerEndpoint::BindForWindow(
+ blink::mojom::ServiceWorkerContainerInfoForClientPtr info) {
// We establish a message pipe for connecting |navigation_client_| to a fake
// navigation client, then simulate sending the navigation commit IPC which
- // carries a service worker provider info over it, then the provider info
+ // carries a service worker container info over it, then the container info
// received there gets its |host_remote| and |client_receiver| associated
// with a message pipe so that their users later can make Mojo calls without
// crash.
- blink::mojom::ServiceWorkerProviderInfoForClientPtr received_info;
+ blink::mojom::ServiceWorkerContainerInfoForClientPtr received_info;
base::RunLoop loop(base::RunLoop::Type::kNestableTasksAllowed);
mojo::MakeSelfOwnedReceiver(
std::make_unique<FakeNavigationClient>(base::BindOnce(
[](base::OnceClosure quit_closure,
- blink::mojom::ServiceWorkerProviderInfoForClientPtr* out_info,
- blink::mojom::ServiceWorkerProviderInfoForClientPtr info) {
+ blink::mojom::ServiceWorkerContainerInfoForClientPtr* out_info,
+ blink::mojom::ServiceWorkerContainerInfoForClientPtr info) {
*out_info = std::move(info);
std::move(quit_closure).Run();
},
@@ -300,14 +304,14 @@ void ServiceWorkerRemoteProviderEndpoint::BindForWindow(
host_remote_.Bind(std::move(received_info->host_remote));
}
-void ServiceWorkerRemoteProviderEndpoint::BindForServiceWorker(
+void ServiceWorkerRemoteContainerEndpoint::BindForServiceWorker(
blink::mojom::ServiceWorkerProviderInfoForStartWorkerPtr info) {
host_remote_.Bind(std::move(info->host_remote));
}
ServiceWorkerContainerHostAndInfo::ServiceWorkerContainerHostAndInfo(
base::WeakPtr<ServiceWorkerContainerHost> host,
- blink::mojom::ServiceWorkerProviderInfoForClientPtr info)
+ blink::mojom::ServiceWorkerContainerInfoForClientPtr info)
: host(std::move(host)), info(std::move(info)) {}
ServiceWorkerContainerHostAndInfo::~ServiceWorkerContainerHostAndInfo() =
@@ -317,7 +321,7 @@ base::WeakPtr<ServiceWorkerContainerHost> CreateContainerHostForWindow(
int process_id,
bool is_parent_frame_secure,
base::WeakPtr<ServiceWorkerContextCore> context,
- ServiceWorkerRemoteProviderEndpoint* output_endpoint) {
+ ServiceWorkerRemoteContainerEndpoint* output_endpoint) {
std::unique_ptr<ServiceWorkerContainerHostAndInfo> host_and_info =
CreateContainerHostAndInfoForWindow(context, is_parent_frame_secure);
base::WeakPtr<ServiceWorkerContainerHost> container_host =
@@ -345,13 +349,13 @@ CreateContainerHostAndInfoForWindow(
client_remote;
mojo::PendingAssociatedReceiver<blink::mojom::ServiceWorkerContainerHost>
host_receiver;
- auto info = blink::mojom::ServiceWorkerProviderInfoForClient::New();
+ auto info = blink::mojom::ServiceWorkerContainerInfoForClient::New();
info->client_receiver = client_remote.InitWithNewEndpointAndPassReceiver();
host_receiver = info->host_remote.InitWithNewEndpointAndPassReceiver();
return std::make_unique<ServiceWorkerContainerHostAndInfo>(
context->CreateContainerHostForWindow(
std::move(host_receiver), are_ancestors_secure,
- std::move(client_remote), FrameTreeNode::kFrameTreeNodeInvalidId),
+ std::move(client_remote), /*frame_tree_node_id=*/1),
std::move(info));
}
@@ -388,16 +392,15 @@ void StopServiceWorker(ServiceWorkerVersion* version) {
run_loop.Run();
}
-std::unique_ptr<ServiceWorkerProviderHost>
-CreateProviderHostForServiceWorkerContext(
+std::unique_ptr<ServiceWorkerHost> CreateServiceWorkerHost(
int process_id,
bool is_parent_frame_secure,
ServiceWorkerVersion* hosted_version,
base::WeakPtr<ServiceWorkerContextCore> context,
- ServiceWorkerRemoteProviderEndpoint* output_endpoint) {
+ ServiceWorkerRemoteContainerEndpoint* output_endpoint) {
auto provider_info =
blink::mojom::ServiceWorkerProviderInfoForStartWorker::New();
- auto host = std::make_unique<ServiceWorkerProviderHost>(
+ auto host = std::make_unique<ServiceWorkerHost>(
provider_info->host_remote.InitWithNewEndpointAndPassReceiver(),
hosted_version, std::move(context));
@@ -543,6 +546,14 @@ MockServiceWorkerResponseReader::MockServiceWorkerResponseReader()
MockServiceWorkerResponseReader::~MockServiceWorkerResponseReader() {}
+mojo::PendingRemote<storage::mojom::ServiceWorkerResourceReader>
+MockServiceWorkerResponseReader::BindNewPipeAndPassRemote(
+ base::OnceClosure disconnect_handler) {
+ auto remote = receiver_.BindNewPipeAndPassRemote();
+ receiver_.set_disconnect_handler(std::move(disconnect_handler));
+ return remote;
+}
+
void MockServiceWorkerResponseReader::ReadInfo(
HttpResponseInfoIOBuffer* info_buf,
net::CompletionOnceCallback callback) {
@@ -560,14 +571,8 @@ void MockServiceWorkerResponseReader::ReadInfo(
DCHECK(!expected_reads_.empty());
ExpectedRead expected = expected_reads_.front();
EXPECT_TRUE(expected.info);
- if (expected.async) {
- pending_info_ = info_buf;
- pending_callback_ = std::move(callback);
- } else {
- expected_reads_.pop();
- info_buf->response_data_size = expected.len;
- std::move(callback).Run(expected.result);
- }
+ pending_info_ = info_buf;
+ pending_callback_ = std::move(callback);
}
void MockServiceWorkerResponseReader::ReadData(
@@ -578,69 +583,105 @@ void MockServiceWorkerResponseReader::ReadData(
ExpectedRead expected = expected_reads_.front();
EXPECT_FALSE(expected.info);
EXPECT_LE(static_cast<int>(expected.len), buf_len);
- if (expected.async) {
- pending_callback_ = std::move(callback);
- pending_buffer_ = buf;
- pending_buffer_len_ = static_cast<size_t>(buf_len);
- } else {
- expected_reads_.pop();
- if (expected.len > 0) {
- size_t to_read = std::min(static_cast<size_t>(buf_len), expected.len);
- memcpy(buf->data(), expected.data, to_read);
- }
- std::move(callback).Run(expected.result);
- }
+ pending_callback_ = std::move(callback);
+ pending_buffer_ = buf;
+ pending_buffer_len_ = static_cast<size_t>(buf_len);
}
-void MockServiceWorkerResponseReader::ExpectReadInfo(size_t len,
- bool async,
- int result) {
- expected_reads_.push(ExpectedRead(len, async, result));
+void MockServiceWorkerResponseReader::ReadResponseHead(
+ storage::mojom::ServiceWorkerResourceReader::ReadResponseHeadCallback
+ callback) {
+ pending_read_response_head_callback_ = std::move(callback);
}
-void MockServiceWorkerResponseReader::ExpectReadInfoOk(size_t len, bool async) {
- expected_reads_.push(ExpectedRead(len, async, len));
+void MockServiceWorkerResponseReader::ReadData(int64_t,
+ ReadDataCallback callback) {
+ DCHECK(!body_.is_valid());
+ mojo::ScopedDataPipeConsumerHandle consumer;
+ MojoCreateDataPipeOptions options;
+ options.struct_size = sizeof(MojoCreateDataPipeOptions);
+ options.flags = MOJO_CREATE_DATA_PIPE_FLAG_NONE;
+ options.element_num_bytes = 1;
+ options.capacity_num_bytes = expected_max_data_bytes_;
+ mojo::CreateDataPipe(&options, &body_, &consumer);
+ std::move(callback).Run(std::move(std::move(consumer)));
+}
+
+void MockServiceWorkerResponseReader::ExpectReadInfo(size_t len, int result) {
+ expected_reads_.push(ExpectedRead(len, result));
+}
+
+void MockServiceWorkerResponseReader::ExpectReadInfoOk(size_t len) {
+ expected_reads_.push(ExpectedRead(len, len));
}
void MockServiceWorkerResponseReader::ExpectReadData(const char* data,
size_t len,
- bool async,
int result) {
- expected_reads_.push(ExpectedRead(data, len, async, result));
+ expected_max_data_bytes_ = std::max(expected_max_data_bytes_, len);
+ expected_reads_.push(ExpectedRead(data, len, result));
}
-void MockServiceWorkerResponseReader::ExpectReadDataOk(const std::string& data,
- bool async) {
- expected_reads_.push(
- ExpectedRead(data.data(), data.size(), async, data.size()));
+void MockServiceWorkerResponseReader::ExpectReadDataOk(
+ const std::string& data) {
+ expected_reads_.push(ExpectedRead(data.data(), data.size(), data.size()));
}
void MockServiceWorkerResponseReader::ExpectReadOk(
const std::vector<std::string>& stored_data,
- const size_t bytes_stored,
- const bool async) {
- ExpectReadInfoOk(bytes_stored, async);
+ const size_t bytes_stored) {
+ ExpectReadInfoOk(bytes_stored);
for (const auto& data : stored_data)
- ExpectReadDataOk(data, async);
+ ExpectReadDataOk(data);
}
void MockServiceWorkerResponseReader::CompletePendingRead() {
DCHECK(!expected_reads_.empty());
ExpectedRead expected = expected_reads_.front();
expected_reads_.pop();
- EXPECT_TRUE(expected.async);
+
+ // Legacy API calls.
+ // TODO(https://crbug.com/1055677): Remove this when ReadInfo() and legacy
+ // ReadData() are removed.
+ if (pending_callback_) {
+ if (expected.info) {
+ pending_info_->response_data_size = expected.len;
+ std::move(pending_callback_).Run(expected.result);
+ } else {
+ if (expected.len > 0) {
+ size_t to_read =
+ std::min(static_cast<size_t>(pending_buffer_len_), expected.len);
+ memcpy(pending_buffer_->data(), expected.data, to_read);
+ }
+ std::move(pending_callback_).Run(expected.result);
+ }
+ return;
+ }
+
+ // Make sure that all messages are received at this point.
+ receiver_.FlushForTesting();
+
if (expected.info) {
- pending_info_->response_data_size = expected.len;
+ DCHECK(pending_read_response_head_callback_);
+ auto response_head = network::mojom::URLResponseHead::New();
+ response_head->headers =
+ base::MakeRefCounted<net::HttpResponseHeaders>("HTTP/1.0 200 OK\0\0");
+ response_head->content_length = expected.len;
+ std::move(pending_read_response_head_callback_)
+ .Run(expected.result, std::move(response_head),
+ /*metadata=*/base::nullopt);
} else {
- size_t to_read = std::min(pending_buffer_len_, expected.len);
- if (to_read > 0)
- memcpy(pending_buffer_->data(), expected.data, to_read);
+ if (expected.len == 0) {
+ body_.reset();
+ } else {
+ DCHECK(body_.is_valid());
+ EXPECT_TRUE(mojo::BlockingCopyFromString(
+ std::string(expected.data, expected.len), body_));
+ }
}
- pending_info_ = nullptr;
- pending_buffer_ = nullptr;
- net::CompletionOnceCallback callback = std::move(pending_callback_);
- pending_callback_.Reset();
- std::move(callback).Run(expected.result);
+
+ // Wait until the body is received by the user of the response reader.
+ base::RunLoop().RunUntilIdle();
}
MockServiceWorkerResponseWriter::MockServiceWorkerResponseWriter()
diff --git a/chromium/content/browser/service_worker/service_worker_test_utils.h b/chromium/content/browser/service_worker/service_worker_test_utils.h
index 79e1ec6379e..335ab186148 100644
--- a/chromium/content/browser/service_worker/service_worker_test_utils.h
+++ b/chromium/content/browser/service_worker/service_worker_test_utils.h
@@ -12,10 +12,11 @@
#include "base/command_line.h"
#include "base/memory/weak_ptr.h"
#include "base/task/post_task.h"
+#include "components/services/storage/public/mojom/service_worker_storage_control.mojom.h"
#include "content/browser/service_worker/service_worker_cache_writer.h"
#include "content/browser/service_worker/service_worker_database.h"
#include "content/browser/service_worker/service_worker_disk_cache.h"
-#include "content/browser/service_worker/service_worker_provider_host.h"
+#include "content/browser/service_worker/service_worker_host.h"
#include "content/browser/service_worker/service_worker_single_script_update_checker.h"
#include "content/common/navigation_client.mojom.h"
#include "content/public/browser/browser_task_traits.h"
@@ -33,7 +34,7 @@ namespace content {
class EmbeddedWorkerTestHelper;
class ServiceWorkerContextCore;
-class ServiceWorkerProviderHost;
+class ServiceWorkerHost;
class ServiceWorkerRegistry;
class ServiceWorkerStorage;
class ServiceWorkerVersion;
@@ -65,16 +66,16 @@ blink::ServiceWorkerStatusCode StartServiceWorker(
void StopServiceWorker(ServiceWorkerVersion* version);
-// Container for keeping the Mojo connection to the service worker provider on
+// Container for keeping the Mojo connection to the service worker container on
// the renderer alive.
-class ServiceWorkerRemoteProviderEndpoint {
+class ServiceWorkerRemoteContainerEndpoint {
public:
- ServiceWorkerRemoteProviderEndpoint();
- ServiceWorkerRemoteProviderEndpoint(
- ServiceWorkerRemoteProviderEndpoint&& other);
- ~ServiceWorkerRemoteProviderEndpoint();
+ ServiceWorkerRemoteContainerEndpoint();
+ ServiceWorkerRemoteContainerEndpoint(
+ ServiceWorkerRemoteContainerEndpoint&& other);
+ ~ServiceWorkerRemoteContainerEndpoint();
- void BindForWindow(blink::mojom::ServiceWorkerProviderInfoForClientPtr info);
+ void BindForWindow(blink::mojom::ServiceWorkerContainerInfoForClientPtr info);
void BindForServiceWorker(
blink::mojom::ServiceWorkerProviderInfoForStartWorkerPtr info);
@@ -96,26 +97,26 @@ class ServiceWorkerRemoteProviderEndpoint {
// blink::mojom::EmbeddedWorkerInstanceClient connection if in the future we
// really need to make |host_remote_| and |client_receiver_| usable for it.
mojo::Remote<mojom::NavigationClient> navigation_client_;
- // Bound with content::ServiceWorkerProviderHost. The provider host will be
+ // Bound with content::ServiceWorkerContainerHost. The container host will be
// removed asynchronously when this remote is closed.
mojo::AssociatedRemote<blink::mojom::ServiceWorkerContainerHost> host_remote_;
// This is the other end of
// mojo::PendingAssociatedRemote<ServiceWorkerContainer> owned by
- // content::ServiceWorkerProviderHost.
+ // content::ServiceWorkerContainerHost.
mojo::PendingAssociatedReceiver<blink::mojom::ServiceWorkerContainer>
client_receiver_;
- DISALLOW_COPY_AND_ASSIGN(ServiceWorkerRemoteProviderEndpoint);
+ DISALLOW_COPY_AND_ASSIGN(ServiceWorkerRemoteContainerEndpoint);
};
struct ServiceWorkerContainerHostAndInfo {
ServiceWorkerContainerHostAndInfo(
base::WeakPtr<ServiceWorkerContainerHost> host,
- blink::mojom::ServiceWorkerProviderInfoForClientPtr);
+ blink::mojom::ServiceWorkerContainerInfoForClientPtr);
~ServiceWorkerContainerHostAndInfo();
base::WeakPtr<ServiceWorkerContainerHost> host;
- blink::mojom::ServiceWorkerProviderInfoForClientPtr info;
+ blink::mojom::ServiceWorkerContainerInfoForClientPtr info;
DISALLOW_COPY_AND_ASSIGN(ServiceWorkerContainerHostAndInfo);
};
@@ -127,7 +128,7 @@ base::WeakPtr<ServiceWorkerContainerHost> CreateContainerHostForWindow(
int process_id,
bool is_parent_frame_secure,
base::WeakPtr<ServiceWorkerContextCore> context,
- ServiceWorkerRemoteProviderEndpoint* output_endpoint);
+ ServiceWorkerRemoteContainerEndpoint* output_endpoint);
// Creates a container host that can be used for a navigation.
std::unique_ptr<ServiceWorkerContainerHostAndInfo>
@@ -135,13 +136,12 @@ CreateContainerHostAndInfoForWindow(
base::WeakPtr<ServiceWorkerContextCore> context,
bool are_ancestors_secure);
-std::unique_ptr<ServiceWorkerProviderHost>
-CreateProviderHostForServiceWorkerContext(
+std::unique_ptr<ServiceWorkerHost> CreateServiceWorkerHost(
int process_id,
bool is_parent_frame_secure,
ServiceWorkerVersion* hosted_version,
base::WeakPtr<ServiceWorkerContextCore> context,
- ServiceWorkerRemoteProviderEndpoint* output_endpoint);
+ ServiceWorkerRemoteContainerEndpoint* output_endpoint);
// Calls CreateNewRegistration() synchronously.
scoped_refptr<ServiceWorkerRegistration> CreateNewServiceWorkerRegistration(
@@ -226,18 +226,29 @@ int64_t GetNewResourceIdSync(ServiceWorkerStorage* storage);
// must be completed by the test using CompletePendingRead().
// These is a convenience method AllExpectedReadsDone() which returns whether
// there are any expected reads that have not yet happened.
-class MockServiceWorkerResponseReader : public ServiceWorkerResponseReader {
+class MockServiceWorkerResponseReader
+ : public ServiceWorkerResponseReader,
+ public storage::mojom::ServiceWorkerResourceReader {
public:
MockServiceWorkerResponseReader();
~MockServiceWorkerResponseReader() override;
- // ServiceWorkerResponseReader overrides
+ mojo::PendingRemote<storage::mojom::ServiceWorkerResourceReader>
+ BindNewPipeAndPassRemote(base::OnceClosure disconnect_handler);
+
+ // ServiceWorkerResponseReader overrides:
void ReadInfo(HttpResponseInfoIOBuffer* info_buf,
net::CompletionOnceCallback callback) override;
void ReadData(net::IOBuffer* buf,
int buf_len,
net::CompletionOnceCallback callback) override;
+ // storage::mojom::ServiceWorkerResourceReader overrides:
+ void ReadResponseHead(
+ storage::mojom::ServiceWorkerResourceReader::ReadResponseHeadCallback
+ callback) override;
+ void ReadData(int64_t, ReadDataCallback callback) override;
+
// Test helpers. ExpectReadInfo() and ExpectReadData() give precise control
// over both the data to be written and the result to return.
// ExpectReadInfoOk() and ExpectReadDataOk() are convenience functions for
@@ -245,20 +256,20 @@ class MockServiceWorkerResponseReader : public ServiceWorkerResponseReader {
// Expect a call to ReadInfo() on this reader. For these functions, |len| will
// be used as |response_data_size|, not as the length of this particular read.
- void ExpectReadInfo(size_t len, bool async, int result);
- void ExpectReadInfoOk(size_t len, bool async);
+ // TODO(https://crbug.com/1055677): Rename this to ExpectReadResponseHead().
+ void ExpectReadInfo(size_t len, int result);
+ void ExpectReadInfoOk(size_t len);
// Expect a call to ReadData() on this reader. For these functions, |len| is
// the length of the data to be written back; in ExpectReadDataOk(), |len| is
// implicitly the length of |data|.
- void ExpectReadData(const char* data, size_t len, bool async, int result);
- void ExpectReadDataOk(const std::string& data, bool async);
+ void ExpectReadData(const char* data, size_t len, int result);
+ void ExpectReadDataOk(const std::string& data);
// Convenient method for calling ExpectReadInfoOk() with the length being
// |bytes_stored|, and ExpectReadDataOk() for each element of |stored_data|.
void ExpectReadOk(const std::vector<std::string>& stored_data,
- const size_t bytes_stored,
- const bool async);
+ const size_t bytes_stored);
// Complete a pending async read. It is an error to call this function without
// a pending async read (ie, a previous call to ReadInfo() or ReadData()
@@ -270,23 +281,31 @@ class MockServiceWorkerResponseReader : public ServiceWorkerResponseReader {
private:
struct ExpectedRead {
- ExpectedRead(size_t len, bool async, int result)
- : data(nullptr), len(len), info(true), async(async), result(result) {}
- ExpectedRead(const char* data, size_t len, bool async, int result)
- : data(data), len(len), info(false), async(async), result(result) {}
+ ExpectedRead(size_t len, int result)
+ : data(nullptr), len(len), info(true), result(result) {}
+ ExpectedRead(const char* data, size_t len, int result)
+ : data(data), len(len), info(false), result(result) {}
const char* data;
size_t len;
bool info;
- bool async;
int result;
};
base::queue<ExpectedRead> expected_reads_;
+ size_t expected_max_data_bytes_ = 0;
+
scoped_refptr<net::IOBuffer> pending_buffer_;
size_t pending_buffer_len_;
scoped_refptr<HttpResponseInfoIOBuffer> pending_info_;
net::CompletionOnceCallback pending_callback_;
+ mojo::Receiver<storage::mojom::ServiceWorkerResourceReader> receiver_{this};
+ storage::mojom::ServiceWorkerResourceReader::ReadResponseHeadCallback
+ pending_read_response_head_callback_;
+ storage::mojom::ServiceWorkerResourceReader::ReadDataCallback
+ pending_read_data_callback_;
+ mojo::ScopedDataPipeProducerHandle body_;
+
DISALLOW_COPY_AND_ASSIGN(MockServiceWorkerResponseReader);
};
diff --git a/chromium/content/browser/service_worker/service_worker_updated_script_loader.cc b/chromium/content/browser/service_worker/service_worker_updated_script_loader.cc
index 5e2fd29c0cb..1d4c25ad57b 100644
--- a/chromium/content/browser/service_worker/service_worker_updated_script_loader.cc
+++ b/chromium/content/browser/service_worker/service_worker_updated_script_loader.cc
@@ -13,7 +13,6 @@
#include "base/task/post_task.h"
#include "content/browser/appcache/appcache_disk_cache_ops.h"
#include "content/browser/frame_host/frame_tree_node.h"
-#include "content/browser/loader/url_loader_throttles.h"
#include "content/browser/service_worker/service_worker_cache_writer.h"
#include "content/browser/service_worker/service_worker_consts.h"
#include "content/browser/service_worker/service_worker_context_core.h"
@@ -25,6 +24,7 @@
#include "content/common/service_worker/service_worker_utils.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/content_browser_client.h"
+#include "content/public/browser/url_loader_throttles.h"
#include "content/public/common/content_client.h"
#include "net/base/ip_endpoint.h"
#include "net/base/load_flags.h"
diff --git a/chromium/content/browser/service_worker/service_worker_version.cc b/chromium/content/browser/service_worker/service_worker_version.cc
index ec5148ecd36..961defbb7dd 100644
--- a/chromium/content/browser/service_worker/service_worker_version.cc
+++ b/chromium/content/browser/service_worker/service_worker_version.cc
@@ -12,6 +12,7 @@
#include "base/bind.h"
#include "base/bind_helpers.h"
+#include "base/check.h"
#include "base/command_line.h"
#include "base/debug/dump_without_crashing.h"
#include "base/guid.h"
@@ -35,8 +36,8 @@
#include "content/browser/service_worker/service_worker_container_host.h"
#include "content/browser/service_worker/service_worker_context_core.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
+#include "content/browser/service_worker/service_worker_host.h"
#include "content/browser/service_worker/service_worker_installed_scripts_sender.h"
-#include "content/browser/service_worker/service_worker_provider_host.h"
#include "content/browser/service_worker/service_worker_registration.h"
#include "content/common/content_navigation_policy.h"
#include "content/common/service_worker/service_worker_utils.h"
@@ -388,12 +389,19 @@ ServiceWorkerVersionInfo ServiceWorkerVersion::GetInfo() {
script_origin(), registration_id(), version_id(),
embedded_worker()->process_id(), embedded_worker()->thread_id(),
embedded_worker()->worker_devtools_agent_route_id());
+
+ UMA_HISTOGRAM_COUNTS_10000("ServiceWorker.VersionInfo.ScriptURLLength",
+ info.script_url.spec().length());
+
for (const auto& controllee : controllee_map_) {
ServiceWorkerContainerHost* container_host = controllee.second;
info.clients.emplace(container_host->client_uuid(),
container_host->GetServiceWorkerClientInfo());
}
+ UMA_HISTOGRAM_COUNTS_10000("ServiceWorker.VersionInfo.ClientCount",
+ info.clients.size());
+
info.script_response_time = script_response_time_for_devtools_;
if (!main_script_response_)
return info;
@@ -458,7 +466,7 @@ void ServiceWorkerVersion::StartWorker(ServiceWorkerMetrics::EventType purpose,
// Ensure the live registration during starting worker so that the worker can
// get associated with it in
- // ServiceWorkerProviderHost::CompleteStartWorkerPreparation.
+ // ServiceWorkerHost::CompleteStartWorkerPreparation.
context_->registry()->FindRegistrationForId(
registration_id_, scope_.GetOrigin(),
base::BindOnce(
@@ -476,6 +484,12 @@ void ServiceWorkerVersion::StopWorker(base::OnceClosure callback) {
switch (running_status()) {
case EmbeddedWorkerStatus::STARTING:
case EmbeddedWorkerStatus::RUNNING: {
+ // Endpoint isn't available after calling StopWorker(). This needs to be
+ // set here without waiting until the worker is actually stopped because
+ // subsequent StartWorker() may read the flag to decide whether an event
+ // can be dispatched or not.
+ is_endpoint_ready_ = false;
+
// EmbeddedWorkerInstance::Stop() may synchronously call
// ServiceWorkerVersion::OnStopped() and destroy |this|. This protection
// avoids it.
@@ -582,8 +596,9 @@ int ServiceWorkerVersion::StartRequestWithCustomTimeout(
StatusCallback error_callback,
const base::TimeDelta& timeout,
TimeoutBehavior timeout_behavior) {
- DCHECK_EQ(EmbeddedWorkerStatus::RUNNING, running_status())
- << "Can only start a request with a running worker.";
+ DCHECK(EmbeddedWorkerStatus::RUNNING == running_status() ||
+ EmbeddedWorkerStatus::STARTING == running_status())
+ << "Can only start a request with a running or starting worker.";
DCHECK(event_type == ServiceWorkerMetrics::EventType::INSTALL ||
event_type == ServiceWorkerMetrics::EventType::ACTIVATE ||
event_type == ServiceWorkerMetrics::EventType::MESSAGE ||
@@ -753,14 +768,11 @@ void ServiceWorkerVersion::AddControllee(
CHECK_NE(status_, INSTALLED);
CHECK_NE(status_, REDUNDANT);
- if (base::FeatureList::IsEnabled(
- features::kServiceWorkerTerminationOnNoControllee) &&
- !HasControllee()) {
- // If the service worker starts to control a new client and the service
- // worker needs to work, let's extend the idle timeout to the default value.
- UpdateIdleDelayIfNeeded(base::TimeDelta::FromSeconds(
- blink::mojom::kServiceWorkerDefaultIdleDelayInSeconds));
- }
+ // Set the idle timeout to the default value if there's no controllee and the
+ // worker is running because the worker's idle delay has been set to a shorter
+ // value when all controllee are gone.
+ MaybeUpdateIdleDelayForTerminationOnNoControllee(base::TimeDelta::FromSeconds(
+ blink::mojom::kServiceWorkerDefaultIdleDelayInSeconds));
controllee_map_[uuid] = container_host;
embedded_worker_->UpdateForegroundPriority();
@@ -777,6 +789,14 @@ void ServiceWorkerVersion::AddControllee(
FROM_HERE, base::BindOnce(&ServiceWorkerVersion::NotifyControlleeAdded,
weak_factory_.GetWeakPtr(), uuid,
container_host->GetServiceWorkerClientInfo()));
+
+ // Also send a notification if OnEndNavigationCommit() was already invoked for
+ // this container.
+ if (container_host->navigation_commit_ended()) {
+ OnControlleeNavigationCommitted(container_host->client_uuid(),
+ container_host->process_id(),
+ container_host->frame_id());
+ }
}
void ServiceWorkerVersion::RemoveControllee(const std::string& client_uuid) {
@@ -787,22 +807,38 @@ void ServiceWorkerVersion::RemoveControllee(const std::string& client_uuid) {
embedded_worker_->UpdateForegroundPriority();
// Notify observers asynchronously since this gets called during
- // ServiceWorkerProviderHost's destructor, and we don't want observers to do
- // work during that.
+ // ServiceWorkerHost's destructor, and we don't want observers to do work
+ // during that.
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(&ServiceWorkerVersion::NotifyControlleeRemoved,
weak_factory_.GetWeakPtr(), client_uuid));
- if (base::FeatureList::IsEnabled(
- features::kServiceWorkerTerminationOnNoControllee) &&
- !HasControllee()) {
- // Terminate the worker after all controllees are gone with a delay set by
- // |kTerminationDelayParam|, which is provided by the field trial.
- // When a new controllee checks in before the delay passes, the idle delay
- // is set to the default in AddControllee().
- UpdateIdleDelayIfNeeded(
- base::TimeDelta::FromMilliseconds(kTerminationDelayParam.Get()));
- }
+ // When a new controllee checks in before the delay passes, the idle delay
+ // is set to the default in AddControllee().
+ MaybeUpdateIdleDelayForTerminationOnNoControllee(
+ base::TimeDelta::FromMilliseconds(kTerminationDelayParam.Get()));
+}
+
+void ServiceWorkerVersion::OnControlleeNavigationCommitted(
+ const std::string& client_uuid,
+ int process_id,
+ int frame_id) {
+ DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId());
+
+#if DCHECK_IS_ON()
+ // Ensures this function is only called for a known window client.
+ auto it = controllee_map_.find(client_uuid);
+ DCHECK(it != controllee_map_.end());
+
+ DCHECK_EQ(it->second->GetClientType(),
+ blink::mojom::ServiceWorkerClientType::kWindow);
+#endif // DCHECK_IS_ON()
+
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE,
+ base::BindOnce(&ServiceWorkerVersion::NotifyControlleeNavigationCommitted,
+ weak_factory_.GetWeakPtr(), client_uuid,
+ GlobalFrameRoutingId(process_id, frame_id)));
}
void ServiceWorkerVersion::MoveControlleeToBackForwardCacheMap(
@@ -998,15 +1034,17 @@ void ServiceWorkerVersion::InitializeGlobalScope(
/*subresource_loader_factories=*/nullptr);
}
- DCHECK(provider_host_);
+ DCHECK(worker_host_);
+ DCHECK(service_worker_remote_);
service_worker_remote_->InitializeGlobalScope(
std::move(service_worker_host_),
- provider_host_->container_host()
- ->CreateServiceWorkerRegistrationObjectInfo(std::move(registration)),
- provider_host_->container_host()->CreateServiceWorkerObjectInfoToSend(
- this),
+ worker_host_->container_host()->CreateServiceWorkerRegistrationObjectInfo(
+ std::move(registration)),
+ worker_host_->container_host()->CreateServiceWorkerObjectInfoToSend(this),
fetch_handler_existence_, std::move(subresource_loader_factories),
std::move(reporting_observer_receiver_));
+
+ is_endpoint_ready_ = true;
}
void ServiceWorkerVersion::SetValidOriginTrialTokens(
@@ -1170,6 +1208,9 @@ void ServiceWorkerVersion::OnStarted(
for (const std::string& request_uuid : pending_external_requests)
StartExternalRequest(request_uuid);
}
+
+ MaybeUpdateIdleDelayForTerminationOnNoControllee(
+ base::TimeDelta::FromMilliseconds(kTerminationDelayParam.Get()));
}
void ServiceWorkerVersion::OnStopping() {
@@ -1807,8 +1848,8 @@ void ServiceWorkerVersion::StartWorkerInternal() {
auto provider_info =
blink::mojom::ServiceWorkerProviderInfoForStartWorker::New();
- DCHECK(!provider_host_);
- provider_host_ = std::make_unique<ServiceWorkerProviderHost>(
+ DCHECK(!worker_host_);
+ worker_host_ = std::make_unique<content::ServiceWorkerHost>(
provider_info->host_remote.InitWithNewEndpointAndPassReceiver(), this,
context());
@@ -1844,11 +1885,13 @@ void ServiceWorkerVersion::StartWorkerInternal() {
base::BindOnce(&OnConnectionError, embedded_worker_->AsWeakPtr()));
receiver_.reset();
receiver_.Bind(service_worker_host_.InitWithNewEndpointAndPassReceiver());
+
// Initialize the global scope now if the worker won't be paused. Otherwise,
// delay initialization until the main script is loaded.
- if (!initialize_global_scope_after_main_script_loaded_)
+ if (!initialize_global_scope_after_main_script_loaded_) {
InitializeGlobalScope(/*script_loader_factories=*/nullptr,
/*subresource_loader_factories=*/nullptr);
+ }
if (!controller_receiver_.is_valid()) {
controller_receiver_ = remote_controller_.BindNewPipeAndPassReceiver();
@@ -1926,8 +1969,8 @@ void ServiceWorkerVersion::OnTimeoutTimer() {
// Detach the worker. Remove |this| as a listener first; otherwise
// OnStoppedInternal might try to restart before the new worker
// is created. Also, protect |this|, since swapping out the
- // EmbeddedWorkerInstance could destroy our ServiceWorkerProviderHost
- // which could in turn destroy |this|.
+ // EmbeddedWorkerInstance could destroy our ServiceWorkerHost which could in
+ // turn destroy |this|.
scoped_refptr<ServiceWorkerVersion> protect_this(this);
embedded_worker_->RemoveObserver(this);
embedded_worker_->Detach();
@@ -2206,13 +2249,14 @@ void ServiceWorkerVersion::OnStoppedInternal(EmbeddedWorkerStatus old_status) {
request_timeouts_.clear();
external_request_uuid_to_request_id_.clear();
service_worker_remote_.reset();
+ is_endpoint_ready_ = false;
remote_controller_.reset();
DCHECK(!controller_receiver_.is_valid());
installed_scripts_sender_.reset();
receiver_.reset();
pending_external_requests_.clear();
worker_is_idle_on_renderer_ = true;
- provider_host_.reset();
+ worker_host_.reset();
for (auto& observer : observers_)
observer.OnRunningStateChanged(this);
@@ -2298,6 +2342,13 @@ void ServiceWorkerVersion::NotifyControlleeRemoved(const std::string& uuid) {
}
}
+void ServiceWorkerVersion::NotifyControlleeNavigationCommitted(
+ const std::string& uuid,
+ GlobalFrameRoutingId render_frame_host_id) {
+ if (context_)
+ context_->OnControlleeNavigationCommitted(this, uuid, render_frame_host_id);
+}
+
void ServiceWorkerVersion::PrepareForUpdate(
std::map<GURL, ServiceWorkerUpdateChecker::ComparedScriptInfo>
compared_script_info_map,
@@ -2377,10 +2428,16 @@ void ServiceWorkerVersion::MaybeReportConsoleMessageToInternals(
script_url_);
}
-void ServiceWorkerVersion::UpdateIdleDelayIfNeeded(base::TimeDelta delay) {
- // The idle delay can be updated only when the worker is still running.
- bool update_idle_delay = running_status() == EmbeddedWorkerStatus::STARTING ||
- running_status() == EmbeddedWorkerStatus::RUNNING;
+void ServiceWorkerVersion::MaybeUpdateIdleDelayForTerminationOnNoControllee(
+ base::TimeDelta delay) {
+ if (!base::FeatureList::IsEnabled(
+ features::kServiceWorkerTerminationOnNoControllee) ||
+ HasControllee() || running_status() != EmbeddedWorkerStatus::RUNNING) {
+ return;
+ }
+
+ // The idle delay can be updated only when the worker is running.
+ bool update_idle_delay = running_status() == EmbeddedWorkerStatus::RUNNING;
// The idle delay should not be updated when the worker needs to be
// terminated ASAP so that the new worker can be activated soon.
diff --git a/chromium/content/browser/service_worker/service_worker_version.h b/chromium/content/browser/service_worker/service_worker_version.h
index 3de68c59447..7be6c0988c9 100644
--- a/chromium/content/browser/service_worker/service_worker_version.h
+++ b/chromium/content/browser/service_worker/service_worker_version.h
@@ -32,7 +32,6 @@
#include "content/browser/frame_host/back_forward_cache_metrics.h"
#include "content/browser/service_worker/embedded_worker_instance.h"
#include "content/browser/service_worker/embedded_worker_status.h"
-#include "content/browser/service_worker/service_worker_client_info.h"
#include "content/browser/service_worker/service_worker_client_utils.h"
#include "content/browser/service_worker/service_worker_metrics.h"
#include "content/browser/service_worker/service_worker_ping_controller.h"
@@ -41,6 +40,8 @@
#include "content/common/content_export.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/global_routing_id.h"
+#include "content/public/browser/service_worker_client_info.h"
#include "ipc/ipc_message.h"
#include "mojo/public/cpp/bindings/associated_receiver.h"
#include "mojo/public/cpp/bindings/pending_associated_remote.h"
@@ -66,8 +67,8 @@ namespace content {
class ServiceWorkerContainerHost;
class ServiceWorkerContextCore;
+class ServiceWorkerHost;
class ServiceWorkerInstalledScriptsSender;
-class ServiceWorkerProviderHost;
class ServiceWorkerRegistration;
struct ServiceWorkerVersionInfo;
@@ -109,9 +110,9 @@ namespace service_worker_registration_unittest {
class ServiceWorkerActivationTest;
} // namespace service_worker_registration_unittest
-namespace service_worker_navigation_loader_unittest {
-class ServiceWorkerNavigationLoaderTest;
-} // namespace service_worker_navigation_loader_unittest
+namespace service_worker_main_resource_loader_unittest {
+class ServiceWorkerMainResourceLoaderTest;
+} // namespace service_worker_main_resource_loader_unittest
// This class corresponds to a specific version of a ServiceWorker
// script for a given scope. When a script is upgraded, there may be
@@ -270,9 +271,6 @@ class CONTENT_EXPORT ServiceWorkerVersion
// subresources).
bool OnRequestTermination();
- // Skips waiting and forces this version to become activated.
- void SkipWaitingFromDevTools();
-
// Schedules an update to be run 'soon'.
void ScheduleUpdate();
@@ -341,7 +339,8 @@ class CONTENT_EXPORT ServiceWorkerVersion
// code and the dispatch time. See service_worker.mojom.
SimpleEventCallback CreateSimpleEventCallback(int request_id);
- // This must be called when the worker is running.
+ // This must be called when is_endpoint_ready() returns true, which is after
+ // InitializeGlobalScope() is called.
blink::mojom::ServiceWorker* endpoint() {
DCHECK(running_status() == EmbeddedWorkerStatus::STARTING ||
running_status() == EmbeddedWorkerStatus::RUNNING);
@@ -349,6 +348,8 @@ class CONTENT_EXPORT ServiceWorkerVersion
return service_worker_remote_.get();
}
+ bool is_endpoint_ready() const { return is_endpoint_ready_; }
+
// Returns the 'controller' interface ptr of this worker. It is expected that
// the worker is already starting or running, or is going to be started soon.
// TODO(kinuko): Relying on the callsites to start the worker when it's
@@ -366,6 +367,12 @@ class CONTENT_EXPORT ServiceWorkerVersion
void AddControllee(ServiceWorkerContainerHost* container_host);
void RemoveControllee(const std::string& client_uuid);
+ // Called when the navigation for a window client commits to a render frame
+ // host.
+ void OnControlleeNavigationCommitted(const std::string& client_uuid,
+ int process_id,
+ int frame_id);
+
// Called when a controllee goes into back-forward cache.
void MoveControlleeToBackForwardCacheMap(const std::string& client_uuid);
// Called when a back-forward cached controllee is restored.
@@ -395,11 +402,11 @@ class CONTENT_EXPORT ServiceWorkerVersion
ServiceWorkerContainerHost* controllee,
BackForwardCacheMetrics::NotRestoredReason reason);
- // The provider host hosting this version. Only valid while the version is
+ // The worker host hosting this version. Only valid while the version is
// running.
- ServiceWorkerProviderHost* provider_host() {
- DCHECK(provider_host_);
- return provider_host_.get();
+ content::ServiceWorkerHost* worker_host() {
+ DCHECK(worker_host_);
+ return worker_host_.get();
}
base::WeakPtr<ServiceWorkerContextCore> context() const { return context_; }
@@ -532,9 +539,9 @@ class CONTENT_EXPORT ServiceWorkerVersion
//
// On each request that dispatches a fetch event to this worker (or would
// have, in the case of a no-fetch event worker), this count is incremented.
- // When the browser-side provider host receives a hint from the renderer that
+ // When the browser-side worker host receives a hint from the renderer that
// it is a good time to update the service worker, the count is decremented.
- // It is also decremented when if the provider host is destroyed before
+ // It is also decremented when if the worker host is destroyed before
// receiving the hint.
//
// When the count transitions from 1 to 0, update is scheduled.
@@ -595,8 +602,8 @@ class CONTENT_EXPORT ServiceWorkerVersion
friend class ServiceWorkerVersionBrowserTest;
friend class ServiceWorkerActivationTest;
friend class service_worker_version_unittest::ServiceWorkerVersionTest;
- friend class service_worker_navigation_loader_unittest::
- ServiceWorkerNavigationLoaderTest;
+ friend class service_worker_main_resource_loader_unittest::
+ ServiceWorkerMainResourceLoaderTest;
FRIEND_TEST_ALL_PREFIXES(service_worker_controllee_request_handler_unittest::
ServiceWorkerControlleeRequestHandlerTest,
@@ -855,6 +862,9 @@ class CONTENT_EXPORT ServiceWorkerVersion
void NotifyControlleeAdded(const std::string& uuid,
const ServiceWorkerClientInfo& info);
void NotifyControlleeRemoved(const std::string& uuid);
+ void NotifyControlleeNavigationCommitted(
+ const std::string& uuid,
+ GlobalFrameRoutingId render_frame_host_id);
void GetClientOnExecutionReady(const std::string& client_uuid,
GetClientCallback callback,
@@ -866,9 +876,10 @@ class CONTENT_EXPORT ServiceWorkerVersion
std::unique_ptr<blink::PendingURLLoaderFactoryBundle>
subresource_loader_factories);
- // Update the idle delay if the worker is starting or running and we don't
+ // When ServiceWorkerTerminationOnNoControlle is enabled and there's no
+ // controllee, update the idle delay if the worker is running and we don't
// have to terminate the worker ASAP (e.g. for activation).
- void UpdateIdleDelayIfNeeded(base::TimeDelta delay);
+ void MaybeUpdateIdleDelayForTerminationOnNoControllee(base::TimeDelta delay);
const int64_t version_id_;
const int64_t registration_id_;
@@ -902,6 +913,9 @@ class CONTENT_EXPORT ServiceWorkerVersion
Status status_ = NEW;
std::unique_ptr<EmbeddedWorkerInstance> embedded_worker_;
+ // True if endpoint() is ready to dispatch events, which means
+ // InitializeGlobalScope() is already called.
+ bool is_endpoint_ready_ = false;
std::vector<StatusCallback> start_callbacks_;
std::vector<base::OnceClosure> stop_callbacks_;
std::vector<base::OnceClosure> status_change_callbacks_;
@@ -954,10 +968,9 @@ class CONTENT_EXPORT ServiceWorkerVersion
// (e.g. activation).
bool needs_to_be_terminated_asap_ = false;
- // Keeps track of the provider hosting this running service worker for this
- // version. |provider_host_| is always valid as long as this version is
- // running.
- std::unique_ptr<ServiceWorkerProviderHost> provider_host_;
+ // The host for this version's running service worker. |worker_host_| is
+ // always valid as long as this version is running.
+ std::unique_ptr<content::ServiceWorkerHost> worker_host_;
// |controllee_map_| and |bfcached_controllee_map_| should not share the same
// controllee.
diff --git a/chromium/content/browser/service_worker/service_worker_version_browsertest.cc b/chromium/content/browser/service_worker/service_worker_version_browsertest.cc
index d3705cc8d4c..90d1ea262fb 100644
--- a/chromium/content/browser/service_worker/service_worker_version_browsertest.cc
+++ b/chromium/content/browser/service_worker/service_worker_version_browsertest.cc
@@ -34,7 +34,7 @@
#include "content/browser/service_worker/service_worker_context_core_observer.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
#include "content/browser/service_worker/service_worker_fetch_dispatcher.h"
-#include "content/browser/service_worker/service_worker_provider_host.h"
+#include "content/browser/service_worker/service_worker_host.h"
#include "content/browser/service_worker/service_worker_registration.h"
#include "content/browser/service_worker/service_worker_test_utils.h"
#include "content/browser/service_worker/service_worker_version.h"
@@ -844,7 +844,7 @@ class ServiceWorkerVersionBrowserTest : public ContentBrowserTest {
scoped_refptr<ServiceWorkerVersion> version_;
scoped_refptr<ServiceWorkerContextWrapper> wrapper_;
std::unique_ptr<ServiceWorkerFetchDispatcher> fetch_dispatcher_;
- std::vector<ServiceWorkerRemoteProviderEndpoint> remote_endpoints_;
+ std::vector<ServiceWorkerRemoteContainerEndpoint> remote_endpoints_;
};
class WaitForLoaded : public EmbeddedWorkerInstance::Listener {
diff --git a/chromium/content/browser/service_worker/service_worker_version_unittest.cc b/chromium/content/browser/service_worker/service_worker_version_unittest.cc
index 37c33a12bc9..28ecdf60bca 100644
--- a/chromium/content/browser/service_worker/service_worker_version_unittest.cc
+++ b/chromium/content/browser/service_worker/service_worker_version_unittest.cc
@@ -14,6 +14,7 @@
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/run_loop.h"
+#include "base/test/bind_test_util.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/simple_test_tick_clock.h"
@@ -168,11 +169,11 @@ class ServiceWorkerVersionTest : public testing::Test {
return ServiceWorkerVersion::FetchHandlerExistence::EXISTS;
}
- ServiceWorkerRemoteProviderEndpoint ActivateWithControllee(
+ ServiceWorkerRemoteContainerEndpoint ActivateWithControllee(
int controllee_process_id = 33) {
version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
registration_->SetActiveVersion(version_);
- ServiceWorkerRemoteProviderEndpoint remote_endpoint;
+ ServiceWorkerRemoteContainerEndpoint remote_endpoint;
base::WeakPtr<ServiceWorkerContainerHost> container_host =
CreateContainerHostForWindow(
controllee_process_id, true /* is_parent_frame_secure */,
@@ -425,7 +426,7 @@ TEST_F(ServiceWorkerVersionTest, Doom) {
// Add a controllee.
version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
registration_->SetActiveVersion(version_);
- ServiceWorkerRemoteProviderEndpoint remote_endpoint;
+ ServiceWorkerRemoteContainerEndpoint remote_endpoint;
base::WeakPtr<ServiceWorkerContainerHost> container_host =
CreateContainerHostForWindow(
33 /* dummy render process id */, true /* is_parent_frame_secure */,
@@ -1189,7 +1190,7 @@ TEST_F(ServiceWorkerVersionTest,
// Add a controllee, but don't begin the navigation commit yet. This will
// cause the client to have an invalid process id like we see in real
// navigations.
- ServiceWorkerRemoteProviderEndpoint remote_endpoint;
+ ServiceWorkerRemoteContainerEndpoint remote_endpoint;
std::unique_ptr<ServiceWorkerContainerHostAndInfo> host_and_info =
CreateContainerHostAndInfoForWindow(helper_->context()->AsWeakPtr(),
/*are_ancestors_secure=*/true);
@@ -1481,7 +1482,7 @@ class ServiceWorkerVersionTerminationOnNoControlleeTest
private:
base::test::ScopedFeatureList feature_list_;
- std::vector<ServiceWorkerRemoteProviderEndpoint> remote_endpoints_;
+ std::vector<ServiceWorkerRemoteContainerEndpoint> remote_endpoints_;
};
// static
@@ -1624,5 +1625,64 @@ TEST_P(ServiceWorkerVersionTerminationOnNoControlleeTest, StoppedWorker) {
version_->RemoveControllee(controllee->client_uuid());
}
+// FakeEmbeddedWorkerInstanceClient which waits to call OnStarted() until
+// CallOnStarted() is called.
+class WaitToCallOnStartedEmbeddedWorkerInstanceClient
+ : public FakeEmbeddedWorkerInstanceClient {
+ public:
+ explicit WaitToCallOnStartedEmbeddedWorkerInstanceClient(
+ EmbeddedWorkerTestHelper* helper)
+ : FakeEmbeddedWorkerInstanceClient(helper) {}
+
+ void CallOnStarted() {
+ host()->OnStarted(blink::mojom::ServiceWorkerStartStatus::kNormalCompletion,
+ true /* has_fetch_handler */, helper()->GetNextThreadId(),
+ blink::mojom::EmbeddedWorkerStartTiming::New());
+ }
+
+ protected:
+ void EvaluateScript() override { host()->OnScriptEvaluationStart(); }
+};
+
+// Call AddControllee() and RemoveControllee() while starting a worker.
+// This is a regression test for https://crbug.com/1099744.
+TEST_P(ServiceWorkerVersionTerminationOnNoControlleeTest,
+ RemoveControlleeBeforeStarted) {
+ version_->SetStatus(ServiceWorkerVersion::ACTIVATED);
+ EXPECT_EQ(EmbeddedWorkerStatus::STOPPED, version_->running_status());
+ auto* embedded_worker_in_renderer = helper_->AddNewPendingInstanceClient<
+ WaitToCallOnStartedEmbeddedWorkerInstanceClient>(helper_.get());
+ auto* service_worker_in_renderer =
+ helper_->AddNewPendingServiceWorker<FakeServiceWorker>(helper_.get());
+ base::RunLoop loop;
+ version_->StartWorker(
+ ServiceWorkerMetrics::EventType::UNKNOWN,
+ base::BindLambdaForTesting(
+ [&](blink::ServiceWorkerStatusCode) { loop.Quit(); }));
+
+ // Add and remove controllee during starting the worker. This doesn't update
+ // the idle delay.
+ ServiceWorkerContainerHost* controllee = CreateControllee();
+ version_->AddControllee(controllee);
+ version_->RemoveControllee(controllee->client_uuid());
+ service_worker_in_renderer->RunUntilInitializeGlobalScope();
+ EXPECT_FALSE(service_worker_in_renderer->idle_delay().has_value());
+ EXPECT_EQ(EmbeddedWorkerStatus::STARTING, version_->running_status());
+
+ // Start the worker and make sure the fake service worker receives all the
+ // messages. At the OnStarted message, the browser sends the idle timeout
+ // because there's no controllee at this point.
+ embedded_worker_in_renderer->CallOnStarted();
+ loop.Run();
+ service_worker_in_renderer->FlushForTesting();
+ EXPECT_EQ(EmbeddedWorkerStatus::RUNNING, version_->running_status());
+ if (IsTerminationEnabled()) {
+ EXPECT_EQ(kTerminationDelay,
+ service_worker_in_renderer->idle_delay().value());
+ } else {
+ EXPECT_FALSE(service_worker_in_renderer->idle_delay().has_value());
+ }
+}
+
} // namespace service_worker_version_unittest
} // namespace content