Attachment #8736435: Unified diff (WIP) for bug #1217544

View | Details | Raw Unified | Return to bug 1217544
Collapse All | Expand All

(-)a/dom/bindings/Bindings.conf (+6 lines)
Line     Link Here 
 Lines 1273-1288   DOMInterfaces = { Link Here 
1273
'SVGUnitTypes' : {
1273
'SVGUnitTypes' : {
1274
    'concrete': False,
1274
    'concrete': False,
1275
},
1275
},
1276
1276
1277
'SVGZoomAndPan' : {
1277
'SVGZoomAndPan' : {
1278
    'concrete': False,
1278
    'concrete': False,
1279
},
1279
},
1280
1280
1281
'SyncEvent': {
1282
    'headerFile': 'mozilla/dom/ServiceWorkerEvents.h',
1283
    'nativeType': 'mozilla::dom::workers::SyncEvent',
1284
    'workers': True
1285
},
1286
1281
'TestFunctions': {
1287
'TestFunctions': {
1282
    'wrapperCache': False
1288
    'wrapperCache': False
1283
},
1289
},
1284
1290
1285
'Text': {
1291
'Text': {
1286
    # Total hack to allow binding code to realize that nsTextNode can
1292
    # Total hack to allow binding code to realize that nsTextNode can
1287
    # in fact be cast to Text.
1293
    # in fact be cast to Text.
1288
    'headerFile': 'nsTextNode.h',
1294
    'headerFile': 'nsTextNode.h',
(-)a/dom/interfaces/base/nsIServiceWorkerManager.idl (+5 lines)
Line     Link Here 
 Lines 192-204   interface nsIServiceWorkerManager : nsIS Link Here 
192
  void sendPushSubscriptionChangeEvent(in ACString aOriginAttributes,
192
  void sendPushSubscriptionChangeEvent(in ACString aOriginAttributes,
193
                                       in ACString scope);
193
                                       in ACString scope);
194
194
195
  void addListener(in nsIServiceWorkerManagerListener aListener);
195
  void addListener(in nsIServiceWorkerManagerListener aListener);
196
196
197
  void removeListener(in nsIServiceWorkerManagerListener aListener);
197
  void removeListener(in nsIServiceWorkerManagerListener aListener);
198
198
199
  bool shouldReportToWindow(in mozIDOMWindowProxy aWindow, in ACString aScope);
199
  bool shouldReportToWindow(in mozIDOMWindowProxy aWindow, in ACString aScope);
200
201
  void sendSyncEvent(in ACString aOriginAttributes,
202
                     in ACString scope,
203
                     in AString aTag,
204
                     in boolean aLastChance);
200
};
205
};
201
206
202
%{ C++
207
%{ C++
203
#define SERVICEWORKERMANAGER_CONTRACTID "@mozilla.org/serviceworkers/manager;1"
208
#define SERVICEWORKERMANAGER_CONTRACTID "@mozilla.org/serviceworkers/manager;1"
204
%}
209
%}
(-)a/dom/moz.build (+1 lines)
Line     Link Here 
 Lines 96-111   DIRS += [ Link Here 
96
    'ipc',
96
    'ipc',
97
    'workers',
97
    'workers',
98
    'camera',
98
    'camera',
99
    'audiochannel',
99
    'audiochannel',
100
    'broadcastchannel',
100
    'broadcastchannel',
101
    'messagechannel',
101
    'messagechannel',
102
    'promise',
102
    'promise',
103
    'smil',
103
    'smil',
104
    'sync',
104
    'telephony',
105
    'telephony',
105
    'tv',
106
    'tv',
106
    'voicemail',
107
    'voicemail',
107
    'inputmethod',
108
    'inputmethod',
108
    'webidl',
109
    'webidl',
109
    'xbl',
110
    'xbl',
110
    'xml',
111
    'xml',
111
    'xslt',
112
    'xslt',
(-)a/dom/sync/PSyncManager.ipdl (+28 lines)
Line     Link Here 
Line 0    Link Here 
1
/* This Source Code Form is subject to the terms of the Mozilla Public
2
 * License, v. 2.0. If a copy of the MPL was not distributed with this
3
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5
include protocol PBackground;
6
7
include SyncIPCTypes;
8
9
using struct nsID from "nsID.h";
10
11
namespace mozilla {
12
namespace dom {
13
14
protocol PSyncManager
15
{
16
  manager PBackground;
17
18
parent: // child -> parent messages
19
  async Request(nsID aRequestId, SyncOp aOp);
20
  async Shutdown();
21
22
child: // parent -> child messages
23
  async Response(nsID requestId, SyncOpResponse aResponse);
24
  async __delete__();
25
};
26
27
} // namespace dom
28
} // namespace mozilla
(-)a/dom/sync/SyncIPCTypes.ipdlh (+88 lines)
Line     Link Here 
Line 0    Link Here 
1
/* This Source Code Form is subject to the terms of the Mozilla Public
2
 * License, v. 2.0. If a copy of the MPL was not distributed with this
3
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5
include PBackgroundSharedTypes;
6
7
namespace mozilla {
8
namespace dom {
9
10
struct SyncRegisterArgs
11
{
12
  nsString mScope;
13
  nsString mTag;
14
};
15
16
struct SyncGetTagsArgs
17
{
18
  nsString mScope;
19
};
20
21
union SyncOpArgs
22
{
23
  SyncRegisterArgs;
24
  SyncGetTagsArgs;
25
};
26
27
struct SyncOp
28
{
29
  PrincipalInfo mPrincipal;
30
  SyncOpArgs mArgs;
31
};
32
33
struct SyncGetAllArgs
34
{
35
};
36
37
struct SyncChangeStateArgs
38
{
39
  nsString mId;
40
  uint16_t mState;
41
};
42
43
struct SyncRemoveArgs
44
{
45
  nsString mId;
46
};
47
48
union SyncInternalOpArgs
49
{
50
  SyncGetAllArgs;
51
  SyncChangeStateArgs;
52
  SyncRemoveArgs;
53
};
54
55
struct SyncInternalOp
56
{
57
  SyncInternalOpArgs mArgs;
58
};
59
60
union SyncOpOrInternalOp
61
{
62
  SyncOp;
63
  SyncInternalOp;
64
};
65
66
struct SyncRegisterResponse
67
{
68
};
69
70
struct SyncGetTagsResponse
71
{
72
  nsString[] mTags;
73
};
74
75
struct SyncOpError
76
{
77
  uint32_t mCode;
78
};
79
80
union SyncOpResponse
81
{
82
  SyncRegisterResponse;
83
  SyncGetTagsResponse;
84
  SyncOpError;
85
};
86
87
} // namespace dom
88
} // namespace mozilla
(-)a/dom/sync/SyncManager.cpp (+440 lines)
Line     Link Here 
Line 0    Link Here 
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 file,
5
 * You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7
#include "SyncManager.h"
8
#include "SyncManagerChild.h"
9
10
#include "mozilla/dom/Promise.h"
11
#include "mozilla/dom/PromiseWorkerProxy.h"
12
#include "mozilla/dom/SyncIPCTypes.h"
13
#include "mozilla/dom/SyncManagerBinding.h"
14
#include "mozilla/ipc/BackgroundChild.h"
15
#include "mozilla/ipc/BackgroundUtils.h"
16
#include "mozilla/ipc/PBackgroundChild.h"
17
#include "mozilla/Preferences.h"
18
#include "mozilla/unused.h"
19
#include "nsIGlobalObject.h"
20
#include "nsISupportsPrimitives.h"
21
#include "WorkerPrivate.h"
22
23
namespace mozilla {
24
25
using namespace ipc;
26
27
namespace dom {
28
29
using namespace workers;
30
31
// Helpers
32
33
class SyncOpRunnable final : public nsICancelableRunnable
34
{
35
public:
36
  NS_DECL_ISUPPORTS
37
38
  SyncOpRunnable(Promise* aPromise, nsAutoPtr<SyncOp>& aOp)
39
    : mPromise(aPromise)
40
    , mOp(aOp)
41
  {
42
    MOZ_ASSERT(mPromise);
43
    MOZ_ASSERT(mOp);
44
  }
45
46
  void SetActor(SyncManagerChild* aActor)
47
  {
48
    MOZ_ASSERT(!mActor);
49
    MOZ_ASSERT(aActor);
50
    mActor = aActor;
51
  }
52
53
  NS_IMETHODIMP Run() override
54
  {
55
    MOZ_ASSERT(mActor);
56
    if (mActor->IsActorDestroyed()) {
57
      return NS_OK;
58
    }
59
60
    return mActor->ExecuteOp(mPromise, mOp);
61
  }
62
63
  NS_IMETHODIMP Cancel() override
64
  {
65
    mActor = nullptr;
66
    mPromise = nullptr;
67
    mOp = nullptr;
68
    return NS_OK;
69
  }
70
71
private:
72
  ~SyncOpRunnable() {}
73
74
  RefPtr<Promise> mPromise;
75
  nsAutoPtr<SyncOp> mOp;
76
  RefPtr<SyncManagerChild> mActor;
77
};
78
79
NS_IMPL_ISUPPORTS(SyncOpRunnable, nsICancelableRunnable, nsIRunnable)
80
81
class TeardownRunnable final : public nsICancelableRunnable
82
{
83
public:
84
  NS_DECL_ISUPPORTS
85
86
  explicit TeardownRunnable(SyncManagerChild* aActor)
87
    : mActor(aActor)
88
  {
89
    MOZ_ASSERT(mActor);
90
  }
91
92
  NS_IMETHODIMP Run() override
93
  {
94
    MOZ_ASSERT(mActor);
95
    if (!mActor->IsActorDestroyed()) {
96
      mActor->SendShutdown();
97
    }
98
    return NS_OK;
99
  }
100
101
  NS_IMETHODIMP Cancel() override
102
  {
103
    mActor = nullptr;
104
    return NS_OK;
105
  }
106
107
private:
108
  ~TeardownRunnable() {};
109
110
  RefPtr<SyncManagerChild> mActor;
111
};
112
113
NS_IMPL_ISUPPORTS(TeardownRunnable, nsICancelableRunnable, nsIRunnable)
114
115
class SyncManagerFeature final : public workers::WorkerFeature
116
{
117
  // The manager keeps alive this feature.
118
  SyncManager* MOZ_NON_OWNING_REF mManager;
119
120
public:
121
  explicit SyncManagerFeature(SyncManager* aManager)
122
    : mManager(aManager)
123
  {
124
    MOZ_ASSERT(aManager);
125
    MOZ_COUNT_CTOR(SyncManagerFeature);
126
  }
127
128
  virtual bool Notify(JSContext* aCtx, workers::Status aStatus) override
129
  {
130
    if (aStatus >= Closing) {
131
      mManager->Shutdown();
132
    }
133
    return true;
134
  }
135
136
private:
137
  ~SyncManagerFeature()
138
  {
139
    MOZ_COUNT_CTOR(SyncManagerFeature);
140
  }
141
};
142
143
// SyncManager
144
145
// static
146
already_AddRefed<SyncManager>
147
SyncManager::CreateOnMainThread(nsIGlobalObject* aGlobal,
148
                                nsIPrincipal* aPrincipal,
149
                                const nsAString& aScope,
150
                                ErrorResult& aRv)
151
{
152
  MOZ_ASSERT(aGlobal);
153
  MOZ_ASSERT(aPrincipal);
154
  MOZ_ASSERT(!aScope.IsEmpty());
155
  MOZ_ASSERT(NS_IsMainThread());
156
157
  PrincipalInfo principalInfo;
158
  aRv = PrincipalToPrincipalInfo(aPrincipal, &principalInfo);
159
  if (NS_WARN_IF(aRv.Failed())) {
160
    return nullptr;
161
  }
162
163
  RefPtr<SyncManager> ref = new SyncManager(aGlobal, principalInfo, aScope);
164
165
  // Register as observer for inner-window-destroyed.
166
  nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
167
  if (obs) {
168
    aRv = obs->AddObserver(ref, "inner-window-destroyed",
169
                           false /* ownsWeak */);
170
    if (NS_WARN_IF(aRv.Failed())) {
171
      return nullptr;
172
    }
173
  } else {
174
    aRv.Throw(NS_ERROR_UNEXPECTED);
175
    return nullptr;
176
  }
177
178
  nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(aGlobal);
179
  MOZ_ASSERT(window);
180
  MOZ_ASSERT(window->IsInnerWindow());
181
  ref->mInnerID = window->WindowID();
182
183
  return ref.forget();
184
}
185
186
// static
187
already_AddRefed<SyncManager>
188
SyncManager::CreateOnWorker(nsIGlobalObject* aGlobal,
189
                            WorkerPrivate* aWorkerPrivate,
190
                            const nsAString& aScope)
191
{
192
  MOZ_ASSERT(aWorkerPrivate);
193
  MOZ_ASSERT(!aScope.IsEmpty());
194
  aWorkerPrivate->AssertIsOnWorkerThread();
195
196
  const PrincipalInfo& principalInfo = aWorkerPrivate->GetPrincipalInfo();
197
198
  RefPtr<SyncManager> ref = new SyncManager(aGlobal, principalInfo, aScope);
199
200
  ref->mWorkerFeature = new SyncManagerFeature(ref);
201
  if (NS_WARN_IF(!aWorkerPrivate->AddFeature(ref->mWorkerFeature))) {
202
    ref->mWorkerFeature = nullptr;
203
    return nullptr;
204
  }
205
206
  return ref.forget();
207
}
208
209
SyncManager::SyncManager(nsIGlobalObject* aGlobal,
210
                         const PrincipalInfo& aPrincipalInfo,
211
                         const nsAString& aScope)
212
  : mInnerID(0)
213
  , mGlobal(aGlobal)
214
  , mShuttingDown(false)
215
  , mPrincipalInfo(MakeUnique<PrincipalInfo>(aPrincipalInfo))
216
  , mScope(aScope)
217
{
218
#ifdef DEBUG
219
  mThread = do_GetCurrentThread();
220
#endif
221
222
  MOZ_ASSERT(aGlobal);
223
224
  // Register this component to PBackground.
225
  PBackgroundChild* actor = BackgroundChild::GetForCurrentThread();
226
  if (actor) {
227
    ActorCreated(actor);
228
  } else {
229
    MOZ_ALWAYS_TRUE(BackgroundChild::GetOrCreateForCurrentThread(this));
230
  }
231
}
232
233
SyncManager::~SyncManager()
234
{
235
  MOZ_ASSERT(IsSyncManagerThread());
236
237
  Shutdown();
238
  MOZ_ASSERT(!mWorkerFeature);
239
  MOZ_ASSERT(!mActor);
240
}
241
242
bool
243
SyncManager::IsSyncManagerThread() {
244
  return mThread == nsCOMPtr<nsIThread>(do_GetCurrentThread());
245
};
246
247
void
248
SyncManager::Shutdown()
249
{
250
  MOZ_ASSERT(IsSyncManagerThread());
251
252
  if (mShuttingDown) {
253
    return;
254
  }
255
256
  mShuttingDown = true;
257
258
  if (NS_IsMainThread()) {
259
    nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
260
    if (obs) {
261
      obs->RemoveObserver(this, "inner-window-destroyed");
262
    }
263
  }
264
265
  if (mWorkerFeature) {
266
    WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
267
    MOZ_ASSERT(workerPrivate);
268
    workerPrivate->AssertIsOnWorkerThread();
269
    workerPrivate->RemoveFeature(mWorkerFeature);
270
    mWorkerFeature = nullptr;
271
  }
272
273
  if (mActor) {
274
    RefPtr<TeardownRunnable> runnable = new TeardownRunnable(mActor);
275
    Unused << NS_WARN_IF(NS_FAILED(NS_DispatchToCurrentThread(runnable)));
276
    mActor = nullptr;
277
  }
278
279
  mPendingOperations.Clear();
280
}
281
282
// Bindings methods.
283
284
JSObject*
285
SyncManager::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
286
{
287
  MOZ_ASSERT(IsSyncManagerThread());
288
289
  return SyncManagerBinding::Wrap(aCx, this, aGivenProto);
290
}
291
292
// static
293
bool
294
SyncManager::PrefEnabled(JSContext* aCx, JSObject* aObj)
295
{
296
  using mozilla::dom::workers::WorkerPrivate;
297
  using mozilla::dom::workers::GetWorkerPrivateFromContext;
298
299
  // If we are on the main thread, then check the pref directly.
300
  if (NS_IsMainThread()) {
301
    bool enabled = false;
302
    Preferences::GetBool("dom.background.sync.enabled", &enabled);
303
    return enabled;
304
  }
305
306
  // Otherwise check the pref via the worker private helper.
307
  WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(aCx);
308
  if (!workerPrivate) {
309
    return false;
310
  }
311
312
  return workerPrivate->BackgroundSyncEnabled();
313
}
314
315
// nsIIPCBackgroundChildCreateCallback methods.
316
317
void
318
SyncManager::ActorFailed()
319
{
320
  MOZ_CRASH("Failed to create a PBackgroundChild actor!");
321
}
322
323
void
324
SyncManager::ActorCreated(PBackgroundChild* aActor)
325
{
326
  MOZ_ASSERT(IsSyncManagerThread());
327
  MOZ_ASSERT(aActor);
328
  MOZ_ASSERT(!mActor);
329
330
  if (mShuttingDown) {
331
    return;
332
  }
333
334
  PSyncManagerChild* actor = aActor->SendPSyncManagerConstructor();
335
  mActor = static_cast<SyncManagerChild*>(actor);
336
  MOZ_ASSERT(mActor);
337
338
  // Flush pending requests.
339
  for (uint32_t i = 0, len = mPendingOperations.Length(); i < len; ++i) {
340
    RefPtr<SyncOpRunnable> runnable = mPendingOperations[i];
341
    MOZ_ASSERT(runnable);
342
    runnable->SetActor(mActor);
343
    if (NS_FAILED(NS_DispatchToCurrentThread(runnable))) {
344
      NS_WARNING("Failed to dispatch to the current thread");
345
      mPendingOperations.Clear();
346
      return;
347
    }
348
  }
349
  mPendingOperations.Clear();
350
}
351
352
// nsIObserver
353
354
NS_IMETHODIMP
355
SyncManager::Observe(nsISupports* aSubject,
356
                     const char* aTopic,
357
                     const char16_t* aData)
358
{
359
  MOZ_ASSERT(IsSyncManagerThread());
360
  MOZ_ASSERT(NS_IsMainThread());
361
  MOZ_ASSERT(!strcmp(aTopic, "inner-window-destroyed"));
362
363
  nsCOMPtr<nsISupportsPRUint64> wrapper = do_QueryInterface(aSubject);
364
  NS_ENSURE_TRUE(wrapper, NS_ERROR_FAILURE);
365
366
  uint64_t innerID;
367
  nsresult rv = wrapper->GetData(&innerID);
368
  NS_ENSURE_SUCCESS(rv, rv);
369
370
  if (innerID != mInnerID) {
371
    return NS_OK;
372
  }
373
374
  Shutdown();
375
376
  return NS_OK;
377
}
378
379
already_AddRefed<Promise>
380
SyncManager::ExecuteOp(const SyncOpArgs& aArgs, ErrorResult& aRv)
381
{
382
  MOZ_ASSERT(IsSyncManagerThread());
383
384
  if (mShuttingDown) {
385
    return nullptr;
386
  }
387
388
  RefPtr<Promise> p = Promise::Create(mGlobal, aRv);
389
  if (NS_WARN_IF(aRv.Failed())) {
390
    return nullptr;
391
  }
392
393
  nsAutoPtr<SyncOp> op(new SyncOp(*mPrincipalInfo, aArgs));
394
  RefPtr<SyncOpRunnable> runnable = new SyncOpRunnable(p, op);
395
396
  if (!mActor) {
397
    mPendingOperations.AppendElement(runnable);
398
    return p.forget();
399
  }
400
401
  runnable->SetActor(mActor);
402
  nsresult rv = NS_DispatchToCurrentThread(runnable);
403
  if (NS_WARN_IF(NS_FAILED(rv))) {
404
    p->MaybeReject(rv);
405
  }
406
407
  return p.forget();
408
}
409
410
// WebIDL interface methods.
411
412
already_AddRefed<Promise>
413
SyncManager::Register(const nsAString& aTag, ErrorResult& aRv)
414
{
415
  MOZ_ASSERT(IsSyncManagerThread());
416
417
  const SyncRegisterArgs args(mScope, (nsString(aTag)));
418
  return ExecuteOp(SyncOpArgs(args), aRv);
419
}
420
421
already_AddRefed<Promise>
422
SyncManager::GetTags(ErrorResult& aRv)
423
{
424
  MOZ_ASSERT(IsSyncManagerThread());
425
426
  const SyncGetTagsArgs args(mScope);
427
  return ExecuteOp(SyncOpArgs(args), aRv);
428
}
429
430
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(SyncManager, mGlobal)
431
NS_IMPL_CYCLE_COLLECTING_ADDREF(SyncManager)
432
NS_IMPL_CYCLE_COLLECTING_RELEASE(SyncManager)
433
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(SyncManager)
434
  NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
