Bug 1842773 - Part 18: Update TypedArray length, byteLength, and byteOffset accesses...
[gecko.git] / dom / serviceworkers / ServiceWorkerInfo.cpp
blob9998cfed6bc1e140f438178d14a9943b495d66c7
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/. */
7 #include "ServiceWorkerInfo.h"
9 #include "ServiceWorkerUtils.h"
10 #include "ServiceWorkerPrivate.h"
11 #include "ServiceWorkerScriptCache.h"
12 #include "mozilla/dom/ClientIPCTypes.h"
13 #include "mozilla/dom/ClientState.h"
14 #include "mozilla/dom/RemoteWorkerTypes.h"
15 #include "mozilla/dom/WorkerPrivate.h"
17 namespace mozilla::dom {
19 using mozilla::ipc::PrincipalInfo;
21 static_assert(nsIServiceWorkerInfo::STATE_PARSED ==
22 static_cast<uint16_t>(ServiceWorkerState::Parsed),
23 "ServiceWorkerState enumeration value should match state values "
24 "from nsIServiceWorkerInfo.");
25 static_assert(nsIServiceWorkerInfo::STATE_INSTALLING ==
26 static_cast<uint16_t>(ServiceWorkerState::Installing),
27 "ServiceWorkerState enumeration value should match state values "
28 "from nsIServiceWorkerInfo.");
29 static_assert(nsIServiceWorkerInfo::STATE_INSTALLED ==
30 static_cast<uint16_t>(ServiceWorkerState::Installed),
31 "ServiceWorkerState enumeration value should match state values "
32 "from nsIServiceWorkerInfo.");
33 static_assert(nsIServiceWorkerInfo::STATE_ACTIVATING ==
34 static_cast<uint16_t>(ServiceWorkerState::Activating),
35 "ServiceWorkerState enumeration value should match state values "
36 "from nsIServiceWorkerInfo.");
37 static_assert(nsIServiceWorkerInfo::STATE_ACTIVATED ==
38 static_cast<uint16_t>(ServiceWorkerState::Activated),
39 "ServiceWorkerState enumeration value should match state values "
40 "from nsIServiceWorkerInfo.");
41 static_assert(nsIServiceWorkerInfo::STATE_REDUNDANT ==
42 static_cast<uint16_t>(ServiceWorkerState::Redundant),
43 "ServiceWorkerState enumeration value should match state values "
44 "from nsIServiceWorkerInfo.");
45 static_assert(nsIServiceWorkerInfo::STATE_UNKNOWN ==
46 ServiceWorkerStateValues::Count,
47 "ServiceWorkerState enumeration value should match state values "
48 "from nsIServiceWorkerInfo.");
50 NS_IMPL_ISUPPORTS(ServiceWorkerInfo, nsIServiceWorkerInfo)
52 NS_IMETHODIMP
53 ServiceWorkerInfo::GetId(nsAString& aId) {
54 MOZ_ASSERT(NS_IsMainThread());
55 aId = mWorkerPrivateId;
56 return NS_OK;
59 NS_IMETHODIMP
60 ServiceWorkerInfo::GetScriptSpec(nsAString& aScriptSpec) {
61 MOZ_ASSERT(NS_IsMainThread());
62 CopyUTF8toUTF16(mDescriptor.ScriptURL(), aScriptSpec);
63 return NS_OK;
66 NS_IMETHODIMP
67 ServiceWorkerInfo::GetCacheName(nsAString& aCacheName) {
68 MOZ_ASSERT(NS_IsMainThread());
69 aCacheName = mCacheName;
70 return NS_OK;
73 NS_IMETHODIMP
74 ServiceWorkerInfo::GetState(uint16_t* aState) {
75 MOZ_ASSERT(aState);
76 MOZ_ASSERT(NS_IsMainThread());
77 *aState = static_cast<uint16_t>(State());
78 return NS_OK;
81 NS_IMETHODIMP
82 ServiceWorkerInfo::GetDebugger(nsIWorkerDebugger** aResult) {
83 if (NS_WARN_IF(!aResult)) {
84 return NS_ERROR_FAILURE;
87 return mServiceWorkerPrivate->GetDebugger(aResult);
90 NS_IMETHODIMP
91 ServiceWorkerInfo::GetHandlesFetchEvents(bool* aValue) {
92 MOZ_ASSERT(aValue);
93 MOZ_ASSERT(NS_IsMainThread());
95 if (mHandlesFetch == Unknown) {
96 return NS_ERROR_FAILURE;
99 *aValue = HandlesFetch();
100 return NS_OK;
103 NS_IMETHODIMP
104 ServiceWorkerInfo::GetInstalledTime(PRTime* _retval) {
105 MOZ_ASSERT(NS_IsMainThread());
106 MOZ_ASSERT(_retval);
107 *_retval = mInstalledTime;
108 return NS_OK;
111 NS_IMETHODIMP
112 ServiceWorkerInfo::GetActivatedTime(PRTime* _retval) {
113 MOZ_ASSERT(NS_IsMainThread());
114 MOZ_ASSERT(_retval);
115 *_retval = mActivatedTime;
116 return NS_OK;
119 NS_IMETHODIMP
120 ServiceWorkerInfo::GetRedundantTime(PRTime* _retval) {
121 MOZ_ASSERT(NS_IsMainThread());
122 MOZ_ASSERT(_retval);
123 *_retval = mRedundantTime;
124 return NS_OK;
127 NS_IMETHODIMP
128 ServiceWorkerInfo::GetNavigationFaultCount(uint32_t* aNavigationFaultCount) {
129 MOZ_ASSERT(NS_IsMainThread());
130 MOZ_ASSERT(aNavigationFaultCount);
131 *aNavigationFaultCount = mNavigationFaultCount;
132 return NS_OK;
135 NS_IMETHODIMP
136 ServiceWorkerInfo::GetTestingInjectCancellation(
137 nsresult* aTestingInjectCancellation) {
138 MOZ_ASSERT(NS_IsMainThread());
139 MOZ_ASSERT(aTestingInjectCancellation);
140 *aTestingInjectCancellation = mTestingInjectCancellation;
141 return NS_OK;
144 NS_IMETHODIMP
145 ServiceWorkerInfo::SetTestingInjectCancellation(
146 nsresult aTestingInjectCancellation) {
147 MOZ_ASSERT(NS_IsMainThread());
148 mTestingInjectCancellation = aTestingInjectCancellation;
149 return NS_OK;
152 NS_IMETHODIMP
153 ServiceWorkerInfo::AttachDebugger() {
154 return mServiceWorkerPrivate->AttachDebugger();
157 NS_IMETHODIMP
158 ServiceWorkerInfo::DetachDebugger() {
159 return mServiceWorkerPrivate->DetachDebugger();
162 void ServiceWorkerInfo::UpdateState(ServiceWorkerState aState) {
163 MOZ_ASSERT(NS_IsMainThread());
164 #ifdef DEBUG
165 // Any state can directly transition to redundant, but everything else is
166 // ordered.
167 if (aState != ServiceWorkerState::Redundant) {
168 MOZ_ASSERT_IF(State() == ServiceWorkerState::EndGuard_,
169 aState == ServiceWorkerState::Installing);
170 MOZ_ASSERT_IF(State() == ServiceWorkerState::Installing,
171 aState == ServiceWorkerState::Installed);
172 MOZ_ASSERT_IF(State() == ServiceWorkerState::Installed,
173 aState == ServiceWorkerState::Activating);
174 MOZ_ASSERT_IF(State() == ServiceWorkerState::Activating,
175 aState == ServiceWorkerState::Activated);
177 // Activated can only go to redundant.
178 MOZ_ASSERT_IF(State() == ServiceWorkerState::Activated,
179 aState == ServiceWorkerState::Redundant);
180 #endif
181 // Flush any pending functional events to the worker when it transitions to
182 // the activated state.
183 // TODO: Do we care that these events will race with the propagation of the
184 // state change?
185 if (State() != aState) {
186 mServiceWorkerPrivate->UpdateState(aState);
188 mDescriptor.SetState(aState);
189 if (State() == ServiceWorkerState::Redundant) {
190 serviceWorkerScriptCache::PurgeCache(mPrincipal, mCacheName);
191 mServiceWorkerPrivate->NoteDeadServiceWorkerInfo();
195 ServiceWorkerInfo::ServiceWorkerInfo(nsIPrincipal* aPrincipal,
196 const nsACString& aScope,
197 uint64_t aRegistrationId,
198 uint64_t aRegistrationVersion,
199 const nsACString& aScriptSpec,
200 const nsAString& aCacheName,
201 nsLoadFlags aImportsLoadFlags)
202 : mPrincipal(aPrincipal),
203 mDescriptor(GetNextID(), aRegistrationId, aRegistrationVersion,
204 aPrincipal, aScope, aScriptSpec, ServiceWorkerState::Parsed),
205 mCacheName(aCacheName),
206 mWorkerPrivateId(ComputeWorkerPrivateId()),
207 mImportsLoadFlags(aImportsLoadFlags),
208 mCreationTime(PR_Now()),
209 mCreationTimeStamp(TimeStamp::Now()),
210 mInstalledTime(0),
211 mActivatedTime(0),
212 mRedundantTime(0),
213 mServiceWorkerPrivate(new ServiceWorkerPrivate(this)),
214 mSkipWaitingFlag(false),
215 mHandlesFetch(Unknown),
216 mNavigationFaultCount(0),
217 mTestingInjectCancellation(NS_OK) {
218 MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
219 MOZ_ASSERT(mPrincipal);
220 // cache origin attributes so we can use them off main thread
221 mOriginAttributes = mPrincipal->OriginAttributesRef();
222 MOZ_ASSERT(!mDescriptor.ScriptURL().IsEmpty());
223 MOZ_ASSERT(!mCacheName.IsEmpty());
224 MOZ_ASSERT(!mWorkerPrivateId.IsEmpty());
226 // Scripts of a service worker should always be loaded bypass service workers.
227 // Otherwise, we might not be able to update a service worker correctly, if
228 // there is a service worker generating the script.
229 MOZ_DIAGNOSTIC_ASSERT(mImportsLoadFlags &
230 nsIChannel::LOAD_BYPASS_SERVICE_WORKER);
233 ServiceWorkerInfo::~ServiceWorkerInfo() {
234 MOZ_ASSERT(mServiceWorkerPrivate);
235 mServiceWorkerPrivate->NoteDeadServiceWorkerInfo();
238 static uint64_t gServiceWorkerInfoCurrentID = 0;
240 uint64_t ServiceWorkerInfo::GetNextID() const {
241 return ++gServiceWorkerInfoCurrentID;
244 void ServiceWorkerInfo::PostMessage(RefPtr<ServiceWorkerCloneData>&& aData,
245 const ClientInfo& aClientInfo,
246 const ClientState& aClientState) {
247 mServiceWorkerPrivate->SendMessageEvent(
248 std::move(aData),
249 ClientInfoAndState(aClientInfo.ToIPC(), aClientState.ToIPC()));
252 void ServiceWorkerInfo::UpdateInstalledTime() {
253 MOZ_ASSERT(State() == ServiceWorkerState::Installed);
254 MOZ_ASSERT(mInstalledTime == 0);
256 mInstalledTime =
257 mCreationTime +
258 static_cast<PRTime>(
259 (TimeStamp::Now() - mCreationTimeStamp).ToMicroseconds());
262 void ServiceWorkerInfo::UpdateActivatedTime() {
263 MOZ_ASSERT(State() == ServiceWorkerState::Activated);
264 MOZ_ASSERT(mActivatedTime == 0);
266 mActivatedTime =
267 mCreationTime +
268 static_cast<PRTime>(
269 (TimeStamp::Now() - mCreationTimeStamp).ToMicroseconds());
272 void ServiceWorkerInfo::UpdateRedundantTime() {
273 MOZ_ASSERT(State() == ServiceWorkerState::Redundant);
274 MOZ_ASSERT(mRedundantTime == 0);
276 mRedundantTime =
277 mCreationTime +
278 static_cast<PRTime>(
279 (TimeStamp::Now() - mCreationTimeStamp).ToMicroseconds());
282 void ServiceWorkerInfo::SetRegistrationVersion(uint64_t aVersion) {
283 mDescriptor.SetRegistrationVersion(aVersion);
286 } // namespace mozilla::dom