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_register_job.h" | 5 #include "content/browser/service_worker/service_worker_register_job.h" |
6 | 6 |
7 #include <vector> | 7 #include <vector> |
8 | 8 |
9 #include "base/message_loop/message_loop.h" | 9 #include "base/message_loop/message_loop.h" |
10 #include "content/browser/service_worker/service_worker_context_core.h" | 10 #include "content/browser/service_worker/service_worker_context_core.h" |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
169 // "If serviceWorkerRegistration is null..." create a new registration. | 169 // "If serviceWorkerRegistration is null..." create a new registration. |
170 if (!existing_registration.get()) { | 170 if (!existing_registration.get()) { |
171 RegisterAndContinue(SERVICE_WORKER_OK); | 171 RegisterAndContinue(SERVICE_WORKER_OK); |
172 return; | 172 return; |
173 } | 173 } |
174 | 174 |
175 // On script URL mismatch, "set serviceWorkerRegistration.scriptUrl to | 175 // On script URL mismatch, "set serviceWorkerRegistration.scriptUrl to |
176 // script." We accomplish this by deleting the existing registration and | 176 // script." We accomplish this by deleting the existing registration and |
177 // registering a new one. | 177 // registering a new one. |
178 // TODO(falken): Match the spec. We now throw away the active_version_ and | 178 // TODO(falken): Match the spec. We now throw away the active_version_ and |
179 // pending_version_ of the existing registration, which isn't in the spec. | 179 // waiting_version_ of the existing registration, which isn't in the spec. |
180 // TODO(michaeln): Deactivate the live existing_registration object and | 180 // TODO(michaeln): Deactivate the live existing_registration object and |
181 // eventually call storage->DeleteVersionResources() | 181 // eventually call storage->DeleteVersionResources() |
182 // when it no longer has any controllees. | 182 // when it no longer has any controllees. |
183 context_->storage()->DeleteRegistration( | 183 context_->storage()->DeleteRegistration( |
184 existing_registration->id(), | 184 existing_registration->id(), |
185 existing_registration->script_url().GetOrigin(), | 185 existing_registration->script_url().GetOrigin(), |
186 base::Bind(&ServiceWorkerRegisterJob::RegisterAndContinue, | 186 base::Bind(&ServiceWorkerRegisterJob::RegisterAndContinue, |
187 weak_factory_.GetWeakPtr())); | 187 weak_factory_.GetWeakPtr())); |
188 } | 188 } |
189 | 189 |
(...skipping 17 matching lines...) Expand all Loading... |
207 // This function corresponds to the spec's _Update algorithm. | 207 // This function corresponds to the spec's _Update algorithm. |
208 void ServiceWorkerRegisterJob::UpdateAndContinue( | 208 void ServiceWorkerRegisterJob::UpdateAndContinue( |
209 ServiceWorkerStatusCode status) { | 209 ServiceWorkerStatusCode status) { |
210 SetPhase(UPDATE); | 210 SetPhase(UPDATE); |
211 if (status != SERVICE_WORKER_OK) { | 211 if (status != SERVICE_WORKER_OK) { |
212 // Abort this registration job. | 212 // Abort this registration job. |
213 Complete(status); | 213 Complete(status); |
214 return; | 214 return; |
215 } | 215 } |
216 | 216 |
217 // TODO(falken): "If serviceWorkerRegistration.pendingWorker is not null..." | 217 // TODO(falken): "If serviceWorkerRegistration.installingWorker is not null.." |
218 // then terminate the pending worker. It doesn't make sense to implement yet | 218 // then terminate the installing worker. It doesn't make sense to implement |
219 // since we always activate the worker if install completed, so there can be | 219 // yet since we always activate the worker if install completed, so there can |
220 // no pending worker at this point. | 220 // be no installing worker at this point. |
221 DCHECK(!registration()->pending_version()); | 221 // TODO(nhiroki): Check 'installing_version()' instead when it's supported. |
| 222 DCHECK(!registration()->waiting_version()); |
222 | 223 |
223 // "Let serviceWorker be a newly-created ServiceWorker object..." and start | 224 // "Let serviceWorker be a newly-created ServiceWorker object..." and start |
224 // the worker. | 225 // the worker. |
225 set_pending_version(new ServiceWorkerVersion( | 226 set_pending_version(new ServiceWorkerVersion( |
226 registration(), context_->storage()->NewVersionId(), context_)); | 227 registration(), context_->storage()->NewVersionId(), context_)); |
227 | 228 |
228 // TODO(michaeln): Start the worker into a paused state where the | 229 // TODO(michaeln): Start the worker into a paused state where the |
229 // script resource is downloaded but not yet evaluated. | 230 // script resource is downloaded but not yet evaluated. |
230 pending_version()->StartWorkerWithCandidateProcesses( | 231 pending_version()->StartWorkerWithCandidateProcesses( |
231 pending_process_ids_, | 232 pending_process_ids_, |
(...skipping 10 matching lines...) Expand all Loading... |
242 return; | 243 return; |
243 } | 244 } |
244 | 245 |
245 // TODO(michaeln): Compare the old and new script. | 246 // TODO(michaeln): Compare the old and new script. |
246 // If different unpause the worker and continue with | 247 // If different unpause the worker and continue with |
247 // the job. If the same ResolvePromise with the current | 248 // the job. If the same ResolvePromise with the current |
248 // version and complete the job, throwing away the new version | 249 // version and complete the job, throwing away the new version |
249 // since there's nothing new. | 250 // since there's nothing new. |
250 | 251 |
251 // "Resolve promise with serviceWorker." | 252 // "Resolve promise with serviceWorker." |
252 // Although the spec doesn't set pendingWorker until after resolving the | 253 // Although the spec doesn't set waitingWorker until after resolving the |
253 // promise, our system's resolving works by passing ServiceWorkerRegistration | 254 // promise, our system's resolving works by passing ServiceWorkerRegistration |
254 // to the callbacks, so pendingWorker must be set first. | 255 // to the callbacks, so waitingWorker must be set first. |
255 DCHECK(!registration()->pending_version()); | 256 DCHECK(!registration()->waiting_version()); |
256 registration()->set_pending_version(pending_version()); | 257 registration()->set_waiting_version(pending_version()); |
257 ResolvePromise(status, registration(), pending_version()); | 258 ResolvePromise(status, registration(), pending_version()); |
258 | 259 |
259 AssociatePendingVersionToDocuments(context_, pending_version()); | 260 AssociateWaitingVersionToDocuments(context_, pending_version()); |
260 | 261 |
261 InstallAndContinue(); | 262 InstallAndContinue(); |
262 } | 263 } |
263 | 264 |
264 // This function corresponds to the spec's _Install algorithm. | 265 // This function corresponds to the spec's _Install algorithm. |
265 void ServiceWorkerRegisterJob::InstallAndContinue() { | 266 void ServiceWorkerRegisterJob::InstallAndContinue() { |
266 SetPhase(INSTALL); | 267 SetPhase(INSTALL); |
267 // "Set serviceWorkerRegistration.pendingWorker._state to installing." | 268 // "Set serviceWorkerRegistration.installingWorker._state to installing." |
268 // "Fire install event on the associated ServiceWorkerGlobalScope object." | 269 // "Fire install event on the associated ServiceWorkerGlobalScope object." |
269 pending_version()->DispatchInstallEvent( | 270 pending_version()->DispatchInstallEvent( |
270 -1, | 271 -1, |
271 base::Bind(&ServiceWorkerRegisterJob::OnInstallFinished, | 272 base::Bind(&ServiceWorkerRegisterJob::OnInstallFinished, |
272 weak_factory_.GetWeakPtr())); | 273 weak_factory_.GetWeakPtr())); |
273 } | 274 } |
274 | 275 |
275 void ServiceWorkerRegisterJob::OnInstallFinished( | 276 void ServiceWorkerRegisterJob::OnInstallFinished( |
276 ServiceWorkerStatusCode status) { | 277 ServiceWorkerStatusCode status) { |
277 // "If any handler called waitUntil()..." and the resulting promise | 278 // "If any handler called waitUntil()..." and the resulting promise |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
316 // registration already has an active version, so we shouldn't come | 317 // registration already has an active version, so we shouldn't come |
317 // this way. | 318 // this way. |
318 NOTREACHED(); | 319 NOTREACHED(); |
319 // TODO(falken): Register an continuation task to wait for NoControllees | 320 // TODO(falken): Register an continuation task to wait for NoControllees |
320 // notification so that we can resume activation later (see comments | 321 // notification so that we can resume activation later (see comments |
321 // in ServiceWorkerVersion::RemoveControllee). | 322 // in ServiceWorkerVersion::RemoveControllee). |
322 Complete(SERVICE_WORKER_OK); | 323 Complete(SERVICE_WORKER_OK); |
323 return; | 324 return; |
324 } | 325 } |
325 | 326 |
326 // "Set serviceWorkerRegistration.pendingWorker to null." | 327 // "Set serviceWorkerRegistration.waitingWorker to null." |
327 // "Set serviceWorkerRegistration.activeWorker to activatingWorker." | 328 // "Set serviceWorkerRegistration.activeWorker to activatingWorker." |
328 DisassociatePendingVersionFromDocuments( | 329 DisassociateWaitingVersionFromDocuments( |
329 context_, pending_version()->version_id()); | 330 context_, pending_version()->version_id()); |
330 registration()->set_pending_version(NULL); | 331 registration()->set_waiting_version(NULL); |
331 DCHECK(!registration()->active_version()); | 332 DCHECK(!registration()->active_version()); |
332 registration()->set_active_version(pending_version()); | 333 registration()->set_active_version(pending_version()); |
333 | 334 |
334 // "Set serviceWorkerRegistration.activeWorker._state to activating." | 335 // "Set serviceWorkerRegistration.activeWorker._state to activating." |
335 // "Fire activate event on the associated ServiceWorkerGlobalScope object." | 336 // "Fire activate event on the associated ServiceWorkerGlobalScope object." |
336 // "Set serviceWorkerRegistration.activeWorker._state to active." | 337 // "Set serviceWorkerRegistration.activeWorker._state to active." |
337 pending_version()->DispatchActivateEvent( | 338 pending_version()->DispatchActivateEvent( |
338 base::Bind(&ServiceWorkerRegisterJob::OnActivateFinished, | 339 base::Bind(&ServiceWorkerRegisterJob::OnActivateFinished, |
339 weak_factory_.GetWeakPtr())); | 340 weak_factory_.GetWeakPtr())); |
340 } | 341 } |
(...skipping 11 matching lines...) Expand all Loading... |
352 } | 353 } |
353 context_->storage()->UpdateToActiveState( | 354 context_->storage()->UpdateToActiveState( |
354 registration(), | 355 registration(), |
355 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback)); | 356 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback)); |
356 Complete(SERVICE_WORKER_OK); | 357 Complete(SERVICE_WORKER_OK); |
357 } | 358 } |
358 | 359 |
359 void ServiceWorkerRegisterJob::Complete(ServiceWorkerStatusCode status) { | 360 void ServiceWorkerRegisterJob::Complete(ServiceWorkerStatusCode status) { |
360 SetPhase(COMPLETE); | 361 SetPhase(COMPLETE); |
361 if (status != SERVICE_WORKER_OK) { | 362 if (status != SERVICE_WORKER_OK) { |
362 if (registration() && registration()->pending_version()) { | 363 if (registration() && registration()->waiting_version()) { |
363 DisassociatePendingVersionFromDocuments( | 364 DisassociateWaitingVersionFromDocuments( |
364 context_, registration()->pending_version()->version_id()); | 365 context_, registration()->waiting_version()->version_id()); |
365 registration()->set_pending_version(NULL); | 366 registration()->set_waiting_version(NULL); |
366 } | 367 } |
367 if (registration() && !registration()->active_version()) { | 368 if (registration() && !registration()->active_version()) { |
368 context_->storage()->DeleteRegistration( | 369 context_->storage()->DeleteRegistration( |
369 registration()->id(), | 370 registration()->id(), |
370 registration()->script_url().GetOrigin(), | 371 registration()->script_url().GetOrigin(), |
371 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback)); | 372 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback)); |
372 } | 373 } |
373 if (!is_promise_resolved_) | 374 if (!is_promise_resolved_) |
374 ResolvePromise(status, NULL, NULL); | 375 ResolvePromise(status, NULL, NULL); |
375 } | 376 } |
(...skipping 16 matching lines...) Expand all Loading... |
392 promise_resolved_version_ = version; | 393 promise_resolved_version_ = version; |
393 for (std::vector<RegistrationCallback>::iterator it = callbacks_.begin(); | 394 for (std::vector<RegistrationCallback>::iterator it = callbacks_.begin(); |
394 it != callbacks_.end(); | 395 it != callbacks_.end(); |
395 ++it) { | 396 ++it) { |
396 it->Run(status, registration, version); | 397 it->Run(status, registration, version); |
397 } | 398 } |
398 callbacks_.clear(); | 399 callbacks_.clear(); |
399 } | 400 } |
400 | 401 |
401 // static | 402 // static |
402 void ServiceWorkerRegisterJob::AssociatePendingVersionToDocuments( | 403 void ServiceWorkerRegisterJob::AssociateWaitingVersionToDocuments( |
403 base::WeakPtr<ServiceWorkerContextCore> context, | 404 base::WeakPtr<ServiceWorkerContextCore> context, |
404 ServiceWorkerVersion* version) { | 405 ServiceWorkerVersion* version) { |
405 DCHECK(context); | 406 DCHECK(context); |
406 DCHECK(version); | 407 DCHECK(version); |
407 | 408 |
408 // TODO(michaeln): This needs to respect the longest prefix wins | 409 // TODO(michaeln): This needs to respect the longest prefix wins |
409 // when it comes to finding a registration for a document url. | 410 // when it comes to finding a registration for a document url. |
410 // This should utilize storage->FindRegistrationForDocument(). | 411 // This should utilize storage->FindRegistrationForDocument(). |
411 for (scoped_ptr<ServiceWorkerContextCore::ProviderHostIterator> it = | 412 for (scoped_ptr<ServiceWorkerContextCore::ProviderHostIterator> it = |
412 context->GetProviderHostIterator(); | 413 context->GetProviderHostIterator(); |
413 !it->IsAtEnd(); | 414 !it->IsAtEnd(); |
414 it->Advance()) { | 415 it->Advance()) { |
415 ServiceWorkerProviderHost* host = it->GetProviderHost(); | 416 ServiceWorkerProviderHost* host = it->GetProviderHost(); |
416 if (ServiceWorkerUtils::ScopeMatches(version->scope(), | 417 if (ServiceWorkerUtils::ScopeMatches(version->scope(), |
417 host->document_url())) | 418 host->document_url())) |
418 host->SetPendingVersion(version); | 419 host->SetWaitingVersion(version); |
| 420 // TODO(nhiroki): Take care of 'installing' version when it's supported. |
419 } | 421 } |
420 } | 422 } |
421 | 423 |
422 // static | 424 // static |
423 void ServiceWorkerRegisterJob::DisassociatePendingVersionFromDocuments( | 425 void ServiceWorkerRegisterJob::DisassociateWaitingVersionFromDocuments( |
424 base::WeakPtr<ServiceWorkerContextCore> context, | 426 base::WeakPtr<ServiceWorkerContextCore> context, |
425 int64 version_id) { | 427 int64 version_id) { |
426 DCHECK(context); | 428 DCHECK(context); |
427 for (scoped_ptr<ServiceWorkerContextCore::ProviderHostIterator> it = | 429 for (scoped_ptr<ServiceWorkerContextCore::ProviderHostIterator> it = |
428 context->GetProviderHostIterator(); | 430 context->GetProviderHostIterator(); |
429 !it->IsAtEnd(); | 431 !it->IsAtEnd(); |
430 it->Advance()) { | 432 it->Advance()) { |
431 ServiceWorkerProviderHost* host = it->GetProviderHost(); | 433 ServiceWorkerProviderHost* host = it->GetProviderHost(); |
432 if (host->pending_version() && | 434 if (host->waiting_version() && |
433 host->pending_version()->version_id() == version_id) { | 435 host->waiting_version()->version_id() == version_id) { |
434 host->SetPendingVersion(NULL); | 436 host->SetWaitingVersion(NULL); |
435 } | 437 } |
436 } | 438 } |
437 } | 439 } |
438 | 440 |
439 } // namespace content | 441 } // namespace content |
OLD | NEW |