435
  NS_INTERFACE_MAP_ENTRY(nsIIPCBackgroundChildCreateCallback)
436
  NS_INTERFACE_MAP_ENTRY(nsIObserver)
437
NS_INTERFACE_MAP_END
438
439
} // namespace dom
440
} // namespace mozilla
(-)a/dom/sync/SyncManager.h (+122 lines)
Line     Link Here 
Line 0    Link Here 
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 file,
5
 * You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7
#ifndef mozilla_dom_SyncManager_h
8
#define mozilla_dom_SyncManager_h
9
10
#include "mozilla/dom/SyncIPCTypes.h"
11
12
#include "nsIIPCBackgroundChildCreateCallback.h"
13
#include "nsIObserver.h"
14
#include "nsIPrincipal.h"
15
#include "nsWrapperCache.h"
16
17
#include "mozilla/AlreadyAddRefed.h"
18
#include "mozilla/dom/BindingDeclarations.h"
19
#include "mozilla/ErrorResult.h"
20
21
#include "nsCOMPtr.h"
22
#include "jsapi.h"
23
24
class nsIGlobalObject;
25
26
namespace mozilla {
27
28
namespace ipc {
29
  class PrincipalInfo;
30
} // namespace ipc
31
32
namespace dom {
33
34
namespace workers {
35
  class WorkerFeature;
36
  class WorkerPrivate;
37
} // namespace workers
38
39
class Promise;
40
class SyncManagerChild;
41
class SyncOpRunnable;
42
43
class SyncManager final : public nsIIPCBackgroundChildCreateCallback
44
                        , public nsIObserver
45
                        , public nsWrapperCache
46
{
47
  NS_DECL_NSIIPCBACKGROUNDCHILDCREATECALLBACK
48
  NS_DECL_NSIOBSERVER
49
50
public:
51
  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
52
  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(
53
      SyncManager, nsIIPCBackgroundChildCreateCallback)
54
55
  static already_AddRefed<SyncManager>
56
  CreateOnMainThread(nsIGlobalObject* aGlobal,
57
                     nsIPrincipal* aPrincipal,
58
                     const nsAString& aScope,
59
                     ErrorResult& aRv);
60
61
  static already_AddRefed<SyncManager>
62
  CreateOnWorker(nsIGlobalObject* aGlobal,
63
                 workers::WorkerPrivate* aWorkerPrivate,
64
                 const nsAString& aScope);
65
66
  // Binding methods.
67
68
  nsIGlobalObject*
69
  GetParentObject() const
70
  {
71
    return mGlobal;
72
  }
73
74
  JSObject*
75
  WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
76
77
  static bool PrefEnabled(JSContext* aCx, JSObject* aObj);
78
79
  // WebIDL interface methods.
80
81
  already_AddRefed<Promise>
82
  Register(const nsAString& aTag, ErrorResult& aRv);
83
84
  already_AddRefed<Promise>
85
  GetTags(ErrorResult& aRv);
86
87
  void Shutdown();
88
private:
89
  SyncManager(nsIGlobalObject* aGlobal,
90
              const mozilla::ipc::PrincipalInfo& aPrincipalInfo,
91
              const nsAString& aScope);
92
93
  ~SyncManager();
94
95
  bool IsSyncManagerThread();
96
97
  already_AddRefed<Promise>
98
  ExecuteOp(const SyncOpArgs& aArgs, ErrorResult& aRv);
99
100
  uint64_t mInnerID;
101
102
  nsCOMPtr<nsIGlobalObject> mGlobal;
103
104
  nsAutoPtr<workers::WorkerFeature> mWorkerFeature;
105
106
  RefPtr<SyncManagerChild> mActor;
107
108
  bool mShuttingDown;
109
110
  UniquePtr<mozilla::ipc::PrincipalInfo> mPrincipalInfo;
111
112
  nsCOMPtr<nsIThread> mThread;
113
114
  nsString mScope;
115
116
  nsTArray<RefPtr<SyncOpRunnable>> mPendingOperations;
117
};
118
119
} // namespace dom
120
} // namespace mozilla
121
122
#endif // mozilla_dom_SyncManager_h
(-)a/dom/sync/SyncManagerChild.cpp (+131 lines)
Line     Link Here 
Line 0    Link Here 
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 file,
5
 * You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7
#include "SyncManagerChild.h"
8
9
#include "mozilla/unused.h"
10
#include "mozilla/ipc/PBackgroundChild.h"
11
12
namespace mozilla {
13
14
using namespace ipc;
15
16
namespace dom {
17
18
struct SyncManagerChild::PendingRequest final
19
{
20
  explicit PendingRequest(Promise* aPromise)
21
    : mPromise(aPromise)
22
  {}
23
24
  RefPtr<Promise> mPromise;
25
};
26
27
SyncManagerChild::SyncManagerChild()
28
  : mActorDestroyed(false)
29
{
30
}
31
32
SyncManagerChild::~SyncManagerChild()
33
{
34
}
35
36
void
37
SyncManagerChild::ActorDestroy(ActorDestroyReason aWhy)
38
{
39
  mActorDestroyed = true;
40
41
  for (auto iter = mPendingRequests.Iter(); !iter.Done(); iter.Next()) {
42
    PendingRequest* request;
43
    mPendingRequests.Get(iter.Key(), &request);
44
    if (NS_WARN_IF(!request)) {
45
      continue;
46
    }
47
    request->mPromise->MaybeReject(NS_ERROR_NOT_AVAILABLE);
48
  }
49
50
  mPendingRequests.Clear();
51
}
52
53
nsresult
54
SyncManagerChild::StorePendingRequest(Promise* aPromise, nsID& aID)
55
{
56
  nsresult rv;
57
  nsCOMPtr<nsIUUIDGenerator> uuidGenerator =
58
    do_GetService("@mozilla.org/uuid-generator;1", &rv);
59
  NS_ENSURE_SUCCESS(rv, rv);
60
61
  nsID id;
62
  rv = uuidGenerator->GenerateUUIDInPlace(&id);
63
  NS_ENSURE_SUCCESS(rv, rv);
64
65
  PendingRequest* request = new PendingRequest(aPromise);
66
  mPendingRequests.Put(id, request);
67
68
  aID = id;
69
70
  return NS_OK;
71
}
72
73
Promise*
74
SyncManagerChild::GetPendingRequest(const nsID& aID)
75
{
76
  PendingRequest* request = mPendingRequests.Get(aID);
77
  if (NS_WARN_IF(!request)) {
78
    return nullptr;
79
  }
80
81
  RefPtr<Promise> promise = request->mPromise;
82
83
  mPendingRequests.Remove(const_cast<nsID&>(aID));
84
  return promise;
85
}
86
87
nsresult
88
SyncManagerChild::ExecuteOp(Promise* aPromise, SyncOp* aOp)
89
{
90
  if (mActorDestroyed) {
91
    return NS_OK;
92
  }
93
94
  nsID requestId;
95
  nsresult rv = StorePendingRequest(aPromise, requestId);
96
  NS_ENSURE_SUCCESS(rv, rv);
97
98
  Unused << SendRequest(requestId, *aOp);
99
100
  return NS_OK;
101
}
102
103
bool
104
SyncManagerChild::RecvResponse(const nsID& aRequestId,
105
                               const SyncOpResponse& aResponse)
106
{
107
  Promise* p = GetPendingRequest(aRequestId);
108
  if (NS_WARN_IF(!p)) {
109
    // This should never happen.
110
    return false;
111
  }
112
113
  switch(aResponse.type()) {
114
    case SyncOpResponse::TSyncRegisterResponse:
115
      p->MaybeResolve(true);
116
      return true;
117
    case SyncOpResponse::TSyncGetTagsResponse:
118
      p->MaybeResolve(aResponse.get_SyncGetTagsResponse().mTags());
119
      return true;
120
    case SyncOpResponse::TSyncOpError:
121
      p->MaybeReject(
122
          static_cast<nsresult>(aResponse.get_SyncOpError().mCode()));
123
      return true;
124
    default:
125
      MOZ_CRASH("Unknown BackgroundSync response");
126
      return false;
127
  }
128
}
129
130
} // namespace dom
131
} // namespace mozilla
(-)a/dom/sync/SyncManagerChild.h (+62 lines)
Line     Link Here 
Line 0    Link Here 
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 file,
5
 * You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7
#ifndef mozilla_dom_SyncManagerChild_h
8
#define mozilla_dom_SyncManagerChild_h
9
10
#include "SyncManager.h"
11
12
#include "mozilla/dom/PSyncManagerChild.h"
13
14
#include "nsID.h"
15
#include "nsClassHashtable.h"
16
17
namespace mozilla {
18
19
namespace ipc {
20
class BackgroundChildImpl;
21
} // namespace ipc
22
23
namespace dom {
24
25
class SyncManager;
26
27
class SyncManagerChild final : public PSyncManagerChild
28
{
29
  friend class mozilla::ipc::BackgroundChildImpl;
30
31
public:
32
  NS_INLINE_DECL_REFCOUNTING(SyncManagerChild)
33
34
  bool IsActorDestroyed() const
35
  {
36
    return mActorDestroyed;
37
  }
38
39
  nsresult ExecuteOp(Promise* aPromise, SyncOp* aOp);
40
41
  virtual bool RecvResponse(const nsID& aRequestId,
42
                            const SyncOpResponse& aResponse) override;
43
44
private:
45
  SyncManagerChild();
46
  ~SyncManagerChild();
47
48
  virtual void ActorDestroy(ActorDestroyReason aWhy) override;
49
50
  nsresult StorePendingRequest(Promise* aPromise, nsID& aID);
51
  Promise* GetPendingRequest(const nsID& aID);
52
53
  bool mActorDestroyed;
54
55
  struct PendingRequest;
56
  nsClassHashtable<nsIDHashKey, PendingRequest> mPendingRequests;
57
};
58
59
} // namespace dom
60
} // namespace mozilla
61
62
#endif // mozilla_dom_SyncManagerChild_h
(-)a/dom/sync/SyncManagerParent.cpp (+96 lines)
Line     Link Here 
Line 0    Link Here 
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 file,
5
 * You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7
#include "SyncManagerParent.h"
8
#include "SyncService.h"
9
10
#include "mozilla/unused.h"
11
#include "mozilla/ipc/BackgroundParent.h"
12
13
namespace mozilla {
14
15
using namespace ipc;
16
17
namespace dom {
18
19
namespace {
20
  uint64_t sSyncManagerParentId = 0;
21
}
22
23
SyncManagerParent::SyncManagerParent()
24
  : mService(SyncService::GetOrCreate())
25
  , mId(++sSyncManagerParentId)
26
  , mActorDestroyed(false)
27
{
28
  AssertIsOnBackgroundThread();
29
30
  mService->RegisterActor(this);
31
}
32
33
SyncManagerParent::~SyncManagerParent()
34
{
35
  AssertIsOnBackgroundThread();
36
}
37
38
void
39
SyncManagerParent::ActorDestroy(ActorDestroyReason aWhy)
40
{
41
  AssertIsOnBackgroundThread();
42
43
  mActorDestroyed = true;
44
45
  if (mService) {
46
    mService->UnregisterActor(this);
47
  }
48
}
49
50
bool
51
SyncManagerParent::RecvRequest(const nsID& aRequestId,
52
                               const SyncOp& aOp)
53
{
54
  AssertIsOnBackgroundThread();
55
56
  if (NS_WARN_IF(!mService)) {
57
    return false;
58
  }
59
60
  mService->Request(mId, aRequestId, aOp);
61
62
  return true;
63
}
64
65
bool
66
SyncManagerParent::RecvShutdown()
67
{
68
  AssertIsOnBackgroundThread();
69
70
  if (NS_WARN_IF(!mService)) {
71
    return false;
72
  }
73
74
  mService->UnregisterActor(this);
75
  mService = nullptr;
76
77
  if (!mActorDestroyed) {
78
    Unused << Send__delete__(this);
79
  }
80
81
  return true;
82
}
83
84
void
85
SyncManagerParent::NotifyResponse(const nsID& aRequestId,
86
                                  const SyncOpResponse& aResponse)
87
{
88
  AssertIsOnBackgroundThread();
89
90
  if (!mActorDestroyed) {
91
    Unused << SendResponse(aRequestId, aResponse);
92
  }
93
}
94
95
} // namespace dom
96
} // namespace mozilla
(-)a/dom/sync/SyncManagerParent.h (+71 lines)
Line     Link Here 
Line 0    Link Here 
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 file,
5
 * You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7
#ifndef mozilla_dom_SyncManagerParent_h
8
#define mozilla_dom_SyncManagerParent_h
9
10
#include "mozilla/dom/PSyncManagerParent.h"
11
#include "mozilla/dom/SyncIPCTypes.h"
12
13
#include "nsID.h"
14
15
namespace mozilla {
16
17
namespace ipc {
18
class BackgroundParentImpl;
19
} // namespace ipc
20
21
namespace dom {
22
23
class SyncService;
24
25
class SyncManagerParent final : public PSyncManagerParent
26
{
27
  friend class mozilla::ipc::BackgroundParentImpl;
28
29
public:
30
  NS_INLINE_DECL_REFCOUNTING(SyncManagerParent)
31
32
  virtual bool RecvRequest(const nsID& aRequestId,
33
                           const SyncOp& aOp) override;
34
35
  virtual bool RecvShutdown() override;
36
37
  void NotifyResponse(const nsID& aRequestId,
38
                      const SyncOpResponse& aResponse);
39
40
  uint64_t Id() const
41
  {
42
    return mId;
43
  }
44
45
  bool ActorDestroyed() const
46
  {
47
    return mActorDestroyed;
48
  }
49
50
private:
51
  SyncManagerParent();
52
  ~SyncManagerParent();
53
54
  virtual void ActorDestroy(ActorDestroyReason aWhy) override;
55
56
  // SyncManagerParent objects keep SyncService alive.
57
  RefPtr<SyncService> mService;
58
59
  // The identifier will be used by the SyncService to know which request
60
  // belongs to which parent actor.
61
  uint64_t mId;
62
63
  bool mActorDestroyed;
64
};
65
66
} // namespace dom
67
} // namespace mozilla
68
69
#endif // mozilla_dom_SyncManagerParent_h
70
71
(-)a/dom/sync/SyncRegistration.cpp (+147 lines)
Line     Link Here 
Line 0    Link Here 
1
/* This Source Code Form is subject to the terms of the Mozilla Public
2
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
3
 * You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5
#include "mozilla/ModuleUtils.h"
6
#include "SyncRegistration.h"
7
8
#define NS_SYNCREGISTRATION_CID \
9
  { 0x566a1540, 0x45d8, 0x4828, {0xbf, 0x8a, 0xf9, 0x6e, 0x58, 0x5d, 0x94, 0xe8} }
10
11
namespace mozilla {
12
namespace dom {
13
14
NS_IMPL_ISUPPORTS(nsSyncRegistration, nsISyncRegistration)
15
16
NS_IMETHODIMP
17
nsSyncRegistration::Init(const nsAString& aId,
18
                         const nsAString& aOriginSuffix,
19
                         const nsAString& aScope,
20
                         const nsAString& aTag,
21
                         uint16_t aState,
22
                         bool aLastChance)
23
{
24
  mId = aId;
25
  mOriginSuffix = aOriginSuffix;
26
  mScope = aScope;
27
  mTag = aTag;
28
  mState = aState;
29
  mLastChance = aLastChance;
30
  return NS_OK;
31
}
32
33
/* attribute DOMString originSuffix; */
34
NS_IMETHODIMP
35
nsSyncRegistration::GetOriginSuffix(nsAString & aOriginSuffix)
36
{
37
  aOriginSuffix = mOriginSuffix;
38
  return NS_OK;
39
}
40
41
NS_IMETHODIMP
42
nsSyncRegistration::SetOriginSuffix(const nsAString & aOriginSuffix)
43
{
44
  mOriginSuffix = aOriginSuffix;
45
  return NS_OK;
46
}
47
48
/* attribute DOMString id; */
49
NS_IMETHODIMP
50
nsSyncRegistration::GetId(nsAString & aId)
51
{
52
  aId = mId;
53
  return NS_OK;
54
}
55
56
NS_IMETHODIMP
57
nsSyncRegistration::SetId(const nsAString & aId)
58
{
59
  mId = aId;
60
  return NS_OK;
61
}
62
63
/* attribute DOMString scope; */
64
NS_IMETHODIMP
65
nsSyncRegistration::GetScope(nsAString & aScope)
66
{
67
  aScope = mScope;
68
  return NS_OK;
69
}
70
71
NS_IMETHODIMP
72
nsSyncRegistration::SetScope(const nsAString & aScope)
73
{
74
  mScope = aScope;
75
  return NS_OK;
76
}
77
78
/* attribute DOMString tag; */
79
NS_IMETHODIMP
80
nsSyncRegistration::GetTag(nsAString & aTag)
81
{
82
  aTag = mTag;
83
  return NS_OK;
84
}
85
86
NS_IMETHODIMP
87
nsSyncRegistration::SetTag(const nsAString & aTag)
88
{
89
  mTag = aTag;
90
  return NS_OK;
91
}
92
93
/* attribute unsigned short state; */
94
NS_IMETHODIMP
95
nsSyncRegistration::GetState(uint16_t *aState)
96
{
97
  *aState = mState;
98
  return NS_OK;
99
}
100
101
NS_IMETHODIMP
102
nsSyncRegistration::SetState(uint16_t aState)
103
{
104
  mState = aState;
105
  return NS_OK;
106
}
107
108
/* attribute boolean lastChance; */
109
NS_IMETHODIMP
110
nsSyncRegistration::GetLastChance(bool *aLastChance)
111
{
112
  *aLastChance = mLastChance;
113
  return NS_OK;
114
}
115
116
NS_IMETHODIMP
117
nsSyncRegistration::SetLastChance(bool aLastChance)
118
{
119
  mLastChance = aLastChance;
120
  return NS_OK;
121
}
122
123
NS_GENERIC_FACTORY_CONSTRUCTOR(nsSyncRegistration);
124
125
NS_DEFINE_NAMED_CID(NS_SYNCREGISTRATION_CID);
126
127
static const mozilla::Module::CIDEntry kSyncRegistrationCIDs[] = {
128
  { &kNS_SYNCREGISTRATION_CID, false, nullptr, nsSyncRegistrationConstructor },
129
  { nullptr }
130
};
131
132
static const mozilla::Module::ContractIDEntry kSyncRegistrationContracts[] = {
133
  { "@mozilla.org/dom/sync/registration;1", &kNS_SYNCREGISTRATION_CID },
134
  { nullptr }
135
};
136
137
static const mozilla::Module kSyncRegistrationModule = {
138
  mozilla::Module::kVersion,
139
  kSyncRegistrationCIDs,
140
  kSyncRegistrationContracts,
141
  nullptr
142
};
143
144
} // namespace dom
145
} // namespace mozilla
146
147
NSMODULE_DEFN(SyncRegistrationModule) = &mozilla::dom::kSyncRegistrationModule;
(-)a/dom/sync/SyncRegistration.h (+35 lines)
Line     Link Here 
Line 0    Link Here 
1
/* This Source Code Form is subject to the terms of the Mozilla Public
2
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
3
 * You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5
#ifndef mozilla_dom_SyncRegistration_h
6
#define mozilla_dom_SyncRegistration_h
7
8
#include "nsISyncRegistry.h"
9
10
namespace mozilla {
11
namespace dom {
12
13
class nsSyncRegistration : public nsISyncRegistration
14
{
15
public:
16
  NS_DECL_THREADSAFE_ISUPPORTS
17
  NS_DECL_NSISYNCREGISTRATION
18
19
  nsSyncRegistration() {}
20
21
private:
22
  virtual ~nsSyncRegistration() {}
23
24
  nsString mOriginSuffix;
25
  nsString mId;
26
  nsString mScope;
27
  nsString mTag;
28
  uint16_t mState;
29
  bool mLastChance;
30
};
31
32
} // namespace dom
33
} // namespace mozilla
34
35
#endif // mozilla_dom_SyncRegistration_h
(-)a/dom/sync/SyncRegistry.js (+169 lines)
Line     Link Here 
Line 0    Link Here 
1
/* This Source Code Form is subject to the terms of the Mozilla Public
2
 * License, v. 2.0. If a copy of the MPL was not distributed with this
3
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5
"use strict"
6
7
function debug(s) {
8
  dump("DEBUG SyncRegistry: " + s + "\n");
9
}
10
11
function error(s) {
12
  dump("ERROR SyncRegistry: " + s + "\n");
13
}
14
15
const { classes: Cc, interfaces: Ci, results: Cr, utils: Cu } = Components;
16
17
Cu.import("resource://gre/modules/IndexedDBHelper.jsm");
18
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
19
20
const RW = "readwrite";
21
const RO = "readonly";
22
23
const SYNC_REGISTRY_DB_NAME    = "background-sync-registry";
24
const SYNC_REGISTRY_DB_VERSION = 1;
25
const SYNC_REGISTRY_STORE_NAME = "registry";
26
27
let gInstance = null;
28
function SyncRegistry() {
29
  if (gInstance) {
30
    return gInstance;
31
  }
32
  gInstance = this;
33
  gInstance.init();
34
  debug("SyncRegistry created");
35
}
36
37
SyncRegistry.prototype = {
38
  __proto__: IndexedDBHelper.prototype,
39
40
  init: function() {
41
    debug("init");
42
    this.initDBHelper(SYNC_REGISTRY_DB_NAME,
43
                      SYNC_REGISTRY_DB_VERSION,
44
                      [SYNC_REGISTRY_STORE_NAME]);
45
  },
46
47
  upgradeSchema: function(aTransaction, aDb, aOldVersion, aNewVersion) {
48
    debug("upgradeSchema");
49
    /**
50
     * We will be storing objects like:
51
     * {
52
     *   id: <string> (key), // concatenation of scope + tag,
53
     *   originSuffix: <string>,
54
     *   scope: <string> (index),
55
     *   tag: <string>,
56
     *   state: <number>,
57
     *   lastChance: <boolean>
58
     * }
59
     */
