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
3 // found in the LICENSE file.
5 #include "content/browser/service_worker/service_worker_register_job.h"
9 #include "content/browser/service_worker/service_worker_job_coordinator.h"
10 #include "content/browser/service_worker/service_worker_registration.h"
11 #include "content/browser/service_worker/service_worker_storage.h"
15 typedef ServiceWorkerRegisterJobBase::RegistrationJobType RegistrationJobType
;
17 ServiceWorkerRegisterJob::ServiceWorkerRegisterJob(
18 ServiceWorkerStorage
* storage
,
19 EmbeddedWorkerRegistry
* worker_registry
,
20 ServiceWorkerJobCoordinator
* coordinator
,
22 const GURL
& script_url
)
24 worker_registry_(worker_registry
),
25 coordinator_(coordinator
),
27 script_url_(script_url
),
28 weak_factory_(this) {}
30 ServiceWorkerRegisterJob::~ServiceWorkerRegisterJob() {}
32 void ServiceWorkerRegisterJob::AddCallback(const RegistrationCallback
& callback
,
34 // If we've created a pending version, associate source_provider it with
35 // that, otherwise queue it up.
36 callbacks_
.push_back(callback
);
37 DCHECK_NE(-1, process_id
);
38 if (pending_version_
) {
39 pending_version_
->AddProcessToWorker(process_id
);
41 pending_process_ids_
.push_back(process_id
);
45 void ServiceWorkerRegisterJob::Start() {
46 storage_
->FindRegistrationForPattern(
49 &ServiceWorkerRegisterJob::HandleExistingRegistrationAndContinue
,
50 weak_factory_
.GetWeakPtr()));
53 bool ServiceWorkerRegisterJob::Equals(ServiceWorkerRegisterJobBase
* job
) {
54 if (job
->GetType() != GetType())
56 ServiceWorkerRegisterJob
* register_job
=
57 static_cast<ServiceWorkerRegisterJob
*>(job
);
58 return register_job
->pattern_
== pattern_
&&
59 register_job
->script_url_
== script_url_
;
62 RegistrationJobType
ServiceWorkerRegisterJob::GetType() {
66 void ServiceWorkerRegisterJob::HandleExistingRegistrationAndContinue(
67 ServiceWorkerStatusCode status
,
68 const scoped_refptr
<ServiceWorkerRegistration
>& registration
) {
69 if (status
== SERVICE_WORKER_ERROR_NOT_FOUND
) {
70 // A previous registration does not exist.
71 RegisterAndContinue(SERVICE_WORKER_OK
);
75 if (status
!= SERVICE_WORKER_OK
) {
76 // Abort this registration job.
81 if (registration
->script_url() != script_url_
) {
82 // Script URL mismatch: delete the existing registration and register a new
84 registration
->Shutdown();
85 storage_
->DeleteRegistration(
87 base::Bind(&ServiceWorkerRegisterJob::RegisterAndContinue
,
88 weak_factory_
.GetWeakPtr()));
92 // Reuse the existing registration.
93 registration_
= registration
;
94 StartWorkerAndContinue(SERVICE_WORKER_OK
);
97 void ServiceWorkerRegisterJob::RegisterAndContinue(
98 ServiceWorkerStatusCode status
) {
99 DCHECK(!registration_
);
100 if (status
!= SERVICE_WORKER_OK
) {
101 // Abort this registration job.
106 registration_
= new ServiceWorkerRegistration(
107 pattern_
, script_url_
, storage_
->NewRegistrationId());
108 storage_
->StoreRegistration(
110 base::Bind(&ServiceWorkerRegisterJob::StartWorkerAndContinue
,
111 weak_factory_
.GetWeakPtr()));
114 void ServiceWorkerRegisterJob::StartWorkerAndContinue(
115 ServiceWorkerStatusCode status
) {
116 // TODO(falken): Handle the case where status is an error code.
117 DCHECK(registration_
);
118 if (registration_
->active_version()) {
119 // We have an active version, so we can complete immediately, even
120 // if the service worker isn't running.
121 Complete(SERVICE_WORKER_OK
);
125 pending_version_
= new ServiceWorkerVersion(
126 registration_
, worker_registry_
,
127 storage_
->NewVersionId());
128 for (std::vector
<int>::const_iterator it
= pending_process_ids_
.begin();
129 it
!= pending_process_ids_
.end();
131 pending_version_
->AddProcessToWorker(*it
);
133 // The callback to watch "installation" actually fires as soon as
134 // the worker is up and running, just before the install event is
135 // dispatched. The job will continue to run even though the main
136 // callback has executed.
137 pending_version_
->StartWorker(base::Bind(&ServiceWorkerRegisterJob::Complete
,
138 weak_factory_
.GetWeakPtr()));
140 // TODO(falken): Don't set the active version until just before
141 // the activate event is dispatched.
142 pending_version_
->SetStatus(ServiceWorkerVersion::ACTIVE
);
143 registration_
->set_active_version(pending_version_
);
146 void ServiceWorkerRegisterJob::Complete(ServiceWorkerStatusCode status
) {
147 for (std::vector
<RegistrationCallback
>::iterator it
= callbacks_
.begin();
148 it
!= callbacks_
.end();
150 it
->Run(status
, registration_
);
152 coordinator_
->FinishJob(pattern_
, this);
155 } // namespace content