From 60bb3c8c86168ba50685231ef9377f8f5508deee Mon Sep 17 00:00:00 2001 From: Luca Greco Date: Fri, 5 Nov 2021 20:27:01 +0000 Subject: [PATCH] Bug 1728326 - Notify WebExtensions internals when a background service worker scripts has been executed. r=asuth This patch includes changes needed to notify the WebExtensions internals when a background service worker script has been fully loaded, through a NotifyWorkerLoadedRunnable (dispatched as low priority) that calls a new mozIExtensionAPIRequestHandler.onExtensionWorkerLoaded method. Differential Revision: https://phabricator.services.mozilla.com/D124701 --- dom/workers/WorkerPrivate.cpp | 16 +++++++++++++- .../mozIExtensionAPIRequestHandling.idl | 10 +++++++++ .../ExtensionAPIRequestForwarder.cpp | 18 +++++++++++++++ .../webidl-api/ExtensionAPIRequestForwarder.h | 22 +++++++++++++++++++ .../webidl-api/ExtensionBrowser.cpp | 8 +++++++ .../extensions/webidl-api/ExtensionBrowser.h | 4 ++++ 6 files changed, 77 insertions(+), 1 deletion(-) diff --git a/dom/workers/WorkerPrivate.cpp b/dom/workers/WorkerPrivate.cpp index 4b5bf68348174..9d3b8cd07f154 100644 --- a/dom/workers/WorkerPrivate.cpp +++ b/dom/workers/WorkerPrivate.cpp @@ -52,7 +52,7 @@ #include "mozilla/dom/WorkerBinding.h" #include "mozilla/dom/JSExecutionManager.h" #include "mozilla/dom/WindowContext.h" -#include "mozilla/extensions/ExtensionBrowser.h" // extensions::Create{AndDispatchInitWorkerContext,WorkerDestroyed}Runnable +#include "mozilla/extensions/ExtensionBrowser.h" // extensions::Create{AndDispatchInitWorkerContext,WorkerLoaded,WorkerDestroyed}Runnable #include "mozilla/extensions/WebExtensionPolicy.h" #include "mozilla/StorageAccess.h" #include "mozilla/StoragePrincipalHelper.h" @@ -369,6 +369,20 @@ class CompileScriptRunnable final : public WorkerDebuggeeRunnable { ErrorResult rv; workerinternals::LoadMainScript(aWorkerPrivate, std::move(mOriginStack), mScriptURL, WorkerScript, rv); + + if (aWorkerPrivate->ExtensionAPIAllowed()) { + MOZ_ASSERT(aWorkerPrivate->IsServiceWorker()); + RefPtr extWorkerRunnable = + extensions::CreateWorkerLoadedRunnable( + aWorkerPrivate->ServiceWorkerID(), aWorkerPrivate->GetBaseURI()); + // Dispatch as a low priority runnable. + if (NS_FAILED(aWorkerPrivate->DispatchToMainThreadForMessaging( + extWorkerRunnable.forget()))) { + NS_WARNING( + "Failed to dispatch runnable to notify extensions worker loaded"); + } + } + rv.WouldReportJSException(); // Explicitly ignore NS_BINDING_ABORTED on rv. Or more precisely, still // return false and don't SetWorkerScriptExecutedSuccessfully() in that diff --git a/toolkit/components/extensions/mozIExtensionAPIRequestHandling.idl b/toolkit/components/extensions/mozIExtensionAPIRequestHandling.idl index 3b8d20c226b48..8d71272aa03f3 100644 --- a/toolkit/components/extensions/mozIExtensionAPIRequestHandling.idl +++ b/toolkit/components/extensions/mozIExtensionAPIRequestHandling.idl @@ -171,6 +171,16 @@ interface mozIExtensionAPIRequestHandler : nsISupports void initExtensionWorker(in nsISupports extension, in mozIExtensionServiceWorkerInfo serviceWorkerInfo); + /** + * A method called when an extension background service worker has loaded its + * main script. + * + * @param extension An instance of the WebExtensionPolicy webidl interface. + * @param serviceWorkerDescriptorId + */ + void onExtensionWorkerLoaded(in nsISupports extension, + in unsigned long long serviceWorkerDescriptorId); + /** * A method called when an extension background service worker is destroyed. * diff --git a/toolkit/components/extensions/webidl-api/ExtensionAPIRequestForwarder.cpp b/toolkit/components/extensions/webidl-api/ExtensionAPIRequestForwarder.cpp index 844f6316be5b9..1d8a557104ebf 100644 --- a/toolkit/components/extensions/webidl-api/ExtensionAPIRequestForwarder.cpp +++ b/toolkit/components/extensions/webidl-api/ExtensionAPIRequestForwarder.cpp @@ -659,6 +659,24 @@ bool RequestInitWorkerRunnable::MainThreadRun() { return true; } +// NotifyWorkerLoadedRunnable + +nsresult NotifyWorkerLoadedRunnable::Run() { + MOZ_ASSERT(NS_IsMainThread()); + + RefPtr policy = + ExtensionPolicyService::GetSingleton().GetByURL(mSWBaseURI.get()); + + nsCOMPtr handler = + &ExtensionAPIRequestForwarder::APIRequestHandler(); + MOZ_ASSERT(handler); + + NS_WARN_IF( + NS_FAILED(handler->OnExtensionWorkerLoaded(policy, mSWDescriptorId))); + + return NS_OK; +} + // NotifyWorkerDestroyedRunnable nsresult NotifyWorkerDestroyedRunnable::Run() { diff --git a/toolkit/components/extensions/webidl-api/ExtensionAPIRequestForwarder.h b/toolkit/components/extensions/webidl-api/ExtensionAPIRequestForwarder.h index 58f815cd49c9c..cca9200d3319c 100644 --- a/toolkit/components/extensions/webidl-api/ExtensionAPIRequestForwarder.h +++ b/toolkit/components/extensions/webidl-api/ExtensionAPIRequestForwarder.h @@ -205,6 +205,28 @@ class RequestInitWorkerRunnable : public dom::WorkerMainThreadRunnable { bool MainThreadRun() override; }; +class NotifyWorkerLoadedRunnable : public Runnable { + uint64_t mSWDescriptorId; + nsCOMPtr mSWBaseURI; + + public: + explicit NotifyWorkerLoadedRunnable(const uint64_t aServiceWorkerDescriptorId, + const nsCOMPtr& aWorkerBaseURI) + : Runnable("extensions::NotifyWorkerLoadedRunnable"), + mSWDescriptorId(aServiceWorkerDescriptorId), + mSWBaseURI(aWorkerBaseURI) { + MOZ_ASSERT(mSWDescriptorId > 0); + MOZ_ASSERT(mSWBaseURI); + } + + NS_IMETHOD Run() override; + + NS_INLINE_DECL_REFCOUNTING_INHERITED(NotifyWorkerLoadedRunnable, Runnable) + + private: + ~NotifyWorkerLoadedRunnable() = default; +}; + class NotifyWorkerDestroyedRunnable : public Runnable { uint64_t mSWDescriptorId; nsCOMPtr mSWBaseURI; diff --git a/toolkit/components/extensions/webidl-api/ExtensionBrowser.cpp b/toolkit/components/extensions/webidl-api/ExtensionBrowser.cpp index 66344c68632ec..a9dbf6bd84ad4 100644 --- a/toolkit/components/extensions/webidl-api/ExtensionBrowser.cpp +++ b/toolkit/components/extensions/webidl-api/ExtensionBrowser.cpp @@ -126,6 +126,14 @@ void CreateAndDispatchInitWorkerContextRunnable() { } } +already_AddRefed CreateWorkerLoadedRunnable( + const uint64_t aServiceWorkerDescriptorId, + const nsCOMPtr& aWorkerBaseURI) { + RefPtr runnable = new NotifyWorkerLoadedRunnable( + aServiceWorkerDescriptorId, aWorkerBaseURI); + return runnable.forget(); +} + already_AddRefed CreateWorkerDestroyedRunnable( const uint64_t aServiceWorkerDescriptorId, const nsCOMPtr& aWorkerBaseURI) { diff --git a/toolkit/components/extensions/webidl-api/ExtensionBrowser.h b/toolkit/components/extensions/webidl-api/ExtensionBrowser.h index 8b70ed087ca20..716fb610b777f 100644 --- a/toolkit/components/extensions/webidl-api/ExtensionBrowser.h +++ b/toolkit/components/extensions/webidl-api/ExtensionBrowser.h @@ -29,6 +29,10 @@ bool ExtensionAPIAllowed(JSContext* aCx, JSObject* aGlobal); void CreateAndDispatchInitWorkerContextRunnable(); +already_AddRefed CreateWorkerLoadedRunnable( + const uint64_t aServiceWorkerDescriptorId, + const nsCOMPtr& aWorkerBaseURI); + already_AddRefed CreateWorkerDestroyedRunnable( const uint64_t aServiceWorkerDescriptorId, const nsCOMPtr& aWorkerBaseURI);