60
    let objectStore = aDb.createObjectStore(SYNC_REGISTRY_STORE_NAME, {
61
      keyPath: "id"
62
    });
63
    objectStore.createIndex("scope", "scope", { unique: false });
64
  },
65
66
  getId(aRegistration) {
67
    return aRegistration.tag + '@' + aRegistration.scope;
68
  },
69
70
  add(aRegistration, aListener) {
71
    debug("add " + JSON.stringify(aRegistration));
72
    if (!aRegistration ||
73
        !aRegistration.tag || !aRegistration.scope ||
74
        !aRegistration.tag.length || !aRegistration.scope.length) {
75
      error("Missing registration info");
76
      aListener.notifyError(Cr.NS_ERROR_ILLEGAL_VALUE);
77
      return;
78
    }
79
80
    this.newTxn(RW, SYNC_REGISTRY_STORE_NAME, (aTxn, aStore) => {
81
      aStore.add({
82
        id: this.getId(aRegistration),
83
        originSuffix: aRegistration.originSuffix,
84
        scope: aRegistration.scope,
85
        tag: aRegistration.tag,
86
        state: Ci.nsISyncRegistry.STATE_PENDING,
87
        lastChance: true // XXX Bug 1260138
88
      });
89
    }, () => {
90
      aListener.notifyAddSuccess();
91
    }, error => {
92
      error = isNaN(error) ? Cr.NS_ERROR_FAILURE : error;
93
      aListener.notifyError(error);
94
    });
95
  },
96
97
  remove(aId, aListener) {
98
    debug("remove " + aId);
99
    this.newTxn(RW, SYNC_REGISTRY_STORE_NAME, (aTxn, aStore) => {
100
      aStore.delete(aId);
101
    }, () => {
102
      debug("registration removed " + aId);
103
    }, error => {
104
      error = isNaN(error) ? Cr.NS_ERROR_FAILURE : error;
105
      aListener.notifyError(error);
106
    });
107
  },
108
109
  getAll(aListener) {
110
    debug("getAll");
111
    this.newTxn(RO, SYNC_REGISTRY_STORE_NAME, (aTxn, aStore) => {
112
      aStore.getAll().onsuccess = event => {
113
        let results = event.target.result;
114
        let registrations = Cc["@mozilla.org/array;1"]
115
                              .createInstance(Ci.nsIMutableArray);;
116
        for (let i = 0; i < results.length; i++) {
117
          let registration = Cc["@mozilla.org/dom/sync/registration;1"]
118
                               .createInstance(Ci.nsISyncRegistration);
119
          let result = results[i];
120
          registration.init(result.id,
121
                            result.originSuffix,
122
                            result.scope,
123
                            result.tag,
124
                            result.state,
125
                            result.lastChance);
126
          debug("registration " + JSON.stringify(registration));
127
          try {
128
            registrations.appendElement(registration, false /* weak */);
129
          } catch(e) {
130
            return aListener.notifyError(Cr.NS_ERROR_OUT_OF_MEMORY);
131
          }
132
        }
133
        aListener.notifyGetAllSuccess(registrations);
134
      };
135
    }, null, error => {
136
      error = isNaN(error) ? Cr.NS_ERROR_FAILURE : error;
137
      aListener.notifyError(error);
138
    });
139
  },
140
141
  changeState(aId, aState, aListener) {
142
    debug("changeState " + aId + " " + aState);
143
    this.newTxn(RW, SYNC_REGISTRY_STORE_NAME, (aTxn, aStore) => {
144
      aStore.get(aId).onsuccess = event => {
145
        let registration = event.target.result;
146
        debug("registration " + JSON.stringify(registration));
147
        registration.state = aState;
148
        aStore.put(registration).onsuccess = event => {
149
          let result = Cc["@mozilla.org/dom/sync/registration;1"]
150
                         .createInstance(Ci.nsISyncRegistration);
151
          ["id", "scope", "tag", "state", "lastChance"].forEach(property => {
152
            result[property] = registration[property];
153
          });
154
          aListener.notifyChangeStateSuccess(result);
155
        };
156
      };
157
    }, null, error => {
158
      error = isNaN(error) ? Cr.NS_ERROR_FAILURE : error;
159
      aListener.notifyError(error);
160
    });
161
  },
162
163
  classID: Components.ID("{c1200834-3ebb-45e2-81cf-986edeb107f6}"),
164
  contractID: "@mozilla.org/dom/sync/registry;1",
165
  QueryInterface: XPCOMUtils.generateQI([Ci.nsISyncRegistry,
166
                                         Ci.nsISupports])
167
};
168
169
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([SyncRegistry]);
(-)a/dom/sync/SyncRegistry.manifest (+2 lines)
Line     Link Here 
Line 0    Link Here 
1
component {c1200834-3ebb-45e2-81cf-986edeb107f6} SyncRegistry.js
2
contract @mozilla.org/dom/sync/registry;1 {c1200834-3ebb-45e2-81cf-986edeb107f6}
(-)a/dom/sync/SyncService.cpp (+654 lines)
Line     Link Here 
Line 0    Link Here 
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 "nsArrayUtils.h"
8
#include "nsIMutableArray.h"
9
#include "nsIOService.h"
10
#include "SyncManagerParent.h"
11
#include "SyncService.h"
12
#include "SyncTypes.h"
13
14
namespace mozilla {
15
16
namespace dom {
17
18
namespace {
19
  SyncService* sInstance = nullptr;
20
} // namespace
21
22
class SyncRegistryResponseRunnable : public nsRunnable
23
{
24
public:
25
  SyncRegistryResponseRunnable(SyncRegistryResponse* aResponse)
26
    : mResponse(aResponse)
27
  {
28
    AssertIsOnMainThread();
29
  }
30
31
  SyncRegistryResponseRunnable(SyncRegistryInternalResponse* aResponse)
32
    : mInternalResponse(aResponse)
33
  {
34
    AssertIsOnMainThread();
35
  }
36
37
  NS_IMETHODIMP Run() override
38
  {
39
    AssertIsOnBackgroundThread();
40
41
    if (mResponse) {
42
      sInstance->Response(mResponse);
43
    } else if (mInternalResponse) {
44
      sInstance->InternalResponse(mInternalResponse);
45
    }
46
47
    return NS_OK;
48
  }
49
50
private:
51
  ~SyncRegistryResponseRunnable() {}
52
53
  RefPtr<SyncRegistryResponse> mResponse;
54
  RefPtr<SyncRegistryInternalResponse> mInternalResponse;
55
};
56
57
class SyncRegistryRequestRunnable final : public nsIRunnable
58
                                        , public nsISyncRegistryListener
59
{
60
61
public:
62
  NS_DECL_THREADSAFE_ISUPPORTS
63
64
  SyncRegistryRequestRunnable(SyncRegistryRequest* aRequest)
65
    : mRequest(aRequest)
66
    , mBackgroundThread(NS_GetCurrentThread())
67
  {
68
    AssertIsOnBackgroundThread();
69
  }
70
71
  NS_IMETHODIMP
72
  GetRequestId(nsID* aRequestId)
73
  {
74
    AssertIsOnMainThread();
75
76
    aRequestId = &(mRequest->mRequestId);
77
    return NS_OK;
78
  }
79
80
  NS_IMETHODIMP
81
  SetRequestId(const nsID aRequestId)
82
  {
83
    return NS_OK;
84
  }
85
86
  NS_IMETHODIMP
87
  GetActorId(uint64_t* aActorId)
88
  {
89
    AssertIsOnMainThread();
90
91
    aActorId = &(mRequest->mActorId);
92
    return NS_OK;
93
  }
94
95
  NS_IMETHODIMP
96
  SetActorId(const uint64_t aActorId)
97
  {
98
    return NS_OK;
99
  }
100
101
  NS_IMETHODIMP
102
  NotifyAddSuccess()
103
  {
104
    AssertIsOnMainThread();
105
106
    return Callback(SyncRegisterResponse());
107
  }
108
109
  NS_IMETHODIMP
110
  NotifyGetAllSuccess(nsIArray* aRegistrations)
111
  {
112
    AssertIsOnMainThread();
113
114
    if (!aRegistrations) {
115
      return Callback(SyncOpError(static_cast<uint32_t>(NS_ERROR_INVALID_ARG)));
116
    }
117
118
    uint32_t length;
119
    nsresult rv = aRegistrations->GetLength(&length);
120
    if (NS_WARN_IF(NS_FAILED(rv))) {
121
      return Callback(SyncOpError(static_cast<uint32_t>(rv)));
122
    }
123
124
    if (mRequest->mActorId == 0) {
125
      // Internal request.
126
      nsTArray<nsCOMPtr<nsISyncRegistration>> registrations;
127
      for (uint32_t i = 0; i < length; i++) {
128
        nsCOMPtr<nsISyncRegistration> registration =
129
          do_QueryElementAt(aRegistrations, i);
130
        if (NS_WARN_IF(!registration)) {
131
          continue;
132
        }
133
        registrations.AppendElement(registration);
134
      }
135
136
      return Callback(new SyncRegistryInternalResponse(
137
        SyncRegistryInternalResponse::TGetAllResponse, registrations));
138
    }
139
140
    // DOM request.
141
    nsTArray<nsString> tags;
142
    for (uint32_t i = 0; i < length; i++) {
143
      nsCOMPtr<nsISyncRegistration> registration =
144
        do_QueryElementAt(aRegistrations, i);
145
      if (NS_WARN_IF(!registration)) {
146
        continue;
147
      }
148
      nsString tag;
149
      registration->GetTag(tag);
150
      tags.AppendElement(tag);
151
    }
152
153
    return Callback(SyncGetTagsResponse(tags));
154
  }
155
156
  NS_IMETHODIMP
157
  NotifyChangeStateSuccess(nsISyncRegistration* aRegistration)
158
  {
159
    AssertIsOnMainThread();
160
161
    nsTArray<nsCOMPtr<nsISyncRegistration>> registrations;
162
    registrations.AppendElement(aRegistration);
163
164
    return Callback(new SyncRegistryInternalResponse(
165
      SyncRegistryInternalResponse::TChangeStateResponse, registrations));
166
  }
167
168
  NS_IMETHODIMP
169
  NotifyError(const uint32_t aError)
170
  {
171
    AssertIsOnMainThread();
172
173
    return Callback(SyncOpError(aError));
174
  }
175
176
  NS_IMETHODIMP
177
  Run() override
178
  {
179
    AssertIsOnMainThread();
180
181
    nsCOMPtr<nsISyncRegistry> registry =
182
      do_CreateInstance("@mozilla.org/dom/sync/registry;1");
183
    MOZ_ASSERT(registry);
184
185
    if (mRequest->mOpOrIOp.type() == SyncOpOrInternalOp::TSyncOp) {
186
      SyncOp op = mRequest->mOpOrIOp.get_SyncOp();
187
188
      switch(op.mArgs().type()) {
189
        case SyncOpArgs::TSyncRegisterArgs:
190
        {
191
          nsCOMPtr<nsISyncRegistration> registration =
192
            do_CreateInstance("@mozilla.org/dom/sync/registration;1");
193
          MOZ_ASSERT(registration);
194
195
          nsCOMPtr<nsIPrincipal> principal =
196
            PrincipalInfoToPrincipal(op.mPrincipal());
197
          if (NS_WARN_IF(!principal)) {
198
            return NotifyError(static_cast<uint32_t>(NS_ERROR_INVALID_ARG));
199
          }
200
201
          nsAutoCString originSuffix;
202
          nsresult rv = principal->GetOriginSuffix(originSuffix);
203
          if (NS_WARN_IF(NS_FAILED(rv))) {
204
            return NotifyError(static_cast<uint32_t>(NS_ERROR_INVALID_ARG));
205
          }
206
207
          registration->SetOriginSuffix(NS_ConvertUTF8toUTF16(originSuffix));
208
          registration->SetScope(op.mArgs().get_SyncRegisterArgs().mScope());
209
          registration->SetTag(op.mArgs().get_SyncRegisterArgs().mTag());
210
211
          registry->Add(registration, this);
212
213
          break;
214
        }
215
        case SyncOpArgs::TSyncGetTagsArgs:
216
          registry->GetAll(this);
217
          break;
218
        default:
219
          MOZ_CRASH("Unknown BackgroundSync request");
220
      }
221
222
    } else if (mRequest->mOpOrIOp.type() == SyncOpOrInternalOp::TSyncInternalOp) {
223
224
      SyncInternalOp op = mRequest->mOpOrIOp.get_SyncInternalOp();
225
226
      switch (op.mArgs().type()) {
227
        case SyncInternalOpArgs::TSyncGetAllArgs:
228
          registry->GetAll(this);
229
          break;
230
        case SyncInternalOpArgs::TSyncChangeStateArgs:
231
          registry->ChangeState(op.mArgs().get_SyncChangeStateArgs().mId(),
232
                                op.mArgs().get_SyncChangeStateArgs().mState(),
233
                                this);
234
          break;
235
        case SyncInternalOpArgs::TSyncRemoveArgs:
236
          registry->Remove(op.mArgs().get_SyncRemoveArgs().mId(), this);
237
          break;
238
        default:
239
          MOZ_CRASH("Unknown BackgroundSync internal request");
240
      }
241
242
    } else {
243
      MOZ_CRASH("Unknown BackgroundSync registry request");
244
    }
245
246
    return NS_OK;
247
  }
248
249
private:
250
  ~SyncRegistryRequestRunnable() {}
251
252
  nsresult
253
  Callback(const SyncOpResponse& aResponse)
254
  {
255
    AssertIsOnMainThread();
256
257
    RefPtr<SyncRegistryResponse> response =
258
      new SyncRegistryResponse(mRequest->mActorId,
259
                               mRequest->mRequestId,
260
                               aResponse);
261
    RefPtr<SyncRegistryResponseRunnable> callback =
262
      new SyncRegistryResponseRunnable(response);
263
    MOZ_ASSERT(callback);
264
265
    mBackgroundThread->Dispatch(callback, NS_DISPATCH_NORMAL);
266
267
    return NS_OK;
268
  }
269
270
  nsresult
271
  Callback(SyncRegistryInternalResponse* aResponse)
272
  {
273
    AssertIsOnMainThread();
274
275
    RefPtr<SyncRegistryResponseRunnable> callback =
276
      new SyncRegistryResponseRunnable(aResponse);
277
    MOZ_ASSERT(callback);
278
279
    mBackgroundThread->Dispatch(callback, NS_DISPATCH_NORMAL);
280
281
    return NS_OK;
282
  }
283
284
  RefPtr<SyncRegistryRequest> mRequest;
285
  nsCOMPtr<nsIThread> mBackgroundThread;
286
};
287
288
NS_IMPL_ISUPPORTS(SyncRegistryRequestRunnable, nsIRunnable, nsISyncRegistryListener);
289
290
class SyncServiceNotifyOnlineStateRunnable final : public nsRunnable
291
{
292
public:
293
  SyncServiceNotifyOnlineStateRunnable(const OnlineState aState)
294
    : mOnlineState(aState)
295
  {
296
    AssertIsOnMainThread();
297
  }
298
299
  NS_IMETHOD
300
  Run() override
301
  {
302
    AssertIsOnBackgroundThread();
303
304
    sInstance->OnlineStateChange(mOnlineState);
305
306
    return NS_OK;
307
  }
308
309
private:
310
  ~SyncServiceNotifyOnlineStateRunnable() {}
311
312
  OnlineState mOnlineState;
313
};
314
315
class SyncServiceInitRunnable final : public nsIRunnable
316
                                    , public nsIObserver
317
{
318
public:
319
  NS_DECL_THREADSAFE_ISUPPORTS
320
321
  SyncServiceInitRunnable()
322
    : mBackgroundThread(NS_GetCurrentThread())
323
  {
324
    AssertIsOnBackgroundThread();
325
  }
326
327
  NS_IMETHOD
328
  Observe(nsISupports* aSubject, const char* aTopic,
329
          const char16_t* aData) override
330
  {
331
    AssertIsOnMainThread();
332
333
    OnlineState state = OFFLINE;
334
    if (nsDependentString(aData).EqualsLiteral(NS_IOSERVICE_ONLINE)) {
335
      state = ONLINE;
336
    }
337
338
    mBackgroundThread->Dispatch(
339
        new SyncServiceNotifyOnlineStateRunnable(state), NS_DISPATCH_NORMAL);
340
341
    return NS_OK;
342
  }
343
344
  NS_IMETHOD
345
  Run() override
346
  {
347
    AssertIsOnMainThread();
348
349
    nsCOMPtr<nsIObserverService> os = services::GetObserverService();
350
    NS_ENSURE_STATE(os);
351
    // The observer service holds us alive.
352
    os->AddObserver(this, NS_IOSERVICE_OFFLINE_STATUS_TOPIC,
353
                    /* holdsWeak */ false);
354
355
    bool offline = true;
356
    nsCOMPtr<nsIIOService> ioService = services::GetIOService();
357
    NS_ENSURE_STATE(ioService);
358
    ioService->GetOffline(&offline);
359
    NS_WARN_IF(NS_FAILED(ioService->GetOffline(&offline)));
360
361
    OnlineState state = UNKNOWN;
362
    if (offline) {
363
      state = OFFLINE;
364
    } else {
365
      state = ONLINE;
366
    }
367
368
    mBackgroundThread->Dispatch(
369
        new SyncServiceNotifyOnlineStateRunnable(state), NS_DISPATCH_NORMAL);
370
371
    return NS_OK;
372
  }
373
374
private:
375
  ~SyncServiceInitRunnable() {}
376
377
  nsCOMPtr<nsIThread> mBackgroundThread;
378
};
379
380
NS_IMPL_ISUPPORTS(SyncServiceInitRunnable, nsIRunnable, nsIObserver)
381
382
SyncService::SyncService()
383
  : mOnlineState(UNKNOWN)
384
{
385
  AssertIsOnBackgroundThread();
386
387
  // sInstance is a raw SyncService*.
388
  MOZ_ASSERT(!sInstance);
389
  sInstance = this;
390
}
391
392
SyncService::~SyncService()
393
{
394
  AssertIsOnBackgroundThread();
395
  MOZ_ASSERT(sInstance == this);
396
  MOZ_ASSERT(mSyncManagerActors.Count() == 0);
397
398
  sInstance = nullptr;
399
}
400
401
// static
402
already_AddRefed<SyncService>
403
SyncService::GetOrCreate()
404
{
405
  AssertIsOnBackgroundThread();
406
407
  RefPtr<SyncService> instance = sInstance;
408
  if (!instance) {
409
    instance = new SyncService();
410
    instance->Init();
411
  }
412
  return instance.forget();
413
}
414
415
void
416
SyncService::Init()
417
{
418
  NS_DispatchToMainThread(new SyncServiceInitRunnable());
419
}
420
421
void
422
SyncService::RegisterActor(SyncManagerParent* aParent)
423
{
424
  AssertIsOnBackgroundThread();
425
  MOZ_ASSERT(aParent);
426
  MOZ_ASSERT(!mSyncManagerActors.Contains(aParent));
427
428
  mSyncManagerActors.PutEntry(aParent);
429
}
430
431
void
432
SyncService::UnregisterActor(SyncManagerParent* aParent)
433
{
434
  AssertIsOnBackgroundThread();
435
  MOZ_ASSERT(aParent);
436
  MOZ_ASSERT(mSyncManagerActors.Contains(aParent));
437
438
  mSyncManagerActors.RemoveEntry(aParent);
439
}
440
441
void
442
SyncService::RegisterActor(workers::ServiceWorkerManagerParent* aParent)
443
{
444
  AssertIsOnBackgroundThread();
445
  MOZ_ASSERT(aParent);
446
  MOZ_ASSERT(!mServiceWorkerManagerActors.Contains(aParent));
447
448
  mServiceWorkerManagerActors.PutEntry(aParent);
449
}
450
451
void
452
SyncService::UnregisterActor(workers::ServiceWorkerManagerParent* aParent)
453
{
454
  AssertIsOnBackgroundThread();
455
  MOZ_ASSERT(aParent);
456
  MOZ_ASSERT(mServiceWorkerManagerActors.Contains(aParent));
457
458
  mServiceWorkerManagerActors.RemoveEntry(aParent);
459
}
460
461
void
462
SyncService::Request(const uint64_t aActorId,
463
                     const nsID& aRequestId,
464
                     const SyncOp& aOp)
465
{
466
  AssertIsOnBackgroundThread();
467
468
  RefPtr<SyncRegistryRequestRunnable> runnable =
469
    new SyncRegistryRequestRunnable(
470
        new SyncRegistryRequest(aActorId, aRequestId, aOp));
471
  NS_DispatchToMainThread(runnable);
472
}
473
474
void
475
SyncService::Response(SyncRegistryResponse* aResponse)
476
{
477
  AssertIsOnBackgroundThread();
478
479
  for (auto iter = mSyncManagerActors.Iter(); !iter.Done(); iter.Next()) {
480
    RefPtr<SyncManagerParent> parent = iter.Get()->GetKey();
481
    MOZ_ASSERT(parent);
482
    if (parent->Id() != aResponse->mActorId ||
483
        parent->ActorDestroyed()) {
484
      continue;
485
    }
486
    parent->NotifyResponse(aResponse->mRequestId, aResponse->mResponse);
487
  }
488
489
  // If we just successfully added a new sync request we try to trigger
490
  // the corresponding sync event.
491
  if (aResponse->mResponse.type() == SyncOpResponse::TSyncRegisterResponse) {
492
    StartTriggerSyncEvents();
493
  }
494
}
495
496
void
497
SyncService::InternalResponse(SyncRegistryInternalResponse* aResponse)
498
{
499
  AssertIsOnBackgroundThread();
500
  MOZ_ASSERT(aResponse);
501
502
  nsTArray<nsCOMPtr<nsISyncRegistration>> registrations;
503
  aResponse->GetRegistrations(registrations);
504
505
  switch (aResponse->type()) {
506
    case SyncRegistryInternalResponse::TGetAllResponse:
507
      ContinueTriggerSyncEvents(registrations);
508
      break;
509
    case SyncRegistryInternalResponse::TChangeStateResponse:
510
      MOZ_ASSERT((registrations.Length() == 1));
511
512
      uint16_t state;
513
      registrations[0]->GetState(&state);
514
515
      if (state == nsISyncRegistry::STATE_FIRING) {
516
        // After setting the state of the registration to STATE_FIRING
517
        // we try to actually trigger the sync event.
518
        TriggerSyncEvent(Move(registrations[0]));
519
      }
520
      break;
521
    default:
522
      MOZ_CRASH("Unknown BackgroundSync internal response");
523
  }
524
}
525
526
void SyncService::InternalRequest(const SyncInternalOpArgs& aArgs)
527
{
528
  AssertIsOnBackgroundThread();
529
530
  const SyncInternalOp op(aArgs);
531
532
  RefPtr<SyncRegistryRequestRunnable> runnable =
533
    new SyncRegistryRequestRunnable(
534
        new SyncRegistryRequest(0 /* internal request */, nsID(), op));
535
  NS_DispatchToMainThread(runnable);
536
}
537
538
void
539
SyncService::StartTriggerSyncEvents()
540
{
541
  AssertIsOnBackgroundThread();
542
543
  // We need to jump to the main thread to get the list of registered
544
  // sync requests. If we are still online while coming back to the
545
  // background thread with this list of sync requests, we will fire
546
  // a sync event for each of them.
547
  const SyncGetAllArgs args;
548
  InternalRequest(args);
549
}
550
551
void
552
SyncService::RemoveSyncRegistration(const nsString& aId)
553
{
554
  AssertIsOnBackgroundThread();
555
556
  const SyncRemoveArgs args(aId);
557
  InternalRequest(args);
558
}
559
560
void
561
SyncService::ContinueTriggerSyncEvents(
562
    nsTArray<nsCOMPtr<nsISyncRegistration>>& aRegistrations)
563
{
564
  AssertIsOnBackgroundThread();
565
566
  // At this point we got the list of registered sync requests from
567
  // the main thread. If we are still online, we try to trigger a sync
568
  // event for each request.
569
  if (mOnlineState != ONLINE) {
570
    return;
571
  }
572
573
  // Before actually triggering the sync event, we need to set each
574
  // registration entry state to STATE_FIRING.
575
  for (uint32_t i = 0; i < aRegistrations.Length(); i++) {
576
    nsCOMPtr<nsISyncRegistration> registration = aRegistrations[i];
577
    if (NS_WARN_IF(!registration)) {
578
      continue;
579
    }
580
581
    // If the state of this registration entry is not 'pending', we ignore it.
582
    uint16_t state;
583
    registration->GetState(&state);
584
    if (state != nsISyncRegistry::STATE_PENDING) {
585
      continue;
586
    }
587
588
    // Otherwise, we set the registration state to 'firing'.
589
    nsString id;
590
    registration->GetId(id);
591
    MOZ_ASSERT(!id.IsEmpty());
592
    const SyncInternalOp op(
593
        (SyncChangeStateArgs(id, nsISyncRegistry::STATE_FIRING)));
594
    RefPtr<SyncRegistryRequestRunnable> runnable =
595
      new SyncRegistryRequestRunnable(
596
          new SyncRegistryRequest(0 /* internal request */, nsID(), op));
597
    NS_DispatchToMainThread(runnable);
598
  }
599
}
600
601
void
602
SyncService::TriggerSyncEvent(nsISyncRegistration* aRegistration)
603
{
604
  AssertIsOnBackgroundThread();
605
  MOZ_ASSERT(aRegistration);
606
607
  uint16_t state;
608
  aRegistration->GetState(&state);
609
  MOZ_ASSERT(state == nsISyncRegistry::STATE_FIRING);
610
611
  nsString originSuffix;
612
  aRegistration->GetOriginSuffix(originSuffix);
613
614
  nsString scope;
615
  aRegistration->GetScope(scope);
616
  MOZ_ASSERT(!scope.IsEmpty());
617
618
  nsString tag;
619
  aRegistration->GetTag(tag);
620
  MOZ_ASSERT(!tag.IsEmpty());
621
622
  bool lastChance;
623
  aRegistration->GetLastChance(&lastChance);
624
625
  for (auto iter = mServiceWorkerManagerActors.Iter(); !iter.Done();
626
       iter.Next()) {
627
    RefPtr<ServiceWorkerManagerParent> parent = iter.Get()->GetKey();
628
    MOZ_ASSERT(parent);
629
    Unused << parent->SendNotifySyncEvent(originSuffix, scope, tag,
630
                                          lastChance);
631
    // XXX Bug 1260141. For now we simply remove the sync registration, but
632
    // we need to implement the sync event handling logic.
633
    nsString id;
634
    aRegistration->GetId(id);
635
    RemoveSyncRegistration(id);
636
  }
637
}
638
639
void
640
SyncService::OnlineStateChange(const OnlineState& aState)
641
{
642
  mOnlineState = aState;
643
644
  if (mOnlineState != ONLINE) {
645
    return;
646
  }
647
648
  // If we are online we need to get the list of registered sync requests
649
  // to trigger the corresponding 'sync' events.
650
  StartTriggerSyncEvents();
651
}
652
653
} // namespace dom
654
} // namespace mozilla
(-)a/dom/sync/SyncService.h (+86 lines)
Line     Link Here 
Line 0    Link Here 
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 file,
5
 * You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7
