Coverage Report

Created: 2018-09-25 14:53

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