Chromium Code Reviews| 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 "content/browser/service_worker/service_worker_job_coordinator.h" | 9 #include "content/browser/service_worker/service_worker_job_coordinator.h" |
| 10 #include "content/browser/service_worker/service_worker_registration.h" | 10 #include "content/browser/service_worker/service_worker_registration.h" |
| 11 #include "content/public/browser/browser_thread.h" | 11 #include "content/public/browser/browser_thread.h" |
| 12 #include "url/gurl.h" | 12 #include "url/gurl.h" |
| 13 | 13 |
| 14 namespace content { | 14 namespace content { |
| 15 | 15 |
| 16 ServiceWorkerRegisterJob::ServiceWorkerRegisterJob( | 16 ServiceWorkerRegisterJob::ServiceWorkerRegisterJob( |
| 17 ServiceWorkerStorage* storage, | 17 ServiceWorkerStorage* storage, |
| 18 EmbeddedWorkerRegistry* worker_registry, | |
| 18 ServiceWorkerJobCoordinator* coordinator, | 19 ServiceWorkerJobCoordinator* coordinator, |
| 19 const GURL& pattern, | 20 const GURL& pattern, |
| 20 const GURL& script_url, | 21 const GURL& script_url, |
| 21 RegistrationType type) | 22 RegistrationType type) |
| 22 : storage_(storage), | 23 : storage_(storage), |
| 24 worker_registry_(worker_registry), | |
| 23 coordinator_(coordinator), | 25 coordinator_(coordinator), |
| 26 pending_version_(NULL), | |
| 24 pattern_(pattern), | 27 pattern_(pattern), |
| 25 script_url_(script_url), | 28 script_url_(script_url), |
| 26 type_(type), | 29 type_(type), |
| 27 weak_factory_(this) {} | 30 weak_factory_(this) {} |
| 28 | 31 |
| 29 ServiceWorkerRegisterJob::~ServiceWorkerRegisterJob() {} | 32 ServiceWorkerRegisterJob::~ServiceWorkerRegisterJob() {} |
| 30 | 33 |
| 31 void ServiceWorkerRegisterJob::AddCallback( | 34 void ServiceWorkerRegisterJob::AddCallback(const RegistrationCallback& callback, |
| 32 const RegistrationCallback& callback) { | 35 int process_id) { |
| 36 // if we've created a pending version, associate source_provider it with | |
| 37 // that, otherwise queue it up | |
| 33 callbacks_.push_back(callback); | 38 callbacks_.push_back(callback); |
| 39 DCHECK(process_id != -1); | |
| 40 if (pending_version_) { | |
| 41 pending_version_->AddProcessToWorker(process_id); | |
| 42 } else { | |
| 43 pending_process_ids_.push_back(process_id); | |
| 44 } | |
| 34 } | 45 } |
| 35 | 46 |
| 36 void ServiceWorkerRegisterJob::Start() { | 47 void ServiceWorkerRegisterJob::Start() { |
| 37 if (type_ == REGISTER) | 48 if (type_ == REGISTER) |
| 38 StartRegister(); | 49 StartRegister(); |
| 39 else | 50 else |
| 40 StartUnregister(); | 51 StartUnregister(); |
| 41 } | 52 } |
| 42 | 53 |
| 43 bool ServiceWorkerRegisterJob::Equals(ServiceWorkerRegisterJob* job) { | 54 bool ServiceWorkerRegisterJob::Equals(ServiceWorkerRegisterJob* job) { |
| 44 return job->type_ == type_ && | 55 return job->type_ == type_ && |
| 45 (type_ == ServiceWorkerRegisterJob::UNREGISTER || | 56 (type_ == ServiceWorkerRegisterJob::UNREGISTER || |
| 46 job->script_url_ == script_url_); | 57 job->script_url_ == script_url_); |
| 47 } | 58 } |
| 48 | 59 |
| 49 void ServiceWorkerRegisterJob::StartRegister() { | 60 void ServiceWorkerRegisterJob::StartRegister() { |
| 50 // Set up a chain of callbacks, in reverse order. Each of these | 61 // Set up a chain of callbacks, in reverse order. Each of these |
| 51 // callbacks may be called asynchronously by the previous callback. | 62 // callbacks may be called asynchronously by the previous callback. |
| 52 RegistrationCallback finish_registration(base::Bind( | 63 StatusCallback finish_registration(base::Bind( |
| 53 &ServiceWorkerRegisterJob::RegisterComplete, weak_factory_.GetWeakPtr())); | 64 &ServiceWorkerRegisterJob::RegisterComplete, weak_factory_.GetWeakPtr())); |
| 54 | 65 |
| 66 RegistrationCallback start_worker( | |
| 67 base::Bind(&ServiceWorkerRegisterJob::StartWorkerAndContinue, | |
| 68 weak_factory_.GetWeakPtr(), | |
| 69 finish_registration)); | |
| 70 | |
| 55 UnregistrationCallback register_new( | 71 UnregistrationCallback register_new( |
| 56 base::Bind(&ServiceWorkerRegisterJob::RegisterPatternAndContinue, | 72 base::Bind(&ServiceWorkerRegisterJob::RegisterPatternAndContinue, |
| 57 weak_factory_.GetWeakPtr(), | 73 weak_factory_.GetWeakPtr(), |
| 58 finish_registration)); | 74 start_worker)); |
| 59 | 75 |
| 60 ServiceWorkerStorage::FindRegistrationCallback unregister_old( | 76 ServiceWorkerStorage::FindRegistrationCallback unregister_old( |
| 61 base::Bind(&ServiceWorkerRegisterJob::UnregisterPatternAndContinue, | 77 base::Bind(&ServiceWorkerRegisterJob::UnregisterPatternAndContinue, |
| 62 weak_factory_.GetWeakPtr(), | 78 weak_factory_.GetWeakPtr(), |
| 63 register_new)); | 79 register_new)); |
| 64 | 80 |
| 65 storage_->FindRegistrationForPattern(pattern_, unregister_old); | 81 storage_->FindRegistrationForPattern(pattern_, unregister_old); |
| 66 } | 82 } |
| 67 | 83 |
| 68 void ServiceWorkerRegisterJob::StartUnregister() { | 84 void ServiceWorkerRegisterJob::StartUnregister() { |
| 69 // Set up a chain of callbacks, in reverse order. Each of these | 85 // Set up a chain of callbacks, in reverse order. Each of these |
| 70 // callbacks may be called asynchronously by the previous callback. | 86 // callbacks may be called asynchronously by the previous callback. |
| 71 UnregistrationCallback finish_unregistration( | 87 UnregistrationCallback finish_unregistration( |
| 72 base::Bind(&ServiceWorkerRegisterJob::UnregisterComplete, | 88 base::Bind(&ServiceWorkerRegisterJob::UnregisterComplete, |
| 73 weak_factory_.GetWeakPtr())); | 89 weak_factory_.GetWeakPtr())); |
| 74 | 90 |
| 75 ServiceWorkerStorage::FindRegistrationCallback unregister( | 91 ServiceWorkerStorage::FindRegistrationCallback unregister( |
| 76 base::Bind(&ServiceWorkerRegisterJob::UnregisterPatternAndContinue, | 92 base::Bind(&ServiceWorkerRegisterJob::UnregisterPatternAndContinue, |
| 77 weak_factory_.GetWeakPtr(), | 93 weak_factory_.GetWeakPtr(), |
| 78 finish_unregistration)); | 94 finish_unregistration)); |
| 79 | 95 |
| 80 storage_->FindRegistrationForPattern(pattern_, unregister); | 96 storage_->FindRegistrationForPattern(pattern_, unregister); |
| 81 } | 97 } |
| 82 | 98 |
| 99 void ServiceWorkerRegisterJob::StartWorkerAndContinue( | |
| 100 const StatusCallback& callback, | |
| 101 ServiceWorkerStatusCode status, | |
| 102 const scoped_refptr<ServiceWorkerRegistration>& registration) { | |
| 103 if (registration->active_version()) { | |
| 104 // We have an active version, so we can complete immediately, even | |
| 105 // if the service worker isn't running. | |
| 106 callback.Run(registration, SERVICE_WORKER_OK); | |
| 107 return; | |
| 108 } | |
| 109 | |
| 110 pending_version_ = new ServiceWorkerVersion( | |
| 111 registration, worker_registry_, registration->next_version_id()); | |
| 112 for (std::vector<int>::const_iterator it = pending_process_ids_.begin(); | |
| 113 it != pending_process_ids_.end(); | |
| 114 ++it) | |
| 115 pending_version_->AddProcessToWorker(*it); | |
| 116 | |
| 117 // The callback to watch "installation" actually fires as soon as | |
| 118 // the worker is up and running, just before the install event is | |
| 119 // dispatched. The job will continue to run even though the main | |
| 120 // callback has executed. | |
| 121 pending_version_->StartWorker(base::Bind(callback, registration)); | |
| 122 | |
| 123 // TODO(alecflett): Don't set the active version until just before | |
| 124 // the activate event is dispatched. | |
| 125 registration->set_active_version(pending_version_); | |
| 126 } | |
| 127 | |
| 83 void ServiceWorkerRegisterJob::RegisterPatternAndContinue( | 128 void ServiceWorkerRegisterJob::RegisterPatternAndContinue( |
| 84 const RegistrationCallback& callback, | 129 const RegistrationCallback& callback, |
| 85 ServiceWorkerStatusCode previous_status) { | 130 ServiceWorkerStatusCode previous_status) { |
| 86 if (previous_status != SERVICE_WORKER_OK) { | 131 if (previous_status != SERVICE_WORKER_OK) { |
| 87 BrowserThread::PostTask( | 132 BrowserThread::PostTask( |
| 88 BrowserThread::IO, | 133 BrowserThread::IO, |
| 89 FROM_HERE, | 134 FROM_HERE, |
| 90 base::Bind(callback, | 135 base::Bind(callback, |
| 91 previous_status, | 136 previous_status, |
| 92 scoped_refptr<ServiceWorkerRegistration>())); | 137 scoped_refptr<ServiceWorkerRegistration>())); |
| 93 return; | 138 return; |
| 94 } | 139 } |
| 95 | 140 |
| 96 // TODO: Eventually RegisterInternal will be replaced by an asynchronous | 141 // TODO: Eventually RegisterInternal will be replaced by an asynchronous |
| 97 // operation. Pass its resulting status through 'callback'. | 142 // operation. Pass its resulting status through 'callback'. |
| 98 scoped_refptr<ServiceWorkerRegistration> registration = | 143 scoped_refptr<ServiceWorkerRegistration> registration = |
| 99 storage_->RegisterInternal(pattern_, script_url_); | 144 storage_->RegisterInternal(pattern_, script_url_); |
| 145 | |
| 100 BrowserThread::PostTask(BrowserThread::IO, | 146 BrowserThread::PostTask(BrowserThread::IO, |
| 101 FROM_HERE, | 147 FROM_HERE, |
| 102 base::Bind(callback, SERVICE_WORKER_OK, | 148 base::Bind(callback, SERVICE_WORKER_OK, |
| 103 registration)); | 149 registration)); |
| 104 } | 150 } |
| 105 | 151 |
| 106 void ServiceWorkerRegisterJob::UnregisterPatternAndContinue( | 152 void ServiceWorkerRegisterJob::UnregisterPatternAndContinue( |
| 107 const UnregistrationCallback& callback, | 153 const UnregistrationCallback& callback, |
| 108 bool found, | 154 bool found, |
| 109 ServiceWorkerStatusCode previous_status, | 155 ServiceWorkerStatusCode previous_status, |
| 110 const scoped_refptr<ServiceWorkerRegistration>& previous_registration) { | 156 const scoped_refptr<ServiceWorkerRegistration>& previous_registration) { |
| 111 | 157 |
| 112 // The previous registration may not exist, which is ok. | 158 // The previous registration may not exist, which is ok. |
| 113 if (previous_status == SERVICE_WORKER_OK && found && | 159 if (previous_status == SERVICE_WORKER_OK && found && |
| 114 (script_url_.is_empty() || | 160 (script_url_.is_empty() || |
| 115 previous_registration->script_url() != script_url_)) { | 161 previous_registration->script_url() != script_url_)) { |
| 116 // TODO: Eventually UnregisterInternal will be replaced by an | 162 // TODO: Eventually UnregisterInternal will be replaced by an |
| 117 // asynchronous operation. Pass its resulting status though | 163 // asynchronous operation. Pass its resulting status though |
| 118 // 'callback'. | 164 // 'callback'. |
| 119 storage_->UnregisterInternal(pattern_); | 165 storage_->UnregisterInternal(pattern_); |
| 120 DCHECK(previous_registration->is_shutdown()); | 166 DCHECK(previous_registration->is_shutdown()); |
| 167 } else { | |
| 168 // TODO(alecflett): We have an existing registration, we should | |
| 169 // schedule an update. | |
| 121 } | 170 } |
| 122 BrowserThread::PostTask( | 171 BrowserThread::PostTask( |
| 123 BrowserThread::IO, FROM_HERE, base::Bind(callback, previous_status)); | 172 BrowserThread::IO, FROM_HERE, base::Bind(callback, previous_status)); |
| 124 } | 173 } |
| 125 | 174 |
| 126 void ServiceWorkerRegisterJob::RunCallbacks( | 175 void ServiceWorkerRegisterJob::RunCallbacks( |
| 127 ServiceWorkerStatusCode status, | 176 ServiceWorkerStatusCode status, |
| 128 const scoped_refptr<ServiceWorkerRegistration>& registration) { | 177 const scoped_refptr<ServiceWorkerRegistration>& registration) { |
| 129 for (std::vector<RegistrationCallback>::iterator it = callbacks_.begin(); | 178 for (std::vector<RegistrationCallback>::iterator it = callbacks_.begin(); |
| 130 it != callbacks_.end(); | 179 it != callbacks_.end(); |
| 131 ++it) { | 180 ++it) { |
| 132 it->Run(status, registration); | 181 it->Run(status, registration); |
| 133 } | 182 } |
| 134 } | 183 } |
| 184 | |
| 135 void ServiceWorkerRegisterJob::RegisterComplete( | 185 void ServiceWorkerRegisterJob::RegisterComplete( |
| 136 ServiceWorkerStatusCode status, | 186 const scoped_refptr<ServiceWorkerRegistration>& registration, |
| 137 const scoped_refptr<ServiceWorkerRegistration>& registration) { | 187 ServiceWorkerStatusCode start_status) { |
| 138 RunCallbacks(status, registration); | 188 RunCallbacks(start_status, registration); |
|
kinuko
2014/02/07 13:59:05
Looks like we should handle error case here (e.g.
| |
| 139 coordinator_->FinishJob(pattern_, this); | 189 coordinator_->FinishJob(pattern_, this); |
| 140 } | 190 } |
| 141 | 191 |
| 142 void ServiceWorkerRegisterJob::UnregisterComplete( | 192 void ServiceWorkerRegisterJob::UnregisterComplete( |
| 143 ServiceWorkerStatusCode status) { | 193 ServiceWorkerStatusCode status) { |
| 144 RunCallbacks(status, NULL); | 194 RunCallbacks(status, NULL); |
| 145 coordinator_->FinishJob(pattern_, this); | 195 coordinator_->FinishJob(pattern_, this); |
| 146 } | 196 } |
| 147 | 197 |
| 148 } // namespace content | 198 } // namespace content |
| OLD | NEW |