#ifndef mozilla_dom_SyncService_h
8
#define mozilla_dom_SyncService_h
9
10
#include "mozilla/dom/SyncIPCTypes.h"
11
#include "nsISupportsImpl.h"
12
#include "nsISyncRegistry.h"
13
#include "nsHashKeys.h"
14
#include "nsTArray.h"
15
#include "nsTHashtable.h"
16
#include "ServiceWorkerManagerParent.h"
17
18
namespace mozilla {
19
namespace dom {
20
21
namespace workers {
22
class ServiceWorkerManagerParent;
23
} // namespace workers
24
25
class SyncManagerParent;
26
class SyncRegistryResponse;
27
class SyncRegistryInternalResponse;
28
29
typedef enum {
30
  ONLINE,
31
  OFFLINE,
32
  UNKNOWN
33
} OnlineState;
34
35
class SyncService final
36
{
37
  friend class SyncRegistryResponseRunnable;
38
  friend class SyncServiceNotifyOnlineStateRunnable;
39
40
public:
41
  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(SyncService)
42
43
  static already_AddRefed<SyncService> GetOrCreate();
44
45
  void RegisterActor(SyncManagerParent* aParent);
46
  void UnregisterActor(SyncManagerParent* aParent);
47
48
  void RegisterActor(workers::ServiceWorkerManagerParent* aParent);
49
  void UnregisterActor(workers::ServiceWorkerManagerParent* aParent);
50
51
  void Request(const uint64_t aActorId,
52
               const nsID& aRequestId,
53
               const SyncOp& aOp);
54
55
  SyncService();
56
57
private:
58
  ~SyncService();
59
60
  void Init();
61
62
  void Response(SyncRegistryResponse* aResponse);
63
  void InternalResponse(SyncRegistryInternalResponse* aResponse);
64
65
  void InternalRequest(const SyncInternalOpArgs& aArgs);
66
67
  void StartTriggerSyncEvents();
68
  void ContinueTriggerSyncEvents(
69
      nsTArray<nsCOMPtr<nsISyncRegistration>>& aRegistrations);
70
  void TriggerSyncEvent(nsISyncRegistration* aRegistration);
71
72
  void RemoveSyncRegistration(const nsString& aId);
73
74
  void OnlineStateChange(const OnlineState& aState);
75
76
  OnlineState mOnlineState;
77
78
  nsTHashtable<nsRefPtrHashKey<SyncManagerParent>> mSyncManagerActors;
79
  nsTHashtable<nsRefPtrHashKey<workers::ServiceWorkerManagerParent>>
80
    mServiceWorkerManagerActors;
81
};
82
83
} // namespace dom
84
} // namespace mozilla
85
86
#endif // mozilla_dom_SyncService_h
(-)a/dom/sync/SyncTypes.h (+110 lines)
Line     Link Here 
Line 0    Link Here 
1
/* This Source Code Form is subject to the terms of the Mozilla Public
2
 * License, v. 2.0. If a copy of the MPL was not distributed with this
3
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5
#ifndef mozilla_dom_sync_Types_h
6
#define mozilla_dom_sync_Types_h
7
8
#include "nsCOMPtr.h"
9
#include "nsTArray.h"
10
11
namespace mozilla {
12
namespace dom {
13
14
class SyncRegistryAction
15
{
16
public:
17
  uint64_t mActorId;
18
  nsID mRequestId;
19
20
protected:
21
  SyncRegistryAction(const uint64_t aActorId,
22
                     const nsID& aRequestId)
23
    : mActorId(aActorId)
24
    , mRequestId(aRequestId)
25
  {}
26
27
  ~SyncRegistryAction() {}
28
};
29
30
class SyncRegistryRequest final : public SyncRegistryAction
31
{
32
public:
33
  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(SyncRegistryRequest)
34
35
  SyncOpOrInternalOp mOpOrIOp;
36
37
  SyncRegistryRequest(const uint64_t aActorId,
38
                      const nsID& aRequestId,
39
                      const SyncOpOrInternalOp& aOpOrIOp)
40
    : SyncRegistryAction(aActorId, aRequestId)
41
    , mOpOrIOp(aOpOrIOp)
42
  {}
43
44
private:
45
  ~SyncRegistryRequest() {}
46
};
47
48
class SyncRegistryResponse final : public SyncRegistryAction
49
{
50
public:
51
  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(SyncRegistryResponse)
52
53
  SyncOpResponse mResponse;
54
55
  SyncRegistryResponse(const uint64_t aActorId,
56
                       const nsID& aRequestId,
57
                       const SyncOpResponse& aResponse)
58
    : SyncRegistryAction(aActorId, aRequestId)
59
    , mResponse(aResponse)
60
  {}
61
62
private:
63
  ~SyncRegistryResponse() {}
64
};
65
66
class SyncRegistryInternalResponse final
67
{
68
public:
69
  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(SyncRegistryInternalResponse)
70
71
  enum Type {
72
    TGetAllResponse,
73
    TChangeStateResponse
74
  };
75
76
  SyncRegistryInternalResponse(
77
      Type aType,
78
      nsTArray<nsCOMPtr<nsISyncRegistration>> &aRegistrations)
79
    : mType(aType)
80
  {
81
    for (uint32_t i = 0; i < aRegistrations.Length(); i++) {
82
      mRegistrations.AppendElement(aRegistrations[i]);
83
    }
84
  }
85
86
  Type
87
  type() {
88
    return mType;
89
  }
90
91
  void
92
  GetRegistrations(nsTArray<nsCOMPtr<nsISyncRegistration>>& aRegistrations)
93
  {
94
    for (uint32_t i = 0; i < mRegistrations.Length(); i++) {
95
      aRegistrations.AppendElement(mRegistrations[i]);
96
    }
97
  }
98
99
private:
100
  ~SyncRegistryInternalResponse() {}
101
102
  Type mType;
103
104
  nsTArray<nsCOMPtr<nsISyncRegistration>> mRegistrations;
105
};
106
107
} // namespace dom
108
} // namespace mozilla
109
110
#endif // mozilla_dom_sync_Types_h
(-)a/dom/sync/moz.build (+41 lines)
Line     Link Here 
Line 0    Link Here 
1
# vim: set filetype=python:
2
# This Source Code Form is subject to the terms of the Mozilla Public
3
# License, v. 2.0. If a copy of the MPL was not distributed with this
4
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
5
6
EXPORTS.mozilla.dom += [
7
    'SyncManager.h'
8
]
9
10
UNIFIED_SOURCES += [
11
    'SyncManager.cpp',
12
    'SyncManagerChild.cpp',
13
    'SyncManagerParent.cpp',
14
    'SyncRegistration.cpp',
15
    'SyncService.cpp'
16
]
17
18
IPDL_SOURCES += [
19
    'PSyncManager.ipdl',
20
    'SyncIPCTypes.ipdlh'
21
]
22
23
LOCAL_INCLUDES += [
24
    '/dom/workers',
25
    '/netwerk/base'
26
]
27
28
XPIDL_SOURCES += [
29
    'nsISyncRegistry.idl'
30
]
31
32
XPIDL_MODULE = 'dom_sync'
33
34
EXTRA_COMPONENTS += [
35
    'SyncRegistry.js',
36
    'SyncRegistry.manifest'
37
]
38
39
include('/ipc/chromium/chromium-config.mozbuild')
40
41
FINAL_LIBRARY = 'xul'
(-)a/dom/sync/nsISyncRegistry.idl (+57 lines)
Line     Link Here 
Line 0    Link Here 
1
/* This Source Code Form is subject to the terms of the Mozilla Public
2
 * License, v. 2.0. If a copy of the MPL was not distributed with this
3
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5
#include "nsIArray.idl"
6
#include "nsISupports.idl"
7
8
[scriptable, uuid(671ea934-232d-47c6-87ba-b72715088914)]
9
interface nsISyncRegistration : nsISupports
10
{
11
  attribute DOMString id;
12
  attribute DOMString originSuffix;
13
  attribute DOMString scope;
14
  attribute DOMString tag;
15
  attribute unsigned short state; // "pending" by default
16
  attribute boolean lastChance;
17
18
  void init(in DOMString id,
19
            in DOMString originSuffix,
20
            in DOMString scope,
21
            in DOMString tag,
22
            in unsigned short state,
23
            in boolean lastChance);
24
};
25
26
[scriptable, uuid(3084a211-3ef4-4fa3-8a20-dab42f062571)]
27
interface nsISyncRegistryListener : nsISupports
28
{
29
  attribute nsID requestId;
30
  attribute unsigned long long actorId;
31
32
  void notifyAddSuccess();
33
  void notifyGetAllSuccess(in nsIArray registrations);
34
  void notifyChangeStateSuccess(in nsISyncRegistration registration);
35
  void notifyError(in uint32_t error);
36
};
37
38
[scriptable, uuid(dfcc3fb2-f40d-44f9-85ea-1127be79fbe9)]
39
interface nsISyncRegistry : nsISupports
40
{
41
  const unsigned short STATE_PENDING                    = 1;
42
  const unsigned short STATE_WAITING                    = 2;
43
  const unsigned short STATE_FIRING                     = 3;
44
  const unsigned short STATE_REREGISTERING_WHILE_FIRING = 4;
45
46
  void add(in nsISyncRegistration registration,
47
           in nsISyncRegistryListener listener);
48
49
  void remove(in DOMString id,
50
              in nsISyncRegistryListener listener);
51
52
  void getAll(in nsISyncRegistryListener listener);
53
54
  void changeState(in DOMString id,
55
                   in unsigned short state,
56
                   in nsISyncRegistryListener listener);
57
};
(-)a/dom/tests/mochitest/general/test_interfaces.html (+2 lines)
Line     Link Here 
 Lines 1301-1316   var interfaceNamesInGlobalScope = Link Here 
1301
    "SVGUseElement",
1301
    "SVGUseElement",
1302
// IMPORTANT: Do not change this list without review from a DOM peer!
1302
// IMPORTANT: Do not change this list without review from a DOM peer!
1303
    "SVGViewElement",
1303
    "SVGViewElement",
1304
// IMPORTANT: Do not change this list without review from a DOM peer!
1304
// IMPORTANT: Do not change this list without review from a DOM peer!
1305
    "SVGZoomAndPan",
1305
    "SVGZoomAndPan",
1306
// IMPORTANT: Do not change this list without review from a DOM peer!
1306
// IMPORTANT: Do not change this list without review from a DOM peer!
1307
    "SVGZoomEvent",
1307
    "SVGZoomEvent",
1308
// IMPORTANT: Do not change this list without review from a DOM peer!
1308
// IMPORTANT: Do not change this list without review from a DOM peer!
1309
    {name: "SyncManager", b2g: true},
1310
// IMPORTANT: Do not change this list without review from a DOM peer!
1309
    {name: "RequestSyncManager", b2g: true, permission: ["requestsync-manager"] },
1311
    {name: "RequestSyncManager", b2g: true, permission: ["requestsync-manager"] },
1310
// IMPORTANT: Do not change this list without review from a DOM peer!
1312
// IMPORTANT: Do not change this list without review from a DOM peer!
1311
    {name: "RequestSyncApp", b2g: true, permission: ["requestsync-manager"] },
1313
    {name: "RequestSyncApp", b2g: true, permission: ["requestsync-manager"] },
1312
// IMPORTANT: Do not change this list without review from a DOM peer!
1314
// IMPORTANT: Do not change this list without review from a DOM peer!
1313
    {name: "RequestSyncTask", b2g: true, permission: ["requestsync-manager"] },
1315
    {name: "RequestSyncTask", b2g: true, permission: ["requestsync-manager"] },
1314
// IMPORTANT: Do not change this list without review from a DOM peer!
1316
// IMPORTANT: Do not change this list without review from a DOM peer!
1315
    {name: "Telephony", b2g: true},
1317
    {name: "Telephony", b2g: true},
1316
// IMPORTANT: Do not change this list without review from a DOM peer!
1318
// IMPORTANT: Do not change this list without review from a DOM peer!
(-)a/dom/webidl/ServiceWorkerRegistration.webidl (+2 lines)
Line     Link Here 
 Lines 27-35   interface ServiceWorkerRegistration : Ev Link Here 
27
  attribute EventHandler onupdatefound;
27
  attribute EventHandler onupdatefound;
28
};
28
};
29
29
30
partial interface ServiceWorkerRegistration {
30
partial interface ServiceWorkerRegistration {
31
#ifndef MOZ_SIMPLEPUSH
31
#ifndef MOZ_SIMPLEPUSH
32
  [Throws, Exposed=(Window,Worker), Func="nsContentUtils::PushEnabled"]
32
  [Throws, Exposed=(Window,Worker), Func="nsContentUtils::PushEnabled"]
33
  readonly attribute PushManager pushManager;
33
  readonly attribute PushManager pushManager;
34
#endif
34
#endif
35
  [Throws, Exposed=(Window,Worker)]
36
  readonly attribute SyncManager sync;
35
};
37
};
(-)a/dom/webidl/SyncEvent.webidl (+20 lines)
Line     Link Here 
Line 0    Link Here 
1
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* This Source Code Form is subject to the terms of the Mozilla Public
3
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
4
 * You can obtain one at http://mozilla.org/MPL/2.0/.
5
 *
6
 * The origin of this IDL file is
7
 * https://wicg.github.io/BackgroundSync/spec/
8
 */
