Source code

Revision control

Other Tools

1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
3
/* This Source Code Form is subject to the terms of the Mozilla Public
4
* License, v. 2.0. If a copy of the MPL was not distributed with this
5
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7
#ifndef mozilla_dom_serviceworkerregistrationinfo_h
8
#define mozilla_dom_serviceworkerregistrationinfo_h
9
10
#include <functional>
11
12
#include "mozilla/dom/ServiceWorkerInfo.h"
13
#include "mozilla/dom/ServiceWorkerRegistrationBinding.h"
14
#include "mozilla/dom/ServiceWorkerRegistrationDescriptor.h"
15
#include "nsProxyRelease.h"
16
#include "nsTObserverArray.h"
17
18
namespace mozilla {
19
namespace dom {
20
21
class ServiceWorkerRegistrationListener;
22
23
class ServiceWorkerRegistrationInfo final
24
: public nsIServiceWorkerRegistrationInfo {
25
nsCOMPtr<nsIPrincipal> mPrincipal;
26
ServiceWorkerRegistrationDescriptor mDescriptor;
27
nsTArray<nsCOMPtr<nsIServiceWorkerRegistrationInfoListener>> mListeners;
28
nsTObserverArray<ServiceWorkerRegistrationListener*> mInstanceList;
29
30
struct VersionEntry {
31
const ServiceWorkerRegistrationDescriptor mDescriptor;
32
TimeStamp mTimeStamp;
33
34
explicit VersionEntry(
35
const ServiceWorkerRegistrationDescriptor& aDescriptor)
36
: mDescriptor(aDescriptor), mTimeStamp(TimeStamp::Now()) {}
37
};
38
nsTArray<UniquePtr<VersionEntry>> mVersionList;
39
40
const nsID mAgentClusterId = nsContentUtils::GenerateUUID();
41
42
uint32_t mControlledClientsCounter;
43
uint32_t mDelayMultiplier;
44
45
enum { NoUpdate, NeedTimeCheckAndUpdate, NeedUpdate } mUpdateState;
46
47
// Timestamp to track SWR's last update time
48
PRTime mCreationTime;
49
TimeStamp mCreationTimeStamp;
50
// The time of update is 0, if SWR've never been updated yet.
51
PRTime mLastUpdateTime;
52
53
RefPtr<ServiceWorkerInfo> mEvaluatingWorker;
54
RefPtr<ServiceWorkerInfo> mActiveWorker;
55
RefPtr<ServiceWorkerInfo> mWaitingWorker;
56
RefPtr<ServiceWorkerInfo> mInstallingWorker;
57
58
virtual ~ServiceWorkerRegistrationInfo();
59
60
// When unregister() is called on a registration, it is removed from the
61
// "scope to registration map" but not immediately "cleared" (i.e. its workers
62
// terminated, updated to the redundant state, etc.) because it may still be
63
// controlling clients. It is marked as unregistered and when all controlled
64
// clients go away, cleared. This way we can tell if a registration
65
// is unregistered by querying the object itself rather than incurring a table
66
// lookup (in the case when the registrations are passed around as pointers).
67
bool mUnregistered;
68
69
bool mCorrupt;
70
71
public:
72
NS_DECL_ISUPPORTS
73
NS_DECL_NSISERVICEWORKERREGISTRATIONINFO
74
75
typedef std::function<void()> TryToActivateCallback;
76
77
ServiceWorkerRegistrationInfo(const nsACString& aScope,
78
nsIPrincipal* aPrincipal,
79
ServiceWorkerUpdateViaCache aUpdateViaCache);
80
81
void AddInstance(ServiceWorkerRegistrationListener* aInstance,
82
const ServiceWorkerRegistrationDescriptor& aDescriptor);
83
84
void RemoveInstance(ServiceWorkerRegistrationListener* aInstance);
85
86
const nsCString& Scope() const;
87
88
nsIPrincipal* Principal() const;
89
90
bool IsUnregistered() const;
91
92
void SetUnregistered();
93
94
already_AddRefed<ServiceWorkerInfo> Newest() const {
95
RefPtr<ServiceWorkerInfo> newest;
96
if (mInstallingWorker) {
97
newest = mInstallingWorker;
98
} else if (mWaitingWorker) {
99
newest = mWaitingWorker;
100
} else {
101
newest = mActiveWorker;
102
}
103
104
return newest.forget();
105
}
106
107
already_AddRefed<ServiceWorkerInfo> NewestIncludingEvaluating() const {
108
if (mEvaluatingWorker) {
109
RefPtr<ServiceWorkerInfo> newest = mEvaluatingWorker;
110
return newest.forget();
111
}
112
return Newest();
113
}
114
115
already_AddRefed<ServiceWorkerInfo> GetServiceWorkerInfoById(uint64_t aId);
116
117
void StartControllingClient() {
118
++mControlledClientsCounter;
119
mDelayMultiplier = 0;
120
}
121
122
void StopControllingClient() {
123
MOZ_ASSERT(mControlledClientsCounter);
124
--mControlledClientsCounter;
125
}
126
127
bool IsControllingClients() const {
128
return mActiveWorker && mControlledClientsCounter;
129
}
130
131
// As a side effect, this nullifies
132
// `m{Evaluating,Installing,Waiting,Active}Worker`s.
133
void ShutdownWorkers();
134
135
void Clear();
136
137
void ClearAsCorrupt();
138
139
bool IsCorrupt() const;
140
141
void TryToActivateAsync(TryToActivateCallback&& aCallback = nullptr);
142
143
void TryToActivate(TryToActivateCallback&& aCallback);
144
145
void Activate();
146
147
void FinishActivate(bool aSuccess);
148
149
void RefreshLastUpdateCheckTime();
150
151
bool IsLastUpdateCheckTimeOverOneDay() const;
152
153
void MaybeScheduleTimeCheckAndUpdate();
154
155
void MaybeScheduleUpdate();
156
157
bool CheckAndClearIfUpdateNeeded();
158
159
ServiceWorkerInfo* GetEvaluating() const;
160
161
ServiceWorkerInfo* GetInstalling() const;
162
163
ServiceWorkerInfo* GetWaiting() const;
164
165
ServiceWorkerInfo* GetActive() const;
166
167
ServiceWorkerInfo* GetByDescriptor(
168
const ServiceWorkerDescriptor& aDescriptor) const;
169
170
// Set the given worker as the evaluating service worker. The worker
171
// state is not changed.
172
void SetEvaluating(ServiceWorkerInfo* aServiceWorker);
173
174
// Remove an existing evaluating worker, if present. The worker will
175
// be transitioned to the Redundant state.
176
void ClearEvaluating();
177
178
// Remove an existing installing worker, if present. The worker will
179
// be transitioned to the Redundant state.
180
void ClearInstalling();
181
182
// Transition the current evaluating worker to be the installing worker. The
183
// worker's state is update to Installing.
184
void TransitionEvaluatingToInstalling();
185
186
// Transition the current installing worker to be the waiting worker. The
187
// worker's state is updated to Installed.
188
void TransitionInstallingToWaiting();
189
190
// Override the current active worker. This is used during browser
191
// initialization to load persisted workers. Its also used to propagate
192
// active workers across child processes in e10s. This second use will
193
// go away once the ServiceWorkerManager moves to the parent process.
194
// The worker is transitioned to the Activated state.
195
void SetActive(ServiceWorkerInfo* aServiceWorker);
196
197
// Transition the current waiting worker to be the new active worker. The
198
// worker is updated to the Activating state.
199
void TransitionWaitingToActive();
200
201
// Determine if the registration is actively performing work.
202
bool IsIdle() const;
203
204
ServiceWorkerUpdateViaCache GetUpdateViaCache() const;
205
206
void SetUpdateViaCache(ServiceWorkerUpdateViaCache aUpdateViaCache);
207
208
int64_t GetLastUpdateTime() const;
209
210
void SetLastUpdateTime(const int64_t aTime);
211
212
const ServiceWorkerRegistrationDescriptor& Descriptor() const;
213
214
uint64_t Id() const;
215
216
uint64_t Version() const;
217
218
uint32_t GetUpdateDelay(const bool aWithMultiplier = true);
219
220
void FireUpdateFound();
221
222
void NotifyCleared();
223
224
void ClearWhenIdle();
225
226
const nsID& AgentClusterId() const;
227
228
private:
229
// Roughly equivalent to [[Update Registration State algorithm]]. Make sure
230
// this is called *before* updating SW instances' state, otherwise they
231
// may get CC-ed.
232
void UpdateRegistrationState();
233
234
void UpdateRegistrationState(ServiceWorkerUpdateViaCache aUpdateViaCache);
235
236
// Used by devtools to track changes to the properties of
237
// *nsIServiceWorkerRegistrationInfo*. Note, this doesn't necessarily need to
238
// be in sync with the DOM registration objects, but it does need to be called
239
// in the same task that changed |mInstallingWorker|, |mWaitingWorker| or
240
// |mActiveWorker|.
241
void NotifyChromeRegistrationListeners();
242
243
static uint64_t GetNextId();
244
245
static uint64_t GetNextVersion();
246
247
// `aFunc`'s argument will be a reference to
248
// `m{Evaluating,Installing,Waiting,Active}Worker` (not to copy of them).
249
// Additionally, a null check will be performed for each worker before each
250
// call to `aFunc`, so `aFunc` will always get a reference to a non-null
251
// pointer.
252
void ForEachWorker(void (*aFunc)(RefPtr<ServiceWorkerInfo>&));
253
};
254
255
} // namespace dom
256
} // namespace mozilla
257
258
#endif // mozilla_dom_serviceworkerregistrationinfo_h