Split ServiceWorkerRegisterJob into two classes.
[chromium-blink-merge.git] / content / browser / service_worker / service_worker_register_job.cc
blob1ed32a267eb6297dc4db84c21aed382a6c296994
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"
7 #include <vector>
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"
13 namespace content {
15 typedef ServiceWorkerRegisterJobBase::RegistrationJobType RegistrationJobType;
17 ServiceWorkerRegisterJob::ServiceWorkerRegisterJob(
18 ServiceWorkerStorage* storage,
19 EmbeddedWorkerRegistry* worker_registry,
20 ServiceWorkerJobCoordinator* coordinator,
21 const GURL& pattern,
22 const GURL& script_url)
23 : storage_(storage),
24 worker_registry_(worker_registry),
25 coordinator_(coordinator),
26 pattern_(pattern),
27 script_url_(script_url),
28 weak_factory_(this) {}
30 ServiceWorkerRegisterJob::~ServiceWorkerRegisterJob() {}
32 void ServiceWorkerRegisterJob::AddCallback(const RegistrationCallback& callback,
33 int process_id) {
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);
40 } else {
41 pending_process_ids_.push_back(process_id);
45 void ServiceWorkerRegisterJob::Start() {
46 storage_->FindRegistrationForPattern(
47 pattern_,
48 base::Bind(
49 &ServiceWorkerRegisterJob::HandleExistingRegistrationAndContinue,
50 weak_factory_.GetWeakPtr()));
53 bool ServiceWorkerRegisterJob::Equals(ServiceWorkerRegisterJobBase* job) {
54 if (job->GetType() != GetType())
55 return false;
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() {
63 return REGISTER;
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);
72 return;
75 if (status != SERVICE_WORKER_OK) {
76 // Abort this registration job.
77 Complete(status);
78 return;
81 if (registration->script_url() != script_url_) {
82 // Script URL mismatch: delete the existing registration and register a new
83 // one.
84 registration->Shutdown();
85 storage_->DeleteRegistration(
86 pattern_,
87 base::Bind(&ServiceWorkerRegisterJob::RegisterAndContinue,
88 weak_factory_.GetWeakPtr()));
89 return;
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.
102 Complete(status);
103 return;
106 registration_ = new ServiceWorkerRegistration(
107 pattern_, script_url_, storage_->NewRegistrationId());
108 storage_->StoreRegistration(
109 registration_.get(),
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);
122 return;
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();
130 ++it)
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();
149 ++it) {
150 it->Run(status, registration_);
152 coordinator_->FinishJob(pattern_, this);
155 } // namespace content