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
#include "RemoteServiceWorkerContainerImpl.h"
8
9
#include "mozilla/ipc/BackgroundChild.h"
10
#include "mozilla/ipc/PBackgroundChild.h"
11
#include "ServiceWorkerContainerChild.h"
12
13
namespace mozilla {
14
namespace dom {
15
16
using mozilla::ipc::BackgroundChild;
17
using mozilla::ipc::PBackgroundChild;
18
using mozilla::ipc::ResponseRejectReason;
19
20
RemoteServiceWorkerContainerImpl::~RemoteServiceWorkerContainerImpl() {
21
Shutdown();
22
MOZ_DIAGNOSTIC_ASSERT(!mOuter);
23
}
24
25
void RemoteServiceWorkerContainerImpl::Shutdown() {
26
if (mShutdown) {
27
return;
28
}
29
mShutdown = true;
30
31
if (mActor) {
32
mActor->RevokeOwner(this);
33
mActor->MaybeStartTeardown();
34
mActor = nullptr;
35
}
36
}
37
38
void RemoteServiceWorkerContainerImpl::AddContainer(
39
ServiceWorkerContainer* aOuter) {
40
MOZ_DIAGNOSTIC_ASSERT(aOuter);
41
MOZ_DIAGNOSTIC_ASSERT(!mOuter);
42
mOuter = aOuter;
43
}
44
45
void RemoteServiceWorkerContainerImpl::RemoveContainer(
46
ServiceWorkerContainer* aOuter) {
47
MOZ_DIAGNOSTIC_ASSERT(aOuter);
48
MOZ_DIAGNOSTIC_ASSERT(mOuter == aOuter);
49
mOuter = nullptr;
50
}
51
52
void RemoteServiceWorkerContainerImpl::Register(
53
const ClientInfo& aClientInfo, const nsACString& aScopeURL,
54
const nsACString& aScriptURL, ServiceWorkerUpdateViaCache aUpdateViaCache,
55
ServiceWorkerRegistrationCallback&& aSuccessCB,
56
ServiceWorkerFailureCallback&& aFailureCB) const {
57
if (!mActor) {
58
aFailureCB(CopyableErrorResult(NS_ERROR_DOM_INVALID_STATE_ERR));
59
return;
60
}
61
62
mActor->SendRegister(
63
aClientInfo.ToIPC(), nsCString(aScopeURL), nsCString(aScriptURL),
64
aUpdateViaCache,
65
[successCB = std::move(aSuccessCB), aFailureCB](
66
const IPCServiceWorkerRegistrationDescriptorOrCopyableErrorResult&
67
aResult) {
68
if (aResult.type() ==
69
IPCServiceWorkerRegistrationDescriptorOrCopyableErrorResult::
70
TCopyableErrorResult) {
71
// application layer error
72
auto& rv = aResult.get_CopyableErrorResult();
73
MOZ_DIAGNOSTIC_ASSERT(rv.Failed());
74
aFailureCB(CopyableErrorResult(rv));
75
return;
76
}
77
// success
78
auto& ipcDesc = aResult.get_IPCServiceWorkerRegistrationDescriptor();
79
successCB(ServiceWorkerRegistrationDescriptor(ipcDesc));
80
},
81
[aFailureCB](ResponseRejectReason&& aReason) {
82
// IPC layer error
83
aFailureCB(CopyableErrorResult(NS_ERROR_DOM_INVALID_STATE_ERR));
84
});
85
}
86
87
void RemoteServiceWorkerContainerImpl::GetRegistration(
88
const ClientInfo& aClientInfo, const nsACString& aURL,
89
ServiceWorkerRegistrationCallback&& aSuccessCB,
90
ServiceWorkerFailureCallback&& aFailureCB) const {
91
if (!mActor) {
92
aFailureCB(CopyableErrorResult(NS_ERROR_DOM_INVALID_STATE_ERR));
93
return;
94
}
95
96
mActor->SendGetRegistration(
97
aClientInfo.ToIPC(), nsCString(aURL),
98
[successCB = std::move(aSuccessCB), aFailureCB](
99
const IPCServiceWorkerRegistrationDescriptorOrCopyableErrorResult&
100
aResult) {
101
if (aResult.type() ==
102
IPCServiceWorkerRegistrationDescriptorOrCopyableErrorResult::
103
TCopyableErrorResult) {
104
auto& rv = aResult.get_CopyableErrorResult();
105
// If rv is a failure then this is an application layer error. Note,
106
// though, we also reject with NS_OK to indicate that we just didn't
107
// find a registration.
108
aFailureCB(CopyableErrorResult(rv));
109
return;
110
}
111
// success
112
auto& ipcDesc = aResult.get_IPCServiceWorkerRegistrationDescriptor();
113
successCB(ServiceWorkerRegistrationDescriptor(ipcDesc));
114
},
115
[aFailureCB](ResponseRejectReason&& aReason) {
116
// IPC layer error
117
aFailureCB(CopyableErrorResult(NS_ERROR_DOM_INVALID_STATE_ERR));
118
});
119
}
120
121
void RemoteServiceWorkerContainerImpl::GetRegistrations(
122
const ClientInfo& aClientInfo,
123
ServiceWorkerRegistrationListCallback&& aSuccessCB,
124
ServiceWorkerFailureCallback&& aFailureCB) const {
125
if (!mActor) {
126
aFailureCB(CopyableErrorResult(NS_ERROR_DOM_INVALID_STATE_ERR));
127
return;
128
}
129
130
mActor->SendGetRegistrations(
131
aClientInfo.ToIPC(),
132
[successCB = std::move(aSuccessCB), aFailureCB](
133
const IPCServiceWorkerRegistrationDescriptorListOrCopyableErrorResult&
134
aResult) {
135
if (aResult.type() ==
136
IPCServiceWorkerRegistrationDescriptorListOrCopyableErrorResult::
137
TCopyableErrorResult) {
138
// application layer error
139
auto& rv = aResult.get_CopyableErrorResult();
140
MOZ_DIAGNOSTIC_ASSERT(rv.Failed());
141
aFailureCB(CopyableErrorResult(rv));
142
return;
143
}
144
// success
145
auto& ipcList =
146
aResult.get_IPCServiceWorkerRegistrationDescriptorList();
147
nsTArray<ServiceWorkerRegistrationDescriptor> list(
148
ipcList.values().Length());
149
for (auto& ipcDesc : ipcList.values()) {
150
list.AppendElement(ServiceWorkerRegistrationDescriptor(ipcDesc));
151
}
152
successCB(std::move(list));
153
},
154
[aFailureCB](ResponseRejectReason&& aReason) {
155
// IPC layer error
156
aFailureCB(CopyableErrorResult(NS_ERROR_DOM_INVALID_STATE_ERR));
157
});
158
}
159
160
void RemoteServiceWorkerContainerImpl::GetReady(
161
const ClientInfo& aClientInfo,
162
ServiceWorkerRegistrationCallback&& aSuccessCB,
163
ServiceWorkerFailureCallback&& aFailureCB) const {
164
if (!mActor) {
165
aFailureCB(CopyableErrorResult(NS_ERROR_DOM_INVALID_STATE_ERR));
166
return;
167
}
168
169
mActor->SendGetReady(
170
aClientInfo.ToIPC(),
171
[successCB = std::move(aSuccessCB), aFailureCB](
172
const IPCServiceWorkerRegistrationDescriptorOrCopyableErrorResult&
173
aResult) {
174
if (aResult.type() ==
175
IPCServiceWorkerRegistrationDescriptorOrCopyableErrorResult::
176
TCopyableErrorResult) {
177
// application layer error
178
auto& rv = aResult.get_CopyableErrorResult();
179
MOZ_DIAGNOSTIC_ASSERT(rv.Failed());
180
aFailureCB(CopyableErrorResult(rv));
181
return;
182
}
183
// success
184
auto& ipcDesc = aResult.get_IPCServiceWorkerRegistrationDescriptor();
185
successCB(ServiceWorkerRegistrationDescriptor(ipcDesc));
186
},
187
[aFailureCB](ResponseRejectReason&& aReason) {
188
// IPC layer error
189
aFailureCB(CopyableErrorResult(NS_ERROR_DOM_INVALID_STATE_ERR));
190
});
191
}
192
193
RemoteServiceWorkerContainerImpl::RemoteServiceWorkerContainerImpl()
194
: mActor(nullptr), mOuter(nullptr), mShutdown(false) {
195
PBackgroundChild* parentActor =
196
BackgroundChild::GetOrCreateForCurrentThread();
197
if (NS_WARN_IF(!parentActor)) {
198
Shutdown();
199
return;
200
}
201
202
ServiceWorkerContainerChild* actor = ServiceWorkerContainerChild::Create();
203
if (NS_WARN_IF(!actor)) {
204
Shutdown();
205
return;
206
}
207
208
PServiceWorkerContainerChild* sentActor =
209
parentActor->SendPServiceWorkerContainerConstructor(actor);
210
if (NS_WARN_IF(!sentActor)) {
211
Shutdown();
212
return;
213
}
214
MOZ_DIAGNOSTIC_ASSERT(sentActor == actor);
215
216
mActor = actor;
217
mActor->SetOwner(this);
218
}
219
220
void RemoteServiceWorkerContainerImpl::RevokeActor(
221
ServiceWorkerContainerChild* aActor) {
222
MOZ_DIAGNOSTIC_ASSERT(mActor);
223
MOZ_DIAGNOSTIC_ASSERT(mActor == aActor);
224
mActor->RevokeOwner(this);
225
mActor = nullptr;
226
227
mShutdown = true;
228
}
229
230
} // namespace dom
231
} // namespace mozilla