Source code

Revision control

Other Tools

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/. */
6
7
#ifndef mozilla_dom_serviceworkerop_h__
8
#define mozilla_dom_serviceworkerop_h__
9
10
#include <functional>
11
12
#include "nsISupportsImpl.h"
13
14
#include "ServiceWorkerEvents.h"
15
#include "ServiceWorkerOpPromise.h"
16
#include "mozilla/Attributes.h"
17
#include "mozilla/Maybe.h"
18
#include "mozilla/RefPtr.h"
19
#include "mozilla/dom/PromiseNativeHandler.h"
20
#include "mozilla/dom/RemoteWorkerChild.h"
21
#include "mozilla/dom/ServiceWorkerOpArgs.h"
22
#include "mozilla/dom/WorkerRunnable.h"
23
24
namespace mozilla {
25
namespace dom {
26
27
class FetchEventOpProxyChild;
28
29
class ServiceWorkerOp : public RemoteWorkerChild::Op {
30
public:
31
// `aCallback` will be called when the operation completes or is canceled.
32
static already_AddRefed<ServiceWorkerOp> Create(
33
const ServiceWorkerOpArgs& aArgs,
34
std::function<void(const ServiceWorkerOpResult&)>&& aCallback);
35
36
ServiceWorkerOp(
37
const ServiceWorkerOpArgs& aArgs,
38
std::function<void(const ServiceWorkerOpResult&)>&& aCallback);
39
40
ServiceWorkerOp(const ServiceWorkerOp&) = delete;
41
42
ServiceWorkerOp& operator=(const ServiceWorkerOp&) = delete;
43
44
ServiceWorkerOp(ServiceWorkerOp&&) = default;
45
46
ServiceWorkerOp& operator=(ServiceWorkerOp&&) = default;
47
48
// Returns `true` if the operation has started and `false` otherwise.
49
bool MaybeStart(RemoteWorkerChild* aOwner,
50
RemoteWorkerChild::State& aState) final;
51
52
void Cancel() final;
53
54
protected:
55
~ServiceWorkerOp();
56
57
bool Started() const;
58
59
bool IsTerminationOp() const;
60
61
// Override to provide a runnable that's not a `ServiceWorkerOpRunnable.`
62
virtual RefPtr<WorkerRunnable> GetRunnable(WorkerPrivate* aWorkerPrivate);
63
64
virtual bool Exec(JSContext* aCx, WorkerPrivate* aWorkerPrivate) = 0;
65
66
// Override to reject any additional MozPromises that subclasses may contain.
67
virtual void RejectAll(nsresult aStatus);
68
69
ServiceWorkerOpArgs mArgs;
70
71
// Subclasses must settle this promise when appropriate.
72
MozPromiseHolder<ServiceWorkerOpPromise> mPromiseHolder;
73
74
private:
75
class ServiceWorkerOpRunnable;
76
77
bool mStarted = false;
78
};
79
80
class ExtendableEventOp : public ServiceWorkerOp,
81
public ExtendableEventCallback {
82
using ServiceWorkerOp::ServiceWorkerOp;
83
84
protected:
85
~ExtendableEventOp() = default;
86
87
void FinishedWithResult(ExtendableEventResult aResult) override;
88
};
89
90
class FetchEventOp final : public ExtendableEventOp,
91
public PromiseNativeHandler {
92
using ExtendableEventOp::ExtendableEventOp;
93
94
public:
95
NS_DECL_THREADSAFE_ISUPPORTS
96
97
/**
98
* This must be called once and only once before the first call to
99
* `MaybeStart()`; `aActor` will be used for `AsyncLog()` and
100
* `ReportCanceled().`
101
*/
102
void SetActor(RefPtr<FetchEventOpProxyChild> aActor);
103
104
void RevokeActor(FetchEventOpProxyChild* aActor);
105
106
// This must be called at most once before the first call to `MaybeStart().`
107
RefPtr<FetchEventRespondWithPromise> GetRespondWithPromise();
108
109
// This must be called when `FetchEvent::RespondWith()` is called.
110
void RespondWithCalledAt(const nsCString& aRespondWithScriptSpec,
111
uint32_t aRespondWithLineNumber,
112
uint32_t aRespondWithColumnNumber);
113
114
void ReportCanceled(const nsCString& aPreventDefaultScriptSpec,
115
uint32_t aPreventDefaultLineNumber,
116
uint32_t aPreventDefaultColumnNumber);
117
118
private:
119
class AutoCancel;
120
121
~FetchEventOp();
122
123
bool Exec(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override;
124
125
void RejectAll(nsresult aStatus) override;
126
127
void FinishedWithResult(ExtendableEventResult aResult) override;
128
129
/**
130
* `{Resolved,Reject}Callback()` are use to handle the
131
* `FetchEvent::RespondWith()` promise.
132
*/
133
void ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue) override;
134
135
void RejectedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue) override;
136
137
void MaybeFinished();
138
139
// Requires mRespondWithClosure to be non-empty.
140
void AsyncLog(const nsCString& aMessageName, nsTArray<nsString> aParams);
141
142
void AsyncLog(const nsCString& aScriptSpec, uint32_t aLineNumber,
143
uint32_t aColumnNumber, const nsCString& aMessageName,
144
nsTArray<nsString> aParams);
145
146
void GetRequestURL(nsAString& aOutRequestURL);
147
148
// A failure code means that the dispatch failed.
149
nsresult DispatchFetchEvent(JSContext* aCx, WorkerPrivate* aWorkerPrivate);
150
151
// Worker Launcher thread only. Used for `AsyncLog().`
152
RefPtr<FetchEventOpProxyChild> mActor;
153
154
/**
155
* Created on the Worker Launcher thread and settled on the worker thread.
156
* If this isn't settled before `mPromiseHolder` (which it should be),
157
* `FetchEventOpChild` will cancel the intercepted network request.
158
*/
159
MozPromiseHolder<FetchEventRespondWithPromise> mRespondWithPromiseHolder;
160
161
// Worker thread only.
162
Maybe<ExtendableEventResult> mResult;
163
bool mPostDispatchChecksDone = false;
164
165
// Worker thread only; set when `FetchEvent::RespondWith()` is called.
166
Maybe<FetchEventRespondWithClosure> mRespondWithClosure;
167
};
168
169
} // namespace dom
170
} // namespace mozilla
171
172
#endif // mozilla_dom_serviceworkerop_h__