9
10
[Constructor(DOMString type, optional SyncEventInit eventInitDict),
11
 Exposed=ServiceWorker]
12
interface SyncEvent : ExtendableEvent {
13
  readonly attribute DOMString tag;
14
  readonly attribute boolean lastChance;
15
};
16
17
dictionary SyncEventInit : ExtendableEventInit {
18
  required DOMString tag;
19
  boolean lastChance = false;
20
};
(-)a/dom/webidl/SyncManager.webidl (+17 lines)
Line     Link Here 
Line 0    Link Here 
1
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* This Source Code Form is subject to the terms of the Mozilla Public
3
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
4
* You can obtain one at http://mozilla.org/MPL/2.0/.
5
*
6
* The origin of this IDL file is
7
* https://wicg.github.io/BackgroundSync/spec/
8
*/
9
10
[Exposed=(Window,Worker),
11
 Func="mozilla::dom::SyncManager::PrefEnabled"]
12
interface SyncManager {
13
  [Throws]
14
  Promise<void> register(DOMString tag);
15
  [Throws]
16
  Promise<sequence<DOMString>> getTags();
17
};
(-)a/dom/webidl/moz.build (+2 lines)
Line     Link Here 
 Lines 533-548   WEBIDL_FILES = [ Link Here 
533
    'SVGTransformList.webidl',
533
    'SVGTransformList.webidl',
534
    'SVGTSpanElement.webidl',
534
    'SVGTSpanElement.webidl',
535
    'SVGUnitTypes.webidl',
535
    'SVGUnitTypes.webidl',
536
    'SVGURIReference.webidl',
536
    'SVGURIReference.webidl',
537
    'SVGUseElement.webidl',
537
    'SVGUseElement.webidl',
538
    'SVGViewElement.webidl',
538
    'SVGViewElement.webidl',
539
    'SVGZoomAndPan.webidl',
539
    'SVGZoomAndPan.webidl',
540
    'SVGZoomEvent.webidl',
540
    'SVGZoomEvent.webidl',
541
    'SyncEvent.webidl',
542
    'SyncManager.webidl',
541
    'SystemUpdate.webidl',
543
    'SystemUpdate.webidl',
542
    'TCPServerSocket.webidl',
544
    'TCPServerSocket.webidl',
543
    'TCPServerSocketEvent.webidl',
545
    'TCPServerSocketEvent.webidl',
544
    'TCPSocket.webidl',
546
    'TCPSocket.webidl',
545
    'TCPSocketErrorEvent.webidl',
547
    'TCPSocketErrorEvent.webidl',
546
    'TCPSocketEvent.webidl',
548
    'TCPSocketEvent.webidl',
547
    'Telephony.webidl',
549
    'Telephony.webidl',
548
    'TelephonyCall.webidl',
550
    'TelephonyCall.webidl',
(-)a/dom/workers/PServiceWorkerManager.ipdl (-2 / +6 lines)
Line     Link Here 
 Lines 28-45   parent: Link Here 
28
  async PropagateRemove(nsCString host);
28
  async PropagateRemove(nsCString host);
29
29
30
  async PropagateRemoveAll();
30
  async PropagateRemoveAll();
31
31
32
  async Shutdown();
32
  async Shutdown();
33
33
34
child:
34
child:
35
  async NotifyRegister(ServiceWorkerRegistrationData data);
35
  async NotifyRegister(ServiceWorkerRegistrationData data);
36
  async NotifySoftUpdate(PrincipalOriginAttributes originAttributes, nsString scope);
36
  async NotifySoftUpdate(PrincipalOriginAttributes originAttributes,
37
                         nsString scope);
37
  async NotifyUnregister(PrincipalInfo principalInfo, nsString scope);
38
  async NotifyUnregister(PrincipalInfo principalInfo, nsString scope);
38
  async NotifyRemove(nsCString host);
39
  async NotifyRemove(nsCString host);
39
  async NotifyRemoveAll();
40
  async NotifyRemoveAll();
40
41
  async NotifySyncEvent(nsString originSuffix,
42
                        nsString scope,
43
                        nsString tag,
44
                        bool lastChance);
41
  async __delete__();
45
  async __delete__();
42
};
46
};
43
47
44
} // namespace dom
48
} // namespace dom
45
} // namespace mozilla
49
} // namespace mozilla
(-)a/dom/workers/ServiceWorkerEvents.cpp (-1 / +25 lines)
Line     Link Here 
 Lines 1003-1019   ExtractBytesFromData(const OwningArrayBu Link Here 
1003
    const ArrayBuffer& buffer = aDataInit.GetAsArrayBuffer();
1003
    const ArrayBuffer& buffer = aDataInit.GetAsArrayBuffer();
1004
    return ExtractBytesFromArrayBuffer(buffer, aBytes);
1004
    return ExtractBytesFromArrayBuffer(buffer, aBytes);
1005
  } else if (aDataInit.IsUSVString()) {
1005
  } else if (aDataInit.IsUSVString()) {
1006
    return ExtractBytesFromUSVString(aDataInit.GetAsUSVString(), aBytes);
1006
    return ExtractBytesFromUSVString(aDataInit.GetAsUSVString(), aBytes);
1007
  }
1007
  }
1008
  NS_NOTREACHED("Unexpected push message data");
1008
  NS_NOTREACHED("Unexpected push message data");
1009
  return NS_ERROR_FAILURE;
1009
  return NS_ERROR_FAILURE;
1010
}
1010
}
1011
}
1011
} // namespace
1012
1012
1013
PushMessageData::PushMessageData(nsISupports* aOwner,
1013
PushMessageData::PushMessageData(nsISupports* aOwner,
1014
                                 const nsTArray<uint8_t>& aBytes)
1014
                                 const nsTArray<uint8_t>& aBytes)
1015
  : mOwner(aOwner), mBytes(aBytes) {}
1015
  : mOwner(aOwner), mBytes(aBytes) {}
1016
1016
1017
PushMessageData::~PushMessageData()
1017
PushMessageData::~PushMessageData()
1018
{
1018
{
1019
}
1019
}
 Lines 1146-1161   NS_IMPL_CYCLE_COLLECTION_INHERITED(PushE Link Here 
1146
JSObject*
1146
JSObject*
1147
PushEvent::WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
1147
PushEvent::WrapObjectInternal(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
1148
{
1148
{
1149
  return mozilla::dom::PushEventBinding::Wrap(aCx, this, aGivenProto);
1149
  return mozilla::dom::PushEventBinding::Wrap(aCx, this, aGivenProto);
1150
}
1150
}
1151
1151
1152
#endif /* ! MOZ_SIMPLEPUSH */
1152
#endif /* ! MOZ_SIMPLEPUSH */
1153
1153
1154
// Background Sync
1155
1156
SyncEvent::SyncEvent(EventTarget* aOwner)
1157
  : ExtendableEvent(aOwner)
1158
{
1159
}
1160
1161
already_AddRefed<SyncEvent>
1162
SyncEvent::Constructor(EventTarget* aOwner,
1163
                       const nsAString& aType,
1164
                       const SyncEventInit& aOptions,
1165
                       ErrorResult& aRv)
1166
{
1167
  RefPtr<SyncEvent> e = new SyncEvent(aOwner);
1168
  bool trusted = e->Init(aOwner);
1169
  e->InitEvent(aType, aOptions.mBubbles, aOptions.mCancelable);
1170
  e->SetTrusted(trusted);
1171
  e->mTag = aOptions.mTag;
1172
  e->mLastChance = aOptions.mLastChance;
1173
  return e.forget();
1174
}
1175
1176
NS_IMPL_ISUPPORTS_INHERITED0(SyncEvent, ExtendableEvent)
1177
1154
ExtendableMessageEvent::ExtendableMessageEvent(EventTarget* aOwner)
1178
ExtendableMessageEvent::ExtendableMessageEvent(EventTarget* aOwner)
1155
  : ExtendableEvent(aOwner)
1179
  : ExtendableEvent(aOwner)
1156
  , mData(JS::UndefinedValue())
1180
  , mData(JS::UndefinedValue())
1157
{
1181
{
1158
  mozilla::HoldJSObjects(this);
1182
  mozilla::HoldJSObjects(this);
1159
}
1183
}
1160
1184
1161
ExtendableMessageEvent::~ExtendableMessageEvent()
1185
ExtendableMessageEvent::~ExtendableMessageEvent()
(-)a/dom/workers/ServiceWorkerEvents.h (+50 lines)
Line     Link Here 
 Lines 14-29    Link Here 
14
#include "mozilla/dom/Promise.h"
14
#include "mozilla/dom/Promise.h"
15
#include "mozilla/dom/Response.h"
15
#include "mozilla/dom/Response.h"
16
#include "mozilla/dom/workers/bindings/ServiceWorker.h"
16
#include "mozilla/dom/workers/bindings/ServiceWorker.h"
17
17
18
#ifndef MOZ_SIMPLEPUSH
18
#ifndef MOZ_SIMPLEPUSH
19
#include "mozilla/dom/File.h"
19
#include "mozilla/dom/File.h"
20
#endif
20
#endif
21
21
22
#include "mozilla/dom/SyncEventBinding.h"
23
22
#include "nsProxyRelease.h"
24
#include "nsProxyRelease.h"
23
#include "nsContentUtils.h"
25
#include "nsContentUtils.h"
24
26
25
class nsIInterceptedChannel;
27
class nsIInterceptedChannel;
26
28
27
namespace mozilla {
29
namespace mozilla {
28
namespace dom {
30
namespace dom {
29
class Blob;
31
class Blob;
 Lines 311-321   public: Link Here 
311
313
312
  void SetPorts(MessagePortList* aPorts);
314
  void SetPorts(MessagePortList* aPorts);
313
315
314
  void SetSource(ServiceWorkerClient* aClient);
316
  void SetSource(ServiceWorkerClient* aClient);
315
317
316
  void SetSource(ServiceWorker* aServiceWorker);
318
  void SetSource(ServiceWorker* aServiceWorker);
317
};
319
};
318
320
321
class SyncEvent final : public ExtendableEvent
322
{
323
  nsString mTag;
324
  bool mLastChance;
325
326
protected:
327
  explicit SyncEvent(EventTarget* aOwner);
328
  ~SyncEvent() {}
329
330
public:
331
  NS_DECL_ISUPPORTS_INHERITED
332
  NS_FORWARD_TO_EVENT
333
334
  virtual JSObject* WrapObjectInternal(JSContext* aCx,
335
                                       JS::Handle<JSObject*> aGivenProto) override
336
  {
337
    return mozilla::dom::SyncEventBinding_workers::Wrap(aCx, this, aGivenProto);
338
  }
339
340
  static already_AddRefed<SyncEvent>
341
  Constructor(EventTarget* aOwner,
342
              const nsAString& aType,
343
              const SyncEventInit& aOptions,
344
              ErrorResult& aRv);
345
346
  static already_AddRefed<SyncEvent>
347
  Constructor(const GlobalObject& aGlobal,
348
              const nsAString& aType,
349
              const SyncEventInit& aOptions,
350
              ErrorResult& aRv)
351
  {
352
    nsCOMPtr<EventTarget> owner = do_QueryInterface(aGlobal.GetAsSupports());
353
    return Constructor(owner, aType, aOptions, aRv);
354
  }
355
356
  void
357
  GetTag(nsAString& aTag)
358
  {
359
    aTag = mTag;
360
  }
361
362
  bool
363
  LastChance()
364
  {
365
    return mLastChance;
366
  }
367
};
368
319
END_WORKERS_NAMESPACE
369
END_WORKERS_NAMESPACE
320
370
321
#endif /* mozilla_dom_workers_serviceworkerevents_h__ */
371
#endif /* mozilla_dom_workers_serviceworkerevents_h__ */
(-)a/dom/workers/ServiceWorkerManager.cpp (+26 lines)
Line     Link Here 
 Lines 5265-5280   ServiceWorkerInfo::~ServiceWorkerInfo() Link Here 
5265
static uint64_t gServiceWorkerInfoCurrentID = 0;
5265
static uint64_t gServiceWorkerInfoCurrentID = 0;
5266
5266
5267
uint64_t
5267
uint64_t
5268
ServiceWorkerInfo::GetNextID() const
5268
ServiceWorkerInfo::GetNextID() const
5269
{
5269
{
5270
  return ++gServiceWorkerInfoCurrentID;
5270
  return ++gServiceWorkerInfoCurrentID;
5271
}
5271
}
5272
5272
5273
// Background Sync
5274
5275
NS_IMETHODIMP
5276
ServiceWorkerManager::SendSyncEvent(const nsACString& aOriginAttributes,
5277
                                    const nsACString& aScope,
5278
                                    const nsAString& aTag,
5279
                                    const bool aLastChance)
5280
{
5281
  PrincipalOriginAttributes attrs;
5282
  if (!attrs.PopulateFromSuffix(aOriginAttributes)) {
5283
    return NS_ERROR_INVALID_ARG;
5284
  }
5285
5286
  ServiceWorkerInfo* serviceWorker =
5287
    GetActiveWorkerInfoForScope(attrs, aScope);
5288
  if (NS_WARN_IF(!serviceWorker)) {
5289
    return NS_ERROR_FAILURE;
5290
  }
5291
5292
  RefPtr<ServiceWorkerRegistrationInfo> registration =
5293
    GetRegistration(serviceWorker->GetPrincipal(), aScope);
5294
5295
  return serviceWorker->WorkerPrivate()->SendSyncEvent(aTag, aLastChance,
5296
                                                       registration);
5297
}
5298
5273
already_AddRefed<ServiceWorker>
5299
already_AddRefed<ServiceWorker>
5274
ServiceWorkerInfo::GetOrCreateInstance(nsPIDOMWindowInner* aWindow)
5300
ServiceWorkerInfo::GetOrCreateInstance(nsPIDOMWindowInner* aWindow)
5275
{
5301
{
5276
  AssertIsOnMainThread();
5302
  AssertIsOnMainThread();
5277
  MOZ_ASSERT(aWindow);
5303
  MOZ_ASSERT(aWindow);
5278
5304
5279
  RefPtr<ServiceWorker> ref;
5305
  RefPtr<ServiceWorker> ref;
5280
5306
(-)a/dom/workers/ServiceWorkerManagerChild.cpp (+19 lines)
Line     Link Here 
 Lines 90-100   ServiceWorkerManagerChild::RecvNotifyRem Link Here 
90
90
91
  RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
91
  RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
92
  MOZ_ASSERT(swm);
92
  MOZ_ASSERT(swm);
93
93
94
  swm->RemoveAll();
94
  swm->RemoveAll();
95
  return true;
95
  return true;
96
}
96
}
97
97
98
bool
99
ServiceWorkerManagerChild::RecvNotifySyncEvent(const nsString& aOriginSuffix,
100
                                               const nsString& aScope,
101
                                               const nsString& aTag,
102
                                               const bool& aLastChance)
103
{
104
  if (mShuttingDown) {
105
    return true;
106
  }
107
108
  RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
109
  MOZ_ASSERT(swm);
110
111
  swm->SendSyncEvent(NS_ConvertUTF16toUTF8(aOriginSuffix),
112
                     NS_ConvertUTF16toUTF8(aScope),
113
                     aTag, aLastChance);
114
  return true;
115
}
116
98
} // namespace workers
117
} // namespace workers
99
} // namespace dom
118
} // namespace dom
100
} // namespace mozilla
119
} // namespace mozilla
(-)a/dom/workers/ServiceWorkerManagerChild.h (+5 lines)
Line     Link Here 
 Lines 41-56   public: Link Here 
41
41
42
  virtual bool RecvNotifyUnregister(const PrincipalInfo& aPrincipalInfo,
42
  virtual bool RecvNotifyUnregister(const PrincipalInfo& aPrincipalInfo,
43
                                    const nsString& aScope) override;
43
                                    const nsString& aScope) override;
44
44
45
  virtual bool RecvNotifyRemove(const nsCString& aHost) override;
45
  virtual bool RecvNotifyRemove(const nsCString& aHost) override;
46
46
47
  virtual bool RecvNotifyRemoveAll() override;
47
  virtual bool RecvNotifyRemoveAll() override;
48
48
49
  virtual bool RecvNotifySyncEvent(const nsString& aOriginSuffix,
50
                                   const nsString& aScope,
51
                                   const nsString& aTag,
52
                                   const bool& aLastChance) override;
53
49
private:
54
private:
50
  ServiceWorkerManagerChild()
55
  ServiceWorkerManagerChild()
51
    : mShuttingDown(false)
56
    : mShuttingDown(false)
52
  {}
57
  {}
53
58
54
  ~ServiceWorkerManagerChild() {}
59
  ~ServiceWorkerManagerChild() {}
55
60
56
  bool mShuttingDown;
61
  bool mShuttingDown;
(-)a/dom/workers/ServiceWorkerManagerParent.cpp (-16 / +28 lines)
Line     Link Here 
 Lines 1-16    Link Here 
1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
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: */
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
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
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/. */
5
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
6
7
#include "ServiceWorkerManagerParent.h"
7
#include "ServiceWorkerManagerParent.h"
8
#include "ServiceWorkerManagerService.h"
8
#include "ServiceWorkerManagerService.h"
9
#include "SyncService.h"
9
#include "mozilla/AppProcessChecker.h"
10
#include "mozilla/AppProcessChecker.h"
10
#include "mozilla/dom/ContentParent.h"
11
#include "mozilla/dom/ContentParent.h"
11
#include "mozilla/dom/ServiceWorkerRegistrar.h"
12
#include "mozilla/dom/ServiceWorkerRegistrar.h"
12
#include "mozilla/ipc/BackgroundParent.h"
13
#include "mozilla/ipc/BackgroundParent.h"
13
#include "mozilla/ipc/BackgroundUtils.h"
14
#include "mozilla/ipc/BackgroundUtils.h"
14
#include "mozilla/unused.h"
15
#include "mozilla/unused.h"
15
#include "nsThreadUtils.h"
16
#include "nsThreadUtils.h"
16
17
 Lines 148-169   private: Link Here 
148
  PrincipalInfo mPrincipalInfo;
149
  PrincipalInfo mPrincipalInfo;
149
  RefPtr<nsRunnable> mCallback;
150
  RefPtr<nsRunnable> mCallback;
150
  nsCOMPtr<nsIThread> mBackgroundThread;
151
  nsCOMPtr<nsIThread> mBackgroundThread;
151
};
152
};
152
153
153
} // namespace
154
} // namespace
154
155
155
ServiceWorkerManagerParent::ServiceWorkerManagerParent()
156
ServiceWorkerManagerParent::ServiceWorkerManagerParent()
156
  : mService(ServiceWorkerManagerService::GetOrCreate())
157
  : mServiceWorkerService(ServiceWorkerManagerService::GetOrCreate())
158
  , mSyncService(SyncService::GetOrCreate())
157
  , mID(++sServiceWorkerManagerParentID)
159
  , mID(++sServiceWorkerManagerParentID)
158
  , mActorDestroyed(false)
160
  , mActorDestroyed(false)
