OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/browser/service_worker/service_worker_registration.h" | 5 #include "content/browser/service_worker/service_worker_registration.h" |
6 | 6 |
7 #include "content/browser/service_worker/service_worker_context_core.h" | 7 #include "content/browser/service_worker/service_worker_context_core.h" |
8 #include "content/browser/service_worker/service_worker_info.h" | 8 #include "content/browser/service_worker/service_worker_info.h" |
9 #include "content/browser/service_worker/service_worker_register_job.h" | 9 #include "content/browser/service_worker/service_worker_register_job.h" |
10 #include "content/browser/service_worker/service_worker_utils.h" | 10 #include "content/browser/service_worker/service_worker_utils.h" |
(...skipping 13 matching lines...) Expand all Loading... | |
24 | 24 |
25 ServiceWorkerRegistration::ServiceWorkerRegistration( | 25 ServiceWorkerRegistration::ServiceWorkerRegistration( |
26 const GURL& pattern, | 26 const GURL& pattern, |
27 const GURL& script_url, | 27 const GURL& script_url, |
28 int64 registration_id, | 28 int64 registration_id, |
29 base::WeakPtr<ServiceWorkerContextCore> context) | 29 base::WeakPtr<ServiceWorkerContextCore> context) |
30 : pattern_(pattern), | 30 : pattern_(pattern), |
31 script_url_(script_url), | 31 script_url_(script_url), |
32 registration_id_(registration_id), | 32 registration_id_(registration_id), |
33 is_deleted_(false), | 33 is_deleted_(false), |
34 is_uninstalling_(false), | |
34 should_activate_when_ready_(false), | 35 should_activate_when_ready_(false), |
35 context_(context) { | 36 context_(context) { |
36 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 37 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
37 DCHECK(context_); | 38 DCHECK(context_); |
38 context_->AddLiveRegistration(this); | 39 context_->AddLiveRegistration(this); |
39 } | 40 } |
40 | 41 |
41 ServiceWorkerRegistration::~ServiceWorkerRegistration() { | 42 ServiceWorkerRegistration::~ServiceWorkerRegistration() { |
42 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 43 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
43 if (context_) | 44 if (context_) |
44 context_->RemoveLiveRegistration(registration_id_); | 45 context_->RemoveLiveRegistration(registration_id_); |
45 ResetShouldActivateWhenReady(); | 46 if (should_activate_when_ready_ || is_uninstalling()) |
47 active_version()->RemoveListener(this); | |
46 } | 48 } |
47 | 49 |
48 void ServiceWorkerRegistration::AddListener(Listener* listener) { | 50 void ServiceWorkerRegistration::AddListener(Listener* listener) { |
49 listeners_.AddObserver(listener); | 51 listeners_.AddObserver(listener); |
50 } | 52 } |
51 | 53 |
52 void ServiceWorkerRegistration::RemoveListener(Listener* listener) { | 54 void ServiceWorkerRegistration::RemoveListener(Listener* listener) { |
53 listeners_.RemoveObserver(listener); | 55 listeners_.RemoveObserver(listener); |
54 } | 56 } |
55 | 57 |
56 ServiceWorkerRegistrationInfo ServiceWorkerRegistration::GetInfo() { | 58 ServiceWorkerRegistrationInfo ServiceWorkerRegistration::GetInfo() { |
57 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 59 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
58 return ServiceWorkerRegistrationInfo( | 60 return ServiceWorkerRegistrationInfo( |
59 script_url(), | 61 script_url(), |
60 pattern(), | 62 pattern(), |
61 registration_id_, | 63 registration_id_, |
62 GetVersionInfo(active_version_), | 64 GetVersionInfo(active_version_), |
63 GetVersionInfo(waiting_version_), | 65 GetVersionInfo(waiting_version_), |
64 GetVersionInfo(installing_version_)); | 66 GetVersionInfo(installing_version_)); |
65 } | 67 } |
66 | 68 |
67 void ServiceWorkerRegistration::SetActiveVersion( | 69 void ServiceWorkerRegistration::SetActiveVersion( |
68 ServiceWorkerVersion* version) { | 70 ServiceWorkerVersion* version) { |
69 ResetShouldActivateWhenReady(); | 71 SetShouldActivateWhenReady(false); |
70 SetVersionInternal(version, &active_version_, | 72 SetVersionInternal(version, &active_version_, |
71 ChangedVersionAttributesMask::ACTIVE_VERSION); | 73 ChangedVersionAttributesMask::ACTIVE_VERSION); |
72 } | 74 } |
73 | 75 |
74 void ServiceWorkerRegistration::SetWaitingVersion( | 76 void ServiceWorkerRegistration::SetWaitingVersion( |
75 ServiceWorkerVersion* version) { | 77 ServiceWorkerVersion* version) { |
76 ResetShouldActivateWhenReady(); | 78 SetShouldActivateWhenReady(false); |
77 SetVersionInternal(version, &waiting_version_, | 79 SetVersionInternal(version, &waiting_version_, |
78 ChangedVersionAttributesMask::WAITING_VERSION); | 80 ChangedVersionAttributesMask::WAITING_VERSION); |
79 } | 81 } |
80 | 82 |
81 void ServiceWorkerRegistration::SetInstallingVersion( | 83 void ServiceWorkerRegistration::SetInstallingVersion( |
82 ServiceWorkerVersion* version) { | 84 ServiceWorkerVersion* version) { |
83 SetVersionInternal(version, &installing_version_, | 85 SetVersionInternal(version, &installing_version_, |
84 ChangedVersionAttributesMask::INSTALLING_VERSION); | 86 ChangedVersionAttributesMask::INSTALLING_VERSION); |
85 } | 87 } |
86 | 88 |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
126 } else if (active_version_ == version) { | 128 } else if (active_version_ == version) { |
127 active_version_ = NULL; | 129 active_version_ = NULL; |
128 mask->add(ChangedVersionAttributesMask::ACTIVE_VERSION); | 130 mask->add(ChangedVersionAttributesMask::ACTIVE_VERSION); |
129 } | 131 } |
130 } | 132 } |
131 | 133 |
132 void ServiceWorkerRegistration::ActivateWaitingVersionWhenReady() { | 134 void ServiceWorkerRegistration::ActivateWaitingVersionWhenReady() { |
133 DCHECK(waiting_version()); | 135 DCHECK(waiting_version()); |
134 if (should_activate_when_ready_) | 136 if (should_activate_when_ready_) |
135 return; | 137 return; |
136 if (active_version() && active_version()->HasControllee()) { | 138 if (active_version() && active_version()->HasControllee()) |
139 SetShouldActivateWhenReady(true); | |
140 else | |
141 ActivateWaitingVersion(); | |
142 } | |
143 | |
144 bool ServiceWorkerRegistration::IsListeningForNoControllees() { | |
145 return active_version() && (should_activate_when_ready_ || is_uninstalling_); | |
146 } | |
147 | |
148 void ServiceWorkerRegistration::SetShouldActivateWhenReady( | |
149 bool should_activate) { | |
150 if (should_activate_when_ready_ == should_activate) | |
151 return; | |
152 bool listening = IsListeningForNoControllees(); | |
153 should_activate_when_ready_ = should_activate; | |
154 if (listening == IsListeningForNoControllees()) | |
155 return; | |
156 if (IsListeningForNoControllees()) | |
137 active_version()->AddListener(this); | 157 active_version()->AddListener(this); |
138 should_activate_when_ready_ = true; | 158 else |
159 active_version()->RemoveListener(this); | |
160 } | |
falken
2014/07/29 14:04:05
It may be better for Registration to always listen
michaeln
2014/07/31 00:08:07
sgtm
| |
161 | |
162 void ServiceWorkerRegistration::SetUninstalling(bool is_uninstalling) { | |
163 if (is_uninstalling_ == is_uninstalling) | |
139 return; | 164 return; |
140 } | 165 bool listening = IsListeningForNoControllees(); |
141 ActivateWaitingVersion(); | 166 is_uninstalling_ = is_uninstalling; |
167 if (listening == IsListeningForNoControllees()) | |
168 return; | |
169 if (IsListeningForNoControllees()) | |
170 active_version()->AddListener(this); | |
171 else | |
172 active_version()->RemoveListener(this); | |
142 } | 173 } |
143 | 174 |
144 void ServiceWorkerRegistration::OnNoControllees(ServiceWorkerVersion* version) { | 175 void ServiceWorkerRegistration::OnNoControllees(ServiceWorkerVersion* version) { |
145 DCHECK_EQ(active_version(), version); | 176 DCHECK_EQ(active_version(), version); |
146 DCHECK(should_activate_when_ready_); | 177 active_version()->RemoveListener(this); |
147 active_version_->RemoveListener(this); | 178 if (is_uninstalling()) |
179 Clear(); | |
180 else if (should_activate_when_ready_) | |
181 ActivateWaitingVersion(); | |
182 is_uninstalling_ = false; | |
148 should_activate_when_ready_ = false; | 183 should_activate_when_ready_ = false; |
149 ActivateWaitingVersion(); | |
150 } | 184 } |
151 | 185 |
152 void ServiceWorkerRegistration::ActivateWaitingVersion() { | 186 void ServiceWorkerRegistration::ActivateWaitingVersion() { |
153 DCHECK(context_); | 187 DCHECK(context_); |
154 DCHECK(waiting_version()); | 188 DCHECK(waiting_version()); |
155 scoped_refptr<ServiceWorkerVersion> activating_version = waiting_version(); | 189 scoped_refptr<ServiceWorkerVersion> activating_version = waiting_version(); |
156 scoped_refptr<ServiceWorkerVersion> exiting_version = active_version(); | 190 scoped_refptr<ServiceWorkerVersion> exiting_version = active_version(); |
157 | 191 |
158 if (activating_version->is_doomed() || | 192 if (activating_version->is_doomed() || |
159 activating_version->status() == ServiceWorkerVersion::REDUNDANT) { | 193 activating_version->status() == ServiceWorkerVersion::REDUNDANT) { |
(...skipping 26 matching lines...) Expand all Loading... | |
186 activating_version->SetStatus(ServiceWorkerVersion::ACTIVATING); | 220 activating_version->SetStatus(ServiceWorkerVersion::ACTIVATING); |
187 | 221 |
188 // TODO(nhiroki): "8. Fire a simple event named controllerchange..." | 222 // TODO(nhiroki): "8. Fire a simple event named controllerchange..." |
189 | 223 |
190 // "9. Queue a task to fire an event named activate..." | 224 // "9. Queue a task to fire an event named activate..." |
191 activating_version->DispatchActivateEvent( | 225 activating_version->DispatchActivateEvent( |
192 base::Bind(&ServiceWorkerRegistration::OnActivateEventFinished, | 226 base::Bind(&ServiceWorkerRegistration::OnActivateEventFinished, |
193 this, activating_version)); | 227 this, activating_version)); |
194 } | 228 } |
195 | 229 |
230 void ServiceWorkerRegistration::ClearWhenReady() { | |
231 DCHECK(context_); | |
232 if (is_uninstalling()) | |
233 return; | |
234 context_->storage()->NotifyUninstallingRegistration(this); | |
235 | |
236 // Delete from DB in case browser dies before we're ready. | |
237 context_->storage()->DeleteRegistration( | |
238 id(), | |
239 script_url().GetOrigin(), | |
240 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback)); | |
241 | |
242 if (active_version() && active_version()->HasControllee()) | |
243 SetUninstalling(true); | |
244 else | |
245 Clear(); | |
246 } | |
247 | |
248 void ServiceWorkerRegistration::AbortPendingClear() { | |
249 DCHECK(context_); | |
250 if (!is_uninstalling()) | |
251 return; | |
252 SetUninstalling(false); | |
253 context_->storage()->NotifyDoneUninstallingRegistration(this); | |
254 | |
255 if (waiting_version()) { | |
256 context_->storage()->StoreRegistration( | |
257 this, | |
258 waiting_version(), | |
259 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback)); | |
260 return; | |
261 } | |
262 if (active_version()) { | |
263 context_->storage()->StoreRegistration( | |
264 this, | |
265 active_version(), | |
266 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback)); | |
267 } | |
268 } | |
269 | |
196 void ServiceWorkerRegistration::OnActivateEventFinished( | 270 void ServiceWorkerRegistration::OnActivateEventFinished( |
197 ServiceWorkerVersion* activating_version, | 271 ServiceWorkerVersion* activating_version, |
198 ServiceWorkerStatusCode status) { | 272 ServiceWorkerStatusCode status) { |
199 if (!context_ || activating_version != active_version()) | 273 if (!context_ || activating_version != active_version()) |
200 return; | 274 return; |
201 // TODO(kinuko,falken): For some error cases (e.g. ServiceWorker is | 275 // TODO(kinuko,falken): For some error cases (e.g. ServiceWorker is |
202 // unexpectedly terminated) we may want to retry sending the event again. | 276 // unexpectedly terminated) we may want to retry sending the event again. |
203 if (status != SERVICE_WORKER_OK) { | 277 if (status != SERVICE_WORKER_OK) { |
204 // "11. If activateFailed is true, then:..." | 278 // "11. If activateFailed is true, then:..." |
205 ServiceWorkerRegisterJob::DisassociateVersionFromDocuments( | 279 ServiceWorkerRegisterJob::DisassociateVersionFromDocuments( |
(...skipping 15 matching lines...) Expand all Loading... | |
221 // "12. Run the [[UpdateState]] algorithm passing registration.activeWorker | 295 // "12. Run the [[UpdateState]] algorithm passing registration.activeWorker |
222 // and "activated" as the arguments." | 296 // and "activated" as the arguments." |
223 activating_version->SetStatus(ServiceWorkerVersion::ACTIVATED); | 297 activating_version->SetStatus(ServiceWorkerVersion::ACTIVATED); |
224 if (context_) { | 298 if (context_) { |
225 context_->storage()->UpdateToActiveState( | 299 context_->storage()->UpdateToActiveState( |
226 this, | 300 this, |
227 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback)); | 301 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback)); |
228 } | 302 } |
229 } | 303 } |
230 | 304 |
231 void ServiceWorkerRegistration::ResetShouldActivateWhenReady() { | |
232 if (should_activate_when_ready_) { | |
233 active_version()->RemoveListener(this); | |
234 should_activate_when_ready_ = false; | |
235 } | |
236 } | |
237 | |
238 void ServiceWorkerRegistration::OnDeleteFinished( | 305 void ServiceWorkerRegistration::OnDeleteFinished( |
239 ServiceWorkerStatusCode status) { | 306 ServiceWorkerStatusCode status) { |
240 // Intentionally empty completion callback, used to prevent | 307 // Intentionally empty completion callback, used to prevent |
241 // |this| from being deleted until the storage method completes. | 308 // |this| from being deleted until the storage method completes. |
242 } | 309 } |
243 | 310 |
311 void ServiceWorkerRegistration::Clear() { | |
312 context_->storage()->NotifyDoneUninstallingRegistration(this); | |
313 | |
314 if (installing_version()) { | |
315 installing_version()->Doom(); | |
316 UnsetVersion(installing_version()); | |
317 } | |
318 | |
319 if (waiting_version()) { | |
320 waiting_version()->Doom(); | |
321 UnsetVersion(waiting_version()); | |
322 } | |
323 | |
324 if (active_version()) { | |
325 active_version()->Doom(); | |
326 UnsetVersion(active_version()); | |
327 } | |
328 } | |
329 | |
244 } // namespace content | 330 } // namespace content |
OLD | NEW |