1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef mozilla_dom_workerscope_h__
8 #define mozilla_dom_workerscope_h__
10 #include "js/TypeDecls.h"
11 #include "mozilla/Assertions.h"
12 #include "mozilla/Attributes.h"
13 #include "mozilla/DOMEventTargetHelper.h"
14 #include "mozilla/Maybe.h"
15 #include "mozilla/NotNull.h"
16 #include "mozilla/RefPtr.h"
17 #include "mozilla/UniquePtr.h"
18 #include "mozilla/TimeStamp.h"
19 #include "mozilla/dom/AnimationFrameProvider.h"
20 #include "mozilla/dom/ImageBitmapBinding.h"
21 #include "mozilla/dom/ImageBitmapSource.h"
22 #include "mozilla/dom/SafeRefPtr.h"
23 #include "mozilla/dom/WorkerPrivate.h"
25 #include "nsCycleCollectionParticipant.h"
26 #include "nsIGlobalObject.h"
27 #include "nsISupports.h"
28 #include "nsWeakReference.h"
35 class nsISerialEventTarget
;
41 namespace extensions
{
43 class ExtensionBrowser
;
45 } // namespace extensions
50 enum class CallerType
: uint32_t;
57 class DebuggerNotificationManager
;
58 enum class EventCallbackDebuggerNotificationType
: uint8_t;
59 class EventHandlerNonNull
;
62 class OnErrorEventHandlerNonNull
;
67 class RequestOrUSVString
;
70 class ServiceWorkerDescriptor
;
71 class ServiceWorkerRegistration
;
72 class ServiceWorkerRegistrationDescriptor
;
73 struct StructuredSerializeOptions
;
74 class WorkerDocumentListener
;
76 class WorkerNavigator
;
78 class VsyncWorkerChild
;
79 class WebTaskScheduler
;
80 class WebTaskSchedulerWorker
;
89 class WorkerGlobalScopeBase
: public DOMEventTargetHelper
,
90 public nsSupportsWeakReference
,
91 public nsIGlobalObject
{
92 friend class WorkerPrivate
;
95 NS_DECL_ISUPPORTS_INHERITED
96 NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(WorkerGlobalScopeBase
,
99 WorkerGlobalScopeBase(WorkerPrivate
* aWorkerPrivate
,
100 UniquePtr
<ClientSource
> aClientSource
);
102 virtual bool WrapGlobalObject(JSContext
* aCx
,
103 JS::MutableHandle
<JSObject
*> aReflector
) = 0;
105 // EventTarget implementation
106 JSObject
* WrapObject(JSContext
* aCx
,
107 JS::Handle
<JSObject
*> aGivenProto
) final
{
108 MOZ_CRASH("WrapObject not supported; use WrapGlobalObject.");
111 // nsIGlobalObject implementation
112 JSObject
* GetGlobalJSObject() final
;
114 JSObject
* GetGlobalJSObjectPreserveColor() const final
;
116 bool IsSharedMemoryAllowed() const final
;
118 bool ShouldResistFingerprinting() const final
;
120 uint32_t GetPrincipalHashValue() const final
;
122 OriginTrials
Trials() const final
;
124 StorageAccess
GetStorageAccess() final
;
126 Maybe
<ClientInfo
> GetClientInfo() const final
;
128 Maybe
<ServiceWorkerDescriptor
> GetController() const final
;
130 virtual void Control(const ServiceWorkerDescriptor
& aServiceWorker
);
132 // DispatcherTrait implementation
133 nsresult
Dispatch(TaskCategory aCategory
,
134 already_AddRefed
<nsIRunnable
>&& aRunnable
) final
;
136 nsISerialEventTarget
* EventTargetFor(TaskCategory
) const final
;
138 AbstractThread
* AbstractMainThreadFor(TaskCategory
) final
{
139 MOZ_CRASH("AbstractMainThreadFor not supported for workers.");
143 void ReportError(JSContext
* aCx
, JS::Handle
<JS::Value
> aError
,
144 CallerType aCallerType
, ErrorResult
& aRv
);
146 // atob, btoa, and dump are declared (separately) by both WorkerGlobalScope
147 // and WorkerDebuggerGlobalScope WebIDL interfaces
148 void Atob(const nsAString
& aAtob
, nsAString
& aOut
, ErrorResult
& aRv
) const;
150 void Btoa(const nsAString
& aBtoa
, nsAString
& aOut
, ErrorResult
& aRv
) const;
152 already_AddRefed
<Console
> GetConsole(ErrorResult
& aRv
);
154 Console
* GetConsoleIfExists() const { return mConsole
; }
156 uint64_t WindowID() const;
158 void NoteTerminating() { StartDying(); }
160 // Usually global scope dies earlier than the WorkerPrivate, but if we see
161 // it leak at least we can tell it to not carry away a dead pointer.
162 void NoteWorkerTerminated() { mWorkerPrivate
= nullptr; }
164 ClientSource
& MutableClientSourceRef() const { return *mClientSource
; }
166 // WorkerPrivate wants to be able to forbid script when its state machine
168 void WorkerPrivateSaysForbidScript() { StartForbiddingScript(); }
169 void WorkerPrivateSaysAllowScript() { StopForbiddingScript(); }
172 ~WorkerGlobalScopeBase();
174 CheckedUnsafePtr
<WorkerPrivate
> mWorkerPrivate
;
176 void AssertIsOnWorkerThread() const {
177 MOZ_ASSERT(mWorkerThreadUsedOnlyForAssert
== PR_GetCurrentThread());
181 RefPtr
<Console
> mConsole
;
182 const UniquePtr
<ClientSource
> mClientSource
;
183 nsCOMPtr
<nsISerialEventTarget
> mSerialEventTarget
;
185 PRThread
* mWorkerThreadUsedOnlyForAssert
;
189 namespace workerinternals
{
191 class NamedWorkerGlobalScopeMixin
{
193 explicit NamedWorkerGlobalScopeMixin(const nsAString
& aName
) : mName(aName
) {}
195 void GetName(DOMString
& aName
) const;
198 ~NamedWorkerGlobalScopeMixin() = default;
201 const nsString mName
;
204 } // namespace workerinternals
206 class WorkerGlobalScope
: public WorkerGlobalScopeBase
{
208 NS_DECL_ISUPPORTS_INHERITED
209 NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(WorkerGlobalScope
,
210 WorkerGlobalScopeBase
)
212 using WorkerGlobalScopeBase::WorkerGlobalScopeBase
;
214 // nsIGlobalObject implementation
215 RefPtr
<ServiceWorkerRegistration
> GetServiceWorkerRegistration(
216 const ServiceWorkerRegistrationDescriptor
& aDescriptor
) const final
;
218 RefPtr
<ServiceWorkerRegistration
> GetOrCreateServiceWorkerRegistration(
219 const ServiceWorkerRegistrationDescriptor
& aDescriptor
) final
;
221 DebuggerNotificationManager
* GetOrCreateDebuggerNotificationManager() final
;
223 DebuggerNotificationManager
* GetExistingDebuggerNotificationManager() final
;
225 Maybe
<EventCallbackDebuggerNotificationType
> GetDebuggerNotificationType()
228 // WorkerGlobalScope WebIDL implementation
229 WorkerGlobalScope
* Self() { return this; }
231 already_AddRefed
<WorkerLocation
> Location();
233 already_AddRefed
<WorkerNavigator
> Navigator();
235 already_AddRefed
<WorkerNavigator
> GetExistingNavigator() const;
237 void ImportScripts(JSContext
* aCx
, const Sequence
<nsString
>& aScriptURLs
,
240 OnErrorEventHandlerNonNull
* GetOnerror();
242 void SetOnerror(OnErrorEventHandlerNonNull
* aHandler
);
244 IMPL_EVENT_HANDLER(languagechange
)
245 IMPL_EVENT_HANDLER(offline
)
246 IMPL_EVENT_HANDLER(online
)
247 IMPL_EVENT_HANDLER(rejectionhandled
)
248 IMPL_EVENT_HANDLER(unhandledrejection
)
250 void Dump(const Optional
<nsAString
>& aString
) const;
252 Performance
* GetPerformance();
254 Performance
* GetPerformanceIfExists() const { return mPerformance
; }
256 static bool IsInAutomation(JSContext
* aCx
, JSObject
*);
258 void GetJSTestingFunctions(JSContext
* aCx
,
259 JS::MutableHandle
<JSObject
*> aFunctions
,
262 // GlobalCrypto WebIDL implementation
263 Crypto
* GetCrypto(ErrorResult
& aError
);
265 // WindowOrWorkerGlobalScope WebIDL implementation
266 void GetOrigin(nsAString
& aOrigin
) const;
268 bool CrossOriginIsolated() const final
;
271 int32_t SetTimeout(JSContext
* aCx
, Function
& aHandler
, int32_t aTimeout
,
272 const Sequence
<JS::Value
>& aArguments
, ErrorResult
& aRv
);
275 int32_t SetTimeout(JSContext
* aCx
, const nsAString
& aHandler
,
276 int32_t aTimeout
, const Sequence
<JS::Value
>&,
280 void ClearTimeout(int32_t aHandle
);
283 int32_t SetInterval(JSContext
* aCx
, Function
& aHandler
, int32_t aTimeout
,
284 const Sequence
<JS::Value
>& aArguments
, ErrorResult
& aRv
);
286 int32_t SetInterval(JSContext
* aCx
, const nsAString
& aHandler
,
287 int32_t aTimeout
, const Sequence
<JS::Value
>&,
291 void ClearInterval(int32_t aHandle
);
293 already_AddRefed
<Promise
> CreateImageBitmap(
294 const ImageBitmapSource
& aImage
, const ImageBitmapOptions
& aOptions
,
297 already_AddRefed
<Promise
> CreateImageBitmap(
298 const ImageBitmapSource
& aImage
, int32_t aSx
, int32_t aSy
, int32_t aSw
,
299 int32_t aSh
, const ImageBitmapOptions
& aOptions
, ErrorResult
& aRv
);
301 void StructuredClone(JSContext
* aCx
, JS::Handle
<JS::Value
> aValue
,
302 const StructuredSerializeOptions
& aOptions
,
303 JS::MutableHandle
<JS::Value
> aRetval
,
304 ErrorResult
& aError
);
306 already_AddRefed
<Promise
> Fetch(const RequestOrUSVString
& aInput
,
307 const RequestInit
& aInit
,
308 CallerType aCallerType
, ErrorResult
& aRv
);
310 bool IsSecureContext() const;
312 already_AddRefed
<IDBFactory
> GetIndexedDB(ErrorResult
& aErrorResult
);
314 already_AddRefed
<cache::CacheStorage
> GetCaches(ErrorResult
& aRv
);
316 WebTaskScheduler
* Scheduler();
317 WebTaskScheduler
* GetExistingScheduler() const;
319 bool WindowInteractionAllowed() const;
321 void AllowWindowInteraction();
323 void ConsumeWindowInteraction();
325 void StorageAccessPermissionGranted();
327 virtual void OnDocumentVisible(bool aVisible
) {}
329 MOZ_CAN_RUN_SCRIPT_BOUNDARY
330 virtual void OnVsync(const VsyncEvent
& aVsync
) {}
333 ~WorkerGlobalScope();
337 int32_t SetTimeoutOrInterval(JSContext
* aCx
, Function
& aHandler
,
339 const Sequence
<JS::Value
>& aArguments
,
340 bool aIsInterval
, ErrorResult
& aRv
);
343 int32_t SetTimeoutOrInterval(JSContext
* aCx
, const nsAString
& aHandler
,
344 int32_t aTimeout
, bool aIsInterval
,
347 RefPtr
<Crypto
> mCrypto
;
348 RefPtr
<WorkerLocation
> mLocation
;
349 RefPtr
<WorkerNavigator
> mNavigator
;
350 RefPtr
<Performance
> mPerformance
;
351 RefPtr
<IDBFactory
> mIndexedDB
;
352 RefPtr
<cache::CacheStorage
> mCacheStorage
;
353 RefPtr
<DebuggerNotificationManager
> mDebuggerNotificationManager
;
354 RefPtr
<WebTaskSchedulerWorker
> mWebTaskScheduler
;
355 uint32_t mWindowInteractionsAllowed
= 0;
358 class DedicatedWorkerGlobalScope final
359 : public WorkerGlobalScope
,
360 public workerinternals::NamedWorkerGlobalScopeMixin
{
362 NS_DECL_ISUPPORTS_INHERITED
363 NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(
364 DedicatedWorkerGlobalScope
, WorkerGlobalScope
)
366 DedicatedWorkerGlobalScope(WorkerPrivate
* aWorkerPrivate
,
367 UniquePtr
<ClientSource
> aClientSource
,
368 const nsString
& aName
);
370 bool WrapGlobalObject(JSContext
* aCx
,
371 JS::MutableHandle
<JSObject
*> aReflector
) override
;
373 void PostMessage(JSContext
* aCx
, JS::Handle
<JS::Value
> aMessage
,
374 const Sequence
<JSObject
*>& aTransferable
, ErrorResult
& aRv
);
376 void PostMessage(JSContext
* aCx
, JS::Handle
<JS::Value
> aMessage
,
377 const StructuredSerializeOptions
& aOptions
,
383 int32_t RequestAnimationFrame(FrameRequestCallback
& aCallback
,
384 ErrorResult
& aError
);
387 void CancelAnimationFrame(int32_t aHandle
, ErrorResult
& aError
);
389 void OnDocumentVisible(bool aVisible
) override
;
391 MOZ_CAN_RUN_SCRIPT_BOUNDARY
392 void OnVsync(const VsyncEvent
& aVsync
) override
;
394 IMPL_EVENT_HANDLER(message
)
395 IMPL_EVENT_HANDLER(messageerror
)
398 ~DedicatedWorkerGlobalScope() = default;
400 FrameRequestManager mFrameRequestManager
;
401 RefPtr
<VsyncWorkerChild
> mVsyncChild
;
402 RefPtr
<WorkerDocumentListener
> mDocListener
;
403 bool mDocumentVisible
= false;
406 class SharedWorkerGlobalScope final
407 : public WorkerGlobalScope
,
408 public workerinternals::NamedWorkerGlobalScopeMixin
{
410 SharedWorkerGlobalScope(WorkerPrivate
* aWorkerPrivate
,
411 UniquePtr
<ClientSource
> aClientSource
,
412 const nsString
& aName
);
414 bool WrapGlobalObject(JSContext
* aCx
,
415 JS::MutableHandle
<JSObject
*> aReflector
) override
;
419 IMPL_EVENT_HANDLER(connect
)
422 ~SharedWorkerGlobalScope() = default;
425 class ServiceWorkerGlobalScope final
: public WorkerGlobalScope
{
427 NS_DECL_ISUPPORTS_INHERITED
428 NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ServiceWorkerGlobalScope
,
431 ServiceWorkerGlobalScope(
432 WorkerPrivate
* aWorkerPrivate
, UniquePtr
<ClientSource
> aClientSource
,
433 const ServiceWorkerRegistrationDescriptor
& aRegistrationDescriptor
);
435 bool WrapGlobalObject(JSContext
* aCx
,
436 JS::MutableHandle
<JSObject
*> aReflector
) override
;
438 already_AddRefed
<Clients
> GetClients();
440 ServiceWorkerRegistration
* Registration();
442 already_AddRefed
<Promise
> SkipWaiting(ErrorResult
& aRv
);
444 SafeRefPtr
<extensions::ExtensionBrowser
> AcquireExtensionBrowser();
446 IMPL_EVENT_HANDLER(install
)
447 IMPL_EVENT_HANDLER(activate
)
449 EventHandlerNonNull
* GetOnfetch();
451 void SetOnfetch(EventHandlerNonNull
* aCallback
);
453 void EventListenerAdded(nsAtom
* aType
) override
;
455 IMPL_EVENT_HANDLER(message
)
456 IMPL_EVENT_HANDLER(messageerror
)
458 IMPL_EVENT_HANDLER(notificationclick
)
459 IMPL_EVENT_HANDLER(notificationclose
)
461 IMPL_EVENT_HANDLER(push
)
462 IMPL_EVENT_HANDLER(pushsubscriptionchange
)
465 ~ServiceWorkerGlobalScope();
467 void NoteFetchHandlerWasAdded() const;
469 RefPtr
<Clients
> mClients
;
470 const nsString mScope
;
471 RefPtr
<ServiceWorkerRegistration
> mRegistration
;
472 SafeRefPtr
<extensions::ExtensionBrowser
> mExtensionBrowser
;
475 class WorkerDebuggerGlobalScope final
: public WorkerGlobalScopeBase
{
477 using WorkerGlobalScopeBase::WorkerGlobalScopeBase
;
479 bool WrapGlobalObject(JSContext
* aCx
,
480 JS::MutableHandle
<JSObject
*> aReflector
) override
;
482 void Control(const ServiceWorkerDescriptor
& aServiceWorker
) override
{
483 MOZ_CRASH("Can't control debugger workers.");
486 void GetGlobal(JSContext
* aCx
, JS::MutableHandle
<JSObject
*> aGlobal
,
489 void CreateSandbox(JSContext
* aCx
, const nsAString
& aName
,
490 JS::Handle
<JSObject
*> aPrototype
,
491 JS::MutableHandle
<JSObject
*> aResult
, ErrorResult
& aRv
);
493 void LoadSubScript(JSContext
* aCx
, const nsAString
& aUrl
,
494 const Optional
<JS::Handle
<JSObject
*>>& aSandbox
,
497 MOZ_CAN_RUN_SCRIPT
void EnterEventLoop();
499 void LeaveEventLoop();
501 void PostMessage(const nsAString
& aMessage
);
503 void SetImmediate(Function
& aHandler
, ErrorResult
& aRv
);
505 void ReportError(JSContext
* aCx
, const nsAString
& aMessage
);
507 void RetrieveConsoleEvents(JSContext
* aCx
, nsTArray
<JS::Value
>& aEvents
,
510 void ClearConsoleEvents(JSContext
* aCx
, ErrorResult
& aRv
);
512 void SetConsoleEventHandler(JSContext
* aCx
, AnyCallback
* aHandler
,
515 void Dump(JSContext
* aCx
, const Optional
<nsAString
>& aString
) const;
517 IMPL_EVENT_HANDLER(message
)
518 IMPL_EVENT_HANDLER(messageerror
)
521 ~WorkerDebuggerGlobalScope() = default;
525 } // namespace mozilla
527 inline nsISupports
* ToSupports(mozilla::dom::WorkerGlobalScope
* aScope
) {
528 return static_cast<mozilla::dom::EventTarget
*>(aScope
);
531 #endif /* mozilla_dom_workerscope_h__ */