159
{
161
{
160
  AssertIsOnBackgroundThread();
162
  AssertIsOnBackgroundThread();
161
  mService->RegisterActor(this);
163
  mServiceWorkerService->RegisterActor(this);
164
  mSyncService->RegisterActor(this);
162
}
165
}
163
166
164
ServiceWorkerManagerParent::~ServiceWorkerManagerParent()
167
ServiceWorkerManagerParent::~ServiceWorkerManagerParent()
165
{
168
{
166
  AssertIsOnBackgroundThread();
169
  AssertIsOnBackgroundThread();
167
}
170
}
168
171
169
already_AddRefed<ContentParent>
172
already_AddRefed<ContentParent>
 Lines 248-336   ServiceWorkerManagerParent::RecvUnregist Link Here 
248
}
251
}
249
252
250
bool
253
bool
251
ServiceWorkerManagerParent::RecvPropagateSoftUpdate(const PrincipalOriginAttributes& aOriginAttributes,
254
ServiceWorkerManagerParent::RecvPropagateSoftUpdate(const PrincipalOriginAttributes& aOriginAttributes,
252
                                                    const nsString& aScope)
255
                                                    const nsString& aScope)
253
{
256
{
254
  AssertIsOnBackgroundThread();
257
  AssertIsOnBackgroundThread();
255
258
256
  if (NS_WARN_IF(!mService)) {
259
  if (NS_WARN_IF(!mServiceWorkerService)) {
257
    return false;
260
    return false;
258
  }
261
  }
259
262
260
  mService->PropagateSoftUpdate(mID, aOriginAttributes, aScope);
263
  mServiceWorkerService->PropagateSoftUpdate(mID, aOriginAttributes, aScope);
261
  return true;
264
  return true;
262
}
265
}
263
266
264
bool
267
bool
265
ServiceWorkerManagerParent::RecvPropagateUnregister(const PrincipalInfo& aPrincipalInfo,
268
ServiceWorkerManagerParent::RecvPropagateUnregister(const PrincipalInfo& aPrincipalInfo,
266
                                                    const nsString& aScope)
269
                                                    const nsString& aScope)
267
{
270
{
268
  AssertIsOnBackgroundThread();
271
  AssertIsOnBackgroundThread();
269
272
270
  if (NS_WARN_IF(!mService)) {
273
  if (NS_WARN_IF(!mServiceWorkerService)) {
271
    return false;
274
    return false;
272
  }
275
  }
273
276
274
  mService->PropagateUnregister(mID, aPrincipalInfo, aScope);
277
  mServiceWorkerService->PropagateUnregister(mID, aPrincipalInfo, aScope);
275
  return true;
278
  return true;
276
}
279
}
277
280
278
bool
281
bool
279
ServiceWorkerManagerParent::RecvPropagateRemove(const nsCString& aHost)
282
ServiceWorkerManagerParent::RecvPropagateRemove(const nsCString& aHost)
280
{
283
{
281
  AssertIsOnBackgroundThread();
284
  AssertIsOnBackgroundThread();
282
285
283
  if (NS_WARN_IF(!mService)) {
286
  if (NS_WARN_IF(!mServiceWorkerService)) {
284
    return false;
287
    return false;
285
  }
288
  }
286
289
287
  mService->PropagateRemove(mID, aHost);
290
  mServiceWorkerService->PropagateRemove(mID, aHost);
288
  return true;
291
  return true;
289
}
292
}
290
293
291
bool
294
bool
292
ServiceWorkerManagerParent::RecvPropagateRemoveAll()
295
ServiceWorkerManagerParent::RecvPropagateRemoveAll()
293
{
296
{
294
  AssertIsOnBackgroundThread();
297
  AssertIsOnBackgroundThread();
295
298
296
  if (NS_WARN_IF(!mService)) {
299
  if (NS_WARN_IF(!mServiceWorkerService)) {
297
    return false;
300
    return false;
298
  }
301
  }
299
302
300
  mService->PropagateRemoveAll(mID);
303
  mServiceWorkerService->PropagateRemoveAll(mID);
301
  return true;
304
  return true;
302
}
305
}
303
306
304
bool
307
bool
305
ServiceWorkerManagerParent::RecvShutdown()
308
ServiceWorkerManagerParent::RecvShutdown()
306
{
309
{
307
  AssertIsOnBackgroundThread();
310
  AssertIsOnBackgroundThread();
308
311
309
  if (NS_WARN_IF(!mService)) {
312
  if (NS_WARN_IF(!mServiceWorkerService)) {
310
    return false;
313
    return false;
311
  }
314
  }
312
315
313
  mService->UnregisterActor(this);
316
  mServiceWorkerService->UnregisterActor(this);
314
  mService = nullptr;
317
  mServiceWorkerService = nullptr;
318
319
  if (mSyncService) {
320
    mSyncService->UnregisterActor(this);
321
    mSyncService = nullptr;
322
  }
315
323
316
  Unused << Send__delete__(this);
324
  Unused << Send__delete__(this);
317
  return true;
325
  return true;
318
}
326
}
319
327
320
void
328
void
321
ServiceWorkerManagerParent::ActorDestroy(ActorDestroyReason aWhy)
329
ServiceWorkerManagerParent::ActorDestroy(ActorDestroyReason aWhy)
322
{
330
{
323
  AssertIsOnBackgroundThread();
331
  AssertIsOnBackgroundThread();
324
332
325
  mActorDestroyed = true;
333
  mActorDestroyed = true;
326
334
327
  if (mService) {
335
  if (mServiceWorkerService) {
328
    // This object is about to be released and with it, also mService will be
336
    // This object is about to be released and with it, also mServiceWorkerService will be
329
    // released too.
337
    // released too.
330
    mService->UnregisterActor(this);
338
    mServiceWorkerService->UnregisterActor(this);
339
  }
340
341
  if (mSyncService) {
342
    mSyncService->UnregisterActor(this);
331
  }
343
  }
332
}
344
}
333
345
334
} // namespace workers
346
} // namespace workers
335
} // namespace dom
347
} // namespace dom
336
} // namespace mozilla
348
} // namespace mozilla
(-)a/dom/workers/ServiceWorkerManagerParent.h (-1 / +5 lines)
Line     Link Here 
 Lines 13-28   namespace mozilla { Link Here 
13
13
14
class PrincipalOriginAttributes;
14
class PrincipalOriginAttributes;
15
15
16
namespace ipc {
16
namespace ipc {
17
class BackgroundParentImpl;
17
class BackgroundParentImpl;
18
} // namespace ipc
18
} // namespace ipc
19
19
20
namespace dom {
20
namespace dom {
21
22
class SyncService;
23
21
namespace workers {
24
namespace workers {
22
25
23
class ServiceWorkerManagerService;
26
class ServiceWorkerManagerService;
24
27
25
class ServiceWorkerManagerParent final : public PServiceWorkerManagerParent
28
class ServiceWorkerManagerParent final : public PServiceWorkerManagerParent
26
{
29
{
27
  friend class mozilla::ipc::BackgroundParentImpl;
30
  friend class mozilla::ipc::BackgroundParentImpl;
28
31
 Lines 59-75   private: Link Here 
59
  virtual bool RecvPropagateRemove(const nsCString& aHost) override;
62
  virtual bool RecvPropagateRemove(const nsCString& aHost) override;
60
63
61
  virtual bool RecvPropagateRemoveAll() override;
64
  virtual bool RecvPropagateRemoveAll() override;
62
65
63
  virtual bool RecvShutdown() override;
66
  virtual bool RecvShutdown() override;
64
67
65
  virtual void ActorDestroy(ActorDestroyReason aWhy) override;
68
  virtual void ActorDestroy(ActorDestroyReason aWhy) override;
66
69
67
  RefPtr<ServiceWorkerManagerService> mService;
70
  RefPtr<ServiceWorkerManagerService> mServiceWorkerService;
71
  RefPtr<SyncService> mSyncService;
68
72
69
  // We use this ID in the Service in order to avoid the sending of messages to
73
  // We use this ID in the Service in order to avoid the sending of messages to
70
  // ourself.
74
  // ourself.
71
  uint64_t mID;
75
  uint64_t mID;
72
76
73
  bool mActorDestroyed;
77
  bool mActorDestroyed;
74
};
78
};
75
79
(-)a/dom/workers/ServiceWorkerPrivate.cpp (-5 / +91 lines)
Line     Link Here 
 Lines 76-92   private: Link Here 
76
76
77
  RefPtr<ServiceWorkerPrivate> mPrivate;
77
  RefPtr<ServiceWorkerPrivate> mPrivate;
78
};
78
};
79
79
80
NS_IMPL_ISUPPORTS0(KeepAliveToken)
80
NS_IMPL_ISUPPORTS0(KeepAliveToken)
81
81
82
ServiceWorkerPrivate::ServiceWorkerPrivate(ServiceWorkerInfo* aInfo)
82
ServiceWorkerPrivate::ServiceWorkerPrivate(ServiceWorkerInfo* aInfo)
83
  : mInfo(aInfo)
83
  : mInfo(aInfo)
84
  , mIsPushWorker(false)
84
  , mIsPushOrSyncWorker(false)
85
  , mDebuggerCount(0)
85
  , mDebuggerCount(0)
86
  , mTokenCount(0)
86
  , mTokenCount(0)
87
{
87
{
88
  AssertIsOnMainThread();
88
  AssertIsOnMainThread();
89
  MOZ_ASSERT(aInfo);
89
  MOZ_ASSERT(aInfo);
90
90
91
  mIdleWorkerTimer = do_CreateInstance(NS_TIMER_CONTRACTID);
91
  mIdleWorkerTimer = do_CreateInstance(NS_TIMER_CONTRACTID);
92
  MOZ_ASSERT(mIdleWorkerTimer);
92
  MOZ_ASSERT(mIdleWorkerTimer);
 Lines 1406-1421   ServiceWorkerPrivate::SendFetchEvent(nsI Link Here 
1406
1406
1407
  if (NS_WARN_IF(!r->Dispatch())) {
1407
  if (NS_WARN_IF(!r->Dispatch())) {
1408
    return NS_ERROR_FAILURE;
1408
    return NS_ERROR_FAILURE;
1409
  }
1409
  }
1410
1410
1411
  return NS_OK;
1411
  return NS_OK;
1412
}
1412
}
1413
1413
1414
namespace {
1415
class SendSyncEventRunnable final : public ExtendableFunctionalEventWorkerRunnable
1416
{
1417
  nsString mTag;
1418
  bool mLastChance;
1419
1420
public:
1421
  SendSyncEventRunnable(WorkerPrivate* aWorkerPrivate,
1422
                        KeepAliveToken* aKeepAliveToken,
1423
                        const nsAString& aTag,
1424
                        const bool aLastChance,
1425
                        nsMainThreadPtrHandle<ServiceWorkerRegistrationInfo> aRegistration)
1426
    : ExtendableFunctionalEventWorkerRunnable(
1427
        aWorkerPrivate, aKeepAliveToken, aRegistration)
1428
    , mTag(aTag)
1429
    , mLastChance(aLastChance)
1430
  {
1431
    AssertIsOnMainThread();
1432
    MOZ_ASSERT(aWorkerPrivate);
1433
    MOZ_ASSERT(aWorkerPrivate->IsServiceWorker());
1434
  }
1435
1436
  bool
1437
  WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override
1438
  {
1439
    MOZ_ASSERT(aWorkerPrivate);
1440
    GlobalObject globalObj(aCx, aWorkerPrivate->GlobalScope()->GetWrapper());
1441
1442
    SyncEventInit sei;
1443
    sei.mTag = mTag;
1444
    sei.mLastChance = mLastChance;
1445
    sei.mBubbles = false;
1446
    sei.mCancelable = false;
1447
1448
    ErrorResult result;
1449
    RefPtr<SyncEvent> event =
1450
      SyncEvent::Constructor(globalObj, NS_LITERAL_STRING("sync"), sei, result);
1451
    if (NS_WARN_IF(result.Failed())) {
1452
      result.SuppressException();
1453
      return false;
1454
    }
1455
    event->SetTrusted(true);
1456
1457
    DispatchExtendableEventOnWorkerScope(aCx, aWorkerPrivate->GlobalScope(),
1458
                                         event, nullptr);
1459
1460
    return true;
1461
  }
1462
};
1463
} // anonymous namespace
1464
1465
nsresult
1466
ServiceWorkerPrivate::SendSyncEvent(const nsAString& aTag,
1467
                                    const bool aLastChance,
1468
                                    ServiceWorkerRegistrationInfo* aRegistration)
1469
{
1470
  nsresult rv = SpawnWorkerIfNeeded(SyncEvent, nullptr);
1471
  NS_ENSURE_SUCCESS(rv, rv);
1472
1473
  MOZ_ASSERT(mKeepAliveToken);
1474
1475
  nsMainThreadPtrHandle<ServiceWorkerRegistrationInfo> regInfo(
1476
      new nsMainThreadPtrHolder<ServiceWorkerRegistrationInfo>(aRegistration, false));
1477
1478
1479
  RefPtr<WorkerRunnable> runnable = new SendSyncEventRunnable(mWorkerPrivate,
1480
                                                              mKeepAliveToken,
1481
                                                              aTag,
1482
                                                              aLastChance,
1483
                                                              regInfo);
1484
1485
  if (mInfo->State() == ServiceWorkerState::Activating) {
1486
    mPendingFunctionalEvents.AppendElement(runnable.forget());
1487
    return NS_OK;
1488
  }
1489
1490
  MOZ_ASSERT(mInfo->State() == ServiceWorkerState::Activated);
1491
1492
  if (NS_WARN_IF(!runnable->Dispatch())) {
1493
    return NS_ERROR_FAILURE;
1494
  }
1495
1496
  return NS_OK;
1497
}
1498
1414
nsresult
1499
nsresult
1415
ServiceWorkerPrivate::SpawnWorkerIfNeeded(WakeUpReason aWhy,
1500
ServiceWorkerPrivate::SpawnWorkerIfNeeded(WakeUpReason aWhy,
1416
                                          nsIRunnable* aLoadFailedRunnable,
1501
                                          nsIRunnable* aLoadFailedRunnable,
1417
                                          nsILoadGroup* aLoadGroup)
1502
                                          nsILoadGroup* aLoadGroup)
1418
{
1503
{
1419
  AssertIsOnMainThread();
1504
  AssertIsOnMainThread();
1420
1505
1421
  // XXXcatalinb: We need to have a separate load group that's linked to
1506
  // XXXcatalinb: We need to have a separate load group that's linked to
 Lines 1500-1516   ServiceWorkerPrivate::SpawnWorkerIfNeede Link Here 
1500
  mWorkerPrivate = WorkerPrivate::Constructor(jsapi.cx(),
1585
  mWorkerPrivate = WorkerPrivate::Constructor(jsapi.cx(),
1501
                                              scriptSpec,
1586
                                              scriptSpec,
1502
                                              false, WorkerTypeService,
1587
                                              false, WorkerTypeService,
1503
                                              mInfo->Scope(), &info, error);
1588
                                              mInfo->Scope(), &info, error);
1504
  if (NS_WARN_IF(error.Failed())) {
1589
  if (NS_WARN_IF(error.Failed())) {
1505
    return error.StealNSResult();
1590
    return error.StealNSResult();
1506
  }
1591
  }
1507
1592
1508
  mIsPushWorker = false;
1593
  mIsPushOrSyncWorker = false;
1509
  RenewKeepAliveToken(aWhy);
1594
  RenewKeepAliveToken(aWhy);
1510
1595
1511
  return NS_OK;
1596
  return NS_OK;
1512
}
1597
}
1513
1598
1514
void
1599
void
1515
ServiceWorkerPrivate::StoreISupports(nsISupports* aSupports)
1600
ServiceWorkerPrivate::StoreISupports(nsISupports* aSupports)
1516
{
1601
{
 Lines 1565-1581   ServiceWorkerPrivate::NoteDeadServiceWor Link Here 
1565
  mInfo = nullptr;
1650
  mInfo = nullptr;
1566
  TerminateWorker();
1651
  TerminateWorker();
1567
}
1652
}
1568
1653
1569
void
1654
void
1570
ServiceWorkerPrivate::NoteStoppedControllingDocuments()
1655
ServiceWorkerPrivate::NoteStoppedControllingDocuments()
1571
{
1656
{
1572
  AssertIsOnMainThread();
1657
  AssertIsOnMainThread();
1573
  if (mIsPushWorker || mDebuggerCount) {
1658
  if (mIsPushOrSyncWorker || mDebuggerCount) {
1574
    return;
1659
    return;
1575
  }
1660
  }
1576
1661
1577
  TerminateWorker();
1662
  TerminateWorker();
1578
}
1663
}
1579
1664
1580
void
1665
void
1581
ServiceWorkerPrivate::Activated()
1666
ServiceWorkerPrivate::Activated()
 Lines 1703-1720   ServiceWorkerPrivate::TerminateWorkerCal Link Here 
1703
}
1788
}
1704
1789
1705
void
1790
void
1706
ServiceWorkerPrivate::RenewKeepAliveToken(WakeUpReason aWhy)
1791
ServiceWorkerPrivate::RenewKeepAliveToken(WakeUpReason aWhy)
1707
{
1792
{
1708
  // We should have an active worker if we're renewing the keep alive token.
1793
  // We should have an active worker if we're renewing the keep alive token.
1709
  MOZ_ASSERT(mWorkerPrivate);
1794
  MOZ_ASSERT(mWorkerPrivate);
1710
1795
1711
  if (aWhy == PushEvent || aWhy == PushSubscriptionChangeEvent) {
1796
  if (aWhy == PushEvent || aWhy == PushSubscriptionChangeEvent ||
1712
    mIsPushWorker = true;
1797
      aWhy == SyncEvent) {
1798
    mIsPushOrSyncWorker = true;
1713
  }
1799
  }
1714
1800
1715
  // If there is at least one debugger attached to the worker, the idle worker
1801
  // If there is at least one debugger attached to the worker, the idle worker
1716
  // timeout was canceled when the first debugger attached to the worker. It
1802
  // timeout was canceled when the first debugger attached to the worker. It
1717
  // should not be reset until the last debugger detaches from the worker.
1803
  // should not be reset until the last debugger detaches from the worker.
1718
  if (!mDebuggerCount) {
1804
  if (!mDebuggerCount) {
1719
    ResetIdleTimeout();
1805
    ResetIdleTimeout();
1720
  }
1806
  }
(-)a/dom/workers/ServiceWorkerPrivate.h (-5 / +11 lines)
Line     Link Here 
 Lines 104-119   public: Link Here 
104
                             const nsAString& aScope);
104
                             const nsAString& aScope);
105
105
106
  nsresult
106
  nsresult
107
  SendFetchEvent(nsIInterceptedChannel* aChannel,
107
  SendFetchEvent(nsIInterceptedChannel* aChannel,
108
                 nsILoadGroup* aLoadGroup,
108
                 nsILoadGroup* aLoadGroup,
109
                 const nsAString& aDocumentId,
109
                 const nsAString& aDocumentId,
110
                 bool aIsReload);
110
                 bool aIsReload);
111
111
112
  nsresult
113
  SendSyncEvent(const nsAString& aTag,
114
                const bool aLastChance,
115
                ServiceWorkerRegistrationInfo* aRegistration);
116
112
  void
117
  void
113
  StoreISupports(nsISupports* aSupports);
118
  StoreISupports(nsISupports* aSupports);
114
119
115
  void
120
  void
116
  RemoveISupports(nsISupports* aSupports);
121
  RemoveISupports(nsISupports* aSupports);
117
122
118
  // This will terminate the current running worker thread and drop the
123
  // This will terminate the current running worker thread and drop the
119
  // workerPrivate reference.
124
  // workerPrivate reference.
 Lines 144-160   public: Link Here 
144
private:
149
private:
145
  enum WakeUpReason {
150
  enum WakeUpReason {
146
    FetchEvent = 0,
151
    FetchEvent = 0,
147
    PushEvent,
152
    PushEvent,
148
    PushSubscriptionChangeEvent,
153
    PushSubscriptionChangeEvent,
149
    MessageEvent,
154
    MessageEvent,
150
    NotificationClickEvent,
155
    NotificationClickEvent,
151
    LifeCycleEvent,
156
    LifeCycleEvent,
152
    AttachEvent
157
    AttachEvent,
158
    SyncEvent
153
  };
159
  };
154
160
155
  // Timer callbacks
161
  // Timer callbacks
156
  static void
162
  static void
157
  NoteIdleWorkerCallback(nsITimer* aTimer, void* aPrivate);
163
  NoteIdleWorkerCallback(nsITimer* aTimer, void* aPrivate);
158
164
159
  static void
165
  static void
160
  TerminateWorkerCallback(nsITimer* aTimer, void *aPrivate);
166
  TerminateWorkerCallback(nsITimer* aTimer, void *aPrivate);
 Lines 187-206   private: Link Here 
187
193
188
  // The WorkerPrivate object can only be closed by this class or by the
194
  // The WorkerPrivate object can only be closed by this class or by the
189
  // RuntimeService class if gecko is shutting down. Closing the worker
195
  // RuntimeService class if gecko is shutting down. Closing the worker
190
  // multiple times is OK, since the second attempt will be a no-op.
196
  // multiple times is OK, since the second attempt will be a no-op.
191
  RefPtr<WorkerPrivate> mWorkerPrivate;
197
  RefPtr<WorkerPrivate> mWorkerPrivate;
192
198
193
  nsCOMPtr<nsITimer> mIdleWorkerTimer;
199
  nsCOMPtr<nsITimer> mIdleWorkerTimer;
194
200
195
  // We keep track if this worker received any push events since it was last
201
  // We keep track if this worker received any push or sync events since it
196
  // woken up. The flag is reset to false every time a new WorkerPrivate
202
  // was last woken up. The flag is reset to false every time a new
197
  // is created.
203
  // WorkerPrivate is created.
198
  bool mIsPushWorker;
204
  bool mIsPushOrSyncWorker;
199
205
200
  // We keep a token for |dom.serviceWorkers.idle_timeout| seconds to give the
206
  // We keep a token for |dom.serviceWorkers.idle_timeout| seconds to give the
201
  // worker a grace period after each event.
207
  // worker a grace period after each event.
202
  RefPtr<KeepAliveToken> mKeepAliveToken;
208
  RefPtr<KeepAliveToken> mKeepAliveToken;
203
209
204
  uint64_t mDebuggerCount;
210
  uint64_t mDebuggerCount;
205
211
206
  uint64_t mTokenCount;
212
  uint64_t mTokenCount;
(-)a/dom/workers/ServiceWorkerRegistration.cpp (-1 / +51 lines)
Line     Link Here 
 Lines 28-43    Link Here 
28
#include "Workers.h"
28
#include "Workers.h"
29
#include "WorkerScope.h"
29
#include "WorkerScope.h"
30
30
31
#ifndef MOZ_SIMPLEPUSH
31
#ifndef MOZ_SIMPLEPUSH
32
#include "mozilla/dom/PushManagerBinding.h"
32
#include "mozilla/dom/PushManagerBinding.h"
33
#include "mozilla/dom/PushManager.h"
33
#include "mozilla/dom/PushManager.h"
34
#endif
34
#endif
35
35
36
#include "mozilla/dom/SyncManagerBinding.h"
37
#include "mozilla/dom/SyncManager.h"
38
36
using namespace mozilla::dom::workers;
39
using namespace mozilla::dom::workers;
37
40
38
namespace mozilla {
41
namespace mozilla {
39
namespace dom {
42
namespace dom {
40
43
41
bool
44
bool
42
ServiceWorkerRegistrationVisible(JSContext* aCx, JSObject* aObj)
45
ServiceWorkerRegistrationVisible(JSContext* aCx, JSObject* aObj)
43
{
46
{
 Lines 87-106   ServiceWorkerRegistrationBase::ServiceWo Link Here 
87
NS_IMPL_ADDREF_INHERITED(ServiceWorkerRegistrationMainThread, ServiceWorkerRegistrationBase)
90
NS_IMPL_ADDREF_INHERITED(ServiceWorkerRegistrationMainThread, ServiceWorkerRegistrationBase)
88
NS_IMPL_RELEASE_INHERITED(ServiceWorkerRegistrationMainThread, ServiceWorkerRegistrationBase)
91
NS_IMPL_RELEASE_INHERITED(ServiceWorkerRegistrationMainThread, ServiceWorkerRegistrationBase)
89
92
90
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(ServiceWorkerRegistrationMainThread)
93
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(ServiceWorkerRegistrationMainThread)
91
NS_INTERFACE_MAP_END_INHERITING(ServiceWorkerRegistrationBase)
94
NS_INTERFACE_MAP_END_INHERITING(ServiceWorkerRegistrationBase)
92
95
93
#ifndef MOZ_SIMPLEPUSH
96
#ifndef MOZ_SIMPLEPUSH
94
NS_IMPL_CYCLE_COLLECTION_INHERITED(ServiceWorkerRegistrationMainThread, ServiceWorkerRegistrationBase,
97
NS_IMPL_CYCLE_COLLECTION_INHERITED(ServiceWorkerRegistrationMainThread, ServiceWorkerRegistrationBase,
95
                                   mPushManager,
98
                                   mPushManager, mSyncManager,
96
                                   mInstallingWorker, mWaitingWorker, mActiveWorker);
99
                                   mInstallingWorker, mWaitingWorker, mActiveWorker);
97
#else
100
#else
98
NS_IMPL_CYCLE_COLLECTION_INHERITED(ServiceWorkerRegistrationMainThread, ServiceWorkerRegistrationBase,
101
NS_IMPL_CYCLE_COLLECTION_INHERITED(ServiceWorkerRegistrationMainThread, ServiceWorkerRegistrationBase,
102
                                   mSyncManager,
99
                                   mInstallingWorker, mWaitingWorker, mActiveWorker);
103
                                   mInstallingWorker, mWaitingWorker, mActiveWorker);
100
#endif
104
#endif
101
105
102
ServiceWorkerRegistrationMainThread::ServiceWorkerRegistrationMainThread(nsPIDOMWindowInner* aWindow,
106
ServiceWorkerRegistrationMainThread::ServiceWorkerRegistrationMainThread(nsPIDOMWindowInner* aWindow,
103
                                                                         const nsAString& aScope)
107
                                                                         const nsAString& aScope)
104
  : ServiceWorkerRegistrationBase(aWindow, aScope)
108
  : ServiceWorkerRegistrationBase(aWindow, aScope)
105
  , mListeningForEvents(false)
109
  , mListeningForEvents(false)
106
{
110
{
 Lines 791-806   ServiceWorkerRegistrationMainThread::Get Link Here 
791
  }
795
  }
792
796
793
  RefPtr<PushManager> ret = mPushManager;
797
  RefPtr<PushManager> ret = mPushManager;
794
  return ret.forget();
798
  return ret.forget();
795
799
796
  #endif /* ! MOZ_SIMPLEPUSH */
800
  #endif /* ! MOZ_SIMPLEPUSH */
797
}
801
}
798
802
803
SyncManager*
804
ServiceWorkerRegistrationMainThread::GetSync(ErrorResult& aRv)
805
{
806
  AssertIsOnMainThread();
807
808
  if (!mSyncManager) {
809
    nsCOMPtr<nsIGlobalObject> globalObject = do_QueryInterface(GetOwner());
810
811
    if (!globalObject) {
812
      aRv.Throw(NS_ERROR_FAILURE);
813
      return nullptr;
814
    }
815
816
    nsCOMPtr<nsIDocument> document = GetOwner()->GetExtantDoc();
817
    if (!document) {
818
      aRv.Throw(NS_ERROR_FAILURE);
819
      return nullptr;
820
    }
821
822
    nsCOMPtr<nsIPrincipal> principal = document->NodePrincipal();
823
    if (!principal) {
824
      aRv.Throw(NS_ERROR_FAILURE);
825
      return nullptr;
826
    }
827
828
    mSyncManager = SyncManager::CreateOnMainThread(globalObject, principal,
829
                                                   mScope, aRv);
830
  }
831
832
  return mSyncManager;
833
}
834
799
////////////////////////////////////////////////////
835
////////////////////////////////////////////////////
800
// Worker Thread implementation
836
// Worker Thread implementation
801
class WorkerListener final : public ServiceWorkerRegistrationListener
837
class WorkerListener final : public ServiceWorkerRegistrationListener
802
{
838
{
803
  // Accessed on the main thread.
839
  // Accessed on the main thread.
804
  WorkerPrivate* mWorkerPrivate;
840
  WorkerPrivate* mWorkerPrivate;
805
  nsString mScope;
841
  nsString mScope;
806
  bool mListeningForEvents;
842
  bool mListeningForEvents;
 Lines 915-937   NS_INTERFACE_MAP_END_INHERITING(ServiceW Link Here 
915
// Expanded macros since we need special behaviour to release the proxy.
951
// Expanded macros since we need special behaviour to release the proxy.
916
NS_IMPL_CYCLE_COLLECTION_CLASS(ServiceWorkerRegistrationWorkerThread)
952
NS_IMPL_CYCLE_COLLECTION_CLASS(ServiceWorkerRegistrationWorkerThread)
917
953
918
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(ServiceWorkerRegistrationWorkerThread,
954
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(ServiceWorkerRegistrationWorkerThread,
919
                                                  ServiceWorkerRegistrationBase)
955
                                                  ServiceWorkerRegistrationBase)
920
#ifndef MOZ_SIMPLEPUSH
956
#ifndef MOZ_SIMPLEPUSH
921
  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPushManager)
957
  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPushManager)
922
#endif
958
#endif
959
  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSyncManager)
923
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
960
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
924
961
925
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(ServiceWorkerRegistrationWorkerThread,
962
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(ServiceWorkerRegistrationWorkerThread,
926
                                                ServiceWorkerRegistrationBase)
963
                                                ServiceWorkerRegistrationBase)
927
#ifndef MOZ_SIMPLEPUSH
964
#ifndef MOZ_SIMPLEPUSH
928
  NS_IMPL_CYCLE_COLLECTION_UNLINK(mPushManager)
965
  NS_IMPL_CYCLE_COLLECTION_UNLINK(mPushManager)
929
#endif
966
#endif
967
  NS_IMPL_CYCLE_COLLECTION_UNLINK(mSyncManager)
930
  tmp->ReleaseListener(RegistrationIsGoingAway);
968
  tmp->ReleaseListener(RegistrationIsGoingAway);
931
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
969
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
932
970
933
ServiceWorkerRegistrationWorkerThread::ServiceWorkerRegistrationWorkerThread(WorkerPrivate* aWorkerPrivate,
971
ServiceWorkerRegistrationWorkerThread::ServiceWorkerRegistrationWorkerThread(WorkerPrivate* aWorkerPrivate,
934
                                                                             const nsAString& aScope)
972
                                                                             const nsAString& aScope)
935
  : ServiceWorkerRegistrationBase(nullptr, aScope)
973
  : ServiceWorkerRegistrationBase(nullptr, aScope)
936
  , mWorkerPrivate(aWorkerPrivate)
974
  , mWorkerPrivate(aWorkerPrivate)
937
{
975
{
 Lines 1229-1238   ServiceWorkerRegistrationWorkerThread::G Link Here 
1229
  }
1267
  }
1230
1268
1231
  RefPtr<WorkerPushManager> ret = mPushManager;
1269
  RefPtr<WorkerPushManager> ret = mPushManager;
1232
  return ret.forget();
1270
  return ret.forget();
1233
1271
1234
  #endif /* ! MOZ_SIMPLEPUSH */
1272
  #endif /* ! MOZ_SIMPLEPUSH */
1235
}
1273
}
1236
1274
1275
SyncManager*
1276
ServiceWorkerRegistrationWorkerThread::GetSync(ErrorResult& aRv)
1277
{
1278
  if (!mSyncManager) {
1279
    mSyncManager = SyncManager::CreateOnWorker(mWorkerPrivate->GlobalScope(),
1280
                                               mWorkerPrivate,
1281
                                               mScope);
1282
  }
1283
1284
  return mSyncManager;
1285
}
1286
1237
} // dom namespace
1287
} // dom namespace
1238
} // mozilla namespace
1288
} // mozilla namespace
(-)a/dom/workers/ServiceWorkerRegistration.h (-1 / +12 lines)
Line     Link Here 
 Lines 17-34    Link Here 
