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_serviceworkerop_h__
8 #define mozilla_dom_serviceworkerop_h__
12 #include "mozilla/dom/ServiceWorkerOpPromise.h"
13 #include "nsISupportsImpl.h"
15 #include "ServiceWorkerEvents.h"
16 #include "ServiceWorkerOpPromise.h"
17 #include "mozilla/Attributes.h"
18 #include "mozilla/Maybe.h"
19 #include "mozilla/RefPtr.h"
20 #include "mozilla/TimeStamp.h"
21 #include "mozilla/dom/PromiseNativeHandler.h"
22 #include "mozilla/dom/RemoteWorkerChild.h"
23 #include "mozilla/dom/ServiceWorkerOpArgs.h"
24 #include "mozilla/dom/WorkerRunnable.h"
26 namespace mozilla::dom
{
28 class FetchEventOpProxyChild
;
30 class ServiceWorkerOp
: public RemoteWorkerChild::Op
{
32 // `aCallback` will be called when the operation completes or is canceled.
33 static already_AddRefed
<ServiceWorkerOp
> Create(
34 ServiceWorkerOpArgs
&& aArgs
,
35 std::function
<void(const ServiceWorkerOpResult
&)>&& aCallback
);
38 ServiceWorkerOpArgs
&& aArgs
,
39 std::function
<void(const ServiceWorkerOpResult
&)>&& aCallback
);
41 ServiceWorkerOp(const ServiceWorkerOp
&) = delete;
43 ServiceWorkerOp
& operator=(const ServiceWorkerOp
&) = delete;
45 ServiceWorkerOp(ServiceWorkerOp
&&) = default;
47 ServiceWorkerOp
& operator=(ServiceWorkerOp
&&) = default;
49 // Returns `true` if the operation has started and `false` otherwise.
50 bool MaybeStart(RemoteWorkerChild
* aOwner
,
51 RemoteWorkerChild::State
& aState
) final
;
53 void StartOnMainThread(RefPtr
<RemoteWorkerChild
>& aOwner
) final
;
62 bool IsTerminationOp() const;
64 // Override to provide a runnable that's not a `ServiceWorkerOpRunnable.`
65 virtual RefPtr
<WorkerThreadRunnable
> GetRunnable(
66 WorkerPrivate
* aWorkerPrivate
);
68 // Overridden by ServiceWorkerOp subclasses, it should return true when
69 // the ServiceWorkerOp was executed successfully (and false if it did fail).
70 // Content throwing an exception during event dispatch is still considered
72 virtual bool Exec(JSContext
* aCx
, WorkerPrivate
* aWorkerPrivate
) = 0;
74 // Override to reject any additional MozPromises that subclasses may contain.
75 virtual void RejectAll(nsresult aStatus
);
77 ServiceWorkerOpArgs mArgs
;
79 // Subclasses must settle this promise when appropriate.
80 MozPromiseHolder
<ServiceWorkerOpPromise
> mPromiseHolder
;
83 class ServiceWorkerOpRunnable
;
85 bool mStarted
= false;
88 class ExtendableEventOp
: public ServiceWorkerOp
,
89 public ExtendableEventCallback
{
90 using ServiceWorkerOp::ServiceWorkerOp
;
93 ~ExtendableEventOp() = default;
95 void FinishedWithResult(ExtendableEventResult aResult
) override
;
98 class FetchEventOp final
: public ExtendableEventOp
,
99 public PromiseNativeHandler
{
100 using ExtendableEventOp::ExtendableEventOp
;
103 NS_DECL_THREADSAFE_ISUPPORTS
106 * This must be called once and only once before the first call to
107 * `MaybeStart()`; `aActor` will be used for `AsyncLog()` and
108 * `ReportCanceled().`
110 void SetActor(RefPtr
<FetchEventOpProxyChild
> aActor
);
112 void RevokeActor(FetchEventOpProxyChild
* aActor
);
114 // This must be called at most once before the first call to `MaybeStart().`
115 RefPtr
<FetchEventRespondWithPromise
> GetRespondWithPromise();
117 // This must be called when `FetchEvent::RespondWith()` is called.
118 void RespondWithCalledAt(const nsCString
& aRespondWithScriptSpec
,
119 uint32_t aRespondWithLineNumber
,
120 uint32_t aRespondWithColumnNumber
);
122 void ReportCanceled(const nsCString
& aPreventDefaultScriptSpec
,
123 uint32_t aPreventDefaultLineNumber
,
124 uint32_t aPreventDefaultColumnNumber
);
131 bool Exec(JSContext
* aCx
, WorkerPrivate
* aWorkerPrivate
) override
;
133 void RejectAll(nsresult aStatus
) override
;
135 void FinishedWithResult(ExtendableEventResult aResult
) override
;
138 * `{Resolved,Reject}Callback()` are use to handle the
139 * `FetchEvent::RespondWith()` promise.
141 void ResolvedCallback(JSContext
* aCx
, JS::Handle
<JS::Value
> aValue
,
142 ErrorResult
& aRv
) override
;
144 void RejectedCallback(JSContext
* aCx
, JS::Handle
<JS::Value
> aValue
,
145 ErrorResult
& aRv
) override
;
147 void MaybeFinished();
149 // Requires mRespondWithClosure to be non-empty.
150 void AsyncLog(const nsCString
& aMessageName
, nsTArray
<nsString
> aParams
);
152 void AsyncLog(const nsCString
& aScriptSpec
, uint32_t aLineNumber
,
153 uint32_t aColumnNumber
, const nsCString
& aMessageName
,
154 nsTArray
<nsString
> aParams
);
156 void GetRequestURL(nsAString
& aOutRequestURL
);
158 // A failure code means that the dispatch failed.
159 nsresult
DispatchFetchEvent(JSContext
* aCx
, WorkerPrivate
* aWorkerPrivate
);
161 // Worker Launcher thread only. Used for `AsyncLog().`
162 RefPtr
<FetchEventOpProxyChild
> mActor
;
165 * Created on the Worker Launcher thread and settled on the worker thread.
166 * If this isn't settled before `mPromiseHolder` (which it should be),
167 * `FetchEventOpChild` will cancel the intercepted network request.
169 MozPromiseHolder
<FetchEventRespondWithPromise
> mRespondWithPromiseHolder
;
171 // Worker thread only.
172 Maybe
<ExtendableEventResult
> mResult
;
173 bool mPostDispatchChecksDone
= false;
175 // Worker thread only; set when `FetchEvent::RespondWith()` is called.
176 Maybe
<FetchEventRespondWithClosure
> mRespondWithClosure
;
178 // Must be set to `nullptr` on the worker thread because `Promise`'s
179 // destructor must be called on the worker thread.
180 RefPtr
<Promise
> mHandled
;
182 // Must be set to `nullptr` on the worker thread because `Promise`'s
183 // destructor must be called on the worker thread.
184 RefPtr
<Promise
> mPreloadResponse
;
186 // Holds the callback that resolves mPreloadResponse.
187 MozPromiseRequestHolder
<FetchEventPreloadResponseAvailablePromise
>
188 mPreloadResponseAvailablePromiseRequestHolder
;
189 MozPromiseRequestHolder
<FetchEventPreloadResponseTimingPromise
>
190 mPreloadResponseTimingPromiseRequestHolder
;
191 MozPromiseRequestHolder
<FetchEventPreloadResponseEndPromise
>
192 mPreloadResponseEndPromiseRequestHolder
;
194 TimeStamp mFetchHandlerStart
;
195 TimeStamp mFetchHandlerFinish
;
198 } // namespace mozilla::dom
200 #endif // mozilla_dom_serviceworkerop_h__