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 "ServiceWorkerContainerProxy.h"
8
9 #include "mozilla/dom/ServiceWorkerContainerParent.h"
10 #include "mozilla/dom/ServiceWorkerManager.h"
11 #include "mozilla/ipc/BackgroundParent.h"
12 #include "mozilla/SchedulerGroup.h"
13 #include "mozilla/ScopeExit.h"
14
15 namespace mozilla {
16 namespace dom {
17
18 using mozilla::ipc::AssertIsOnBackgroundThread;
19
~ServiceWorkerContainerProxy()20 ServiceWorkerContainerProxy::~ServiceWorkerContainerProxy() {
21 // Any thread
22 MOZ_DIAGNOSTIC_ASSERT(!mActor);
23 }
24
ServiceWorkerContainerProxy(ServiceWorkerContainerParent * aActor)25 ServiceWorkerContainerProxy::ServiceWorkerContainerProxy(
26 ServiceWorkerContainerParent* aActor)
27 : mActor(aActor) {
28 AssertIsOnBackgroundThread();
29 MOZ_DIAGNOSTIC_ASSERT(mActor);
30
31 // The container does not directly listen for updates, so we don't need
32 // to immediately initialize. The controllerchange event comes via the
33 // ClientSource associated with the ServiceWorkerContainer's bound global.
34 }
35
RevokeActor(ServiceWorkerContainerParent * aActor)36 void ServiceWorkerContainerProxy::RevokeActor(
37 ServiceWorkerContainerParent* aActor) {
38 AssertIsOnBackgroundThread();
39 MOZ_DIAGNOSTIC_ASSERT(mActor);
40 MOZ_DIAGNOSTIC_ASSERT(mActor == aActor);
41 mActor = nullptr;
42 }
43
Register(const ClientInfo & aClientInfo,const nsCString & aScopeURL,const nsCString & aScriptURL,ServiceWorkerUpdateViaCache aUpdateViaCache)44 RefPtr<ServiceWorkerRegistrationPromise> ServiceWorkerContainerProxy::Register(
45 const ClientInfo& aClientInfo, const nsCString& aScopeURL,
46 const nsCString& aScriptURL, ServiceWorkerUpdateViaCache aUpdateViaCache) {
47 AssertIsOnBackgroundThread();
48
49 RefPtr<ServiceWorkerRegistrationPromise::Private> promise =
50 new ServiceWorkerRegistrationPromise::Private(__func__);
51
52 nsCOMPtr<nsIRunnable> r = NS_NewRunnableFunction(
53 __func__,
54 [aClientInfo, aScopeURL, aScriptURL, aUpdateViaCache, promise]() mutable {
55 auto scopeExit = MakeScopeExit(
56 [&] { promise->Reject(NS_ERROR_DOM_INVALID_STATE_ERR, __func__); });
57
58 RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
59 NS_ENSURE_TRUE_VOID(swm);
60
61 swm->Register(aClientInfo, aScopeURL, aScriptURL, aUpdateViaCache)
62 ->ChainTo(promise.forget(), __func__);
63
64 scopeExit.release();
65 });
66
67 MOZ_ALWAYS_SUCCEEDS(
68 SchedulerGroup::Dispatch(TaskCategory::Other, r.forget()));
69
70 return promise;
71 }
72
73 RefPtr<ServiceWorkerRegistrationPromise>
GetRegistration(const ClientInfo & aClientInfo,const nsCString & aURL)74 ServiceWorkerContainerProxy::GetRegistration(const ClientInfo& aClientInfo,
75 const nsCString& aURL) {
76 AssertIsOnBackgroundThread();
77
78 RefPtr<ServiceWorkerRegistrationPromise::Private> promise =
79 new ServiceWorkerRegistrationPromise::Private(__func__);
80
81 nsCOMPtr<nsIRunnable> r =
82 NS_NewRunnableFunction(__func__, [aClientInfo, aURL, promise]() mutable {
83 auto scopeExit = MakeScopeExit(
84 [&] { promise->Reject(NS_ERROR_DOM_INVALID_STATE_ERR, __func__); });
85
86 RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
87 NS_ENSURE_TRUE_VOID(swm);
88
89 swm->GetRegistration(aClientInfo, aURL)
90 ->ChainTo(promise.forget(), __func__);
91
92 scopeExit.release();
93 });
94
95 MOZ_ALWAYS_SUCCEEDS(
96 SchedulerGroup::Dispatch(TaskCategory::Other, r.forget()));
97
98 return promise;
99 }
100
101 RefPtr<ServiceWorkerRegistrationListPromise>
GetRegistrations(const ClientInfo & aClientInfo)102 ServiceWorkerContainerProxy::GetRegistrations(const ClientInfo& aClientInfo) {
103 AssertIsOnBackgroundThread();
104
105 RefPtr<ServiceWorkerRegistrationListPromise::Private> promise =
106 new ServiceWorkerRegistrationListPromise::Private(__func__);
107
108 nsCOMPtr<nsIRunnable> r =
109 NS_NewRunnableFunction(__func__, [aClientInfo, promise]() mutable {
110 auto scopeExit = MakeScopeExit(
111 [&] { promise->Reject(NS_ERROR_DOM_INVALID_STATE_ERR, __func__); });
112
113 RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
114 NS_ENSURE_TRUE_VOID(swm);
115
116 swm->GetRegistrations(aClientInfo)->ChainTo(promise.forget(), __func__);
117
118 scopeExit.release();
119 });
120
121 MOZ_ALWAYS_SUCCEEDS(
122 SchedulerGroup::Dispatch(TaskCategory::Other, r.forget()));
123
124 return promise;
125 }
126
GetReady(const ClientInfo & aClientInfo)127 RefPtr<ServiceWorkerRegistrationPromise> ServiceWorkerContainerProxy::GetReady(
128 const ClientInfo& aClientInfo) {
129 AssertIsOnBackgroundThread();
130
131 RefPtr<ServiceWorkerRegistrationPromise::Private> promise =
132 new ServiceWorkerRegistrationPromise::Private(__func__);
133
134 nsCOMPtr<nsIRunnable> r =
135 NS_NewRunnableFunction(__func__, [aClientInfo, promise]() mutable {
136 auto scopeExit = MakeScopeExit(
137 [&] { promise->Reject(NS_ERROR_DOM_INVALID_STATE_ERR, __func__); });
138
139 RefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
140 NS_ENSURE_TRUE_VOID(swm);
141
142 swm->WhenReady(aClientInfo)->ChainTo(promise.forget(), __func__);
143
144 scopeExit.release();
145 });
146
147 MOZ_ALWAYS_SUCCEEDS(
148 SchedulerGroup::Dispatch(TaskCategory::Other, r.forget()));
149
150 return promise;
151 }
152
153 } // namespace dom
154 } // namespace mozilla
155