17
17
18
class nsPIDOMWindowInner;
18
class nsPIDOMWindowInner;
19
19
20
namespace mozilla {
20
namespace mozilla {
21
namespace dom {
21
namespace dom {
22
22
23
class Promise;
23
class Promise;
24
class PushManager;
24
class PushManager;
25
class SyncManager;
26
class WorkerListener;
25
class WorkerPushManager;
27
class WorkerPushManager;
26
class WorkerListener;
27
28
28
namespace workers {
29
namespace workers {
29
class ServiceWorker;
30
class ServiceWorker;
30
class WorkerPrivate;
31
class WorkerPrivate;
31
} // namespace workers
32
} // namespace workers
32
33
33
bool
34
bool
34
ServiceWorkerRegistrationVisible(JSContext* aCx, JSObject* aObj);
35
ServiceWorkerRegistrationVisible(JSContext* aCx, JSObject* aObj);
 Lines 136-151   public: Link Here 
136
  GetWaiting() override;
137
  GetWaiting() override;
137
138
138
  already_AddRefed<workers::ServiceWorker>
139
  already_AddRefed<workers::ServiceWorker>
139
  GetActive() override;
140
  GetActive() override;
140
141
141
  already_AddRefed<PushManager>
142
  already_AddRefed<PushManager>
142
  GetPushManager(ErrorResult& aRv);
143
  GetPushManager(ErrorResult& aRv);
143
144
145
  SyncManager*
146
  GetSync(ErrorResult& aRv);
147
144
  // DOMEventTargethelper
148
  // DOMEventTargethelper
145
  void DisconnectFromOwner() override
149
  void DisconnectFromOwner() override
146
  {
150
  {
147
    StopListeningForEvents();
151
    StopListeningForEvents();
148
    ServiceWorkerRegistrationBase::DisconnectFromOwner();
152
    ServiceWorkerRegistrationBase::DisconnectFromOwner();
149
  }
153
  }
150
154
151
  // ServiceWorkerRegistrationListener
155
  // ServiceWorkerRegistrationListener
 Lines 186-201   private: Link Here 
186
  // These three may change to a new worker at any time.
190
  // These three may change to a new worker at any time.
187
  RefPtr<workers::ServiceWorker> mInstallingWorker;
191
  RefPtr<workers::ServiceWorker> mInstallingWorker;
188
  RefPtr<workers::ServiceWorker> mWaitingWorker;
192
  RefPtr<workers::ServiceWorker> mWaitingWorker;
189
  RefPtr<workers::ServiceWorker> mActiveWorker;
193
  RefPtr<workers::ServiceWorker> mActiveWorker;
190
194
191
#ifndef MOZ_SIMPLEPUSH
195
#ifndef MOZ_SIMPLEPUSH
192
  RefPtr<PushManager> mPushManager;
196
  RefPtr<PushManager> mPushManager;
193
#endif
197
#endif
198
199
  RefPtr<SyncManager> mSyncManager;
194
};
200
};
195
201
196
class ServiceWorkerRegistrationWorkerThread final : public ServiceWorkerRegistrationBase
202
class ServiceWorkerRegistrationWorkerThread final : public ServiceWorkerRegistrationBase
197
                                                  , public workers::WorkerFeature
203
                                                  , public workers::WorkerFeature
198
{
204
{
199
public:
205
public:
200
  NS_DECL_ISUPPORTS_INHERITED
206
  NS_DECL_ISUPPORTS_INHERITED
201
  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ServiceWorkerRegistrationWorkerThread,
207
  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(ServiceWorkerRegistrationWorkerThread,
 Lines 239-254   public: Link Here 
239
  }
245
  }
240
246
241
  bool
247
  bool
242
  Notify(JSContext* aCx, workers::Status aStatus) override;
248
  Notify(JSContext* aCx, workers::Status aStatus) override;
243
249
244
  already_AddRefed<WorkerPushManager>
250
  already_AddRefed<WorkerPushManager>
245
  GetPushManager(ErrorResult& aRv);
251
  GetPushManager(ErrorResult& aRv);
246
252
253
  SyncManager*
254
  GetSync(ErrorResult& aRv);
255
247
private:
256
private:
248
  enum Reason
257
  enum Reason
249
  {
258
  {
250
    RegistrationIsGoingAway = 0,
259
    RegistrationIsGoingAway = 0,
251
    WorkerIsGoingAway,
260
    WorkerIsGoingAway,
252
  };
261
  };
253
262
254
  ~ServiceWorkerRegistrationWorkerThread();
263
  ~ServiceWorkerRegistrationWorkerThread();
 Lines 260-273   private: Link Here 
260
  ReleaseListener(Reason aReason);
269
  ReleaseListener(Reason aReason);
261
270
262
  workers::WorkerPrivate* mWorkerPrivate;
271
  workers::WorkerPrivate* mWorkerPrivate;
263
  RefPtr<WorkerListener> mListener;
272
  RefPtr<WorkerListener> mListener;
264
273
265
#ifndef MOZ_SIMPLEPUSH
274
#ifndef MOZ_SIMPLEPUSH
266
  RefPtr<WorkerPushManager> mPushManager;
275
  RefPtr<WorkerPushManager> mPushManager;
267
#endif
276
#endif
277
278
  RefPtr<SyncManager> mSyncManager;
268
};
279
};
269
280
270
} // namespace dom
281
} // namespace dom
271
} // namespace mozilla
282
} // namespace mozilla
272
283
273
#endif /* mozilla_dom_ServiceWorkerRegistration_h */
284
#endif /* mozilla_dom_ServiceWorkerRegistration_h */
(-)a/dom/workers/WorkerPrefs.h (+1 lines)
Line     Link Here 
 Lines 28-43   WORKER_SIMPLE_PREF("dom.caches.enabled", Link Here 
28
WORKER_SIMPLE_PREF("dom.caches.testing.enabled", DOMCachesTestingEnabled, DOM_CACHES_TESTING)
28
WORKER_SIMPLE_PREF("dom.caches.testing.enabled", DOMCachesTestingEnabled, DOM_CACHES_TESTING)
29
WORKER_SIMPLE_PREF("dom.performance.enable_user_timing_logging", PerformanceLoggingEnabled, PERFORMANCE_LOGGING_ENABLED)
29
WORKER_SIMPLE_PREF("dom.performance.enable_user_timing_logging", PerformanceLoggingEnabled, PERFORMANCE_LOGGING_ENABLED)
30
WORKER_SIMPLE_PREF("dom.webnotifications.enabled", DOMWorkerNotificationEnabled, DOM_WORKERNOTIFICATION)
30
WORKER_SIMPLE_PREF("dom.webnotifications.enabled", DOMWorkerNotificationEnabled, DOM_WORKERNOTIFICATION)
31
WORKER_SIMPLE_PREF("dom.webnotifications.serviceworker.enabled", DOMServiceWorkerNotificationEnabled, DOM_SERVICEWORKERNOTIFICATION)
31
WORKER_SIMPLE_PREF("dom.webnotifications.serviceworker.enabled", DOMServiceWorkerNotificationEnabled, DOM_SERVICEWORKERNOTIFICATION)
32
WORKER_SIMPLE_PREF("dom.serviceWorkers.enabled", ServiceWorkersEnabled, SERVICEWORKERS_ENABLED)
32
WORKER_SIMPLE_PREF("dom.serviceWorkers.enabled", ServiceWorkersEnabled, SERVICEWORKERS_ENABLED)
33
WORKER_SIMPLE_PREF("dom.serviceWorkers.testing.enabled", ServiceWorkersTestingEnabled, SERVICEWORKERS_TESTING_ENABLED)
33
WORKER_SIMPLE_PREF("dom.serviceWorkers.testing.enabled", ServiceWorkersTestingEnabled, SERVICEWORKERS_TESTING_ENABLED)
34
WORKER_SIMPLE_PREF("dom.serviceWorkers.openWindow.enabled", OpenWindowEnabled, OPEN_WINDOW_ENABLED)
34
WORKER_SIMPLE_PREF("dom.serviceWorkers.openWindow.enabled", OpenWindowEnabled, OPEN_WINDOW_ENABLED)
35
WORKER_SIMPLE_PREF("dom.push.enabled", PushEnabled, PUSH_ENABLED)
35
WORKER_SIMPLE_PREF("dom.push.enabled", PushEnabled, PUSH_ENABLED)
36
WORKER_SIMPLE_PREF("dom.background.sync.enabled", BackgroundSyncEnabled, BACKGROUND_SYNC_ENABLED)
36
WORKER_SIMPLE_PREF("dom.requestcontext.enabled", RequestContextEnabled, REQUESTCONTEXT_ENABLED)
37
WORKER_SIMPLE_PREF("dom.requestcontext.enabled", RequestContextEnabled, REQUESTCONTEXT_ENABLED)
37
WORKER_SIMPLE_PREF("gfx.offscreencanvas.enabled", OffscreenCanvasEnabled, OFFSCREENCANVAS_ENABLED)
38
WORKER_SIMPLE_PREF("gfx.offscreencanvas.enabled", OffscreenCanvasEnabled, OFFSCREENCANVAS_ENABLED)
38
WORKER_PREF("dom.workers.latestJSVersion", JSVersionChanged)
39
WORKER_PREF("dom.workers.latestJSVersion", JSVersionChanged)
39
WORKER_PREF("intl.accept_languages", PrefLanguagesChanged)
40
WORKER_PREF("intl.accept_languages", PrefLanguagesChanged)
40
WORKER_PREF("general.appname.override", AppNameOverrideChanged)
41
WORKER_PREF("general.appname.override", AppNameOverrideChanged)
41
WORKER_PREF("general.appversion.override", AppVersionOverrideChanged)
42
WORKER_PREF("general.appversion.override", AppVersionOverrideChanged)
42
WORKER_PREF("general.platform.override", PlatformOverrideChanged)
43
WORKER_PREF("general.platform.override", PlatformOverrideChanged)
43
#ifdef JS_GC_ZEAL
44
#ifdef JS_GC_ZEAL
(-)a/dom/workers/moz.build (+1 lines)
Line     Link Here 
 Lines 93-108   IPDL_SOURCES += [ Link Here 
93
    'PServiceWorkerManager.ipdl',
93
    'PServiceWorkerManager.ipdl',
94
    'ServiceWorkerRegistrarTypes.ipdlh',
94
    'ServiceWorkerRegistrarTypes.ipdlh',
95
]
95
]
96
96
97
LOCAL_INCLUDES += [
97
LOCAL_INCLUDES += [
98
    '../base',
98
    '../base',
99
    '../system',
99
    '../system',
100
    '/dom/base',
100
    '/dom/base',
101
    '/dom/sync',
101
    '/xpcom/build',
102
    '/xpcom/build',
102
    '/xpcom/threads',
103
    '/xpcom/threads',
103
]
104
]
104
105
105
include('/ipc/chromium/chromium-config.mozbuild')
106
include('/ipc/chromium/chromium-config.mozbuild')
106
107
107
FINAL_LIBRARY = 'xul'
108
FINAL_LIBRARY = 'xul'
108
109
(-)a/ipc/glue/BackgroundChildImpl.cpp (+22 lines)
Line     Link Here 
 Lines 2-17    Link Here 
