summaryrefslogtreecommitdiffstats
path: root/dom/workers/WorkerScope.h
diff options
context:
space:
mode:
Diffstat (limited to 'dom/workers/WorkerScope.h')
-rw-r--r--dom/workers/WorkerScope.h562
1 files changed, 562 insertions, 0 deletions
diff --git a/dom/workers/WorkerScope.h b/dom/workers/WorkerScope.h
new file mode 100644
index 0000000000..5a3414572a
--- /dev/null
+++ b/dom/workers/WorkerScope.h
@@ -0,0 +1,562 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_dom_workerscope_h__
+#define mozilla_dom_workerscope_h__
+
+#include "js/TypeDecls.h"
+#include "js/loader/ModuleLoaderBase.h"
+#include "mozilla/Assertions.h"
+#include "mozilla/Attributes.h"
+#include "mozilla/DOMEventTargetHelper.h"
+#include "mozilla/Maybe.h"
+#include "mozilla/NotNull.h"
+#include "mozilla/RefPtr.h"
+#include "mozilla/UniquePtr.h"
+#include "mozilla/TimeStamp.h"
+#include "mozilla/dom/AnimationFrameProvider.h"
+#include "mozilla/dom/ImageBitmapBinding.h"
+#include "mozilla/dom/ImageBitmapSource.h"
+#include "mozilla/dom/PerformanceWorker.h"
+#include "mozilla/dom/SafeRefPtr.h"
+#include "mozilla/dom/WorkerPrivate.h"
+#include "nsCOMPtr.h"
+#include "nsCycleCollectionParticipant.h"
+#include "nsIGlobalObject.h"
+#include "nsISupports.h"
+#include "nsWeakReference.h"
+
+#ifdef XP_WIN
+# undef PostMessage
+#endif
+
+class nsAtom;
+class nsISerialEventTarget;
+
+namespace mozilla {
+class ErrorResult;
+struct VsyncEvent;
+
+namespace extensions {
+
+class ExtensionBrowser;
+
+} // namespace extensions
+
+namespace dom {
+
+class AnyCallback;
+enum class CallerType : uint32_t;
+class ClientInfo;
+class ClientSource;
+class Clients;
+class Console;
+class Crypto;
+class DOMString;
+class DebuggerNotificationManager;
+enum class EventCallbackDebuggerNotificationType : uint8_t;
+class EventHandlerNonNull;
+class FontFaceSet;
+class Function;
+class IDBFactory;
+class OnErrorEventHandlerNonNull;
+template <typename T>
+class Optional;
+class Performance;
+class Promise;
+class RequestOrUSVString;
+template <typename T>
+class Sequence;
+class ServiceWorkerDescriptor;
+class ServiceWorkerRegistration;
+class ServiceWorkerRegistrationDescriptor;
+struct StructuredSerializeOptions;
+class WorkerDocumentListener;
+class WorkerLocation;
+class WorkerNavigator;
+class WorkerPrivate;
+class VsyncWorkerChild;
+class WebTaskScheduler;
+class WebTaskSchedulerWorker;
+struct RequestInit;
+
+namespace cache {
+
+class CacheStorage;
+
+} // namespace cache
+
+class WorkerGlobalScopeBase : public DOMEventTargetHelper,
+ public nsSupportsWeakReference,
+ public nsIGlobalObject {
+ friend class WorkerPrivate;
+
+ public:
+ NS_DECL_ISUPPORTS_INHERITED
+ NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(WorkerGlobalScopeBase,
+ DOMEventTargetHelper)
+
+ WorkerGlobalScopeBase(WorkerPrivate* aWorkerPrivate,
+ UniquePtr<ClientSource> aClientSource,
+ bool aShouldResistFingerprinting);
+
+ virtual bool WrapGlobalObject(JSContext* aCx,
+ JS::MutableHandle<JSObject*> aReflector) = 0;
+
+ // EventTarget implementation
+ JSObject* WrapObject(JSContext* aCx,
+ JS::Handle<JSObject*> aGivenProto) final {
+ MOZ_CRASH("WrapObject not supported; use WrapGlobalObject.");
+ }
+
+ // nsIGlobalObject implementation
+ JSObject* GetGlobalJSObject() final;
+
+ JSObject* GetGlobalJSObjectPreserveColor() const final;
+
+ bool IsSharedMemoryAllowed() const final;
+
+ bool ShouldResistFingerprinting(RFPTarget aTarget) const final;
+
+ OriginTrials Trials() const final;
+
+ StorageAccess GetStorageAccess() final;
+
+ Maybe<ClientInfo> GetClientInfo() const final;
+
+ Maybe<ServiceWorkerDescriptor> GetController() const final;
+
+ mozilla::Result<mozilla::ipc::PrincipalInfo, nsresult> GetStorageKey() final;
+
+ virtual void Control(const ServiceWorkerDescriptor& aServiceWorker);
+
+ // DispatcherTrait implementation
+ nsresult Dispatch(TaskCategory aCategory,
+ already_AddRefed<nsIRunnable>&& aRunnable) final;
+
+ nsISerialEventTarget* EventTargetFor(TaskCategory) const final;
+
+ AbstractThread* AbstractMainThreadFor(TaskCategory) final {
+ MOZ_CRASH("AbstractMainThreadFor not supported for workers.");
+ }
+
+ MOZ_CAN_RUN_SCRIPT
+ void ReportError(JSContext* aCx, JS::Handle<JS::Value> aError,
+ CallerType aCallerType, ErrorResult& aRv);
+
+ // atob, btoa, and dump are declared (separately) by both WorkerGlobalScope
+ // and WorkerDebuggerGlobalScope WebIDL interfaces
+ void Atob(const nsAString& aAtob, nsAString& aOut, ErrorResult& aRv) const;
+
+ void Btoa(const nsAString& aBtoa, nsAString& aOut, ErrorResult& aRv) const;
+
+ already_AddRefed<Console> GetConsole(ErrorResult& aRv);
+
+ Console* GetConsoleIfExists() const { return mConsole; }
+
+ void InitModuleLoader(JS::loader::ModuleLoaderBase* aModuleLoader) {
+ if (!mModuleLoader) {
+ mModuleLoader = aModuleLoader;
+ }
+ }
+
+ // The nullptr here is not used, but is required to make the override method
+ // have the same signature as other GetModuleLoader methods on globals.
+ JS::loader::ModuleLoaderBase* GetModuleLoader(
+ JSContext* aCx = nullptr) override {
+ return mModuleLoader;
+ };
+
+ uint64_t WindowID() const;
+
+ // Usually global scope dies earlier than the WorkerPrivate, but if we see
+ // it leak at least we can tell it to not carry away a dead pointer.
+ void NoteWorkerTerminated() { mWorkerPrivate = nullptr; }
+
+ ClientSource& MutableClientSourceRef() const { return *mClientSource; }
+
+ // WorkerPrivate wants to be able to forbid script when its state machine
+ // demands it.
+ void WorkerPrivateSaysForbidScript() { StartForbiddingScript(); }
+ void WorkerPrivateSaysAllowScript() { StopForbiddingScript(); }
+
+ protected:
+ ~WorkerGlobalScopeBase();
+
+ CheckedUnsafePtr<WorkerPrivate> mWorkerPrivate;
+
+ void AssertIsOnWorkerThread() const {
+ MOZ_ASSERT(mWorkerThreadUsedOnlyForAssert == PR_GetCurrentThread());
+ }
+
+ private:
+ RefPtr<Console> mConsole;
+ RefPtr<JS::loader::ModuleLoaderBase> mModuleLoader;
+ const UniquePtr<ClientSource> mClientSource;
+ nsCOMPtr<nsISerialEventTarget> mSerialEventTarget;
+ bool mShouldResistFingerprinting;
+#ifdef DEBUG
+ PRThread* mWorkerThreadUsedOnlyForAssert;
+#endif
+};
+
+namespace workerinternals {
+
+class NamedWorkerGlobalScopeMixin {
+ public:
+ explicit NamedWorkerGlobalScopeMixin(const nsAString& aName) : mName(aName) {}
+
+ void GetName(DOMString& aName) const;
+
+ protected:
+ ~NamedWorkerGlobalScopeMixin() = default;
+
+ private:
+ const nsString mName;
+};
+
+} // namespace workerinternals
+
+class WorkerGlobalScope : public WorkerGlobalScopeBase {
+ public:
+ NS_DECL_ISUPPORTS_INHERITED
+ NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(WorkerGlobalScope,
+ WorkerGlobalScopeBase)
+
+ using WorkerGlobalScopeBase::WorkerGlobalScopeBase;
+
+ void NoteTerminating();
+
+ void NoteShuttingDown();
+
+ // nsIGlobalObject implementation
+ RefPtr<ServiceWorkerRegistration> GetServiceWorkerRegistration(
+ const ServiceWorkerRegistrationDescriptor& aDescriptor) const final;
+
+ RefPtr<ServiceWorkerRegistration> GetOrCreateServiceWorkerRegistration(
+ const ServiceWorkerRegistrationDescriptor& aDescriptor) final;
+
+ DebuggerNotificationManager* GetOrCreateDebuggerNotificationManager() final;
+
+ DebuggerNotificationManager* GetExistingDebuggerNotificationManager() final;
+
+ Maybe<EventCallbackDebuggerNotificationType> GetDebuggerNotificationType()
+ const final;
+
+ mozilla::dom::StorageManager* GetStorageManager() final;
+
+ // WorkerGlobalScope WebIDL implementation
+ WorkerGlobalScope* Self() { return this; }
+
+ already_AddRefed<WorkerLocation> Location();
+
+ already_AddRefed<WorkerNavigator> Navigator();
+
+ already_AddRefed<WorkerNavigator> GetExistingNavigator() const;
+
+ FontFaceSet* GetFonts(ErrorResult&);
+ FontFaceSet* GetFonts() final { return GetFonts(IgnoreErrors()); }
+
+ void ImportScripts(JSContext* aCx, const Sequence<nsString>& aScriptURLs,
+ ErrorResult& aRv);
+
+ OnErrorEventHandlerNonNull* GetOnerror();
+
+ void SetOnerror(OnErrorEventHandlerNonNull* aHandler);
+
+ IMPL_EVENT_HANDLER(languagechange)
+ IMPL_EVENT_HANDLER(offline)
+ IMPL_EVENT_HANDLER(online)
+ IMPL_EVENT_HANDLER(rejectionhandled)
+ IMPL_EVENT_HANDLER(unhandledrejection)
+
+ void Dump(const Optional<nsAString>& aString) const;
+
+ Performance* GetPerformance();
+
+ Performance* GetPerformanceIfExists() const { return mPerformance; }
+
+ static bool IsInAutomation(JSContext* aCx, JSObject*);
+
+ void GetJSTestingFunctions(JSContext* aCx,
+ JS::MutableHandle<JSObject*> aFunctions,
+ ErrorResult& aRv);
+
+ // GlobalCrypto WebIDL implementation
+ Crypto* GetCrypto(ErrorResult& aError);
+
+ // WindowOrWorkerGlobalScope WebIDL implementation
+ void GetOrigin(nsAString& aOrigin) const;
+
+ bool CrossOriginIsolated() const final;
+
+ MOZ_CAN_RUN_SCRIPT
+ int32_t SetTimeout(JSContext* aCx, Function& aHandler, int32_t aTimeout,
+ const Sequence<JS::Value>& aArguments, ErrorResult& aRv);
+
+ MOZ_CAN_RUN_SCRIPT
+ int32_t SetTimeout(JSContext* aCx, const nsAString& aHandler,
+ int32_t aTimeout, const Sequence<JS::Value>&,
+ ErrorResult& aRv);
+
+ MOZ_CAN_RUN_SCRIPT
+ void ClearTimeout(int32_t aHandle);
+
+ MOZ_CAN_RUN_SCRIPT
+ int32_t SetInterval(JSContext* aCx, Function& aHandler, int32_t aTimeout,
+ const Sequence<JS::Value>& aArguments, ErrorResult& aRv);
+ MOZ_CAN_RUN_SCRIPT
+ int32_t SetInterval(JSContext* aCx, const nsAString& aHandler,
+ int32_t aTimeout, const Sequence<JS::Value>&,
+ ErrorResult& aRv);
+
+ MOZ_CAN_RUN_SCRIPT
+ void ClearInterval(int32_t aHandle);
+
+ already_AddRefed<Promise> CreateImageBitmap(
+ const ImageBitmapSource& aImage, const ImageBitmapOptions& aOptions,
+ ErrorResult& aRv);
+
+ already_AddRefed<Promise> CreateImageBitmap(
+ const ImageBitmapSource& aImage, int32_t aSx, int32_t aSy, int32_t aSw,
+ int32_t aSh, const ImageBitmapOptions& aOptions, ErrorResult& aRv);
+
+ void StructuredClone(JSContext* aCx, JS::Handle<JS::Value> aValue,
+ const StructuredSerializeOptions& aOptions,
+ JS::MutableHandle<JS::Value> aRetval,
+ ErrorResult& aError);
+
+ already_AddRefed<Promise> Fetch(const RequestOrUSVString& aInput,
+ const RequestInit& aInit,
+ CallerType aCallerType, ErrorResult& aRv);
+
+ bool IsSecureContext() const;
+
+ already_AddRefed<IDBFactory> GetIndexedDB(JSContext* aCx,
+ ErrorResult& aErrorResult);
+
+ already_AddRefed<cache::CacheStorage> GetCaches(ErrorResult& aRv);
+
+ WebTaskScheduler* Scheduler();
+ WebTaskScheduler* GetExistingScheduler() const;
+
+ bool WindowInteractionAllowed() const;
+
+ void AllowWindowInteraction();
+
+ void ConsumeWindowInteraction();
+
+ void StorageAccessPermissionGranted();
+
+ virtual void OnDocumentVisible(bool aVisible) {}
+
+ MOZ_CAN_RUN_SCRIPT_BOUNDARY
+ virtual void OnVsync(const VsyncEvent& aVsync) {}
+
+ protected:
+ ~WorkerGlobalScope();
+
+ private:
+ MOZ_CAN_RUN_SCRIPT
+ int32_t SetTimeoutOrInterval(JSContext* aCx, Function& aHandler,
+ int32_t aTimeout,
+ const Sequence<JS::Value>& aArguments,
+ bool aIsInterval, ErrorResult& aRv);
+
+ MOZ_CAN_RUN_SCRIPT
+ int32_t SetTimeoutOrInterval(JSContext* aCx, const nsAString& aHandler,
+ int32_t aTimeout, bool aIsInterval,
+ ErrorResult& aRv);
+
+ RefPtr<Crypto> mCrypto;
+ RefPtr<WorkerLocation> mLocation;
+ RefPtr<WorkerNavigator> mNavigator;
+ RefPtr<FontFaceSet> mFontFaceSet;
+ RefPtr<Performance> mPerformance;
+ RefPtr<IDBFactory> mIndexedDB;
+ RefPtr<cache::CacheStorage> mCacheStorage;
+ RefPtr<DebuggerNotificationManager> mDebuggerNotificationManager;
+ RefPtr<WebTaskSchedulerWorker> mWebTaskScheduler;
+ uint32_t mWindowInteractionsAllowed = 0;
+};
+
+class DedicatedWorkerGlobalScope final
+ : public WorkerGlobalScope,
+ public workerinternals::NamedWorkerGlobalScopeMixin {
+ public:
+ NS_DECL_ISUPPORTS_INHERITED
+ NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(
+ DedicatedWorkerGlobalScope, WorkerGlobalScope)
+
+ DedicatedWorkerGlobalScope(WorkerPrivate* aWorkerPrivate,
+ UniquePtr<ClientSource> aClientSource,
+ const nsString& aName,
+ bool aShouldResistFingerprinting);
+
+ bool WrapGlobalObject(JSContext* aCx,
+ JS::MutableHandle<JSObject*> aReflector) override;
+
+ void PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage,
+ const Sequence<JSObject*>& aTransferable, ErrorResult& aRv);
+
+ void PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage,
+ const StructuredSerializeOptions& aOptions,
+ ErrorResult& aRv);
+
+ void Close();
+
+ MOZ_CAN_RUN_SCRIPT
+ int32_t RequestAnimationFrame(FrameRequestCallback& aCallback,
+ ErrorResult& aError);
+
+ MOZ_CAN_RUN_SCRIPT
+ void CancelAnimationFrame(int32_t aHandle, ErrorResult& aError);
+
+ void OnDocumentVisible(bool aVisible) override;
+
+ MOZ_CAN_RUN_SCRIPT_BOUNDARY
+ void OnVsync(const VsyncEvent& aVsync) override;
+
+ IMPL_EVENT_HANDLER(message)
+ IMPL_EVENT_HANDLER(messageerror)
+
+ private:
+ ~DedicatedWorkerGlobalScope() = default;
+
+ FrameRequestManager mFrameRequestManager;
+ RefPtr<VsyncWorkerChild> mVsyncChild;
+ RefPtr<WorkerDocumentListener> mDocListener;
+ bool mDocumentVisible = false;
+};
+
+class SharedWorkerGlobalScope final
+ : public WorkerGlobalScope,
+ public workerinternals::NamedWorkerGlobalScopeMixin {
+ public:
+ SharedWorkerGlobalScope(WorkerPrivate* aWorkerPrivate,
+ UniquePtr<ClientSource> aClientSource,
+ const nsString& aName,
+ bool aShouldResistFingerprinting);
+
+ bool WrapGlobalObject(JSContext* aCx,
+ JS::MutableHandle<JSObject*> aReflector) override;
+
+ void Close();
+
+ IMPL_EVENT_HANDLER(connect)
+
+ private:
+ ~SharedWorkerGlobalScope() = default;
+};
+
+class ServiceWorkerGlobalScope final : public WorkerGlobalScope {
+ public:
+ NS_DECL_ISUPPORTS_INHERITED
+ NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ServiceWorkerGlobalScope,
+ WorkerGlobalScope)
+
+ ServiceWorkerGlobalScope(
+ WorkerPrivate* aWorkerPrivate, UniquePtr<ClientSource> aClientSource,
+ const ServiceWorkerRegistrationDescriptor& aRegistrationDescriptor,
+ bool aShouldResistFingerprinting);
+
+ bool WrapGlobalObject(JSContext* aCx,
+ JS::MutableHandle<JSObject*> aReflector) override;
+
+ already_AddRefed<Clients> GetClients();
+
+ ServiceWorkerRegistration* Registration();
+
+ already_AddRefed<Promise> SkipWaiting(ErrorResult& aRv);
+
+ SafeRefPtr<extensions::ExtensionBrowser> AcquireExtensionBrowser();
+
+ IMPL_EVENT_HANDLER(install)
+ IMPL_EVENT_HANDLER(activate)
+
+ EventHandlerNonNull* GetOnfetch();
+
+ void SetOnfetch(EventHandlerNonNull* aCallback);
+
+ void EventListenerAdded(nsAtom* aType) override;
+
+ IMPL_EVENT_HANDLER(message)
+ IMPL_EVENT_HANDLER(messageerror)
+
+ IMPL_EVENT_HANDLER(notificationclick)
+ IMPL_EVENT_HANDLER(notificationclose)
+
+ IMPL_EVENT_HANDLER(push)
+ IMPL_EVENT_HANDLER(pushsubscriptionchange)
+
+ private:
+ ~ServiceWorkerGlobalScope();
+
+ void NoteFetchHandlerWasAdded() const;
+
+ RefPtr<Clients> mClients;
+ const nsString mScope;
+ RefPtr<ServiceWorkerRegistration> mRegistration;
+ SafeRefPtr<extensions::ExtensionBrowser> mExtensionBrowser;
+};
+
+class WorkerDebuggerGlobalScope final : public WorkerGlobalScopeBase {
+ public:
+ using WorkerGlobalScopeBase::WorkerGlobalScopeBase;
+
+ bool WrapGlobalObject(JSContext* aCx,
+ JS::MutableHandle<JSObject*> aReflector) override;
+
+ void Control(const ServiceWorkerDescriptor& aServiceWorker) override {
+ MOZ_CRASH("Can't control debugger workers.");
+ }
+
+ void GetGlobal(JSContext* aCx, JS::MutableHandle<JSObject*> aGlobal,
+ ErrorResult& aRv);
+
+ void CreateSandbox(JSContext* aCx, const nsAString& aName,
+ JS::Handle<JSObject*> aPrototype,
+ JS::MutableHandle<JSObject*> aResult, ErrorResult& aRv);
+
+ void LoadSubScript(JSContext* aCx, const nsAString& aUrl,
+ const Optional<JS::Handle<JSObject*>>& aSandbox,
+ ErrorResult& aRv);
+
+ MOZ_CAN_RUN_SCRIPT void EnterEventLoop();
+
+ void LeaveEventLoop();
+
+ void PostMessage(const nsAString& aMessage);
+
+ void SetImmediate(Function& aHandler, ErrorResult& aRv);
+
+ void ReportError(JSContext* aCx, const nsAString& aMessage);
+
+ void RetrieveConsoleEvents(JSContext* aCx, nsTArray<JS::Value>& aEvents,
+ ErrorResult& aRv);
+
+ void ClearConsoleEvents(JSContext* aCx, ErrorResult& aRv);
+
+ void SetConsoleEventHandler(JSContext* aCx, AnyCallback* aHandler,
+ ErrorResult& aRv);
+
+ void Dump(JSContext* aCx, const Optional<nsAString>& aString) const;
+
+ IMPL_EVENT_HANDLER(message)
+ IMPL_EVENT_HANDLER(messageerror)
+
+ private:
+ ~WorkerDebuggerGlobalScope() = default;
+};
+
+} // namespace dom
+} // namespace mozilla
+
+inline nsISupports* ToSupports(mozilla::dom::WorkerGlobalScope* aScope) {
+ return static_cast<mozilla::dom::EventTarget*>(aScope);
+}
+
+#endif /* mozilla_dom_workerscope_h__ */