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 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
203 Clear(); | 203 Clear(); |
204 else if (should_activate_when_ready_) | 204 else if (should_activate_when_ready_) |
205 ActivateWaitingVersion(); | 205 ActivateWaitingVersion(); |
206 is_uninstalling_ = false; | 206 is_uninstalling_ = false; |
207 should_activate_when_ready_ = false; | 207 should_activate_when_ready_ = false; |
208 } | 208 } |
209 | 209 |
210 void ServiceWorkerRegistration::ActivateWaitingVersion() { | 210 void ServiceWorkerRegistration::ActivateWaitingVersion() { |
211 DCHECK(context_); | 211 DCHECK(context_); |
212 DCHECK(waiting_version()); | 212 DCHECK(waiting_version()); |
213 DCHECK(should_activate_when_ready_); | |
214 should_activate_when_ready_ = false; | 213 should_activate_when_ready_ = false; |
215 scoped_refptr<ServiceWorkerVersion> activating_version = waiting_version(); | 214 scoped_refptr<ServiceWorkerVersion> activating_version = waiting_version(); |
216 scoped_refptr<ServiceWorkerVersion> exiting_version = active_version(); | 215 scoped_refptr<ServiceWorkerVersion> exiting_version = active_version(); |
217 | 216 |
218 if (activating_version->is_doomed() || | 217 if (activating_version->is_doomed() || |
219 activating_version->status() == ServiceWorkerVersion::REDUNDANT) { | 218 activating_version->status() == ServiceWorkerVersion::REDUNDANT) { |
220 return; // Activation is no longer relevant. | 219 return; // Activation is no longer relevant. |
221 } | 220 } |
222 | 221 |
222 if (activating_version->skip_waiting()) | |
223 PrepareProviderHostsToSkipWaiting(); | |
224 | |
223 // "4. If exitingWorker is not null, | 225 // "4. If exitingWorker is not null, |
224 if (exiting_version.get()) { | 226 if (exiting_version.get()) { |
225 DCHECK(!exiting_version->HasControllee()); | 227 DCHECK(!exiting_version->HasControllee()); |
226 // TODO(michaeln): should wait for events to be complete | 228 // TODO(michaeln): should wait for events to be complete |
227 // "1. Wait for exitingWorker to finish handling any in-progress requests." | 229 // "1. Wait for exitingWorker to finish handling any in-progress requests." |
228 // "2. Terminate exitingWorker." | 230 // "2. Terminate exitingWorker." |
229 exiting_version->StopWorker( | 231 exiting_version->StopWorker( |
230 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback)); | 232 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback)); |
231 // "3. Run the [[UpdateState]] algorithm passing exitingWorker and | 233 // "3. Run the [[UpdateState]] algorithm passing exitingWorker and |
232 // "redundant" as the arguments." | 234 // "redundant" as the arguments." |
233 exiting_version->SetStatus(ServiceWorkerVersion::REDUNDANT); | 235 exiting_version->SetStatus(ServiceWorkerVersion::REDUNDANT); |
234 } | 236 } |
235 | 237 |
236 // "5. Set serviceWorkerRegistration.activeWorker to activatingWorker." | 238 // "5. Set serviceWorkerRegistration.activeWorker to activatingWorker." |
237 // "6. Set serviceWorkerRegistration.waitingWorker to null." | 239 // "6. Set serviceWorkerRegistration.waitingWorker to null." |
238 SetActiveVersion(activating_version.get()); | 240 SetActiveVersion(activating_version.get()); |
239 | 241 |
240 // "7. Run the [[UpdateState]] algorithm passing registration.activeWorker and | 242 // "7. Run the [[UpdateState]] algorithm passing registration.activeWorker and |
241 // "activating" as arguments." | 243 // "activating" as arguments." |
244 // "8. Fire a simple event named controllerchange..." | |
242 activating_version->SetStatus(ServiceWorkerVersion::ACTIVATING); | 245 activating_version->SetStatus(ServiceWorkerVersion::ACTIVATING); |
243 | 246 |
244 // TODO(nhiroki): "8. Fire a simple event named controllerchange..." | |
245 | |
246 // "9. Queue a task to fire an event named activate..." | 247 // "9. Queue a task to fire an event named activate..." |
247 activating_version->DispatchActivateEvent( | 248 activating_version->DispatchActivateEvent( |
248 base::Bind(&ServiceWorkerRegistration::OnActivateEventFinished, | 249 base::Bind(&ServiceWorkerRegistration::OnActivateEventFinished, |
249 this, activating_version)); | 250 this, activating_version)); |
250 } | 251 } |
251 | 252 |
253 void ServiceWorkerRegistration::PrepareProviderHostsToSkipWaiting() { | |
254 for (scoped_ptr<ServiceWorkerContextCore::ProviderHostIterator> it = | |
255 context_->GetProviderHostIterator(); | |
256 !it->IsAtEnd(); it->Advance()) { | |
257 ServiceWorkerProviderHost* host = it->GetProviderHost(); | |
258 if (!ServiceWorkerUtils::ScopeMatches(pattern(), | |
259 host->document_url())) | |
260 continue; | |
261 scoped_refptr<ServiceWorkerVersion> exiting_version = | |
262 host->active_version(); | |
falken
2014/11/14 04:00:15
You can add "1. Let exitingWorker be the active wo
| |
263 // "2. If exitingWorker is not null, then:" | |
264 if (!exiting_version.get()) | |
265 continue; | |
266 // TODO(xiang): should wait for events to be complete | |
267 // "1. Wait for exitingWorker to finish handling any in-progress requests." | |
268 // "2. Terminate exitingWorker." | |
269 exiting_version->StopWorker( | |
270 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback)); | |
271 exiting_version->SetStatus(ServiceWorkerVersion::REDUNDANT); | |
michaeln
2014/11/14 02:05:11
I don't believe this is the desired behavior. What
falken
2014/11/14 04:00:15
Right I think this can happen if this registration
xiang
2014/11/14 13:17:28
Yes, a longer matched registration should not be a
michaeln
2014/11/14 23:06:39
Hmmm, section 7.9 for the [[Install]] algo is obvi
| |
272 if (host->associated_registration() != this) { | |
273 host->DisassociateRegistration(); | |
274 host->AssociateRegistration(this); | |
275 } | |
276 } | |
277 } | |
278 | |
252 void ServiceWorkerRegistration::OnActivateEventFinished( | 279 void ServiceWorkerRegistration::OnActivateEventFinished( |
253 ServiceWorkerVersion* activating_version, | 280 ServiceWorkerVersion* activating_version, |
254 ServiceWorkerStatusCode status) { | 281 ServiceWorkerStatusCode status) { |
255 if (!context_ || activating_version != active_version()) | 282 if (!context_ || activating_version != active_version()) |
256 return; | 283 return; |
257 // TODO(kinuko,falken): For some error cases (e.g. ServiceWorker is | 284 // TODO(kinuko,falken): For some error cases (e.g. ServiceWorker is |
258 // unexpectedly terminated) we may want to retry sending the event again. | 285 // unexpectedly terminated) we may want to retry sending the event again. |
259 if (status != SERVICE_WORKER_OK) { | 286 if (status != SERVICE_WORKER_OK) { |
260 // "11. If activateFailed is true, then:..." | 287 // "11. If activateFailed is true, then:..." |
261 UnsetVersion(activating_version); | 288 UnsetVersion(activating_version); |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
328 if (!context_) { | 355 if (!context_) { |
329 callback.Run(SERVICE_WORKER_ERROR_ABORT); | 356 callback.Run(SERVICE_WORKER_ERROR_ABORT); |
330 return; | 357 return; |
331 } | 358 } |
332 context_->storage()->NotifyDoneInstallingRegistration( | 359 context_->storage()->NotifyDoneInstallingRegistration( |
333 this, version.get(), status); | 360 this, version.get(), status); |
334 callback.Run(status); | 361 callback.Run(status); |
335 } | 362 } |
336 | 363 |
337 } // namespace content | 364 } // namespace content |
OLD | NEW |