2
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
2
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
3
 * You can obtain one at http://mozilla.org/MPL/2.0/. */
3
 * You can obtain one at http://mozilla.org/MPL/2.0/. */
4
4
5
#include "BackgroundChildImpl.h"
5
#include "BackgroundChildImpl.h"
6
6
7
#include "ActorsChild.h" // IndexedDB
7
#include "ActorsChild.h" // IndexedDB
8
#include "BroadcastChannelChild.h"
8
#include "BroadcastChannelChild.h"
9
#include "ServiceWorkerManagerChild.h"
9
#include "ServiceWorkerManagerChild.h"
10
#include "SyncManagerChild.h"
10
#include "FileDescriptorSetChild.h"
11
#include "FileDescriptorSetChild.h"
11
#ifdef MOZ_WEBRTC
12
#ifdef MOZ_WEBRTC
12
#include "CamerasChild.h"
13
#include "CamerasChild.h"
13
#endif
14
#endif
14
#include "mozilla/media/MediaChild.h"
15
#include "mozilla/media/MediaChild.h"
15
#include "mozilla/Assertions.h"
16
#include "mozilla/Assertions.h"
16
#include "mozilla/dom/PBlobChild.h"
17
#include "mozilla/dom/PBlobChild.h"
17
#include "mozilla/dom/asmjscache/AsmJSCache.h"
18
#include "mozilla/dom/asmjscache/AsmJSCache.h"
 Lines 62-77   namespace ipc { Link Here 
62
using mozilla::dom::UDPSocketChild;
63
using mozilla::dom::UDPSocketChild;
63
using mozilla::net::PUDPSocketChild;
64
using mozilla::net::PUDPSocketChild;
64
65
65
using mozilla::dom::asmjscache::PAsmJSCacheEntryChild;
66
using mozilla::dom::asmjscache::PAsmJSCacheEntryChild;
66
using mozilla::dom::cache::PCacheChild;
67
using mozilla::dom::cache::PCacheChild;
67
using mozilla::dom::cache::PCacheStorageChild;
68
using mozilla::dom::cache::PCacheStorageChild;
68
using mozilla::dom::cache::PCacheStreamControlChild;
69
using mozilla::dom::cache::PCacheStreamControlChild;
69
using mozilla::dom::PNuwaChild;
70
using mozilla::dom::PNuwaChild;
71
using mozilla::dom::SyncManagerChild;
70
72
71
// -----------------------------------------------------------------------------
73
// -----------------------------------------------------------------------------
72
// BackgroundChildImpl::ThreadLocal
74
// BackgroundChildImpl::ThreadLocal
73
// -----------------------------------------------------------------------------
75
// -----------------------------------------------------------------------------
74
76
75
BackgroundChildImpl::
77
BackgroundChildImpl::
76
ThreadLocal::ThreadLocal()
78
ThreadLocal::ThreadLocal()
77
  : mCurrentFileHandle(nullptr)
79
  : mCurrentFileHandle(nullptr)
 Lines 444-459   bool Link Here 
444
BackgroundChildImpl::DeallocPQuotaChild(PQuotaChild* aActor)
446
BackgroundChildImpl::DeallocPQuotaChild(PQuotaChild* aActor)
445
{
447
{
446
  MOZ_ASSERT(aActor);
448
  MOZ_ASSERT(aActor);
447
449
448
  delete aActor;
450
  delete aActor;
449
  return true;
451
  return true;
450
}
452
}
451
453
454
// -----------------------------------------------------------------------------
455
// Background Sync API
456
// -----------------------------------------------------------------------------
457
458
dom::PSyncManagerChild*
459
BackgroundChildImpl::AllocPSyncManagerChild()
460
{
461
  RefPtr<SyncManagerChild> agent = new SyncManagerChild();
462
  return agent.forget().take();
463
}
464
465
bool
466
BackgroundChildImpl::DeallocPSyncManagerChild(PSyncManagerChild* aActor)
467
{
468
  RefPtr<SyncManagerChild> child =
469
    dont_AddRef(static_cast<SyncManagerChild*>(aActor));
470
  MOZ_ASSERT(child);
471
  return true;
472
}
473
452
} // namespace ipc
474
} // namespace ipc
453
} // namespace mozilla
475
} // namespace mozilla
454
476
455
bool
477
bool
456
TestChild::Recv__delete__(const nsCString& aTestArg)
478
TestChild::Recv__delete__(const nsCString& aTestArg)
457
{
479
{
458
  MOZ_RELEASE_ASSERT(aTestArg == mTestArg,
480
  MOZ_RELEASE_ASSERT(aTestArg == mTestArg,
459
                     "BackgroundTest message was corrupted!");
481
                     "BackgroundTest message was corrupted!");
(-)a/ipc/glue/BackgroundChildImpl.h (+6 lines)
Line     Link Here 
 Lines 153-168   protected: Link Here 
153
  virtual bool
153
  virtual bool
154
  DeallocPAsmJSCacheEntryChild(PAsmJSCacheEntryChild* aActor) override;
154
  DeallocPAsmJSCacheEntryChild(PAsmJSCacheEntryChild* aActor) override;
155
155
156
  virtual PQuotaChild*
156
  virtual PQuotaChild*
157
  AllocPQuotaChild() override;
157
  AllocPQuotaChild() override;
158
158
159
  virtual bool
159
  virtual bool
160
  DeallocPQuotaChild(PQuotaChild* aActor) override;
160
  DeallocPQuotaChild(PQuotaChild* aActor) override;
161
162
  virtual PSyncManagerChild*
163
  AllocPSyncManagerChild() override;
164
165
  virtual bool
166
  DeallocPSyncManagerChild(PSyncManagerChild* aActor) override;
161
};
167
};
162
168
163
class BackgroundChildImpl::ThreadLocal final
169
class BackgroundChildImpl::ThreadLocal final
164
{
170
{
165
  friend class nsAutoPtr<ThreadLocal>;
171
  friend class nsAutoPtr<ThreadLocal>;
166
172
167
public:
173
public:
168
  nsAutoPtr<mozilla::dom::indexedDB::ThreadLocal> mIndexedDBThreadLocal;
174
  nsAutoPtr<mozilla::dom::indexedDB::ThreadLocal> mIndexedDBThreadLocal;
(-)a/ipc/glue/BackgroundParentImpl.cpp (+27 lines)
Line     Link Here 
 Lines 32-63    Link Here 
32
#include "nsIAppsService.h"
32
#include "nsIAppsService.h"
33
#include "nsNetUtil.h"
33
#include "nsNetUtil.h"
34
#include "nsIScriptSecurityManager.h"
34
#include "nsIScriptSecurityManager.h"
35
#include "mozilla/RefPtr.h"
35
#include "mozilla/RefPtr.h"
36
#include "nsThreadUtils.h"
36
#include "nsThreadUtils.h"
37
#include "nsTraceRefcnt.h"
37
#include "nsTraceRefcnt.h"
38
#include "nsXULAppAPI.h"
38
#include "nsXULAppAPI.h"
39
#include "ServiceWorkerManagerParent.h"
39
#include "ServiceWorkerManagerParent.h"
40
#include "SyncManagerParent.h"
40
41
41
#ifdef DISABLE_ASSERTS_FOR_FUZZING
42
#ifdef DISABLE_ASSERTS_FOR_FUZZING
42
#define ASSERT_UNLESS_FUZZING(...) do { } while (0)
43
#define ASSERT_UNLESS_FUZZING(...) do { } while (0)
43
#else
44
#else
44
#define ASSERT_UNLESS_FUZZING(...) MOZ_ASSERT(false)
45
#define ASSERT_UNLESS_FUZZING(...) MOZ_ASSERT(false)
45
#endif
46
#endif
46
47
47
using mozilla::ipc::AssertIsOnBackgroundThread;
48
using mozilla::ipc::AssertIsOnBackgroundThread;
48
using mozilla::dom::asmjscache::PAsmJSCacheEntryParent;
49
using mozilla::dom::asmjscache::PAsmJSCacheEntryParent;
49
using mozilla::dom::cache::PCacheParent;
50
using mozilla::dom::cache::PCacheParent;
50
using mozilla::dom::cache::PCacheStorageParent;
51
using mozilla::dom::cache::PCacheStorageParent;
51
using mozilla::dom::cache::PCacheStreamControlParent;
52
using mozilla::dom::cache::PCacheStreamControlParent;
52
using mozilla::dom::MessagePortParent;
53
using mozilla::dom::MessagePortParent;
53
using mozilla::dom::PMessagePortParent;
54
using mozilla::dom::PMessagePortParent;
54
using mozilla::dom::PNuwaParent;
55
using mozilla::dom::PNuwaParent;
55
using mozilla::dom::NuwaParent;
56
using mozilla::dom::NuwaParent;
57
using mozilla::dom::SyncManagerParent;
56
using mozilla::dom::UDPSocketParent;
58
using mozilla::dom::UDPSocketParent;
57
59
58
namespace {
60
namespace {
59
61
60
void
62
void
61
AssertIsOnMainThread()
63
AssertIsOnMainThread()
62
{
64
{
63
  MOZ_ASSERT(NS_IsMainThread());
65
  MOZ_ASSERT(NS_IsMainThread());
 Lines 86-101   public: Link Here 
86
} // namespace
88
} // namespace
87
89
88
namespace mozilla {
90
namespace mozilla {
89
namespace ipc {
91
namespace ipc {
90
92
91
using mozilla::dom::ContentParent;
93
using mozilla::dom::ContentParent;
92
using mozilla::dom::BroadcastChannelParent;
94
using mozilla::dom::BroadcastChannelParent;
93
using mozilla::dom::ServiceWorkerRegistrationData;
95
using mozilla::dom::ServiceWorkerRegistrationData;
96
using mozilla::dom::SyncManagerParent;
94
using mozilla::dom::workers::ServiceWorkerManagerParent;
97
using mozilla::dom::workers::ServiceWorkerManagerParent;
95
98
96
BackgroundParentImpl::BackgroundParentImpl()
99
BackgroundParentImpl::BackgroundParentImpl()
97
{
100
{
98
  AssertIsInMainProcess();
101
  AssertIsInMainProcess();
99
  AssertIsOnMainThread();
102
  AssertIsOnMainThread();
100
103
101
  MOZ_COUNT_CTOR(mozilla::ipc::BackgroundParentImpl);
104
  MOZ_COUNT_CTOR(mozilla::ipc::BackgroundParentImpl);
 Lines 735-750   BackgroundParentImpl::DeallocPQuotaParen Link Here 
735
{
738
{
736
  AssertIsInMainProcess();
739
  AssertIsInMainProcess();
737
  AssertIsOnBackgroundThread();
740
  AssertIsOnBackgroundThread();
738
  MOZ_ASSERT(aActor);
741
  MOZ_ASSERT(aActor);
739
742
740
  return mozilla::dom::quota::DeallocPQuotaParent(aActor);
743
  return mozilla::dom::quota::DeallocPQuotaParent(aActor);
741
}
744
}
742
745
746
mozilla::dom::PSyncManagerParent*
747
BackgroundParentImpl::AllocPSyncManagerParent()
748
{
749
  AssertIsInMainProcess();
750
  AssertIsOnBackgroundThread();
751
752
  RefPtr<SyncManagerParent> agent = new SyncManagerParent();
753
  return agent.forget().take();
754
}
755
756
bool
757
BackgroundParentImpl::DeallocPSyncManagerParent(PSyncManagerParent* aActor)
758
{
759
  AssertIsInMainProcess();
760
  AssertIsOnBackgroundThread();
761
  MOZ_ASSERT(aActor);
762
763
  RefPtr<SyncManagerParent> parent =
764
    dont_AddRef(static_cast<SyncManagerParent*>(aActor));
765
  MOZ_ASSERT(parent);
766
767
  return true;
768
}
769
743
} // namespace ipc
770
} // namespace ipc
744
} // namespace mozilla
771
} // namespace mozilla
745
772
746
void
773
void
747
TestParent::ActorDestroy(ActorDestroyReason aWhy)
774
TestParent::ActorDestroy(ActorDestroyReason aWhy)
748
{
775
{
749
  mozilla::ipc::AssertIsInMainProcess();
776
  mozilla::ipc::AssertIsInMainProcess();
750
  AssertIsOnBackgroundThread();
777
  AssertIsOnBackgroundThread();
(-)a/ipc/glue/BackgroundParentImpl.h (+6 lines)
Line     Link Here 
 Lines 181-194   protected: Link Here 
181
  virtual bool
181
  virtual bool
182
  DeallocPAsmJSCacheEntryParent(PAsmJSCacheEntryParent* aActor) override;
182
  DeallocPAsmJSCacheEntryParent(PAsmJSCacheEntryParent* aActor) override;
183
183
184
  virtual PQuotaParent*
184
  virtual PQuotaParent*
185
  AllocPQuotaParent() override;
185
  AllocPQuotaParent() override;
186
186
187
  virtual bool
187
  virtual bool
188
  DeallocPQuotaParent(PQuotaParent* aActor) override;
188
  DeallocPQuotaParent(PQuotaParent* aActor) override;
189
190
  virtual PSyncManagerParent*
191
  AllocPSyncManagerParent() override;
192
193
  virtual bool
194
  DeallocPSyncManagerParent(PSyncManagerParent* aActor) override;
189
};
195
};
190
196
191
} // namespace ipc
197
} // namespace ipc
192
} // namespace mozilla
198
} // namespace mozilla
193
199
194
#endif // mozilla_ipc_backgroundparentimpl_h__
200
#endif // mozilla_ipc_backgroundparentimpl_h__
(-)a/ipc/glue/PBackground.ipdl (+4 lines)
Line     Link Here 
 Lines 12-27   include protocol PCache; Link Here 
12
include protocol PCacheStorage;
12
include protocol PCacheStorage;
13
include protocol PCacheStreamControl;
13
include protocol PCacheStreamControl;
14
include protocol PFileDescriptorSet;
14
include protocol PFileDescriptorSet;
15
include protocol PMessagePort;
15
include protocol PMessagePort;
16
include protocol PCameras;
16
include protocol PCameras;
17
include protocol PNuwa;
17
include protocol PNuwa;
18
include protocol PQuota;
18
include protocol PQuota;
19
include protocol PServiceWorkerManager;
19
include protocol PServiceWorkerManager;
20
include protocol PSyncManager;
20
include protocol PUDPSocket;
21
include protocol PUDPSocket;
21
include protocol PVsync;
22
include protocol PVsync;
22
23
23
include DOMTypes;
24
include DOMTypes;
24
include PBackgroundSharedTypes;
25
include PBackgroundSharedTypes;
25
include PBackgroundIDBSharedTypes;
26
include PBackgroundIDBSharedTypes;
26
27
27
include "mozilla/dom/cache/IPCUtils.h";
28
include "mozilla/dom/cache/IPCUtils.h";
 Lines 50-65   sync protocol PBackground Link Here 
50
  manages PCacheStorage;
51
  manages PCacheStorage;
51
  manages PCacheStreamControl;
52
  manages PCacheStreamControl;
52
  manages PFileDescriptorSet;
53
  manages PFileDescriptorSet;
53
  manages PMessagePort;
54
  manages PMessagePort;
54
  manages PCameras;
55
  manages PCameras;
55
  manages PNuwa;
56
  manages PNuwa;
56
  manages PQuota;
57
  manages PQuota;
57
  manages PServiceWorkerManager;
58
  manages PServiceWorkerManager;
59
  manages PSyncManager;
58
  manages PUDPSocket;
60
  manages PUDPSocket;
59
  manages PVsync;
61
  manages PVsync;
60
62
61
parent:
63
parent:
62
  // Only called at startup during mochitests to check the basic infrastructure.
64
  // Only called at startup during mochitests to check the basic infrastructure.
63
  async PBackgroundTest(nsCString testArg);
65
  async PBackgroundTest(nsCString testArg);
64
66
65
  async PBackgroundIDBFactory(LoggingInfo loggingInfo);
67
  async PBackgroundIDBFactory(LoggingInfo loggingInfo);
 Lines 90-105   parent: Link Here 
90
  async MessagePortForceClose(nsID uuid, nsID destinationUuid, uint32_t sequenceId);
92
  async MessagePortForceClose(nsID uuid, nsID destinationUuid, uint32_t sequenceId);
91
93
92
  async PAsmJSCacheEntry(OpenMode openMode,
94
  async PAsmJSCacheEntry(OpenMode openMode,
93
                         WriteParams write,
95
                         WriteParams write,
94
                         PrincipalInfo principalInfo);
96
                         PrincipalInfo principalInfo);
95
97
96
  async PQuota();
98
  async PQuota();
97
99
100
  async PSyncManager();
101
98
child:
102
child:
99
  async PCache();
103
  async PCache();
100
  async PCacheStreamControl();
104
  async PCacheStreamControl();
101
105
102
both:
106
both:
103
  async PBlob(BlobConstructorParams params);
107
  async PBlob(BlobConstructorParams params);
104
108
105
  async PFileDescriptorSet(FileDescriptor fd);
109
  async PFileDescriptorSet(FileDescriptor fd);
(-)a/ipc/glue/moz.build (+1 lines)
Line     Link Here 
 Lines 141-156   if CONFIG['_MSC_VER']: Link Here 
141
    # 'reinterpret_cast': conversion from 'DWORD' to 'HANDLE' of greater size
141
    # 'reinterpret_cast': conversion from 'DWORD' to 'HANDLE' of greater size
142
    SOURCES['BackgroundChildImpl.cpp'].flags += ['-wd4312']
142
    SOURCES['BackgroundChildImpl.cpp'].flags += ['-wd4312']
143
    SOURCES['BackgroundParentImpl.cpp'].flags += ['-wd4312']
143
    SOURCES['BackgroundParentImpl.cpp'].flags += ['-wd4312']
144
144
145
LOCAL_INCLUDES += [
145
LOCAL_INCLUDES += [
146
    '/caps',
146
    '/caps',
147
    '/dom/broadcastchannel',
147
    '/dom/broadcastchannel',
148
    '/dom/indexedDB',
148
    '/dom/indexedDB',
149
    '/dom/sync',
149
    '/dom/workers',
150
    '/dom/workers',
150
    '/media/webrtc/trunk',
151
    '/media/webrtc/trunk',
151
    '/xpcom/build',
152
    '/xpcom/build',
152
]
153
]
153
154
154
IPDL_SOURCES = [
155
IPDL_SOURCES = [
155
    'InputStreamParams.ipdlh',
156
    'InputStreamParams.ipdlh',
156
    'PBackground.ipdl',
157
    'PBackground.ipdl',

Return to bug 1217544