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 "mozilla/dom/ServiceWorkerRegistrationDescriptor.h"
8
9
#include "mozilla/dom/IPCServiceWorkerRegistrationDescriptor.h"
10
#include "mozilla/ipc/PBackgroundSharedTypes.h"
11
#include "ServiceWorkerInfo.h"
12
13
namespace mozilla {
14
namespace dom {
15
16
using mozilla::ipc::PrincipalInfo;
17
using mozilla::ipc::PrincipalInfoToPrincipal;
18
19
Maybe<IPCServiceWorkerDescriptor>
20
ServiceWorkerRegistrationDescriptor::NewestInternal() const {
21
Maybe<IPCServiceWorkerDescriptor> result;
22
if (mData->installing().isSome()) {
23
result.emplace(mData->installing().ref());
24
} else if (mData->waiting().isSome()) {
25
result.emplace(mData->waiting().ref());
26
} else if (mData->active().isSome()) {
27
result.emplace(mData->active().ref());
28
}
29
return result;
30
}
31
32
ServiceWorkerRegistrationDescriptor::ServiceWorkerRegistrationDescriptor(
33
uint64_t aId, uint64_t aVersion, nsIPrincipal* aPrincipal,
34
const nsACString& aScope, ServiceWorkerUpdateViaCache aUpdateViaCache)
35
: mData(MakeUnique<IPCServiceWorkerRegistrationDescriptor>()) {
36
MOZ_ALWAYS_SUCCEEDS(
37
PrincipalToPrincipalInfo(aPrincipal, &mData->principalInfo()));
38
39
mData->id() = aId;
40
mData->version() = aVersion;
41
mData->scope() = aScope;
42
mData->updateViaCache() = aUpdateViaCache;
43
mData->installing() = Nothing();
44
mData->waiting() = Nothing();
45
mData->active() = Nothing();
46
}
47
48
ServiceWorkerRegistrationDescriptor::ServiceWorkerRegistrationDescriptor(
49
uint64_t aId, uint64_t aVersion,
50
const mozilla::ipc::PrincipalInfo& aPrincipalInfo, const nsACString& aScope,
51
ServiceWorkerUpdateViaCache aUpdateViaCache)
52
: mData(MakeUnique<IPCServiceWorkerRegistrationDescriptor>(
53
aId, aVersion, aPrincipalInfo, nsCString(aScope), aUpdateViaCache,
54
Nothing(), Nothing(), Nothing())) {}
55
56
ServiceWorkerRegistrationDescriptor::ServiceWorkerRegistrationDescriptor(
57
const IPCServiceWorkerRegistrationDescriptor& aDescriptor)
58
: mData(MakeUnique<IPCServiceWorkerRegistrationDescriptor>(aDescriptor)) {
59
MOZ_DIAGNOSTIC_ASSERT(IsValid());
60
}
61
62
ServiceWorkerRegistrationDescriptor::ServiceWorkerRegistrationDescriptor(
63
const ServiceWorkerRegistrationDescriptor& aRight) {
64
// UniquePtr doesn't have a default copy constructor, so we can't rely
65
// on default copy construction. Use the assignment operator to
66
// minimize duplication.
67
operator=(aRight);
68
}
69
70
ServiceWorkerRegistrationDescriptor&
71
ServiceWorkerRegistrationDescriptor::operator=(
72
const ServiceWorkerRegistrationDescriptor& aRight) {
73
if (this == &aRight) {
74
return *this;
75
}
76
mData.reset();
77
mData = MakeUnique<IPCServiceWorkerRegistrationDescriptor>(*aRight.mData);
78
MOZ_DIAGNOSTIC_ASSERT(IsValid());
79
return *this;
80
}
81
82
ServiceWorkerRegistrationDescriptor::ServiceWorkerRegistrationDescriptor(
83
ServiceWorkerRegistrationDescriptor&& aRight)
84
: mData(std::move(aRight.mData)) {
85
MOZ_DIAGNOSTIC_ASSERT(IsValid());
86
}
87
88
ServiceWorkerRegistrationDescriptor&
89
ServiceWorkerRegistrationDescriptor::operator=(
90
ServiceWorkerRegistrationDescriptor&& aRight) {
91
mData.reset();
92
mData = std::move(aRight.mData);
93
MOZ_DIAGNOSTIC_ASSERT(IsValid());
94
return *this;
95
}
96
97
ServiceWorkerRegistrationDescriptor::~ServiceWorkerRegistrationDescriptor() {
98
// Non-default destructor to avoid exposing the IPC type in the header.
99
}
100
101
bool ServiceWorkerRegistrationDescriptor::operator==(
102
const ServiceWorkerRegistrationDescriptor& aRight) const {
103
return *mData == *aRight.mData;
104
}
105
106
uint64_t ServiceWorkerRegistrationDescriptor::Id() const { return mData->id(); }
107
108
uint64_t ServiceWorkerRegistrationDescriptor::Version() const {
109
return mData->version();
110
}
111
112
ServiceWorkerUpdateViaCache
113
ServiceWorkerRegistrationDescriptor::UpdateViaCache() const {
114
return mData->updateViaCache();
115
}
116
117
const mozilla::ipc::PrincipalInfo&
118
ServiceWorkerRegistrationDescriptor::PrincipalInfo() const {
119
return mData->principalInfo();
120
}
121
122
nsCOMPtr<nsIPrincipal> ServiceWorkerRegistrationDescriptor::GetPrincipal()
123
const {
124
AssertIsOnMainThread();
125
nsCOMPtr<nsIPrincipal> ref = PrincipalInfoToPrincipal(mData->principalInfo());
126
return ref;
127
}
128
129
const nsCString& ServiceWorkerRegistrationDescriptor::Scope() const {
130
return mData->scope();
131
}
132
133
Maybe<ServiceWorkerDescriptor>
134
ServiceWorkerRegistrationDescriptor::GetInstalling() const {
135
Maybe<ServiceWorkerDescriptor> result;
136
137
if (mData->installing().isSome()) {
138
result.emplace(ServiceWorkerDescriptor(mData->installing().ref()));
139
}
140
141
return result;
142
}
143
144
Maybe<ServiceWorkerDescriptor> ServiceWorkerRegistrationDescriptor::GetWaiting()
145
const {
146
Maybe<ServiceWorkerDescriptor> result;
147
148
if (mData->waiting().isSome()) {
149
result.emplace(ServiceWorkerDescriptor(mData->waiting().ref()));
150
}
151
152
return result;
153
}
154
155
Maybe<ServiceWorkerDescriptor> ServiceWorkerRegistrationDescriptor::GetActive()
156
const {
157
Maybe<ServiceWorkerDescriptor> result;
158
159
if (mData->active().isSome()) {
160
result.emplace(ServiceWorkerDescriptor(mData->active().ref()));
161
}
162
163
return result;
164
}
165
166
Maybe<ServiceWorkerDescriptor> ServiceWorkerRegistrationDescriptor::Newest()
167
const {
168
Maybe<ServiceWorkerDescriptor> result;
169
Maybe<IPCServiceWorkerDescriptor> newest(NewestInternal());
170
if (newest.isSome()) {
171
result.emplace(ServiceWorkerDescriptor(newest.ref()));
172
}
173
return result;
174
}
175
176
bool ServiceWorkerRegistrationDescriptor::HasWorker(
177
const ServiceWorkerDescriptor& aDescriptor) const {
178
Maybe<ServiceWorkerDescriptor> installing = GetInstalling();
179
Maybe<ServiceWorkerDescriptor> waiting = GetWaiting();
180
Maybe<ServiceWorkerDescriptor> active = GetActive();
181
return (installing.isSome() && installing.ref().Matches(aDescriptor)) ||
182
(waiting.isSome() && waiting.ref().Matches(aDescriptor)) ||
183
(active.isSome() && active.ref().Matches(aDescriptor));
184
}
185
186
namespace {
187
188
bool IsValidWorker(
189
const Maybe<IPCServiceWorkerDescriptor>& aWorker, const nsACString& aScope,
190
const mozilla::ipc::ContentPrincipalInfo& aContentPrincipal) {
191
if (aWorker.isNothing()) {
192
return true;
193
}
194
195
auto& worker = aWorker.ref();
196
if (worker.scope() != aScope) {
197
return false;
198
}
199
200
auto& principalInfo = worker.principalInfo();
201
if (principalInfo.type() !=
202
mozilla::ipc::PrincipalInfo::TContentPrincipalInfo) {
203
return false;
204
}
205
206
auto& contentPrincipal = principalInfo.get_ContentPrincipalInfo();
207
if (contentPrincipal.originNoSuffix() != aContentPrincipal.originNoSuffix() ||
208
contentPrincipal.attrs() != aContentPrincipal.attrs()) {
209
return false;
210
}
211
212
return true;
213
}
214
215
} // anonymous namespace
216
217
bool ServiceWorkerRegistrationDescriptor::IsValid() const {
218
auto& principalInfo = PrincipalInfo();
219
if (principalInfo.type() !=
220
mozilla::ipc::PrincipalInfo::TContentPrincipalInfo) {
221
return false;
222
}
223
224
auto& contentPrincipal = principalInfo.get_ContentPrincipalInfo();
225
if (!IsValidWorker(mData->installing(), Scope(), contentPrincipal) ||
226
!IsValidWorker(mData->waiting(), Scope(), contentPrincipal) ||
227
!IsValidWorker(mData->active(), Scope(), contentPrincipal)) {
228
return false;
229
}
230
231
return true;
232
}
233
234
void ServiceWorkerRegistrationDescriptor::SetUpdateViaCache(
235
ServiceWorkerUpdateViaCache aUpdateViaCache) {
236
mData->updateViaCache() = aUpdateViaCache;
237
}
238
239
void ServiceWorkerRegistrationDescriptor::SetWorkers(
240
ServiceWorkerInfo* aInstalling, ServiceWorkerInfo* aWaiting,
241
ServiceWorkerInfo* aActive) {
242
if (aInstalling) {
243
aInstalling->SetRegistrationVersion(Version());
244
mData->installing() = Some(aInstalling->Descriptor().ToIPC());
245
} else {
246
mData->installing() = Nothing();
247
}
248
249
if (aWaiting) {
250
aWaiting->SetRegistrationVersion(Version());
251
mData->waiting() = Some(aWaiting->Descriptor().ToIPC());
252
} else {
253
mData->waiting() = Nothing();
254
}
255
256
if (aActive) {
257
aActive->SetRegistrationVersion(Version());
258
mData->active() = Some(aActive->Descriptor().ToIPC());
259
} else {
260
mData->active() = Nothing();
261
}
262
263
MOZ_DIAGNOSTIC_ASSERT(IsValid());
264
}
265
266
void ServiceWorkerRegistrationDescriptor::SetVersion(uint64_t aVersion) {
267
MOZ_DIAGNOSTIC_ASSERT(aVersion > mData->version());
268
mData->version() = aVersion;
269
}
270
271
const IPCServiceWorkerRegistrationDescriptor&
272
ServiceWorkerRegistrationDescriptor::ToIPC() const {
273
return *mData;
274
}
275
276
} // namespace dom
277
} // namespace mozilla