summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/modules/service_worker
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2019-05-24 11:40:17 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2019-05-24 12:42:11 +0000
commit5d87695f37678f96492b258bbab36486c59866b4 (patch)
treebe9783bbaf04fb930c4d74ca9c00b5e7954c8bc6 /chromium/third_party/blink/renderer/modules/service_worker
parent6c11fb357ec39bf087b8b632e2b1e375aef1b38b (diff)
downloadqtwebengine-chromium-5d87695f37678f96492b258bbab36486c59866b4.tar.gz
BASELINE: Update Chromium to 75.0.3770.56
Change-Id: I86d2007fd27a45d5797eee06f4c9369b8b50ac4f Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Diffstat (limited to 'chromium/third_party/blink/renderer/modules/service_worker')
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/fetch_event.h2
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/fetch_respond_with_observer.cc10
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/navigation_preload_manager.cc6
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/navigator_service_worker.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/respond_with_observer.cc46
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/respond_with_observer.h11
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker.cc2
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker.idl2
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_clients.cc8
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_container.cc51
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_container.h3
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_container_test.cc3
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc308
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h44
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_proxy.cc27
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_proxy.h12
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_installed_scripts_manager.cc56
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_installed_scripts_manager_test.cc28
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_registration.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_script_cached_metadata_handler.cc9
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_script_cached_metadata_handler.h11
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_thread.cc55
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_thread.h16
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/service_worker_window_client.cc4
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/thread_safe_script_container.cc13
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/thread_safe_script_container.h25
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/thread_safe_script_container_test.cc9
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/wait_until_observer.cc69
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/wait_until_observer.h28
-rw-r--r--chromium/third_party/blink/renderer/modules/service_worker/web_embedded_worker_impl_test.cc272
30 files changed, 816 insertions, 320 deletions
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/fetch_event.h b/chromium/third_party/blink/renderer/modules/service_worker/fetch_event.h
index abc9f4cca60..083665e6367 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/fetch_event.h
+++ b/chromium/third_party/blink/renderer/modules/service_worker/fetch_event.h
@@ -92,7 +92,7 @@ class MODULES_EXPORT FetchEvent final
private:
Member<FetchRespondWithObserver> observer_;
- TraceWrapperMember<Request> request_;
+ Member<Request> request_;
Member<PreloadResponseProperty> preload_response_property_;
std::unique_ptr<WebURLResponse> preload_response_;
Member<DataPipeBytesConsumer::CompletionNotifier> body_completion_notifier_;
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/fetch_respond_with_observer.cc b/chromium/third_party/blink/renderer/modules/service_worker/fetch_respond_with_observer.cc
index d8ea0a1685b..8e711000b66 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/fetch_respond_with_observer.cc
+++ b/chromium/third_party/blink/renderer/modules/service_worker/fetch_respond_with_observer.cc
@@ -12,6 +12,7 @@
#include "base/metrics/histogram_macros.h"
#include "services/network/public/mojom/fetch_api.mojom-blink.h"
#include "services/network/public/mojom/request_context_frame_type.mojom-blink.h"
+#include "third_party/blink/public/mojom/devtools/console_message.mojom-shared.h"
#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_response.h"
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/renderer/bindings/core/v8/script_value.h"
@@ -20,7 +21,6 @@
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/fetch/body_stream_buffer.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
-#include "third_party/blink/renderer/core/inspector/console_types.h"
#include "third_party/blink/renderer/modules/service_worker/service_worker_global_scope_client.h"
#include "third_party/blink/renderer/modules/service_worker/wait_until_observer.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
@@ -216,9 +216,10 @@ FetchRespondWithObserver* FetchRespondWithObserver::Create(
void FetchRespondWithObserver::OnResponseRejected(
ServiceWorkerResponseError error) {
DCHECK(GetExecutionContext());
- GetExecutionContext()->AddConsoleMessage(ConsoleMessage::Create(
- kJSMessageSource, mojom::ConsoleMessageLevel::kWarning,
- GetMessageForResponseError(error, request_url_)));
+ GetExecutionContext()->AddConsoleMessage(
+ ConsoleMessage::Create(mojom::ConsoleMessageSource::kJavaScript,
+ mojom::ConsoleMessageLevel::kWarning,
+ GetMessageForResponseError(error, request_url_)));
// The default value of WebServiceWorkerResponse's status is 0, which maps
// to a network error.
@@ -366,6 +367,7 @@ void FetchRespondWithObserver::OnResponseFulfilled(
}
void FetchRespondWithObserver::OnNoResponse() {
+ DCHECK(GetExecutionContext());
ServiceWorkerGlobalScopeClient::From(GetExecutionContext())
->RespondToFetchEventWithNoResponse(event_id_, event_dispatch_time_,
base::TimeTicks::Now());
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/navigation_preload_manager.cc b/chromium/third_party/blink/renderer/modules/service_worker/navigation_preload_manager.cc
index 7183dc9dd14..3c48c20ce58 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/navigation_preload_manager.cc
+++ b/chromium/third_party/blink/renderer/modules/service_worker/navigation_preload_manager.cc
@@ -32,14 +32,14 @@ ScriptPromise NavigationPreloadManager::setHeaderValue(
"') is not a valid HTTP header field value."));
}
- ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+ auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
ScriptPromise promise = resolver->Promise();
registration_->SetNavigationPreloadHeader(value, resolver);
return promise;
}
ScriptPromise NavigationPreloadManager::getState(ScriptState* script_state) {
- ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+ auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
ScriptPromise promise = resolver->Promise();
registration_->GetNavigationPreloadState(resolver);
return promise;
@@ -51,7 +51,7 @@ NavigationPreloadManager::NavigationPreloadManager(
ScriptPromise NavigationPreloadManager::SetEnabled(bool enable,
ScriptState* script_state) {
- ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+ auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
ScriptPromise promise = resolver->Promise();
registration_->EnableNavigationPreload(enable, resolver);
return promise;
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/navigator_service_worker.cc b/chromium/third_party/blink/renderer/modules/service_worker/navigator_service_worker.cc
index 7f43d541d1d..eb0a2d7f0a6 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/navigator_service_worker.cc
+++ b/chromium/third_party/blink/renderer/modules/service_worker/navigator_service_worker.cc
@@ -90,7 +90,7 @@ ServiceWorkerContainer* NavigatorServiceWorker::GetOrCreateContainer(
->GetSecurityOrigin()
->CanAccessServiceWorkers()) {
String error_message;
- if (frame->GetSecurityContext()->IsSandboxed(kSandboxOrigin)) {
+ if (frame->GetSecurityContext()->IsSandboxed(WebSandboxFlags::kOrigin)) {
error_message =
"Service worker is disabled because the context is sandboxed and "
"lacks the 'allow-same-origin' flag.";
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/respond_with_observer.cc b/chromium/third_party/blink/renderer/modules/service_worker/respond_with_observer.cc
index 216334f6947..d1082d43cc4 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/respond_with_observer.cc
+++ b/chromium/third_party/blink/renderer/modules/service_worker/respond_with_observer.cc
@@ -18,21 +18,12 @@ using blink::mojom::ServiceWorkerResponseError;
namespace blink {
-void RespondWithObserver::ContextDestroyed(ExecutionContext*) {
- if (observer_) {
- DCHECK_EQ(kPending, state_);
- observer_.Clear();
- }
- state_ = kDone;
-}
-
void RespondWithObserver::WillDispatchEvent() {
event_dispatch_time_ = WTF::CurrentTimeTicks();
}
void RespondWithObserver::DidDispatchEvent(
DispatchEventResult dispatch_result) {
- DCHECK(GetExecutionContext());
if (state_ != kInitial)
return;
@@ -43,21 +34,35 @@ void RespondWithObserver::DidDispatchEvent(
}
state_ = kDone;
- observer_.Clear();
}
+// https://w3c.github.io/ServiceWorker/#fetch-event-respondwith
void RespondWithObserver::RespondWith(ScriptState* script_state,
ScriptPromise script_promise,
ExceptionState& exception_state) {
+ // 1. `If the dispatch flag is unset, throw an "InvalidStateError"
+ // DOMException.`
+ if (!observer_->IsDispatchingEvent()) {
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ "The event handler is already finished.");
+ return;
+ }
+
+ // 2. `If the respond-with entered flag is set, throw an "InvalidStateError"
+ // DOMException.`
if (state_ != kInitial) {
- exception_state.ThrowDOMException(
- DOMExceptionCode::kInvalidStateError,
- "The event has already been responded to.");
+ // Non-initial state during event dispatch means respondWith() was already
+ // called.
+ exception_state.ThrowDOMException(DOMExceptionCode::kInvalidStateError,
+ "respondWith() was already called.");
return;
}
+ // 3. `Add r to the extend lifetime promises.`
+ // 4. `Increment the pending promises count by one.`
+ // This is accomplised by WaitUntil().
state_ = kPending;
- observer_->WaitUntil(
+ bool will_wait = observer_->WaitUntil(
script_state, script_promise, exception_state,
WTF::BindRepeating(&RespondWithObserver::ResponseWasFulfilled,
WrapPersistent(this), exception_state.Context(),
@@ -66,13 +71,19 @@ void RespondWithObserver::RespondWith(ScriptState* script_state,
WTF::BindRepeating(&RespondWithObserver::ResponseWasRejected,
WrapPersistent(this),
ServiceWorkerResponseError::kPromiseRejected));
+ // If the WaitUntilObserver won't observe the response promise, the event can
+ // end before the response result is reported back to the
+ // ServiceWorkerContextClient, which it doesn't expect (e.g., for fetch
+ // events, RespondToFetchEvent*() must be called before
+ // DidHandleFetchEvent()). So WaitUntilObserver must observe the promise and
+ // call our callbacks before it determines the event is done.
+ DCHECK(will_wait);
}
void RespondWithObserver::ResponseWasRejected(ServiceWorkerResponseError error,
const ScriptValue& value) {
OnResponseRejected(error);
state_ = kDone;
- observer_.Clear();
}
void RespondWithObserver::ResponseWasFulfilled(
@@ -82,20 +93,19 @@ void RespondWithObserver::ResponseWasFulfilled(
const ScriptValue& value) {
OnResponseFulfilled(value, context_type, interface_name, property_name);
state_ = kDone;
- observer_.Clear();
}
RespondWithObserver::RespondWithObserver(ExecutionContext* context,
int event_id,
WaitUntilObserver* observer)
- : ContextLifecycleObserver(context),
+ : ContextClient(context),
event_id_(event_id),
state_(kInitial),
observer_(observer) {}
void RespondWithObserver::Trace(blink::Visitor* visitor) {
visitor->Trace(observer_);
- ContextLifecycleObserver::Trace(visitor);
+ ContextClient::Trace(visitor);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/respond_with_observer.h b/chromium/third_party/blink/renderer/modules/service_worker/respond_with_observer.h
index 42130eaf4da..1a356dd83d2 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/respond_with_observer.h
+++ b/chromium/third_party/blink/renderer/modules/service_worker/respond_with_observer.h
@@ -26,20 +26,19 @@ class WaitUntilObserver;
// overriding onResponseFulfilled, onResponseRejected and onNoResponse.
class MODULES_EXPORT RespondWithObserver
: public GarbageCollectedFinalized<RespondWithObserver>,
- public ContextLifecycleObserver {
+ public ContextClient {
USING_GARBAGE_COLLECTED_MIXIN(RespondWithObserver);
public:
virtual ~RespondWithObserver() = default;
- void ContextDestroyed(ExecutionContext*) override;
-
void WillDispatchEvent();
void DidDispatchEvent(DispatchEventResult dispatch_result);
- // The respondWith() observes the promise until the given promise is resolved
- // or rejected and then delays calling ServiceWorkerGlobalScopeClient::
- // didHandle*Event() in order to notify the result to the client.
+ // Observes the given promise and calls OnResponseRejected() or
+ // OnResponseFulfilled() when it settles. It also keeps the event alive by
+ // telling the event's WaitUntilObserver to observe the promise. The result of
+ // RespondWith() is therefore reported back before the event finishes.
void RespondWith(ScriptState*, ScriptPromise, ExceptionState&);
// Called when the respondWith() promise was rejected.
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker.cc b/chromium/third_party/blink/renderer/modules/service_worker/service_worker.cc
index 89173f7e2bc..bb612367bcf 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker.cc
+++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker.cc
@@ -101,7 +101,7 @@ void ServiceWorker::postMessage(ScriptState* script_state,
}
ScriptPromise ServiceWorker::InternalsTerminate(ScriptState* script_state) {
- ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+ auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
ScriptPromise promise = resolver->Promise();
host_->TerminateForTesting(
WTF::Bind([](ScriptPromiseResolver* resolver) { resolver->Resolve(); },
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker.idl b/chromium/third_party/blink/renderer/modules/service_worker/service_worker.idl
index 8ee3e022618..ab4fbd7ecc2 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker.idl
+++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker.idl
@@ -52,4 +52,4 @@ enum ServiceWorkerState {
attribute EventHandler onstatechange;
};
-ServiceWorker implements AbstractWorker;
+ServiceWorker includes AbstractWorker;
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_clients.cc b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_clients.cc
index 6ea5d173152..f0a4897a219 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_clients.cc
+++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_clients.cc
@@ -117,7 +117,7 @@ ScriptPromise ServiceWorkerClients::get(ScriptState* script_state,
if (!execution_context)
return ScriptPromise();
- ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+ auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
ServiceWorkerGlobalScopeClient::From(execution_context)
->GetClient(id, WTF::Bind(&DidGetClient, WrapPersistent(resolver)));
return resolver->Promise();
@@ -131,7 +131,7 @@ ScriptPromise ServiceWorkerClients::matchAll(
if (!execution_context)
return ScriptPromise();
- ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+ auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
ServiceWorkerGlobalScopeClient::From(execution_context)
->GetClients(
mojom::blink::ServiceWorkerClientQueryOptions::New(
@@ -147,7 +147,7 @@ ScriptPromise ServiceWorkerClients::claim(ScriptState* script_state) {
if (!execution_context)
return ScriptPromise();
- ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+ auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
ServiceWorkerGlobalScopeClient::From(execution_context)
->Claim(WTF::Bind(&DidClaim, WrapPersistent(resolver)));
return resolver->Promise();
@@ -155,7 +155,7 @@ ScriptPromise ServiceWorkerClients::claim(ScriptState* script_state) {
ScriptPromise ServiceWorkerClients::openWindow(ScriptState* script_state,
const String& url) {
- ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+ auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
ScriptPromise promise = resolver->Promise();
ExecutionContext* context = ExecutionContext::From(script_state);
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_container.cc b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_container.cc
index ca5e8c657a3..e9123ef2246 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_container.cc
+++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_container.cc
@@ -63,6 +63,7 @@
#include "third_party/blink/renderer/platform/bindings/v8_throw_exception.h"
#include "third_party/blink/renderer/platform/weborigin/scheme_registry.h"
#include "third_party/blink/renderer/platform/weborigin/security_violation_reporting_policy.h"
+#include "third_party/blink/renderer/platform/wtf/functional.h"
namespace blink {
@@ -148,31 +149,6 @@ class ServiceWorkerContainer::DomContentLoadedListener final
}
};
-class ServiceWorkerContainer::GetRegistrationForReadyCallback
- : public WebServiceWorkerProvider::
- WebServiceWorkerGetRegistrationForReadyCallbacks {
- public:
- explicit GetRegistrationForReadyCallback(ReadyProperty* ready)
- : ready_(ready) {}
- ~GetRegistrationForReadyCallback() override = default;
-
- void OnSuccess(WebServiceWorkerRegistrationObjectInfo info) override {
- DCHECK_EQ(ready_->GetState(), ReadyProperty::kPending);
-
- if (ready_->GetExecutionContext() &&
- !ready_->GetExecutionContext()->IsContextDestroyed()) {
- ready_->Resolve(
- ServiceWorkerContainer::From(
- To<Document>(ready_->GetExecutionContext()))
- ->GetOrCreateServiceWorkerRegistration(std::move(info)));
- }
- }
-
- private:
- Persistent<ReadyProperty> ready_;
- DISALLOW_COPY_AND_ASSIGN(GetRegistrationForReadyCallback);
-};
-
const char ServiceWorkerContainer::kSupplementName[] = "ServiceWorkerContainer";
ServiceWorkerContainer* ServiceWorkerContainer::From(Document* document) {
@@ -234,7 +210,7 @@ ScriptPromise ServiceWorkerContainer::registerServiceWorker(
ScriptState* script_state,
const String& url,
const RegistrationOptions* options) {
- ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+ auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
ScriptPromise promise = resolver->Promise();
// TODO(asamidoi): Remove this check after module loading for
@@ -370,7 +346,7 @@ ScriptPromise ServiceWorkerContainer::registerServiceWorker(
ScriptPromise ServiceWorkerContainer::getRegistration(
ScriptState* script_state,
const String& document_url) {
- ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+ auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
ScriptPromise promise = resolver->Promise();
ExecutionContext* execution_context = ExecutionContext::From(script_state);
@@ -422,7 +398,7 @@ ScriptPromise ServiceWorkerContainer::getRegistration(
ScriptPromise ServiceWorkerContainer::getRegistrations(
ScriptState* script_state) {
- ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+ auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
ScriptPromise promise = resolver->Promise();
if (!provider_) {
@@ -483,7 +459,8 @@ ScriptPromise ServiceWorkerContainer::ready(ScriptState* caller_state) {
ready_ = CreateReadyProperty();
if (provider_) {
provider_->GetRegistrationForReady(
- std::make_unique<GetRegistrationForReadyCallback>(ready_.Get()));
+ WTF::Bind(&ServiceWorkerContainer::OnGetRegistrationForReady,
+ WrapPersistent(this)));
}
}
@@ -499,6 +476,9 @@ void ServiceWorkerContainer::SetController(
if (controller_) {
UseCounter::Count(GetExecutionContext(),
WebFeature::kServiceWorkerControlledPage);
+ GetExecutionContext()->GetScheduler()->RegisterStickyFeature(
+ SchedulingPolicy::Feature::kServiceWorkerControlledPage,
+ {SchedulingPolicy::RecordMetricsForBackForwardCache()});
}
if (should_notify_controller_change)
DispatchEvent(*Event::Create(event_type_names::kControllerchange));
@@ -655,4 +635,17 @@ void ServiceWorkerContainer::DispatchMessageEvent(
EnqueueEvent(*event, TaskType::kServiceWorkerClientMessage);
}
+void ServiceWorkerContainer::OnGetRegistrationForReady(
+ WebServiceWorkerRegistrationObjectInfo info) {
+ DCHECK_EQ(ready_->GetState(), ReadyProperty::kPending);
+
+ if (ready_->GetExecutionContext() &&
+ !ready_->GetExecutionContext()->IsContextDestroyed()) {
+ ready_->Resolve(
+ ServiceWorkerContainer::From(
+ To<Document>(ready_->GetExecutionContext()))
+ ->GetOrCreateServiceWorkerRegistration(std::move(info)));
+ }
+}
+
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_container.h b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_container.h
index 59053342879..817fc4e62e4 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_container.h
+++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_container.h
@@ -120,7 +120,6 @@ class MODULES_EXPORT ServiceWorkerContainer final
private:
class DomContentLoadedListener;
- class GetRegistrationForReadyCallback;
using ReadyProperty =
ScriptPromiseProperty<Member<ServiceWorkerContainer>,
@@ -132,6 +131,8 @@ class MODULES_EXPORT ServiceWorkerContainer final
void DispatchMessageEvent(WebServiceWorkerObjectInfo source,
TransferableMessage);
+ void OnGetRegistrationForReady(WebServiceWorkerRegistrationObjectInfo info);
+
std::unique_ptr<WebServiceWorkerProvider> provider_;
Member<ServiceWorker> controller_;
Member<ReadyProperty> ready_;
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_container_test.cc b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_container_test.cc
index f2838ed468d..57d91f605fc 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_container_test.cc
+++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_container_test.cc
@@ -26,6 +26,7 @@
#include "third_party/blink/renderer/platform/bindings/script_state.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
+#include "third_party/blink/renderer/platform/wtf/allocator.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "v8/include/v8.h"
@@ -276,6 +277,8 @@ TEST_F(ServiceWorkerContainerTest, GetRegistration_CrossOriginURLIsRejected) {
}
class StubWebServiceWorkerProvider {
+ DISALLOW_NEW();
+
public:
StubWebServiceWorkerProvider()
: register_call_count_(0),
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc
index f7e2c95b4e6..9643b11c37e 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc
+++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.cc
@@ -53,9 +53,11 @@
#include "third_party/blink/renderer/core/inspector/worker_thread_debugger.h"
#include "third_party/blink/renderer/core/loader/threadable_loader.h"
#include "third_party/blink/renderer/core/origin_trials/origin_trial_context.h"
+#include "third_party/blink/renderer/core/probe/core_probes.h"
#include "third_party/blink/renderer/core/trustedtypes/trusted_script_url.h"
#include "third_party/blink/renderer/core/workers/global_scope_creation_params.h"
#include "third_party/blink/renderer/core/workers/installed_scripts_manager.h"
+#include "third_party/blink/renderer/core/workers/worker_classic_script_loader.h"
#include "third_party/blink/renderer/core/workers/worker_clients.h"
#include "third_party/blink/renderer/core/workers/worker_reporting_proxy.h"
#include "third_party/blink/renderer/modules/event_target_modules.h"
@@ -71,11 +73,13 @@
#include "third_party/blink/renderer/platform/bindings/script_state.h"
#include "third_party/blink/renderer/platform/bindings/v8_throw_exception.h"
#include "third_party/blink/renderer/platform/histogram.h"
+#include "third_party/blink/renderer/platform/loader/fetch/fetch_client_settings_object_snapshot.h"
#include "third_party/blink/renderer/platform/loader/fetch/memory_cache.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_loader_options.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_request.h"
#include "third_party/blink/renderer/platform/network/content_security_policy_response_headers.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
+#include "third_party/blink/renderer/platform/weborigin/security_policy.h"
#include "third_party/blink/renderer/platform/wtf/time.h"
namespace blink {
@@ -106,7 +110,7 @@ ServiceWorkerGlobalScope* ServiceWorkerGlobalScope::Create(
creation_params->script_url)) {
// CSP headers, referrer policy, and origin trial tokens will be provided by
// the InstalledScriptsManager in EvaluateClassicScript().
- DCHECK(creation_params->content_security_policy_parsed_headers.IsEmpty());
+ DCHECK(creation_params->outside_content_security_policy_headers.IsEmpty());
DCHECK_EQ(network::mojom::ReferrerPolicy::kDefault,
creation_params->referrer_policy);
DCHECK(creation_params->origin_trial_tokens->IsEmpty());
@@ -138,25 +142,123 @@ bool ServiceWorkerGlobalScope::ShouldInstallV8Extensions() const {
WebSecurityOrigin(GetSecurityOrigin()));
}
-void ServiceWorkerGlobalScope::ImportModuleScript(
+// https://w3c.github.io/ServiceWorker/#update
+void ServiceWorkerGlobalScope::FetchAndRunClassicScript(
+ const KURL& script_url,
+ const FetchClientSettingsObjectSnapshot& outside_settings_object,
+ const v8_inspector::V8StackTraceId& stack_id) {
+ DCHECK(base::FeatureList::IsEnabled(
+ features::kOffMainThreadServiceWorkerScriptFetch));
+ DCHECK(!IsContextPaused());
+
+ // Step 9. "Switching on job's worker type, run these substeps with the
+ // following options:"
+ // "classic: Fetch a classic worker script given job's serialized script url,
+ // job's client, "serviceworker", and the to-be-created environment settings
+ // object for this service worker."
+ auto destination = mojom::RequestContextType::SERVICE_WORKER;
+
+ // "To perform the fetch given request, run the following steps:"
+ // Step 9.1. "Append `Service-Worker`/`script` to request's header list."
+ // Step 9.2. "Set request's cache mode to "no-cache" if any of the following
+ // are true:"
+ // Step 9.3. "Set request's service-workers mode to "none"."
+ // The browser process takes care of these steps.
+
+ // Step 9.4. "If the is top-level flag is unset, then return the result of
+ // fetching request."
+ // This step makes sense only when the worker type is "module". For classic
+ // script fetch, the top-level flag is always set.
+
+ // Step 9.5. "Set request's redirect mode to "error"."
+ // The browser process takes care of this step.
+
+ // Step 9.6. "Fetch request, and asynchronously wait to run the remaining
+ // steps as part of fetch's process response for the response response."
+ WorkerClassicScriptLoader* classic_script_loader =
+ MakeGarbageCollected<WorkerClassicScriptLoader>();
+ classic_script_loader->LoadTopLevelScriptAsynchronously(
+ *this, CreateOutsideSettingsFetcher(outside_settings_object), script_url,
+ destination, network::mojom::FetchRequestMode::kSameOrigin,
+ network::mojom::FetchCredentialsMode::kSameOrigin,
+ outside_settings_object.GetAddressSpace(),
+ WTF::Bind(&ServiceWorkerGlobalScope::DidReceiveResponseForClassicScript,
+ WrapWeakPersistent(this),
+ WrapPersistent(classic_script_loader)),
+ WTF::Bind(&ServiceWorkerGlobalScope::DidFetchClassicScript,
+ WrapWeakPersistent(this), WrapPersistent(classic_script_loader),
+ stack_id));
+}
+
+void ServiceWorkerGlobalScope::FetchAndRunModuleScript(
const KURL& module_url_record,
const FetchClientSettingsObjectSnapshot& outside_settings_object,
network::mojom::FetchCredentialsMode credentials_mode) {
- Modulator* modulator = Modulator::From(ScriptController()->GetScriptState());
+ DCHECK(IsContextThread());
+ FetchModuleScript(module_url_record, outside_settings_object,
+ mojom::RequestContextType::SERVICE_WORKER, credentials_mode,
+ ModuleScriptCustomFetchType::kWorkerConstructor,
+ MakeGarbageCollected<ServiceWorkerModuleTreeClient>(
+ Modulator::From(ScriptController()->GetScriptState())));
+}
+
+void ServiceWorkerGlobalScope::RunInstalledClassicScript(
+ const KURL& script_url,
+ const v8_inspector::V8StackTraceId& stack_id) {
+ DCHECK(IsContextThread());
- ModuleScriptCustomFetchType fetch_type =
- ModuleScriptCustomFetchType::kWorkerConstructor;
InstalledScriptsManager* installed_scripts_manager =
GetThread()->GetInstalledScriptsManager();
- if (installed_scripts_manager &&
- installed_scripts_manager->IsScriptInstalled(module_url_record)) {
- fetch_type = ModuleScriptCustomFetchType::kInstalledServiceWorker;
+ DCHECK(installed_scripts_manager);
+ DCHECK(installed_scripts_manager->IsScriptInstalled(script_url));
+
+ // GetScriptData blocks until the script is received from the browser.
+ std::unique_ptr<InstalledScriptsManager::ScriptData> script_data =
+ installed_scripts_manager->GetScriptData(script_url);
+ if (!script_data) {
+ ReportingProxy().DidFailToLoadClassicScript();
+ // This will eventually initiate worker thread termination. See
+ // ServiceWorkerGlobalScopeProxy::DidCloseWorkerGlobalScope() for details.
+ close();
+ return;
+ }
+ ReportingProxy().DidLoadClassicScript();
+
+ std::unique_ptr<Vector<String>> origin_trial_tokens =
+ script_data->CreateOriginTrialTokens();
+ OriginTrialContext::AddTokens(this, origin_trial_tokens.get());
+
+ auto referrer_policy = network::mojom::ReferrerPolicy::kDefault;
+ if (!script_data->GetReferrerPolicy().IsNull()) {
+ SecurityPolicy::ReferrerPolicyFromHeaderValue(
+ script_data->GetReferrerPolicy(),
+ kDoNotSupportReferrerPolicyLegacyKeywords, &referrer_policy);
}
- FetchModuleScript(
- module_url_record, outside_settings_object,
- mojom::RequestContextType::SERVICE_WORKER, credentials_mode, fetch_type,
- MakeGarbageCollected<ServiceWorkerModuleTreeClient>(modulator));
+ // Construct a ContentSecurityPolicy object to convert
+ // ContentSecurityPolicyResponseHeaders to CSPHeaderAndType.
+ // TODO(nhiroki): Find an efficient way to do this.
+ auto* content_security_policy = MakeGarbageCollected<ContentSecurityPolicy>();
+ content_security_policy->DidReceiveHeaders(
+ script_data->GetContentSecurityPolicyResponseHeaders());
+
+ RunClassicScript(
+ script_url, referrer_policy, content_security_policy->Headers(),
+ script_data->TakeSourceText(), script_data->TakeMetaData(), stack_id);
+}
+
+void ServiceWorkerGlobalScope::RunInstalledModuleScript(
+ const KURL& module_url_record,
+ const FetchClientSettingsObjectSnapshot& outside_settings_object,
+ network::mojom::FetchCredentialsMode credentials_mode) {
+ DCHECK(IsContextThread());
+ // The installed scripts will be read from the service worker script storage
+ // during module script fetch.
+ FetchModuleScript(module_url_record, outside_settings_object,
+ mojom::RequestContextType::SERVICE_WORKER, credentials_mode,
+ ModuleScriptCustomFetchType::kInstalledServiceWorker,
+ MakeGarbageCollected<ServiceWorkerModuleTreeClient>(
+ Modulator::From(ScriptController()->GetScriptState())));
}
void ServiceWorkerGlobalScope::Dispose() {
@@ -225,6 +327,111 @@ void ServiceWorkerGlobalScope::DidEvaluateScript() {
}
}
+void ServiceWorkerGlobalScope::DidReceiveResponseForClassicScript(
+ WorkerClassicScriptLoader* classic_script_loader) {
+ DCHECK(IsContextThread());
+ DCHECK(base::FeatureList::IsEnabled(
+ features::kOffMainThreadServiceWorkerScriptFetch));
+ probe::DidReceiveScriptResponse(this, classic_script_loader->Identifier());
+}
+
+// https://w3c.github.io/ServiceWorker/#update
+void ServiceWorkerGlobalScope::DidFetchClassicScript(
+ WorkerClassicScriptLoader* classic_script_loader,
+ const v8_inspector::V8StackTraceId& stack_id) {
+ DCHECK(IsContextThread());
+ DCHECK(base::FeatureList::IsEnabled(
+ features::kOffMainThreadServiceWorkerScriptFetch));
+
+ // Step 9. "If the algorithm asynchronously completes with null, then:"
+ if (classic_script_loader->Failed()) {
+ // Step 9.1. "Invoke Reject Job Promise with job and TypeError."
+ // Step 9.2. "If newestWorker is null, invoke Clear Registration algorithm
+ // passing registration as its argument."
+ // Step 9.3. "Invoke Finish Job with job and abort these steps."
+ // The browser process takes care of these steps.
+ ReportingProxy().DidFailToFetchClassicScript();
+ return;
+ }
+ ReportingProxy().DidFetchScript();
+ probe::ScriptImported(this, classic_script_loader->Identifier(),
+ classic_script_loader->SourceText());
+
+ // Step 10. "If hasUpdatedResources is false, then:"
+ // Step 10.1. "Invoke Resolve Job Promise with job and registration."
+ // Steo 10.2. "Invoke Finish Job with job and abort these steps."
+ // Step 11. "Let worker be a new service worker."
+ // Step 12. "Set worker's script url to job's script url, worker's script
+ // resource to script, worker's type to job's worker type, and worker's
+ // script resource map to updatedResourceMap."
+ // Step 13. "Append url to worker's set of used scripts."
+ // The browser process takes care of these steps.
+
+ // Step 14. "Set worker's script resource's HTTPS state to httpsState."
+ // This is done in the constructor of WorkerGlobalScope.
+
+ // Step 15. "Set worker's script resource's referrer policy to
+ // referrerPolicy."
+ auto referrer_policy = network::mojom::ReferrerPolicy::kDefault;
+ if (!classic_script_loader->GetReferrerPolicy().IsNull()) {
+ SecurityPolicy::ReferrerPolicyFromHeaderValue(
+ classic_script_loader->GetReferrerPolicy(),
+ kDoNotSupportReferrerPolicyLegacyKeywords, &referrer_policy);
+ }
+
+ // Step 16. "Invoke Run Service Worker algorithm given worker, with the force
+ // bypass cache for importscripts flag set if job’s force bypass cache flag
+ // is set, and with the following callback steps given evaluationStatus:"
+ RunClassicScript(
+ classic_script_loader->ResponseURL(), referrer_policy,
+ classic_script_loader->GetContentSecurityPolicy()
+ ? classic_script_loader->GetContentSecurityPolicy()->Headers()
+ : Vector<CSPHeaderAndType>(),
+ classic_script_loader->SourceText(),
+ classic_script_loader->ReleaseCachedMetadata(), stack_id);
+}
+
+// https://w3c.github.io/ServiceWorker/#run-service-worker-algorithm
+void ServiceWorkerGlobalScope::RunClassicScript(
+ const KURL& response_url,
+ network::mojom::ReferrerPolicy referrer_policy,
+ const Vector<CSPHeaderAndType> csp_headers,
+ const String& source_code,
+ std::unique_ptr<Vector<uint8_t>> cached_meta_data,
+ const v8_inspector::V8StackTraceId& stack_id) {
+ // Step 4.5. "Set workerGlobalScope's url to serviceWorker's script url."
+ InitializeURL(response_url);
+
+ // Step 4.6. "Set workerGlobalScope's HTTPS state to serviceWorker's script
+ // resource's HTTPS state."
+ // This is done in the constructor of WorkerGlobalScope.
+
+ // Step 4.7. "Set workerGlobalScope's referrer policy to serviceWorker's
+ // script resource's referrer policy."
+ SetReferrerPolicy(referrer_policy);
+
+ // TODO(nhiroki): Clarify mappings between the steps 4.8-4.11 and
+ // implementation.
+
+ // This is quoted from the "Content Security Policy" algorithm:
+ // "Whenever a user agent invokes Run Service Worker algorithm with a service
+ // worker serviceWorker:
+ // - If serviceWorker's script resource was delivered with a
+ // Content-Security-Policy HTTP header containing the value policy, the
+ // user agent must enforce policy for serviceWorker.
+ // - If serviceWorker's script resource was delivered with a
+ // Content-Security-Policy-Report-Only HTTP header containing the value
+ // policy, the user agent must monitor policy for serviceWorker."
+ InitContentSecurityPolicyFromVector(csp_headers);
+ BindContentSecurityPolicyToExecutionContext();
+
+ // Step 4.12. "Let evaluationStatus be the result of running the classic
+ // script script if script is a classic script, otherwise, the result of
+ // running the module script script if script is a module script."
+ EvaluateClassicScript(response_url, source_code, std::move(cached_meta_data),
+ stack_id);
+}
+
void ServiceWorkerGlobalScope::CountScriptInternal(
size_t script_size,
size_t cached_metadata_size) {
@@ -250,7 +457,7 @@ ScriptPromise ServiceWorkerGlobalScope::skipWaiting(ScriptState* script_state) {
if (!execution_context)
return ScriptPromise();
- ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+ auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
ServiceWorkerGlobalScopeClient::From(execution_context)
->SkipWaiting(WTF::Bind(&DidSkipWaiting, WrapPersistent(resolver)));
return resolver->Promise();
@@ -270,6 +477,16 @@ void ServiceWorkerGlobalScope::SetRegistration(
GetExecutionContext(), std::move(info));
}
+void ServiceWorkerGlobalScope::SetFetchHandlerExistence(
+ FetchHandlerExistence fetch_handler_existence) {
+ DCHECK(IsContextThread());
+ if (fetch_handler_existence == FetchHandlerExistence::EXISTS &&
+ base::FeatureList::IsEnabled(
+ features::kServiceWorkerIsolateInForeground)) {
+ GetThread()->GetIsolate()->IsolateInForegroundNotification();
+ }
+}
+
ServiceWorker* ServiceWorkerGlobalScope::GetOrCreateServiceWorker(
WebServiceWorkerObjectInfo info) {
if (info.version_id == mojom::blink::kInvalidServiceWorkerVersionId)
@@ -291,8 +508,9 @@ bool ServiceWorkerGlobalScope::AddEventListenerInternal(
"Event handler of '%s' event must be added on the initial evaluation "
"of worker script.",
event_type.Utf8().data());
- AddConsoleMessage(ConsoleMessage::Create(
- kJSMessageSource, mojom::ConsoleMessageLevel::kWarning, message));
+ AddConsoleMessage(
+ ConsoleMessage::Create(mojom::ConsoleMessageSource::kJavaScript,
+ mojom::ConsoleMessageLevel::kWarning, message));
}
return WorkerGlobalScope::AddEventListenerInternal(event_type, listener,
options);
@@ -304,6 +522,8 @@ void ServiceWorkerGlobalScope::EvaluateClassicScriptInternal(
std::unique_ptr<Vector<uint8_t>> cached_meta_data) {
DCHECK(IsContextThread());
+ // TODO(nhiroki): Move this mechanism to
+ // WorkerGlobalScope::EvaluateClassicScriptInternal().
if (!evaluate_script_ready_) {
evaluate_script_ =
WTF::Bind(&ServiceWorkerGlobalScope::EvaluateClassicScriptInternal,
@@ -312,55 +532,6 @@ void ServiceWorkerGlobalScope::EvaluateClassicScriptInternal(
return;
}
- // Receive the main script via script streaming if needed.
- // TODO(nhiroki): Merge script loading from the installed script manager
- // into regular off-the-main-thread script fetch path so that we can remove
- // this special casing.
- InstalledScriptsManager* installed_scripts_manager =
- GetThread()->GetInstalledScriptsManager();
- if (installed_scripts_manager &&
- installed_scripts_manager->IsScriptInstalled(script_url)) {
- // GetScriptData blocks until the script is received from the browser.
- std::unique_ptr<InstalledScriptsManager::ScriptData> script_data =
- installed_scripts_manager->GetScriptData(script_url);
- if (!script_data) {
- ReportingProxy().DidFailToLoadClassicScript();
- // This will eventually initiate worker thread termination. See
- // ServiceWorkerGlobalScopeProxy::DidCloseWorkerGlobalScope() for details.
- close();
- return;
- }
-
- if (base::FeatureList::IsEnabled(
- features::kOffMainThreadServiceWorkerScriptFetch)) {
- // WorkerGlobalScope sets the URL in DidImportClassicScript() when
- // off-the-main-thread fetch is enabled. Since we bypass calling
- // DidImportClassicScript(), set the URL here.
- InitializeURL(script_url);
- }
-
- DCHECK(source_code.IsEmpty());
- DCHECK(!cached_meta_data);
- source_code = script_data->TakeSourceText();
- cached_meta_data = script_data->TakeMetaData();
-
- base::Optional<ContentSecurityPolicyResponseHeaders>
- content_security_policy_raw_headers =
- script_data->GetContentSecurityPolicyResponseHeaders();
- ApplyContentSecurityPolicyFromHeaders(
- content_security_policy_raw_headers.value());
-
- String referrer_policy = script_data->GetReferrerPolicy();
- if (!referrer_policy.IsNull())
- ParseAndSetReferrerPolicy(referrer_policy);
-
- std::unique_ptr<Vector<String>> origin_trial_tokens =
- script_data->CreateOriginTrialTokens();
- OriginTrialContext::AddTokens(this, origin_trial_tokens.get());
-
- ReportingProxy().DidLoadClassicScript();
- }
-
WorkerGlobalScope::EvaluateClassicScriptInternal(script_url, source_code,
std::move(cached_meta_data));
}
@@ -433,9 +604,9 @@ void ServiceWorkerGlobalScope::importScripts(
SingleCachedMetadataHandler*
ServiceWorkerGlobalScope::CreateWorkerScriptCachedMetadataHandler(
const KURL& script_url,
- const Vector<uint8_t>* meta_data) {
+ std::unique_ptr<Vector<uint8_t>> meta_data) {
return ServiceWorkerScriptCachedMetadataHandler::Create(this, script_url,
- meta_data);
+ std::move(meta_data));
}
ScriptPromise ServiceWorkerGlobalScope::fetch(ScriptState* script_state,
@@ -452,11 +623,6 @@ void ServiceWorkerGlobalScope::ExceptionThrown(ErrorEvent* event) {
debugger->ExceptionThrown(GetThread(), event);
}
-mojom::RequestContextType
-ServiceWorkerGlobalScope::GetDestinationForMainScript() {
- return mojom::RequestContextType::SERVICE_WORKER;
-}
-
void ServiceWorkerGlobalScope::CountCacheStorageInstalledScript(
uint64_t script_size,
uint64_t script_metadata_size) {
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h
index b399e8bc3eb..ad08b81c53c 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h
+++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h
@@ -53,6 +53,7 @@ class ServiceWorkerRegistration;
class ServiceWorkerThread;
class StringOrTrustedScriptURL;
class WaitUntilObserver;
+class WorkerClassicScriptLoader;
struct GlobalScopeCreationParams;
struct WebServiceWorkerObjectInfo;
struct WebServiceWorkerRegistrationObjectInfo;
@@ -63,6 +64,8 @@ class MODULES_EXPORT ServiceWorkerGlobalScope final : public WorkerGlobalScope {
DEFINE_WRAPPERTYPEINFO();
public:
+ using FetchHandlerExistence = mojom::FetchHandlerExistence;
+
static ServiceWorkerGlobalScope* Create(
ServiceWorkerThread*,
std::unique_ptr<GlobalScopeCreationParams>,
@@ -79,13 +82,33 @@ class MODULES_EXPORT ServiceWorkerGlobalScope final : public WorkerGlobalScope {
bool IsServiceWorkerGlobalScope() const override { return true; }
bool ShouldInstallV8Extensions() const final;
- // Implements WorkerGlobalScope.
- void ImportModuleScript(
+ // Implements WorkerGlobalScope:
+ // Fetches and runs the top-level classic worker script for the 'new' or
+ // 'update' service worker cases.
+ void FetchAndRunClassicScript(
+ const KURL& script_url,
+ const FetchClientSettingsObjectSnapshot& outside_settings_object,
+ const v8_inspector::V8StackTraceId& stack_id) override;
+ // Fetches and runs the top-level module worker script for the 'new' or
+ // 'update' service worker cases.
+ void FetchAndRunModuleScript(
const KURL& module_url_record,
const FetchClientSettingsObjectSnapshot& outside_settings_object,
network::mojom::FetchCredentialsMode) override;
void Dispose() override;
+ // Runs the installed top-level classic worker script for the 'installed'
+ // service worker case.
+ void RunInstalledClassicScript(const KURL& script_url,
+ const v8_inspector::V8StackTraceId& stack_id);
+
+ // Runs the installed top-level module worker script for the 'installed'
+ // service worker case.
+ void RunInstalledModuleScript(
+ const KURL& module_url_record,
+ const FetchClientSettingsObjectSnapshot& outside_settings_object,
+ network::mojom::FetchCredentialsMode);
+
// Counts an evaluated script and its size. Called for the main worker script.
void CountWorkerScript(size_t script_size, size_t cached_metadata_size);
@@ -110,6 +133,7 @@ class MODULES_EXPORT ServiceWorkerGlobalScope final : public WorkerGlobalScope {
void BindServiceWorkerHost(mojom::blink::ServiceWorkerHostAssociatedPtrInfo);
void SetRegistration(WebServiceWorkerRegistrationObjectInfo info);
+ void SetFetchHandlerExistence(FetchHandlerExistence fetch_handler_existence);
// Returns the ServiceWorker object described by the given info. Creates a new
// object if needed, or else returns the existing one.
@@ -165,9 +189,21 @@ class MODULES_EXPORT ServiceWorkerGlobalScope final : public WorkerGlobalScope {
ExceptionState&) override;
SingleCachedMetadataHandler* CreateWorkerScriptCachedMetadataHandler(
const KURL& script_url,
- const Vector<uint8_t>* meta_data) override;
+ std::unique_ptr<Vector<uint8_t>> meta_data) override;
void ExceptionThrown(ErrorEvent*) override;
- mojom::RequestContextType GetDestinationForMainScript() override;
+
+ void DidReceiveResponseForClassicScript(
+ WorkerClassicScriptLoader* classic_script_loader);
+ void DidFetchClassicScript(WorkerClassicScriptLoader* classic_script_loader,
+ const v8_inspector::V8StackTraceId& stack_id);
+
+ // https://w3c.github.io/ServiceWorker/#run-service-worker-algorithm
+ void RunClassicScript(const KURL& response_url,
+ network::mojom::ReferrerPolicy,
+ const Vector<CSPHeaderAndType>,
+ const String& source_code,
+ std::unique_ptr<Vector<uint8_t>> cached_meta_data,
+ const v8_inspector::V8StackTraceId&);
// Counts the |script_size| and |cached_metadata_size| for UMA to measure the
// number of scripts and the total bytes of scripts.
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_proxy.cc b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_proxy.cc
index 69f8f1e3b9b..63b63bbe9f3 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_proxy.cc
+++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_proxy.cc
@@ -187,6 +187,11 @@ void ServiceWorkerGlobalScopeProxy::SetRegistration(
WorkerGlobalScope()->SetRegistration(std::move(info));
}
+void ServiceWorkerGlobalScopeProxy::SetFetchHandlerExistence(
+ FetchHandlerExistence fetch_handler_existence) {
+ WorkerGlobalScope()->SetFetchHandlerExistence(fetch_handler_existence);
+}
+
void ServiceWorkerGlobalScopeProxy::ReadyToEvaluateScript() {
DCHECK_CALLED_ON_VALID_THREAD(worker_thread_checker_);
WorkerGlobalScope()->ReadyToEvaluateScript();
@@ -194,7 +199,7 @@ void ServiceWorkerGlobalScopeProxy::ReadyToEvaluateScript() {
void ServiceWorkerGlobalScopeProxy::DispatchBackgroundFetchAbortEvent(
int event_id,
- const WebBackgroundFetchRegistration& registration) {
+ WebBackgroundFetchRegistration registration) {
DCHECK_CALLED_ON_VALID_THREAD(worker_thread_checker_);
WaitUntilObserver* observer = WaitUntilObserver::Create(
WorkerGlobalScope(), WaitUntilObserver::kBackgroundFetchAbort, event_id);
@@ -209,7 +214,7 @@ void ServiceWorkerGlobalScopeProxy::DispatchBackgroundFetchAbortEvent(
BackgroundFetchEventInit* init = BackgroundFetchEventInit::Create();
init->setRegistration(MakeGarbageCollected<BackgroundFetchRegistration>(
WorkerGlobalScope()->registration() /* service_worker_registration */,
- registration));
+ std::move(registration)));
BackgroundFetchEvent* event = BackgroundFetchEvent::Create(
event_type_names::kBackgroundfetchabort, init, observer);
@@ -219,7 +224,7 @@ void ServiceWorkerGlobalScopeProxy::DispatchBackgroundFetchAbortEvent(
void ServiceWorkerGlobalScopeProxy::DispatchBackgroundFetchClickEvent(
int event_id,
- const WebBackgroundFetchRegistration& registration) {
+ WebBackgroundFetchRegistration registration) {
DCHECK_CALLED_ON_VALID_THREAD(worker_thread_checker_);
WaitUntilObserver* observer = WaitUntilObserver::Create(
WorkerGlobalScope(), WaitUntilObserver::kBackgroundFetchClick, event_id);
@@ -227,7 +232,7 @@ void ServiceWorkerGlobalScopeProxy::DispatchBackgroundFetchClickEvent(
BackgroundFetchEventInit* init = BackgroundFetchEventInit::Create();
init->setRegistration(MakeGarbageCollected<BackgroundFetchRegistration>(
WorkerGlobalScope()->registration() /* service_worker_registration */,
- registration));
+ std::move(registration)));
BackgroundFetchEvent* event = BackgroundFetchEvent::Create(
event_type_names::kBackgroundfetchclick, init, observer);
@@ -237,7 +242,7 @@ void ServiceWorkerGlobalScopeProxy::DispatchBackgroundFetchClickEvent(
void ServiceWorkerGlobalScopeProxy::DispatchBackgroundFetchFailEvent(
int event_id,
- const WebBackgroundFetchRegistration& registration) {
+ WebBackgroundFetchRegistration registration) {
DCHECK_CALLED_ON_VALID_THREAD(worker_thread_checker_);
WaitUntilObserver* observer = WaitUntilObserver::Create(
WorkerGlobalScope(), WaitUntilObserver::kBackgroundFetchFail, event_id);
@@ -252,7 +257,7 @@ void ServiceWorkerGlobalScopeProxy::DispatchBackgroundFetchFailEvent(
BackgroundFetchEventInit* init = BackgroundFetchEventInit::Create();
init->setRegistration(MakeGarbageCollected<BackgroundFetchRegistration>(
WorkerGlobalScope()->registration() /* service_worker_registration */,
- registration));
+ std::move(registration)));
BackgroundFetchUpdateUIEvent* event = BackgroundFetchUpdateUIEvent::Create(
event_type_names::kBackgroundfetchfail, init, observer,
@@ -263,7 +268,7 @@ void ServiceWorkerGlobalScopeProxy::DispatchBackgroundFetchFailEvent(
void ServiceWorkerGlobalScopeProxy::DispatchBackgroundFetchSuccessEvent(
int event_id,
- const WebBackgroundFetchRegistration& registration) {
+ WebBackgroundFetchRegistration registration) {
DCHECK_CALLED_ON_VALID_THREAD(worker_thread_checker_);
WaitUntilObserver* observer = WaitUntilObserver::Create(
WorkerGlobalScope(), WaitUntilObserver::kBackgroundFetchSuccess,
@@ -279,7 +284,7 @@ void ServiceWorkerGlobalScopeProxy::DispatchBackgroundFetchSuccessEvent(
BackgroundFetchEventInit* init = BackgroundFetchEventInit::Create();
init->setRegistration(MakeGarbageCollected<BackgroundFetchRegistration>(
WorkerGlobalScope()->registration() /* service_worker_registration */,
- registration));
+ std::move(registration)));
BackgroundFetchUpdateUIEvent* event = BackgroundFetchUpdateUIEvent::Create(
event_type_names::kBackgroundfetchsuccess, init, observer,
@@ -434,8 +439,8 @@ void ServiceWorkerGlobalScopeProxy::OnNavigationPreloadError(
: error->unsanitized_message;
if (!error_message.IsEmpty()) {
WorkerGlobalScope()->AddConsoleMessage(ConsoleMessage::Create(
- kWorkerMessageSource, mojom::ConsoleMessageLevel::kError,
- error_message));
+ mojom::ConsoleMessageSource::kWorker,
+ mojom::ConsoleMessageLevel::kError, error_message));
}
// Reject the preloadResponse promise.
fetch_event->OnNavigationPreloadError(
@@ -613,7 +618,7 @@ void ServiceWorkerGlobalScopeProxy::ReportException(
}
void ServiceWorkerGlobalScopeProxy::ReportConsoleMessage(
- MessageSource source,
+ mojom::ConsoleMessageSource source,
mojom::ConsoleMessageLevel level,
const String& message,
SourceLocation* location) {
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_proxy.h b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_proxy.h
index f841f009a83..9e55234a0f3 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_proxy.h
+++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_global_scope_proxy.h
@@ -83,22 +83,24 @@ class ServiceWorkerGlobalScopeProxy final
void BindServiceWorkerHost(
mojo::ScopedInterfaceEndpointHandle service_worker_host) override;
void SetRegistration(WebServiceWorkerRegistrationObjectInfo info) override;
+ void SetFetchHandlerExistence(
+ FetchHandlerExistence fetch_handler_existence) override;
// Must be called after the above BindServiceWorkerHost() and
// SetRegistration() got called.
void ReadyToEvaluateScript() override;
void DispatchActivateEvent(int) override;
void DispatchBackgroundFetchAbortEvent(
int event_id,
- const WebBackgroundFetchRegistration& registration) override;
+ WebBackgroundFetchRegistration registration) override;
void DispatchBackgroundFetchClickEvent(
int event_id,
- const WebBackgroundFetchRegistration& registration) override;
+ WebBackgroundFetchRegistration registration) override;
void DispatchBackgroundFetchFailEvent(
int event_id,
- const WebBackgroundFetchRegistration& registration) override;
+ WebBackgroundFetchRegistration registration) override;
void DispatchBackgroundFetchSuccessEvent(
int event_id,
- const WebBackgroundFetchRegistration& registration) override;
+ WebBackgroundFetchRegistration registration) override;
void DispatchCookieChangeEvent(
int event_id,
const WebCanonicalCookie& cookie,
@@ -151,7 +153,7 @@ class ServiceWorkerGlobalScopeProxy final
void ReportException(const String& error_message,
std::unique_ptr<SourceLocation>,
int exception_id) override;
- void ReportConsoleMessage(MessageSource,
+ void ReportConsoleMessage(mojom::ConsoleMessageSource,
mojom::ConsoleMessageLevel,
const String& message,
SourceLocation*) override;
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_installed_scripts_manager.cc b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_installed_scripts_manager.cc
index 96e90785cce..aad7f26c6df 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_installed_scripts_manager.cc
+++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_installed_scripts_manager.cc
@@ -34,8 +34,6 @@ class Receiver {
DISALLOW_NEW();
public:
- using BytesChunk = Vector<char>;
-
Receiver(mojo::ScopedDataPipeConsumerHandle handle,
uint64_t total_bytes,
scoped_refptr<base::SingleThreadTaskRunner> task_runner)
@@ -43,7 +41,9 @@ class Receiver {
watcher_(FROM_HERE,
mojo::SimpleWatcher::ArmingPolicy::MANUAL,
std::move(task_runner)),
- remaining_bytes_(total_bytes) {}
+ remaining_bytes_(total_bytes) {
+ data_.ReserveInitialCapacity(SafeCast<wtf_size_t>(total_bytes));
+ }
void Start(base::OnceClosure callback) {
if (!handle_.is_valid()) {
@@ -88,11 +88,9 @@ class Receiver {
return;
}
- if (bytes_read > 0) {
- BytesChunk chunk;
- chunk.Append(static_cast<const char*>(buffer), bytes_read);
- chunks_.emplace_back(std::move(chunk));
- }
+ if (bytes_read > 0)
+ data_.Append(static_cast<const uint8_t*>(buffer), bytes_read);
+
rv = handle_->EndReadData(bytes_read);
DCHECK_EQ(rv, MOJO_RESULT_OK);
CHECK_GE(remaining_bytes_, bytes_read);
@@ -103,9 +101,9 @@ class Receiver {
bool IsRunning() const { return handle_.is_valid(); }
bool HasReceivedAllData() const { return remaining_bytes_ == 0; }
- Vector<BytesChunk> TakeChunks() {
+ Vector<uint8_t> TakeData() {
DCHECK(!IsRunning());
- return std::move(chunks_);
+ return std::move(data_);
}
private:
@@ -113,7 +111,7 @@ class Receiver {
handle_.reset();
watcher_.Cancel();
if (!HasReceivedAllData())
- chunks_.clear();
+ data_.clear();
DCHECK(callback_);
std::move(callback_).Run();
}
@@ -122,7 +120,7 @@ class Receiver {
mojo::ScopedDataPipeConsumerHandle handle_;
mojo::SimpleWatcher watcher_;
- Vector<BytesChunk> chunks_;
+ Vector<uint8_t> data_;
uint64_t remaining_bytes_;
};
@@ -218,9 +216,9 @@ class Internal : public mojom::blink::ServiceWorkerInstalledScriptsManager {
return;
}
- auto script_data = RawScriptData::Create(
- script_info->encoding, receivers->body()->TakeChunks(),
- receivers->meta_data()->TakeChunks());
+ auto script_data = std::make_unique<RawScriptData>(
+ script_info->encoding, receivers->body()->TakeData(),
+ receivers->meta_data()->TakeData());
for (const auto& entry : script_info->headers)
script_data->AddHeader(entry.key, entry.value);
script_container_->AddOnIOThread(script_info->script_url,
@@ -267,6 +265,9 @@ bool ServiceWorkerInstalledScriptsManager::IsScriptInstalled(
std::unique_ptr<InstalledScriptsManager::ScriptData>
ServiceWorkerInstalledScriptsManager::GetScriptData(const KURL& script_url) {
DCHECK(!IsMainThread());
+ TRACE_EVENT1("ServiceWorker",
+ "ServiceWorkerInstalledScriptsManager::GetScriptData", "url",
+ script_url.GetString().Utf8().data());
if (!IsScriptInstalled(script_url))
return nullptr;
@@ -277,30 +278,25 @@ ServiceWorkerInstalledScriptsManager::GetScriptData(const KURL& script_url) {
// This is from WorkerClassicScriptLoader::DidReceiveData.
std::unique_ptr<TextResourceDecoder> decoder =
- TextResourceDecoder::Create(TextResourceDecoderOptions(
+ std::make_unique<TextResourceDecoder>(TextResourceDecoderOptions(
TextResourceDecoderOptions::kPlainTextContent,
raw_script_data->Encoding().IsEmpty()
? UTF8Encoding()
: WTF::TextEncoding(raw_script_data->Encoding())));
- StringBuilder source_text_builder;
- for (const auto& chunk : raw_script_data->ScriptTextChunks())
- source_text_builder.Append(decoder->Decode(chunk.data(), chunk.size()));
+ Vector<uint8_t> source_text = raw_script_data->TakeScriptText();
+ String decoded_source_text = decoder->Decode(
+ reinterpret_cast<const char*>(source_text.data()), source_text.size());
+ // TODO(crbug.com/946676): Remove the unique_ptr<> wrapper around the Vector
+ // as we can just use Vector::IsEmpty() to distinguish missing code cache.
std::unique_ptr<Vector<uint8_t>> meta_data;
- if (raw_script_data->MetaDataChunks().size() > 0) {
- size_t total_metadata_size = 0;
- for (const auto& chunk : raw_script_data->MetaDataChunks())
- total_metadata_size += chunk.size();
- meta_data = std::make_unique<Vector<uint8_t>>();
- meta_data->ReserveInitialCapacity(
- SafeCast<wtf_size_t>(total_metadata_size));
- for (const auto& chunk : raw_script_data->MetaDataChunks())
- meta_data->Append(chunk.data(), static_cast<wtf_size_t>(chunk.size()));
- }
+ Vector<uint8_t> meta_data_in = raw_script_data->TakeMetaData();
+ if (meta_data_in.size() > 0)
+ meta_data = std::make_unique<Vector<uint8_t>>(std::move(meta_data_in));
return std::make_unique<InstalledScriptsManager::ScriptData>(
- script_url, source_text_builder.ToString(), std::move(meta_data),
+ script_url, decoded_source_text, std::move(meta_data),
raw_script_data->TakeHeaders());
}
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_installed_scripts_manager_test.cc b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_installed_scripts_manager_test.cc
index 637064031e2..e266f992cec 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_installed_scripts_manager_test.cc
+++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_installed_scripts_manager_test.cc
@@ -245,16 +245,14 @@ TEST_F(ServiceWorkerInstalledScriptsManagerTest, GetRawScriptData) {
// Wait for the script's arrival.
get_raw_script_data_waiter->Wait();
EXPECT_TRUE(script_data);
- ASSERT_EQ(1u, script_data->ScriptTextChunks().size());
- ASSERT_EQ(kExpectedBody.size() + 1,
- script_data->ScriptTextChunks()[0].size());
+ Vector<uint8_t> script_text = script_data->TakeScriptText();
+ Vector<uint8_t> meta_data = script_data->TakeMetaData();
+ ASSERT_EQ(kExpectedBody.size() + 1, script_text.size());
EXPECT_STREQ(kExpectedBody.data(),
- script_data->ScriptTextChunks()[0].data());
- ASSERT_EQ(1u, script_data->MetaDataChunks().size());
- ASSERT_EQ(kExpectedMetaData.size() + 1,
- script_data->MetaDataChunks()[0].size());
+ reinterpret_cast<const char*>(script_text.data()));
+ ASSERT_EQ(kExpectedMetaData.size() + 1, meta_data.size());
EXPECT_STREQ(kExpectedMetaData.data(),
- script_data->MetaDataChunks()[0].data());
+ reinterpret_cast<const char*>(meta_data.data()));
EXPECT_EQ(kScriptInfoEncoding, script_data->Encoding());
EXPECT_EQ(ToCrossThreadHTTPHeaderMapData(kScriptInfoHeaders),
*(script_data->TakeHeaders()));
@@ -290,16 +288,14 @@ TEST_F(ServiceWorkerInstalledScriptsManagerTest, GetRawScriptData) {
// Wait for the script's arrival.
get_raw_script_data_waiter->Wait();
EXPECT_TRUE(script_data);
- ASSERT_EQ(1u, script_data->ScriptTextChunks().size());
- ASSERT_EQ(kExpectedBody.size() + 1,
- script_data->ScriptTextChunks()[0].size());
+ Vector<uint8_t> script_text = script_data->TakeScriptText();
+ Vector<uint8_t> meta_data = script_data->TakeMetaData();
+ ASSERT_EQ(kExpectedBody.size() + 1, script_text.size());
EXPECT_STREQ(kExpectedBody.data(),
- script_data->ScriptTextChunks()[0].data());
- ASSERT_EQ(1u, script_data->MetaDataChunks().size());
- ASSERT_EQ(kExpectedMetaData.size() + 1,
- script_data->MetaDataChunks()[0].size());
+ reinterpret_cast<const char*>(script_text.data()));
+ ASSERT_EQ(kExpectedMetaData.size() + 1, meta_data.size());
EXPECT_STREQ(kExpectedMetaData.data(),
- script_data->MetaDataChunks()[0].data());
+ reinterpret_cast<const char*>(meta_data.data()));
EXPECT_EQ(kScriptInfoEncoding, script_data->Encoding());
EXPECT_EQ(ToCrossThreadHTTPHeaderMapData(kScriptInfoHeaders),
*(script_data->TakeHeaders()));
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_registration.cc b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_registration.cc
index 1f9aba8b0a0..918c9e28698 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_registration.cc
+++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_registration.cc
@@ -228,7 +228,7 @@ ScriptPromise ServiceWorkerRegistration::update(ScriptState* script_state) {
"Failed to update a ServiceWorkerRegistration: No "
"associated provider is available."));
}
- ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+ auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
host_->Update(
WTF::Bind(&DidUpdate, WrapPersistent(resolver), WrapPersistent(this)));
return resolver->Promise();
@@ -243,7 +243,7 @@ ScriptPromise ServiceWorkerRegistration::unregister(ScriptState* script_state) {
"ServiceWorkerRegistration: No "
"associated provider is available."));
}
- ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+ auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
host_->Unregister(WTF::Bind(&DidUnregister, WrapPersistent(resolver)));
return resolver->Promise();
}
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_script_cached_metadata_handler.cc b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_script_cached_metadata_handler.cc
index fc05eaca6f4..cc887664175 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_script_cached_metadata_handler.cc
+++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_script_cached_metadata_handler.cc
@@ -15,11 +15,12 @@ ServiceWorkerScriptCachedMetadataHandler::
ServiceWorkerScriptCachedMetadataHandler(
WorkerGlobalScope* worker_global_scope,
const KURL& script_url,
- const Vector<uint8_t>* meta_data)
+ std::unique_ptr<Vector<uint8_t>> meta_data)
: worker_global_scope_(worker_global_scope), script_url_(script_url) {
- if (meta_data)
- cached_metadata_ = CachedMetadata::CreateFromSerializedData(
- meta_data->data(), meta_data->size());
+ if (meta_data) {
+ cached_metadata_ =
+ CachedMetadata::CreateFromSerializedData(std::move(*meta_data));
+ }
}
ServiceWorkerScriptCachedMetadataHandler::
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_script_cached_metadata_handler.h b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_script_cached_metadata_handler.h
index d395583226b..46a52fa0d5c 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_script_cached_metadata_handler.h
+++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_script_cached_metadata_handler.h
@@ -22,14 +22,15 @@ class ServiceWorkerScriptCachedMetadataHandler
static ServiceWorkerScriptCachedMetadataHandler* Create(
WorkerGlobalScope* worker_global_scope,
const KURL& script_url,
- const Vector<uint8_t>* meta_data) {
+ std::unique_ptr<Vector<uint8_t>> meta_data) {
return MakeGarbageCollected<ServiceWorkerScriptCachedMetadataHandler>(
- worker_global_scope, script_url, meta_data);
+ worker_global_scope, script_url, std::move(meta_data));
}
- ServiceWorkerScriptCachedMetadataHandler(WorkerGlobalScope*,
- const KURL& script_url,
- const Vector<uint8_t>* meta_data);
+ ServiceWorkerScriptCachedMetadataHandler(
+ WorkerGlobalScope*,
+ const KURL& script_url,
+ std::unique_ptr<Vector<uint8_t>> meta_data);
~ServiceWorkerScriptCachedMetadataHandler() override;
void Trace(blink::Visitor*) override;
void SetCachedMetadata(uint32_t data_type_id,
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_thread.cc b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_thread.cc
index 338ac091918..c0c6a49fe31 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_thread.cc
+++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_thread.cc
@@ -32,11 +32,16 @@
#include <memory>
+#include "third_party/blink/renderer/core/inspector/thread_debugger.h"
#include "third_party/blink/renderer/core/workers/global_scope_creation_params.h"
#include "third_party/blink/renderer/core/workers/worker_backing_thread.h"
#include "third_party/blink/renderer/modules/service_worker/service_worker_global_scope.h"
#include "third_party/blink/renderer/modules/service_worker/service_worker_global_scope_proxy.h"
#include "third_party/blink/renderer/modules/service_worker/service_worker_installed_scripts_manager.h"
+#include "third_party/blink/renderer/platform/cross_thread_functional.h"
+#include "third_party/blink/renderer/platform/loader/fetch/fetch_client_settings_object_snapshot.h"
+#include "third_party/blink/renderer/platform/scheduler/public/post_cross_thread_task.h"
+#include "v8/include/v8-inspector.h"
namespace blink {
@@ -47,8 +52,8 @@ ServiceWorkerThread::ServiceWorkerThread(
mojom::blink::CacheStoragePtrInfo cache_storage_info)
: WorkerThread(*global_scope_proxy),
global_scope_proxy_(global_scope_proxy),
- worker_backing_thread_(
- WorkerBackingThread::Create(ThreadCreationParams(GetThreadType()))),
+ worker_backing_thread_(std::make_unique<WorkerBackingThread>(
+ ThreadCreationParams(GetThreadType()))),
installed_scripts_manager_(std::move(installed_scripts_manager)),
cache_storage_info_(std::move(cache_storage_info)) {}
@@ -69,6 +74,52 @@ void ServiceWorkerThread::TerminateForTesting() {
WorkerThread::TerminateForTesting();
}
+void ServiceWorkerThread::RunInstalledClassicScript(
+ const KURL& script_url,
+ const v8_inspector::V8StackTraceId& stack_id) {
+ // Use TaskType::kDOMManipulation for consistency with
+ // WorkerThread::EvaluateClassicScript().
+ PostCrossThreadTask(
+ *GetTaskRunner(TaskType::kDOMManipulation), FROM_HERE,
+ CrossThreadBind(
+ &ServiceWorkerThread::RunInstalledClassicScriptOnWorkerThread,
+ CrossThreadUnretained(this), script_url, stack_id));
+}
+
+void ServiceWorkerThread::RunInstalledModuleScript(
+ const KURL& module_url_record,
+ const FetchClientSettingsObjectSnapshot& outside_settings_object,
+ network::mojom::FetchCredentialsMode credentials_mode) {
+ PostCrossThreadTask(
+ *GetTaskRunner(TaskType::kDOMManipulation), FROM_HERE,
+ CrossThreadBind(
+ &ServiceWorkerThread::RunInstalledModuleScriptOnWorkerThread,
+ CrossThreadUnretained(this), module_url_record,
+ WTF::Passed(outside_settings_object.CopyData()), credentials_mode));
+}
+
+void ServiceWorkerThread::RunInstalledClassicScriptOnWorkerThread(
+ const KURL& script_url,
+ const v8_inspector::V8StackTraceId& stack_id) {
+ DCHECK(IsCurrentThread());
+ To<ServiceWorkerGlobalScope>(GlobalScope())
+ ->RunInstalledClassicScript(script_url, stack_id);
+}
+
+void ServiceWorkerThread::RunInstalledModuleScriptOnWorkerThread(
+ const KURL& module_url_record,
+ std::unique_ptr<CrossThreadFetchClientSettingsObjectData>
+ outside_settings_object,
+ network::mojom::FetchCredentialsMode credentials_mode) {
+ DCHECK(IsCurrentThread());
+ To<ServiceWorkerGlobalScope>(GlobalScope())
+ ->RunInstalledModuleScript(
+ module_url_record,
+ *MakeGarbageCollected<FetchClientSettingsObjectSnapshot>(
+ std::move(outside_settings_object)),
+ credentials_mode);
+}
+
WorkerOrWorkletGlobalScope* ServiceWorkerThread::CreateWorkerGlobalScope(
std::unique_ptr<GlobalScopeCreationParams> creation_params) {
return ServiceWorkerGlobalScope::Create(this, std::move(creation_params),
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_thread.h b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_thread.h
index 43b427e46d0..2cf6ecf7971 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_thread.h
+++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_thread.h
@@ -59,6 +59,13 @@ class MODULES_EXPORT ServiceWorkerThread final : public WorkerThread {
InstalledScriptsManager* GetInstalledScriptsManager() override;
void TerminateForTesting() override;
+ void RunInstalledClassicScript(const KURL& script_url,
+ const v8_inspector::V8StackTraceId& stack_id);
+ void RunInstalledModuleScript(
+ const KURL& module_url_record,
+ const FetchClientSettingsObjectSnapshot& outside_settings_object,
+ network::mojom::FetchCredentialsMode);
+
private:
WorkerOrWorkletGlobalScope* CreateWorkerGlobalScope(
std::unique_ptr<GlobalScopeCreationParams>) override;
@@ -67,6 +74,15 @@ class MODULES_EXPORT ServiceWorkerThread final : public WorkerThread {
return WebThreadType::kServiceWorkerThread;
}
+ void RunInstalledClassicScriptOnWorkerThread(
+ const KURL& script_url,
+ const v8_inspector::V8StackTraceId& stack_id);
+ void RunInstalledModuleScriptOnWorkerThread(
+ const KURL& module_url_record,
+ std::unique_ptr<CrossThreadFetchClientSettingsObjectData>
+ outside_settings_object,
+ network::mojom::FetchCredentialsMode);
+
Persistent<ServiceWorkerGlobalScopeProxy> global_scope_proxy_;
std::unique_ptr<WorkerBackingThread> worker_backing_thread_;
std::unique_ptr<ServiceWorkerInstalledScriptsManager>
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_window_client.cc b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_window_client.cc
index 72637d13b2d..3cd6cc05fdb 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/service_worker_window_client.cc
+++ b/chromium/third_party/blink/renderer/modules/service_worker/service_worker_window_client.cc
@@ -71,7 +71,7 @@ String ServiceWorkerWindowClient::visibilityState() const {
}
ScriptPromise ServiceWorkerWindowClient::focus(ScriptState* script_state) {
- ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+ auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
ScriptPromise promise = resolver->Promise();
if (!ExecutionContext::From(script_state)->IsWindowInteractionAllowed()) {
@@ -88,7 +88,7 @@ ScriptPromise ServiceWorkerWindowClient::focus(ScriptState* script_state) {
ScriptPromise ServiceWorkerWindowClient::navigate(ScriptState* script_state,
const String& url) {
- ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+ auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
ScriptPromise promise = resolver->Promise();
ExecutionContext* context = ExecutionContext::From(script_state);
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/thread_safe_script_container.cc b/chromium/third_party/blink/renderer/modules/service_worker/thread_safe_script_container.cc
index 4d0db13a062..2596ead94fb 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/thread_safe_script_container.cc
+++ b/chromium/third_party/blink/renderer/modules/service_worker/thread_safe_script_container.cc
@@ -8,19 +8,10 @@
namespace blink {
-// static
-std::unique_ptr<ThreadSafeScriptContainer::RawScriptData>
-ThreadSafeScriptContainer::RawScriptData::Create(const String& encoding,
- Vector<BytesChunk> script_text,
- Vector<BytesChunk> meta_data) {
- return base::WrapUnique(new RawScriptData(encoding, std::move(script_text),
- std::move(meta_data)));
-}
-
ThreadSafeScriptContainer::RawScriptData::RawScriptData(
const String& encoding,
- Vector<BytesChunk> script_text,
- Vector<BytesChunk> meta_data)
+ Vector<uint8_t> script_text,
+ Vector<uint8_t> meta_data)
: encoding_(encoding.IsolatedCopy()),
script_text_(std::move(script_text)),
meta_data_(std::move(meta_data)),
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/thread_safe_script_container.h b/chromium/third_party/blink/renderer/modules/service_worker/thread_safe_script_container.h
index 22069d93198..654849333f3 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/thread_safe_script_container.h
+++ b/chromium/third_party/blink/renderer/modules/service_worker/thread_safe_script_container.h
@@ -47,21 +47,21 @@ class MODULES_EXPORT ThreadSafeScriptContainer
USING_FAST_MALLOC(RawScriptData);
public:
- static std::unique_ptr<RawScriptData> Create(const String& encoding,
- Vector<BytesChunk> script_text,
- Vector<BytesChunk> meta_data);
-
+ RawScriptData(const String& encoding,
+ Vector<uint8_t> script_text,
+ Vector<uint8_t> meta_data);
~RawScriptData();
void AddHeader(const String& key, const String& value);
// The encoding of the script text.
const String& Encoding() const { return encoding_; }
- // An array of raw byte chunks of the script text.
- const Vector<BytesChunk>& ScriptTextChunks() const { return script_text_; }
- // An array of raw byte chunks of the scripts's meta data from the script's
- // V8 code cache.
- const Vector<BytesChunk>& MetaDataChunks() const { return meta_data_; }
+
+ // An array of raw bytes representing the script text.
+ Vector<uint8_t> TakeScriptText() { return std::move(script_text_); }
+
+ // An array of raw bytes representing the cached metadata.
+ Vector<uint8_t> TakeMetaData() { return std::move(meta_data_); }
// The HTTP headers of the script.
std::unique_ptr<CrossThreadHTTPHeaderMapData> TakeHeaders() {
@@ -69,12 +69,9 @@ class MODULES_EXPORT ThreadSafeScriptContainer
}
private:
- RawScriptData(const String& encoding,
- Vector<BytesChunk> script_text,
- Vector<BytesChunk> meta_data);
String encoding_;
- Vector<BytesChunk> script_text_;
- Vector<BytesChunk> meta_data_;
+ Vector<uint8_t> script_text_;
+ Vector<uint8_t> meta_data_;
std::unique_ptr<CrossThreadHTTPHeaderMapData> headers_;
};
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/thread_safe_script_container_test.cc b/chromium/third_party/blink/renderer/modules/service_worker/thread_safe_script_container_test.cc
index d321c139fe6..d4bb1e036c9 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/thread_safe_script_container_test.cc
+++ b/chromium/third_party/blink/renderer/modules/service_worker/thread_safe_script_container_test.cc
@@ -46,10 +46,11 @@ class ThreadSafeScriptContainerTest : public ::testing::Test {
[](scoped_refptr<ThreadSafeScriptContainer> container,
ThreadSafeScriptContainer::RawScriptData** out_data,
base::WaitableEvent* waiter) {
- auto data = ThreadSafeScriptContainer::RawScriptData::Create(
- String::FromUTF8("utf-8") /* encoding */,
- Vector<Vector<char>>() /* script_text */,
- Vector<Vector<char>>() /* meta_data */);
+ auto data =
+ std::make_unique<ThreadSafeScriptContainer::RawScriptData>(
+ String::FromUTF8("utf-8") /* encoding */,
+ Vector<uint8_t>() /* script_text */,
+ Vector<uint8_t>() /* meta_data */);
*out_data = data.get();
container->AddOnIOThread(KURL(kKeyUrl), std::move(data));
waiter->Signal();
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/wait_until_observer.cc b/chromium/third_party/blink/renderer/modules/service_worker/wait_until_observer.cc
index 473f8b106fb..c8ab77268cc 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/wait_until_observer.cc
+++ b/chromium/third_party/blink/renderer/modules/service_worker/wait_until_observer.cc
@@ -111,6 +111,8 @@ WaitUntilObserver* WaitUntilObserver::Create(ExecutionContext* context,
}
void WaitUntilObserver::WillDispatchEvent() {
+ DCHECK(GetExecutionContext());
+
// When handling a notificationclick, paymentrequest, or backgroundfetchclick
// event, we want to allow one window to be focused or opened. These calls are
// allowed between the call to willDispatchEvent() and the last call to
@@ -118,7 +120,7 @@ void WaitUntilObserver::WillDispatchEvent() {
// between willDispatchEvent() and didDispatchEvent().
if (type_ == kNotificationClick || type_ == kPaymentRequest ||
type_ == kBackgroundFetchClick) {
- execution_context_->AllowWindowInteraction();
+ GetExecutionContext()->AllowWindowInteraction();
}
DCHECK_EQ(EventDispatchState::kInitial, event_dispatch_state_);
@@ -132,24 +134,27 @@ void WaitUntilObserver::DidDispatchEvent(bool event_dispatch_failed) {
MaybeCompleteEvent();
}
-void WaitUntilObserver::WaitUntil(ScriptState* script_state,
+// https://w3c.github.io/ServiceWorker/#dom-extendableevent-waituntil
+bool WaitUntilObserver::WaitUntil(ScriptState* script_state,
ScriptPromise script_promise,
ExceptionState& exception_state,
PromiseSettledCallback on_promise_fulfilled,
PromiseSettledCallback on_promise_rejected) {
DCHECK_NE(event_dispatch_state_, EventDispatchState::kInitial);
- if (!IsEventActive(script_state)) {
+ // 1. `If the isTrusted attribute is false, throw an "InvalidStateError"
+ // DOMException.`
+ // This might not yet be implemented.
+
+ // 2. `If not active, throw an "InvalidStateError" DOMException.`
+ if (!IsEventActive()) {
exception_state.ThrowDOMException(
DOMExceptionCode::kInvalidStateError,
"The event handler is already finished and no extend lifetime "
"promises are outstanding.");
- return;
+ return false;
}
- if (!execution_context_)
- return;
-
// When handling a notificationclick event, we want to allow one window to
// be focused or opened. See comments in ::willDispatchEvent(). When
// waitUntil() is being used, opening or closing a window must happen in a
@@ -160,42 +165,33 @@ void WaitUntilObserver::WaitUntil(ScriptState* script_state,
FROM_HERE);
}
+ // 3. `Add f to the extend lifetime promises.`
+ // 4. `Increment the pending promises count by one.`
IncrementPendingPromiseCount();
script_promise.Then(
ThenFunction::CreateFunction(script_state, this, ThenFunction::kFulfilled,
std::move(on_promise_fulfilled)),
ThenFunction::CreateFunction(script_state, this, ThenFunction::kRejected,
std::move(on_promise_rejected)));
+ return true;
}
-bool WaitUntilObserver::IsEventActive(ScriptState* script_state) const {
- if (pending_promises_ > 0)
- return true;
+// https://w3c.github.io/ServiceWorker/#extendableevent-active
+bool WaitUntilObserver::IsEventActive() const {
+ // `An ExtendableEvent object is said to be active when its timed out flag is
+ // unset and either its pending promises count is greater than zero or its
+ // dispatch flag is set.`
+ return pending_promises_ > 0 || IsDispatchingEvent();
+}
- switch (event_dispatch_state_) {
- case EventDispatchState::kDispatching:
- // DidDispatchEvent() is called after both the event handler
- // execution finished and microtasks queued by the event handler execution
- // finished, it's hard to get the precise time point between the 2
- // execution phases.
- // So even in EventDispatchState::kDispatching state at this time point,
- // running microtask indicates that event handler execution has actually
- // finished, in such case if there aren't any outstanding extend lifetime
- // promises.
- return !v8::MicrotasksScope::IsRunningMicrotasks(
- script_state->GetIsolate());
- case EventDispatchState::kInitial:
- case EventDispatchState::kDispatched:
- case EventDispatchState::kFailed:
- return false;
- }
- NOTREACHED();
+bool WaitUntilObserver::IsDispatchingEvent() const {
+ return event_dispatch_state_ == EventDispatchState::kDispatching;
}
WaitUntilObserver::WaitUntilObserver(ExecutionContext* context,
EventType type,
int event_id)
- : execution_context_(context),
+ : ContextClient(context),
type_(type),
event_id_(event_id),
consume_window_interaction_timer_(
@@ -223,7 +219,7 @@ void WaitUntilObserver::DecrementPendingPromiseCount() {
}
void WaitUntilObserver::MaybeCompleteEvent() {
- if (!execution_context_)
+ if (!GetExecutionContext())
return;
switch (event_dispatch_state_) {
@@ -246,7 +242,7 @@ void WaitUntilObserver::MaybeCompleteEvent() {
}
ServiceWorkerGlobalScopeClient* client =
- ServiceWorkerGlobalScopeClient::From(execution_context_);
+ ServiceWorkerGlobalScopeClient::From(GetExecutionContext());
mojom::ServiceWorkerEventStatus status =
(event_dispatch_state_ == EventDispatchState::kFailed ||
has_rejected_promise_)
@@ -269,7 +265,8 @@ void WaitUntilObserver::MaybeCompleteEvent() {
client->DidHandleFetchEvent(event_id_, status);
break;
case kInstall:
- To<ServiceWorkerGlobalScope>(*execution_context_).SetIsInstalling(false);
+ To<ServiceWorkerGlobalScope>(*GetExecutionContext())
+ .SetIsInstalling(false);
client->DidHandleInstallEvent(event_id_, status);
break;
case kMessage:
@@ -305,17 +302,15 @@ void WaitUntilObserver::MaybeCompleteEvent() {
client->DidHandleBackgroundFetchSuccessEvent(event_id_, status);
break;
}
- execution_context_ = nullptr;
}
void WaitUntilObserver::ConsumeWindowInteraction(TimerBase*) {
- if (!execution_context_)
- return;
- execution_context_->ConsumeWindowInteraction();
+ if (ExecutionContext* context = GetExecutionContext())
+ context->ConsumeWindowInteraction();
}
void WaitUntilObserver::Trace(blink::Visitor* visitor) {
- visitor->Trace(execution_context_);
+ ContextClient::Trace(visitor);
}
} // namespace blink
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/wait_until_observer.h b/chromium/third_party/blink/renderer/modules/service_worker/wait_until_observer.h
index 2f025fc8070..4a80d125d2e 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/wait_until_observer.h
+++ b/chromium/third_party/blink/renderer/modules/service_worker/wait_until_observer.h
@@ -6,6 +6,7 @@
#define THIRD_PARTY_BLINK_RENDERER_MODULES_SERVICE_WORKER_WAIT_UNTIL_OBSERVER_H_
#include "base/callback.h"
+#include "third_party/blink/renderer/core/execution_context/context_lifecycle_observer.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/modules/service_worker/service_worker_global_scope_client.h"
#include "third_party/blink/renderer/platform/timer.h"
@@ -14,14 +15,16 @@
namespace blink {
class ExceptionState;
-class ExecutionContext;
class ScriptPromise;
class ScriptState;
class ScriptValue;
// Created for each ExtendableEvent instance.
class MODULES_EXPORT WaitUntilObserver final
- : public GarbageCollectedFinalized<WaitUntilObserver> {
+ : public GarbageCollectedFinalized<WaitUntilObserver>,
+ public ContextClient {
+ USING_GARBAGE_COLLECTED_MIXIN(WaitUntilObserver);
+
public:
using PromiseSettledCallback =
base::RepeatingCallback<void(const ScriptValue&)>;
@@ -58,13 +61,19 @@ class MODULES_EXPORT WaitUntilObserver final
void DidDispatchEvent(bool event_dispatch_failed);
// Observes the promise and delays reporting to ServiceWorkerGlobalScopeClient
- // that the event completed until the given promise is resolved or rejected.
+ // that the event completed until the promise is resolved or rejected.
+ //
// WaitUntil may be called multiple times. The event is extended until all
// promises have settled.
+ //
// If provided, |on_promise_fulfilled| or |on_promise_rejected| is invoked
// once |script_promise| fulfills or rejects. This enables the caller to do
// custom handling.
- void WaitUntil(
+ //
+ // If the event is not active, throws a DOMException and returns false. In
+ // this case the promise is ignored, and |on_promise_fulfilled| and
+ // |on_promise_rejected| will not be called.
+ bool WaitUntil(
ScriptState*,
ScriptPromise /* script_promise */,
ExceptionState&,
@@ -73,9 +82,15 @@ class MODULES_EXPORT WaitUntilObserver final
// Whether the associated event is active.
// https://w3c.github.io/ServiceWorker/#extendableevent-active.
- bool IsEventActive(ScriptState* script_state) const;
+ bool IsEventActive() const;
+
+ // Whether the event is being dispatched, i.e., the event handler
+ // is being run.
+ // https://dom.spec.whatwg.org/#dispatch-flag
+ // TODO(falken): Can this just use Event::IsBeingDispatched?
+ bool IsDispatchingEvent() const;
- virtual void Trace(blink::Visitor*);
+ void Trace(blink::Visitor*) override;
private:
friend class InternalsServiceWorker;
@@ -108,7 +123,6 @@ class MODULES_EXPORT WaitUntilObserver final
void MaybeCompleteEvent();
- Member<ExecutionContext> execution_context_;
EventType type_;
int event_id_;
int pending_promises_ = 0;
diff --git a/chromium/third_party/blink/renderer/modules/service_worker/web_embedded_worker_impl_test.cc b/chromium/third_party/blink/renderer/modules/service_worker/web_embedded_worker_impl_test.cc
index 8153e348947..1ae16b666e3 100644
--- a/chromium/third_party/blink/renderer/modules/service_worker/web_embedded_worker_impl_test.cc
+++ b/chromium/third_party/blink/renderer/modules/service_worker/web_embedded_worker_impl_test.cc
@@ -6,15 +6,20 @@
#include <memory>
+#include "base/feature_list.h"
#include "base/synchronization/waitable_event.h"
+#include "base/test/scoped_feature_list.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/common/messaging/message_port_channel.h"
+#include "third_party/blink/public/mojom/service_worker/controller_service_worker_mode.mojom-blink.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_installed_scripts_manager.mojom-blink.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_object.mojom-blink.h"
#include "third_party/blink/public/platform/modules/service_worker/web_service_worker_network_provider.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/web_content_settings_client.h"
+#include "third_party/blink/public/platform/web_url_loader_client.h"
#include "third_party/blink/public/platform/web_url_loader_mock_factory.h"
#include "third_party/blink/public/platform/web_url_response.h"
#include "third_party/blink/public/web/modules/service_worker/web_service_worker_context_client.h"
@@ -25,14 +30,17 @@
#include "third_party/blink/renderer/modules/service_worker/thread_safe_script_container.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_error.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
+#include "third_party/blink/renderer/platform/scheduler/test/fake_task_runner.h"
#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
#include "third_party/blink/renderer/platform/testing/url_test_helpers.h"
namespace blink {
namespace {
+const char* kNotFoundScriptURL = "https://www.example.com/sw-404.js";
+
// Fake network provider for service worker execution contexts.
-class FakeServiceWorkerNetworkProvider
+class FakeServiceWorkerNetworkProvider final
: public WebServiceWorkerNetworkProvider {
public:
FakeServiceWorkerNetworkProvider() = default;
@@ -62,7 +70,85 @@ class FakeServiceWorkerNetworkProvider
void DispatchNetworkQuiet() override {}
};
-class MockServiceWorkerContextClient : public WebServiceWorkerContextClient {
+// A fake WebURLLoader which is used for off-main-thread script fetch tests.
+class FakeWebURLLoader final : public WebURLLoader {
+ public:
+ FakeWebURLLoader() {}
+ ~FakeWebURLLoader() override = default;
+
+ void LoadSynchronously(const WebURLRequest&,
+ WebURLLoaderClient*,
+ WebURLResponse&,
+ base::Optional<WebURLError>&,
+ WebData&,
+ int64_t& encoded_data_length,
+ int64_t& encoded_body_length,
+ WebBlobInfo& downloaded_blob) override {
+ NOTREACHED();
+ }
+
+ void LoadAsynchronously(const WebURLRequest& request,
+ WebURLLoaderClient* client) override {
+ if (request.Url().GetString() == kNotFoundScriptURL) {
+ WebURLResponse response;
+ response.SetMimeType("text/javascript");
+ response.SetHttpStatusCode(404);
+ client->DidReceiveResponse(response);
+ client->DidFinishLoading(TimeTicks(), 0, 0, 0, false, {});
+ return;
+ }
+ // Don't handle other requests intentionally to emulate ongoing load.
+ }
+
+ void Cancel() override {}
+ void SetDefersLoading(bool defers) override {}
+ void DidChangePriority(WebURLRequest::Priority, int) override {}
+ scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner() override {
+ return base::MakeRefCounted<scheduler::FakeTaskRunner>();
+ }
+};
+
+// A fake WebURLLoaderFactory which is used for off-main-thread script fetch
+// tests.
+class FakeWebURLLoaderFactory final : public WebURLLoaderFactory {
+ public:
+ std::unique_ptr<WebURLLoader> CreateURLLoader(
+ const WebURLRequest&,
+ std::unique_ptr<scheduler::WebResourceLoadingTaskRunnerHandle>) override {
+ return std::make_unique<FakeWebURLLoader>();
+ }
+};
+
+// A fake WebWorkerFetchContext which is used for off-main-thread script fetch
+// tests.
+class FakeWebWorkerFetchContext final : public WebWorkerFetchContext {
+ public:
+ void SetTerminateSyncLoadEvent(base::WaitableEvent*) override {}
+ void InitializeOnWorkerThread(AcceptLanguagesWatcher*) override {}
+ WebURLLoaderFactory* GetURLLoaderFactory() override {
+ return &fake_web_url_loader_factory_;
+ }
+ std::unique_ptr<WebURLLoaderFactory> WrapURLLoaderFactory(
+ mojo::ScopedMessagePipeHandle url_loader_factory_handle) override {
+ return nullptr;
+ }
+ void WillSendRequest(WebURLRequest&) override {}
+ mojom::ControllerServiceWorkerMode IsControlledByServiceWorker()
+ const override {
+ return mojom::ControllerServiceWorkerMode::kNoController;
+ }
+ WebURL SiteForCookies() const override { return WebURL(); }
+ base::Optional<WebSecurityOrigin> TopFrameOrigin() const override {
+ return base::Optional<WebSecurityOrigin>();
+ }
+ WebString GetAcceptLanguages() const override { return WebString(); }
+
+ private:
+ FakeWebURLLoaderFactory fake_web_url_loader_factory_;
+};
+
+class MockServiceWorkerContextClient final
+ : public WebServiceWorkerContextClient {
public:
MockServiceWorkerContextClient() = default;
~MockServiceWorkerContextClient() override = default;
@@ -78,6 +164,14 @@ class MockServiceWorkerContextClient : public WebServiceWorkerContextClient {
// message.
proxy->ReadyToEvaluateScript();
}
+
+ void FailedToLoadClassicScript() override {
+ // off-main-script fetch:
+ // In production code, calling FailedToLoadClassicScript results in
+ // terminating the worker.
+ classic_script_load_failure_event_.Signal();
+ }
+
void DidEvaluateScript(bool /* success */) override {
script_evaluated_event_.Signal();
}
@@ -86,14 +180,26 @@ class MockServiceWorkerContextClient : public WebServiceWorkerContextClient {
CreateServiceWorkerNetworkProviderOnMainThread() override {
return std::make_unique<FakeServiceWorkerNetworkProvider>();
}
+
+ scoped_refptr<WebWorkerFetchContext>
+ CreateServiceWorkerFetchContextOnMainThread(
+ WebServiceWorkerNetworkProvider* network_provider) override {
+ return base::MakeRefCounted<FakeWebWorkerFetchContext>();
+ }
+
void WorkerContextDestroyed() override { termination_event_.Signal(); }
+ // These methods must be called on the main thread.
void WaitUntilScriptEvaluated() { script_evaluated_event_.Wait(); }
void WaitUntilThreadTermination() { termination_event_.Wait(); }
+ void WaitUntilFailedToLoadClassicScript() {
+ classic_script_load_failure_event_.Wait();
+ }
private:
base::WaitableEvent script_evaluated_event_;
base::WaitableEvent termination_event_;
+ base::WaitableEvent classic_script_load_failure_event_;
};
class MockServiceWorkerInstalledScriptsManager
@@ -123,18 +229,17 @@ class MockServiceWorkerInstalledScriptsManager
class WebEmbeddedWorkerImplTest : public testing::Test {
protected:
void SetUp() override {
- auto client = std::make_unique<MockServiceWorkerContextClient>();
auto installed_scripts_manager =
std::make_unique<MockServiceWorkerInstalledScriptsManager>();
- mock_client_ = client.get();
mock_installed_scripts_manager_ = installed_scripts_manager.get();
+ mock_client_ = std::make_unique<MockServiceWorkerContextClient>();
worker_ = WebEmbeddedWorkerImpl::CreateForTesting(
- std::move(client), std::move(installed_scripts_manager));
+ mock_client_.get(), std::move(installed_scripts_manager));
WebURL script_url =
url_test_helpers::ToKURL("https://www.example.com/sw.js");
WebURLResponse response(script_url);
- response.SetMIMEType("text/javascript");
+ response.SetMimeType("text/javascript");
response.SetHttpStatusCode(200);
Platform::Current()->GetURLLoaderMockFactory()->RegisterURL(script_url,
response, "");
@@ -156,7 +261,7 @@ class WebEmbeddedWorkerImplTest : public testing::Test {
}
WebEmbeddedWorkerStartData start_data_;
- MockServiceWorkerContextClient* mock_client_;
+ std::unique_ptr<MockServiceWorkerContextClient> mock_client_;
MockServiceWorkerInstalledScriptsManager* mock_installed_scripts_manager_;
std::unique_ptr<WebEmbeddedWorkerImpl> worker_;
};
@@ -164,28 +269,69 @@ class WebEmbeddedWorkerImplTest : public testing::Test {
} // namespace
TEST_F(WebEmbeddedWorkerImplTest, TerminateSoonAfterStart) {
+ base::test::ScopedFeatureList scoped_list;
+ scoped_list.InitAndDisableFeature(
+ features::kOffMainThreadServiceWorkerScriptFetch);
+
EXPECT_CALL(*mock_client_, WorkerReadyForInspectionOnMainThread()).Times(1);
worker_->StartWorkerContext(start_data_);
- testing::Mock::VerifyAndClearExpectations(mock_client_);
+ testing::Mock::VerifyAndClearExpectations(mock_client_.get());
EXPECT_CALL(*mock_client_, WorkerContextFailedToStartOnMainThread()).Times(1);
worker_->TerminateWorkerContext();
- testing::Mock::VerifyAndClearExpectations(mock_client_);
+ testing::Mock::VerifyAndClearExpectations(mock_client_.get());
+}
+
+TEST_F(WebEmbeddedWorkerImplTest, TerminateSoonAfterStart_OMT_Fetch) {
+ base::test::ScopedFeatureList scoped_list;
+ scoped_list.InitAndEnableFeature(
+ features::kOffMainThreadServiceWorkerScriptFetch);
+
+ EXPECT_CALL(*mock_client_, WorkerReadyForInspectionOnMainThread()).Times(1);
+ worker_->StartWorkerContext(start_data_);
+ testing::Mock::VerifyAndClearExpectations(mock_client_.get());
+
+ worker_->TerminateWorkerContext();
+ // The worker thread was started. Wait for shutdown tasks to finish.
+ worker_->WaitForShutdownForTesting();
}
TEST_F(WebEmbeddedWorkerImplTest, TerminateWhileWaitingForDebugger) {
+ base::test::ScopedFeatureList scoped_list;
+ scoped_list.InitAndDisableFeature(
+ features::kOffMainThreadServiceWorkerScriptFetch);
+
EXPECT_CALL(*mock_client_, WorkerReadyForInspectionOnMainThread()).Times(1);
start_data_.wait_for_debugger_mode =
WebEmbeddedWorkerStartData::kWaitForDebugger;
worker_->StartWorkerContext(start_data_);
- testing::Mock::VerifyAndClearExpectations(mock_client_);
+ testing::Mock::VerifyAndClearExpectations(mock_client_.get());
EXPECT_CALL(*mock_client_, WorkerContextFailedToStartOnMainThread()).Times(1);
worker_->TerminateWorkerContext();
- testing::Mock::VerifyAndClearExpectations(mock_client_);
+ testing::Mock::VerifyAndClearExpectations(mock_client_.get());
+}
+
+TEST_F(WebEmbeddedWorkerImplTest, TerminateWhileWaitingForDebugger_OMT_Fetch) {
+ base::test::ScopedFeatureList scoped_list;
+ scoped_list.InitAndEnableFeature(
+ features::kOffMainThreadServiceWorkerScriptFetch);
+
+ EXPECT_CALL(*mock_client_, WorkerReadyForInspectionOnMainThread()).Times(1);
+ start_data_.wait_for_debugger_mode =
+ WebEmbeddedWorkerStartData::kWaitForDebugger;
+ worker_->StartWorkerContext(start_data_);
+ testing::Mock::VerifyAndClearExpectations(mock_client_.get());
+
+ worker_->TerminateWorkerContext();
+ // The worker thread isn't started yet so we don't have to wait for shutdown.
}
TEST_F(WebEmbeddedWorkerImplTest, TerminateWhileLoadingScript) {
+ base::test::ScopedFeatureList scoped_list;
+ scoped_list.InitAndDisableFeature(
+ features::kOffMainThreadServiceWorkerScriptFetch);
+
// Load the shadow page.
EXPECT_CALL(*mock_client_, WorkerReadyForInspectionOnMainThread()).Times(1);
EXPECT_CALL(*mock_installed_scripts_manager_,
@@ -193,16 +339,45 @@ TEST_F(WebEmbeddedWorkerImplTest, TerminateWhileLoadingScript) {
.Times(testing::AtLeast(1))
.WillRepeatedly(testing::Return(false));
worker_->StartWorkerContext(start_data_);
- testing::Mock::VerifyAndClearExpectations(mock_client_);
+ testing::Mock::VerifyAndClearExpectations(mock_client_.get());
testing::Mock::VerifyAndClearExpectations(mock_installed_scripts_manager_);
// Terminate before loading the script.
EXPECT_CALL(*mock_client_, WorkerContextFailedToStartOnMainThread()).Times(1);
worker_->TerminateWorkerContext();
- testing::Mock::VerifyAndClearExpectations(mock_client_);
+ testing::Mock::VerifyAndClearExpectations(mock_client_.get());
+}
+
+TEST_F(WebEmbeddedWorkerImplTest, TerminateWhileLoadingScript_OMT_Fetch) {
+ base::test::ScopedFeatureList scoped_list;
+ scoped_list.InitAndEnableFeature(
+ features::kOffMainThreadServiceWorkerScriptFetch);
+
+ // Load the shadow page.
+ EXPECT_CALL(*mock_client_, WorkerReadyForInspectionOnMainThread()).Times(1);
+ EXPECT_CALL(*mock_installed_scripts_manager_,
+ IsScriptInstalled(KURL(start_data_.script_url)))
+ .Times(testing::AtLeast(1))
+ .WillRepeatedly(testing::Return(false));
+ worker_->StartWorkerContext(start_data_);
+ testing::Mock::VerifyAndClearExpectations(mock_client_.get());
+ testing::Mock::VerifyAndClearExpectations(mock_installed_scripts_manager_);
+
+ // Terminate before finishing the script load.
+ worker_->TerminateWorkerContext();
+ // The worker thread was started. Wait for shutdown tasks to finish.
+ worker_->WaitForShutdownForTesting();
}
+// Tests terminating worker context between script download and execution.
+// No "OMT_Fetch" variant for this test because "pause after download" doesn't
+// have effect for off-main-thread script fetch. When off-main-thread fetch
+// is on, pausing/resuming is handled in ServiceWorkerGlobalScope.
TEST_F(WebEmbeddedWorkerImplTest, TerminateWhilePausedAfterDownload) {
+ base::test::ScopedFeatureList scoped_list;
+ scoped_list.InitAndDisableFeature(
+ features::kOffMainThreadServiceWorkerScriptFetch);
+
// Load the shadow page.
start_data_.pause_after_download_mode =
WebEmbeddedWorkerStartData::kPauseAfterDownload;
@@ -212,26 +387,29 @@ TEST_F(WebEmbeddedWorkerImplTest, TerminateWhilePausedAfterDownload) {
.Times(testing::AtLeast(1))
.WillRepeatedly(testing::Return(false));
worker_->StartWorkerContext(start_data_);
- testing::Mock::VerifyAndClearExpectations(mock_client_);
+ testing::Mock::VerifyAndClearExpectations(mock_client_.get());
testing::Mock::VerifyAndClearExpectations(mock_installed_scripts_manager_);
// Load the script.
EXPECT_CALL(*mock_client_, WorkerScriptLoadedOnMainThread()).Times(1);
Platform::Current()->GetURLLoaderMockFactory()->ServeAsynchronousRequests();
- testing::Mock::VerifyAndClearExpectations(mock_client_);
+ testing::Mock::VerifyAndClearExpectations(mock_client_.get());
// Terminate before resuming after download.
EXPECT_CALL(*mock_client_, WorkerContextFailedToStartOnMainThread()).Times(1);
worker_->TerminateWorkerContext();
- testing::Mock::VerifyAndClearExpectations(mock_client_);
+ testing::Mock::VerifyAndClearExpectations(mock_client_.get());
}
TEST_F(WebEmbeddedWorkerImplTest, ScriptNotFound) {
+ base::test::ScopedFeatureList scoped_list;
+ scoped_list.InitAndDisableFeature(
+ features::kOffMainThreadServiceWorkerScriptFetch);
+
// Load the shadow page.
- WebURL script_url =
- url_test_helpers::ToKURL("https://www.example.com/sw-404.js");
+ WebURL script_url = url_test_helpers::ToKURL(kNotFoundScriptURL);
WebURLResponse response;
- response.SetMIMEType("text/javascript");
+ response.SetMimeType("text/javascript");
response.SetHttpStatusCode(404);
ResourceError error = ResourceError::Failure(script_url);
Platform::Current()->GetURLLoaderMockFactory()->RegisterErrorURL(
@@ -243,24 +421,61 @@ TEST_F(WebEmbeddedWorkerImplTest, ScriptNotFound) {
.Times(testing::AtLeast(1))
.WillRepeatedly(testing::Return(false));
worker_->StartWorkerContext(start_data_);
- testing::Mock::VerifyAndClearExpectations(mock_client_);
+ testing::Mock::VerifyAndClearExpectations(mock_client_.get());
testing::Mock::VerifyAndClearExpectations(mock_installed_scripts_manager_);
// Load the script.
EXPECT_CALL(*mock_client_, WorkerScriptLoadedOnMainThread()).Times(0);
EXPECT_CALL(*mock_client_, WorkerContextFailedToStartOnMainThread()).Times(1);
Platform::Current()->GetURLLoaderMockFactory()->ServeAsynchronousRequests();
- testing::Mock::VerifyAndClearExpectations(mock_client_);
+ testing::Mock::VerifyAndClearExpectations(mock_client_.get());
+}
+
+TEST_F(WebEmbeddedWorkerImplTest, ScriptNotFound_OMT_Fetch) {
+ base::test::ScopedFeatureList scoped_list;
+ scoped_list.InitAndEnableFeature(
+ features::kOffMainThreadServiceWorkerScriptFetch);
+
+ // Load the shadow page.
+ WebURL script_url = url_test_helpers::ToKURL(kNotFoundScriptURL);
+ WebURLResponse response;
+ response.SetMimeType("text/javascript");
+ response.SetHttpStatusCode(404);
+ ResourceError error = ResourceError::Failure(script_url);
+ Platform::Current()->GetURLLoaderMockFactory()->RegisterErrorURL(
+ script_url, response, error);
+ start_data_.script_url = script_url;
+ EXPECT_CALL(*mock_client_, WorkerReadyForInspectionOnMainThread()).Times(1);
+ EXPECT_CALL(*mock_installed_scripts_manager_,
+ IsScriptInstalled(KURL(start_data_.script_url)))
+ .Times(testing::AtLeast(1))
+ .WillRepeatedly(testing::Return(false));
+ // Start worker and load the script.
+ worker_->StartWorkerContext(start_data_);
+ testing::Mock::VerifyAndClearExpectations(mock_client_.get());
+ testing::Mock::VerifyAndClearExpectations(mock_installed_scripts_manager_);
+
+ mock_client_->WaitUntilFailedToLoadClassicScript();
+
+ // The worker thread was started. Ask to shutdown and wait for shutdown
+ // tasks to finish.
+ worker_->TerminateWorkerContext();
+ worker_->WaitForShutdownForTesting();
}
// The running worker is detected as a memory leak. crbug.com/586897 and
// crbug.com/807754.
+// No "OMT_Fetch" variant. See comments on TerminateWhilePausedAfterDownload.
#if defined(ADDRESS_SANITIZER)
#define MAYBE_DontPauseAfterDownload DISABLED_DontPauseAfterDownload
#else
#define MAYBE_DontPauseAfterDownload DontPauseAfterDownload
#endif
TEST_F(WebEmbeddedWorkerImplTest, MAYBE_DontPauseAfterDownload) {
+ base::test::ScopedFeatureList scoped_list;
+ scoped_list.InitAndDisableFeature(
+ features::kOffMainThreadServiceWorkerScriptFetch);
+
// Load the shadow page.
EXPECT_CALL(*mock_client_, WorkerReadyForInspectionOnMainThread()).Times(1);
EXPECT_CALL(*mock_installed_scripts_manager_,
@@ -268,7 +483,7 @@ TEST_F(WebEmbeddedWorkerImplTest, MAYBE_DontPauseAfterDownload) {
.Times(testing::AtLeast(1))
.WillRepeatedly(testing::Return(false));
worker_->StartWorkerContext(start_data_);
- testing::Mock::VerifyAndClearExpectations(mock_client_);
+ testing::Mock::VerifyAndClearExpectations(mock_client_.get());
testing::Mock::VerifyAndClearExpectations(mock_installed_scripts_manager_);
// Load the script.
@@ -280,7 +495,7 @@ TEST_F(WebEmbeddedWorkerImplTest, MAYBE_DontPauseAfterDownload) {
.WillRepeatedly(testing::Return(false));
Platform::Current()->GetURLLoaderMockFactory()->ServeAsynchronousRequests();
mock_client_->WaitUntilScriptEvaluated();
- testing::Mock::VerifyAndClearExpectations(mock_client_);
+ testing::Mock::VerifyAndClearExpectations(mock_client_.get());
testing::Mock::VerifyAndClearExpectations(mock_installed_scripts_manager_);
// Terminate the running worker thread.
@@ -291,12 +506,17 @@ TEST_F(WebEmbeddedWorkerImplTest, MAYBE_DontPauseAfterDownload) {
// The running worker is detected as a memory leak. crbug.com/586897 and
// crbug.com/807754.
+// No "OMT_Fetch" variant. See comments on TerminateWhilePausedAfterDownload.
#if defined(ADDRESS_SANITIZER)
#define MAYBE_PauseAfterDownload DISABLED_PauseAfterDownload
#else
#define MAYBE_PauseAfterDownload PauseAfterDownload
#endif
TEST_F(WebEmbeddedWorkerImplTest, MAYBE_PauseAfterDownload) {
+ base::test::ScopedFeatureList scoped_list;
+ scoped_list.InitAndDisableFeature(
+ features::kOffMainThreadServiceWorkerScriptFetch);
+
// Load the shadow page.
EXPECT_CALL(*mock_client_, WorkerReadyForInspectionOnMainThread()).Times(1);
EXPECT_CALL(*mock_installed_scripts_manager_,
@@ -306,13 +526,13 @@ TEST_F(WebEmbeddedWorkerImplTest, MAYBE_PauseAfterDownload) {
start_data_.pause_after_download_mode =
WebEmbeddedWorkerStartData::kPauseAfterDownload;
worker_->StartWorkerContext(start_data_);
- testing::Mock::VerifyAndClearExpectations(mock_client_);
+ testing::Mock::VerifyAndClearExpectations(mock_client_.get());
testing::Mock::VerifyAndClearExpectations(mock_installed_scripts_manager_);
// Load the script.
EXPECT_CALL(*mock_client_, WorkerScriptLoadedOnMainThread()).Times(1);
Platform::Current()->GetURLLoaderMockFactory()->ServeAsynchronousRequests();
- testing::Mock::VerifyAndClearExpectations(mock_client_);
+ testing::Mock::VerifyAndClearExpectations(mock_client_.get());
// Resume after download.
// This is called on the worker thread.
@@ -322,7 +542,7 @@ TEST_F(WebEmbeddedWorkerImplTest, MAYBE_PauseAfterDownload) {
.WillRepeatedly(testing::Return(false));
worker_->ResumeAfterDownload();
mock_client_->WaitUntilScriptEvaluated();
- testing::Mock::VerifyAndClearExpectations(mock_client_);
+ testing::Mock::VerifyAndClearExpectations(mock_client_.get());
testing::Mock::VerifyAndClearExpectations(mock_installed_scripts_manager_);
// Terminate the running worker thread.