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" |
11 #include "content/browser/service_worker/service_worker_job_coordinator.h" | 11 #include "content/browser/service_worker/service_worker_job_coordinator.h" |
12 #include "content/browser/service_worker/service_worker_registration.h" | 12 #include "content/browser/service_worker/service_worker_registration.h" |
13 #include "content/browser/service_worker/service_worker_storage.h" | 13 #include "content/browser/service_worker/service_worker_storage.h" |
14 #include "content/browser/service_worker/service_worker_utils.h" | 14 #include "content/browser/service_worker/service_worker_utils.h" |
15 | 15 |
16 namespace content { | 16 namespace content { |
17 | 17 |
18 namespace { | 18 namespace { |
19 | 19 |
20 void RunSoon(const base::Closure& closure) { | 20 void RunSoon(const base::Closure& closure) { |
21 base::MessageLoop::current()->PostTask(FROM_HERE, closure); | 21 base::MessageLoop::current()->PostTask(FROM_HERE, closure); |
22 } | 22 } |
23 | 23 |
24 } | 24 // Helper class for the [[Update]] algo. |
25 class DeferredActivationHelper : public ServiceWorkerVersion::Listener { | |
26 public: | |
27 explicit DeferredActivationHelper(ServiceWorkerRegistration* registration) | |
28 : registration_(registration), | |
29 active_version_(registration->active_version()), | |
30 waiting_version_(registration->waiting_version()) { | |
31 active_version_->AddListener(this); | |
32 } | |
33 | |
34 virtual ~DeferredActivationHelper() {} | |
35 | |
36 private: | |
37 virtual void OnNoControllees(ServiceWorkerVersion* version) OVERRIDE { | |
38 DCHECK_EQ(active_version_, version); | |
39 scoped_ptr<DeferredActivationHelper> self_deletor(this); | |
40 active_version_->RemoveListener(this); | |
41 if (registration_->active_version() != active_version_ || | |
42 registration_->waiting_version() != waiting_version_) { | |
43 return; // Something has changed making activation n/a. | |
44 } | |
45 registration_->ActivateWaitingVersion( | |
46 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback)); | |
47 } | |
48 | |
49 scoped_refptr<ServiceWorkerRegistration> registration_; | |
50 scoped_refptr<ServiceWorkerVersion> active_version_; | |
51 scoped_refptr<ServiceWorkerVersion> waiting_version_; | |
52 DISALLOW_COPY_AND_ASSIGN(DeferredActivationHelper); | |
53 }; | |
54 | |
55 } // namespace | |
25 | 56 |
26 typedef ServiceWorkerRegisterJobBase::RegistrationJobType RegistrationJobType; | 57 typedef ServiceWorkerRegisterJobBase::RegistrationJobType RegistrationJobType; |
27 | 58 |
28 ServiceWorkerRegisterJob::ServiceWorkerRegisterJob( | 59 ServiceWorkerRegisterJob::ServiceWorkerRegisterJob( |
29 base::WeakPtr<ServiceWorkerContextCore> context, | 60 base::WeakPtr<ServiceWorkerContextCore> context, |
30 const GURL& pattern, | 61 const GURL& pattern, |
31 const GURL& script_url) | 62 const GURL& script_url) |
32 : context_(context), | 63 : context_(context), |
64 job_type_(REGISTRATION), | |
33 pattern_(pattern), | 65 pattern_(pattern), |
34 script_url_(script_url), | 66 script_url_(script_url), |
35 phase_(INITIAL), | 67 phase_(INITIAL), |
36 is_promise_resolved_(false), | 68 is_promise_resolved_(false), |
37 promise_resolved_status_(SERVICE_WORKER_OK), | 69 promise_resolved_status_(SERVICE_WORKER_OK), |
38 weak_factory_(this) {} | 70 weak_factory_(this) {} |
39 | 71 |
72 ServiceWorkerRegisterJob::ServiceWorkerRegisterJob( | |
73 base::WeakPtr<ServiceWorkerContextCore> context, | |
74 ServiceWorkerRegistration* registration) | |
75 : context_(context), | |
76 job_type_(UPDATE_JOB), | |
77 pattern_(registration->pattern()), | |
78 script_url_(registration->script_url()), | |
79 phase_(INITIAL), | |
80 is_promise_resolved_(false), | |
81 promise_resolved_status_(SERVICE_WORKER_OK), | |
82 weak_factory_(this) { | |
83 internal_.registration = registration; | |
84 } | |
85 | |
40 ServiceWorkerRegisterJob::~ServiceWorkerRegisterJob() { | 86 ServiceWorkerRegisterJob::~ServiceWorkerRegisterJob() { |
41 DCHECK(!context_ || | 87 DCHECK(!context_ || |
42 phase_ == INITIAL || phase_ == COMPLETE || phase_ == ABORT) | 88 phase_ == INITIAL || phase_ == COMPLETE || phase_ == ABORT) |
43 << "Jobs should only be interrupted during shutdown."; | 89 << "Jobs should only be interrupted during shutdown."; |
44 } | 90 } |
45 | 91 |
46 void ServiceWorkerRegisterJob::AddCallback(const RegistrationCallback& callback, | 92 void ServiceWorkerRegisterJob::AddCallback(const RegistrationCallback& callback, |
47 int process_id) { | 93 int process_id) { |
48 if (!is_promise_resolved_) { | 94 if (!is_promise_resolved_) { |
49 callbacks_.push_back(callback); | 95 callbacks_.push_back(callback); |
50 if (process_id != -1 && (phase_ < UPDATE || !new_version())) | 96 if (process_id != -1 && (phase_ < UPDATE || !new_version())) |
51 pending_process_ids_.push_back(process_id); | 97 pending_process_ids_.push_back(process_id); |
52 return; | 98 return; |
53 } | 99 } |
54 RunSoon(base::Bind( | 100 RunSoon(base::Bind( |
55 callback, promise_resolved_status_, | 101 callback, promise_resolved_status_, |
56 promise_resolved_registration_, promise_resolved_version_)); | 102 promise_resolved_registration_, promise_resolved_version_)); |
57 } | 103 } |
58 | 104 |
59 void ServiceWorkerRegisterJob::Start() { | 105 void ServiceWorkerRegisterJob::Start() { |
60 SetPhase(START); | 106 SetPhase(START); |
107 ServiceWorkerStorage::FindRegistrationCallback next_step; | |
108 if (job_type_ == REGISTRATION) { | |
109 next_step = base::Bind( | |
110 &ServiceWorkerRegisterJob::ContinueWithRegistration, | |
111 weak_factory_.GetWeakPtr()); | |
112 } else { | |
113 next_step = base::Bind( | |
114 &ServiceWorkerRegisterJob::ContinueWithUpdate, | |
115 weak_factory_.GetWeakPtr()); | |
116 } | |
61 context_->storage()->FindRegistrationForPattern( | 117 context_->storage()->FindRegistrationForPattern( |
62 pattern_, | 118 pattern_, next_step); |
nhiroki
2014/07/15 03:57:04
nit: Maybe you can squash this line into the previ
michaeln
2014/07/16 00:32:53
Done.
| |
63 base::Bind( | |
64 &ServiceWorkerRegisterJob::HandleExistingRegistrationAndContinue, | |
65 weak_factory_.GetWeakPtr())); | |
66 } | 119 } |
67 | 120 |
68 void ServiceWorkerRegisterJob::Abort() { | 121 void ServiceWorkerRegisterJob::Abort() { |
69 SetPhase(ABORT); | 122 SetPhase(ABORT); |
70 CompleteInternal(SERVICE_WORKER_ERROR_ABORT); | 123 CompleteInternal(SERVICE_WORKER_ERROR_ABORT); |
71 // Don't have to call FinishJob() because the caller takes care of removing | 124 // Don't have to call FinishJob() because the caller takes care of removing |
72 // the jobs from the queue. | 125 // the jobs from the queue. |
73 } | 126 } |
74 | 127 |
75 bool ServiceWorkerRegisterJob::Equals(ServiceWorkerRegisterJobBase* job) { | 128 bool ServiceWorkerRegisterJob::Equals(ServiceWorkerRegisterJobBase* job) { |
76 if (job->GetType() != GetType()) | 129 if (job->GetType() != GetType()) |
77 return false; | 130 return false; |
78 ServiceWorkerRegisterJob* register_job = | 131 ServiceWorkerRegisterJob* register_job = |
79 static_cast<ServiceWorkerRegisterJob*>(job); | 132 static_cast<ServiceWorkerRegisterJob*>(job); |
80 return register_job->pattern_ == pattern_ && | 133 return register_job->pattern_ == pattern_ && |
81 register_job->script_url_ == script_url_; | 134 register_job->script_url_ == script_url_; |
82 } | 135 } |
83 | 136 |
84 RegistrationJobType ServiceWorkerRegisterJob::GetType() { | 137 RegistrationJobType ServiceWorkerRegisterJob::GetType() { |
85 return REGISTRATION; | 138 return job_type_; |
86 } | 139 } |
87 | 140 |
88 ServiceWorkerRegisterJob::Internal::Internal() {} | 141 ServiceWorkerRegisterJob::Internal::Internal() {} |
89 | 142 |
90 ServiceWorkerRegisterJob::Internal::~Internal() {} | 143 ServiceWorkerRegisterJob::Internal::~Internal() {} |
91 | 144 |
92 void ServiceWorkerRegisterJob::set_registration( | 145 void ServiceWorkerRegisterJob::set_registration( |
93 ServiceWorkerRegistration* registration) { | 146 ServiceWorkerRegistration* registration) { |
94 DCHECK(phase_ == START || phase_ == REGISTER) << phase_; | 147 DCHECK(phase_ == START || phase_ == REGISTER) << phase_; |
95 DCHECK(!internal_.registration); | 148 DCHECK(!internal_.registration); |
96 internal_.registration = registration; | 149 internal_.registration = registration; |
97 } | 150 } |
98 | 151 |
99 ServiceWorkerRegistration* ServiceWorkerRegisterJob::registration() { | 152 ServiceWorkerRegistration* ServiceWorkerRegisterJob::registration() { |
100 DCHECK(phase_ >= REGISTER) << phase_; | 153 DCHECK(phase_ >= REGISTER || job_type_ == UPDATE_JOB) << phase_; |
101 return internal_.registration; | 154 return internal_.registration; |
102 } | 155 } |
103 | 156 |
104 void ServiceWorkerRegisterJob::set_new_version( | 157 void ServiceWorkerRegisterJob::set_new_version( |
105 ServiceWorkerVersion* version) { | 158 ServiceWorkerVersion* version) { |
106 DCHECK(phase_ == UPDATE) << phase_; | 159 DCHECK(phase_ == UPDATE) << phase_; |
107 DCHECK(!internal_.new_version); | 160 DCHECK(!internal_.new_version); |
108 internal_.new_version = version; | 161 internal_.new_version = version; |
109 } | 162 } |
110 | 163 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
142 case ABORT: | 195 case ABORT: |
143 break; | 196 break; |
144 } | 197 } |
145 phase_ = phase; | 198 phase_ = phase; |
146 } | 199 } |
147 | 200 |
148 // This function corresponds to the steps in Register following | 201 // This function corresponds to the steps in Register following |
149 // "Let serviceWorkerRegistration be _GetRegistration(scope)" | 202 // "Let serviceWorkerRegistration be _GetRegistration(scope)" |
150 // |existing_registration| corresponds to serviceWorkerRegistration. | 203 // |existing_registration| corresponds to serviceWorkerRegistration. |
151 // Throughout this file, comments in quotes are excerpts from the spec. | 204 // Throughout this file, comments in quotes are excerpts from the spec. |
152 void ServiceWorkerRegisterJob::HandleExistingRegistrationAndContinue( | 205 void ServiceWorkerRegisterJob::ContinueWithRegistration( |
153 ServiceWorkerStatusCode status, | 206 ServiceWorkerStatusCode status, |
154 const scoped_refptr<ServiceWorkerRegistration>& existing_registration) { | 207 const scoped_refptr<ServiceWorkerRegistration>& existing_registration) { |
208 DCHECK_EQ(REGISTRATION, job_type_); | |
155 // On unexpected error, abort this registration job. | 209 // On unexpected error, abort this registration job. |
156 if (status != SERVICE_WORKER_ERROR_NOT_FOUND && status != SERVICE_WORKER_OK) { | 210 if (status != SERVICE_WORKER_ERROR_NOT_FOUND && status != SERVICE_WORKER_OK) { |
157 Complete(status); | 211 Complete(status); |
158 return; | 212 return; |
159 } | 213 } |
160 | 214 |
161 // "If serviceWorkerRegistration is not null and script is equal to | 215 // "If serviceWorkerRegistration is not null and script is equal to |
162 // serviceWorkerRegistration.scriptUrl..." resolve with the existing | 216 // serviceWorkerRegistration.scriptUrl..." resolve with the existing |
163 // registration and abort. | 217 // registration and abort. |
164 if (existing_registration.get() && | 218 if (existing_registration.get() && |
165 existing_registration->script_url() == script_url_) { | 219 existing_registration->script_url() == script_url_) { |
166 set_registration(existing_registration); | 220 set_registration(existing_registration); |
167 // If there's no active version, go ahead to Update (this isn't in the spec | 221 // If there's no active version, go ahead to Update (this isn't in the spec |
168 // but seems reasonable, and without SoftUpdate implemented we can never | 222 // but seems reasonable, and without SoftUpdate implemented we can never |
169 // Update otherwise). | 223 // Update otherwise). |
170 if (!existing_registration->active_version()) { | 224 if (!existing_registration->active_version()) { |
171 UpdateAndContinue(status); | 225 UpdateAndContinue(); |
172 return; | 226 return; |
173 } | 227 } |
174 ResolvePromise( | 228 ResolvePromise( |
175 status, existing_registration, existing_registration->active_version()); | 229 status, existing_registration, existing_registration->active_version()); |
176 Complete(SERVICE_WORKER_OK); | 230 Complete(SERVICE_WORKER_OK); |
177 return; | 231 return; |
178 } | 232 } |
179 | 233 |
180 // "If serviceWorkerRegistration is null..." create a new registration. | 234 // "If serviceWorkerRegistration is null..." create a new registration. |
181 if (!existing_registration.get()) { | 235 if (!existing_registration.get()) { |
182 RegisterAndContinue(SERVICE_WORKER_OK); | 236 RegisterAndContinue(SERVICE_WORKER_OK); |
183 return; | 237 return; |
184 } | 238 } |
185 | 239 |
186 // On script URL mismatch, "set serviceWorkerRegistration.scriptUrl to | 240 // On script URL mismatch, "set serviceWorkerRegistration.scriptUrl to |
187 // script." We accomplish this by deleting the existing registration and | 241 // script." We accomplish this by deleting the existing registration and |
188 // registering a new one. | 242 // registering a new one. |
189 // TODO(falken): Match the spec. We now throw away the active_version_ and | 243 // TODO(falken): Match the spec. We now throw away the active_version_ and |
190 // waiting_version_ of the existing registration, which isn't in the spec. | 244 // waiting_version_ of the existing registration, which isn't in the spec. |
191 // TODO(michaeln): Deactivate the live existing_registration object and | 245 // TODO(michaeln): Deactivate the live existing_registration object and |
192 // eventually call storage->DeleteVersionResources() | 246 // eventually call storage->DeleteVersionResources() |
193 // when it no longer has any controllees. | 247 // when it no longer has any controllees. |
194 context_->storage()->DeleteRegistration( | 248 context_->storage()->DeleteRegistration( |
195 existing_registration->id(), | 249 existing_registration->id(), |
196 existing_registration->script_url().GetOrigin(), | 250 existing_registration->script_url().GetOrigin(), |
197 base::Bind(&ServiceWorkerRegisterJob::RegisterAndContinue, | 251 base::Bind(&ServiceWorkerRegisterJob::RegisterAndContinue, |
198 weak_factory_.GetWeakPtr())); | 252 weak_factory_.GetWeakPtr())); |
199 } | 253 } |
200 | 254 |
255 void ServiceWorkerRegisterJob::ContinueWithUpdate( | |
256 ServiceWorkerStatusCode status, | |
257 const scoped_refptr<ServiceWorkerRegistration>& existing_registration) { | |
258 DCHECK_EQ(UPDATE_JOB, job_type_); | |
259 if (status != SERVICE_WORKER_OK) { | |
260 Complete(status); | |
261 return; | |
262 } | |
263 | |
264 if (existing_registration != registration()) { | |
265 Complete(SERVICE_WORKER_ERROR_NOT_FOUND); | |
266 return; | |
267 } | |
268 | |
269 UpdateAndContinue(); | |
270 } | |
271 | |
201 // Creates a new ServiceWorkerRegistration. | 272 // Creates a new ServiceWorkerRegistration. |
202 void ServiceWorkerRegisterJob::RegisterAndContinue( | 273 void ServiceWorkerRegisterJob::RegisterAndContinue( |
203 ServiceWorkerStatusCode status) { | 274 ServiceWorkerStatusCode status) { |
204 SetPhase(REGISTER); | 275 SetPhase(REGISTER); |
205 if (status != SERVICE_WORKER_OK) { | 276 if (status != SERVICE_WORKER_OK) { |
206 // Abort this registration job. | 277 // Abort this registration job. |
207 Complete(status); | 278 Complete(status); |
208 return; | 279 return; |
209 } | 280 } |
210 | 281 |
211 set_registration(new ServiceWorkerRegistration( | 282 set_registration(new ServiceWorkerRegistration( |
212 pattern_, script_url_, context_->storage()->NewRegistrationId(), | 283 pattern_, script_url_, context_->storage()->NewRegistrationId(), |
213 context_)); | 284 context_)); |
214 context_->storage()->NotifyInstallingRegistration(registration()); | 285 UpdateAndContinue(); |
215 UpdateAndContinue(SERVICE_WORKER_OK); | |
216 } | 286 } |
217 | 287 |
218 // This function corresponds to the spec's _Update algorithm. | 288 // This function corresponds to the spec's _Update algorithm. |
219 void ServiceWorkerRegisterJob::UpdateAndContinue( | 289 void ServiceWorkerRegisterJob::UpdateAndContinue() { |
220 ServiceWorkerStatusCode status) { | |
221 SetPhase(UPDATE); | 290 SetPhase(UPDATE); |
222 if (status != SERVICE_WORKER_OK) { | 291 context_->storage()->NotifyInstallingRegistration(registration()); |
223 // Abort this registration job. | |
224 Complete(status); | |
225 return; | |
226 } | |
227 | 292 |
228 // TODO(falken): "If serviceWorkerRegistration.installingWorker is not null.." | 293 // TODO(falken): "If serviceWorkerRegistration.installingWorker is not null.." |
229 // then terminate the installing worker. It doesn't make sense to implement | 294 // then terminate the installing worker. It doesn't make sense to implement |
230 // yet since we always activate the worker if install completed, so there can | 295 // yet since we always activate the worker if install completed, so there can |
231 // be no installing worker at this point. | 296 // be no installing worker at this point. |
232 | 297 |
233 // "Let serviceWorker be a newly-created ServiceWorker object..." and start | 298 // "Let serviceWorker be a newly-created ServiceWorker object..." and start |
234 // the worker. | 299 // the worker. |
235 set_new_version(new ServiceWorkerVersion( | 300 set_new_version(new ServiceWorkerVersion( |
236 registration(), context_->storage()->NewVersionId(), context_)); | 301 registration(), context_->storage()->NewVersionId(), context_)); |
237 | 302 |
238 // TODO(michaeln): Pause after downloading when performing an update. | 303 bool pause_after_download = job_type_ == UPDATE_JOB; |
239 bool pause_after_download = false; | |
240 if (pause_after_download) | 304 if (pause_after_download) |
241 new_version()->embedded_worker()->AddListener(this); | 305 new_version()->embedded_worker()->AddListener(this); |
242 new_version()->StartWorkerWithCandidateProcesses( | 306 new_version()->StartWorkerWithCandidateProcesses( |
243 pending_process_ids_, | 307 pending_process_ids_, |
244 pause_after_download, | 308 pause_after_download, |
245 base::Bind(&ServiceWorkerRegisterJob::OnStartWorkerFinished, | 309 base::Bind(&ServiceWorkerRegisterJob::OnStartWorkerFinished, |
246 weak_factory_.GetWeakPtr())); | 310 weak_factory_.GetWeakPtr())); |
247 } | 311 } |
248 | 312 |
249 void ServiceWorkerRegisterJob::OnStartWorkerFinished( | 313 void ServiceWorkerRegisterJob::OnStartWorkerFinished( |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
300 weak_factory_.GetWeakPtr())); | 364 weak_factory_.GetWeakPtr())); |
301 } | 365 } |
302 | 366 |
303 void ServiceWorkerRegisterJob::OnStoreRegistrationComplete( | 367 void ServiceWorkerRegisterJob::OnStoreRegistrationComplete( |
304 ServiceWorkerStatusCode status) { | 368 ServiceWorkerStatusCode status) { |
305 if (status != SERVICE_WORKER_OK) { | 369 if (status != SERVICE_WORKER_OK) { |
306 Complete(status); | 370 Complete(status); |
307 return; | 371 return; |
308 } | 372 } |
309 | 373 |
310 // TODO(nhiroki): "9. If registration.waitingWorker is not null, then:..." | 374 // "9. If registration.waitingWorker is not null, then:..." |
375 if (registration()->waiting_version()) { | |
376 // "1. Run the [[UpdateState]] algorithm passing registration.waitingWorker | |
377 // and "redundant" as the arguments." | |
378 registration()->waiting_version()->SetStatus( | |
379 ServiceWorkerVersion::REDUNDANT); | |
380 } | |
311 | 381 |
312 // "10. Set registration.waitingWorker to registration.installingWorker." | 382 // "10. Set registration.waitingWorker to registration.installingWorker." |
313 // "11. Set registration.installingWorker to null." | 383 // "11. Set registration.installingWorker to null." |
314 DisassociateVersionFromDocuments(context_, new_version()); | 384 DisassociateVersionFromDocuments(context_, new_version()); |
315 registration()->SetWaitingVersion(new_version()); | 385 registration()->SetWaitingVersion(new_version()); |
316 AssociateWaitingVersionToDocuments(context_, new_version()); | 386 AssociateWaitingVersionToDocuments(context_, new_version()); |
317 | 387 |
318 // "12. Run the [[UpdateState]] algorithm passing registration.waitingWorker | 388 // "12. Run the [[UpdateState]] algorithm passing registration.waitingWorker |
319 // and "installed" as the arguments." | 389 // and "installed" as the arguments." |
320 new_version()->SetStatus(ServiceWorkerVersion::INSTALLED); | 390 new_version()->SetStatus(ServiceWorkerVersion::INSTALLED); |
321 ActivateAndContinue(); | |
322 } | |
323 | 391 |
324 // This function corresponds to the spec's _Activate algorithm. | 392 // TODO(michaeln): "13. If activateImmediate is true, then..." |
325 void ServiceWorkerRegisterJob::ActivateAndContinue() { | |
326 SetPhase(ACTIVATE); | |
327 | 393 |
328 // "4. If existingWorker is not null, then: wait for exitingWorker to finish | 394 // "14. Wait until no document is using registration as their |
329 // handling any in-progress requests." | 395 // Service Worker registration." |
330 // See if we already have an active_version for the scope and it has | |
331 // controllee documents (if so activating the new version should wait | |
332 // until we have no documents controlled by the version). | |
333 if (registration()->active_version() && | 396 if (registration()->active_version() && |
334 registration()->active_version()->HasControllee()) { | 397 registration()->active_version()->HasControllee()) { |
335 // TODO(kinuko,falken): Currently we immediately return if the existing | 398 scoped_ptr<DeferredActivationHelper> deferred_activation( |
336 // registration already has an active version, so we shouldn't come | 399 new DeferredActivationHelper(registration())); |
337 // this way. | 400 // It will delete itself when done. |
338 NOTREACHED(); | 401 ignore_result(deferred_activation.release()); |
339 // TODO(falken): Register an continuation task to wait for NoControllees | |
340 // notification so that we can resume activation later. | |
341 Complete(SERVICE_WORKER_OK); | 402 Complete(SERVICE_WORKER_OK); |
342 return; | 403 return; |
343 } | 404 } |
344 | 405 |
345 // "5. Set serviceWorkerRegistration.activeWorker to activatingWorker." | 406 SetPhase(ACTIVATE); |
346 // "6. Set serviceWorkerRegistration.waitingWorker to null." | 407 registration()->ActivateWaitingVersion( |
347 DisassociateVersionFromDocuments(context_, new_version()); | 408 base::Bind(&ServiceWorkerRegisterJob::Complete, |
348 registration()->SetActiveVersion(new_version()); | |
349 AssociateActiveVersionToDocuments(context_, new_version()); | |
350 | |
351 // "7. Run the [[UpdateState]] algorithm passing registration.activeWorker and | |
352 // "activating" as arguments." | |
353 new_version()->SetStatus(ServiceWorkerVersion::ACTIVATING); | |
354 | |
355 // TODO(nhiroki): "8. Fire a simple event named controllerchange..." | |
356 | |
357 // "9. Fire an event named activate..." | |
358 new_version()->DispatchActivateEvent( | |
359 base::Bind(&ServiceWorkerRegisterJob::OnActivateFinished, | |
360 weak_factory_.GetWeakPtr())); | 409 weak_factory_.GetWeakPtr())); |
361 } | 410 } |
362 | 411 |
363 void ServiceWorkerRegisterJob::OnActivateFinished( | |
364 ServiceWorkerStatusCode status) { | |
365 // TODO(kinuko,falken): For some error cases (e.g. ServiceWorker is | |
366 // unexpectedly terminated) we may want to retry sending the event again. | |
367 if (status != SERVICE_WORKER_OK) { | |
368 // "11. If activateFailed is true, then:..." | |
369 Complete(status); | |
370 return; | |
371 } | |
372 | |
373 // "12. Run the [[UpdateState]] algorithm passing registration.activeWorker | |
374 // and "activated" as the arguments." | |
375 new_version()->SetStatus(ServiceWorkerVersion::ACTIVATED); | |
376 context_->storage()->UpdateToActiveState( | |
377 registration(), | |
378 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback)); | |
379 Complete(SERVICE_WORKER_OK); | |
380 } | |
381 | |
382 void ServiceWorkerRegisterJob::Complete(ServiceWorkerStatusCode status) { | 412 void ServiceWorkerRegisterJob::Complete(ServiceWorkerStatusCode status) { |
383 CompleteInternal(status); | 413 CompleteInternal(status); |
384 context_->job_coordinator()->FinishJob(pattern_, this); | 414 context_->job_coordinator()->FinishJob(pattern_, this); |
385 } | 415 } |
386 | 416 |
387 void ServiceWorkerRegisterJob::CompleteInternal( | 417 void ServiceWorkerRegisterJob::CompleteInternal( |
388 ServiceWorkerStatusCode status) { | 418 ServiceWorkerStatusCode status) { |
389 SetPhase(COMPLETE); | 419 SetPhase(COMPLETE); |
390 if (status != SERVICE_WORKER_OK) { | 420 if (status != SERVICE_WORKER_OK) { |
391 if (registration()) { | 421 if (registration()) { |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
424 promise_resolved_version_ = version; | 454 promise_resolved_version_ = version; |
425 for (std::vector<RegistrationCallback>::iterator it = callbacks_.begin(); | 455 for (std::vector<RegistrationCallback>::iterator it = callbacks_.begin(); |
426 it != callbacks_.end(); | 456 it != callbacks_.end(); |
427 ++it) { | 457 ++it) { |
428 it->Run(status, registration, version); | 458 it->Run(status, registration, version); |
429 } | 459 } |
430 callbacks_.clear(); | 460 callbacks_.clear(); |
431 } | 461 } |
432 | 462 |
433 void ServiceWorkerRegisterJob::OnPausedAfterDownload() { | 463 void ServiceWorkerRegisterJob::OnPausedAfterDownload() { |
434 // TODO(michaeln): Compare the old and new script. | 464 // This happens prior to OnStartWorkerFinished time. |
435 // If different unpause the worker and continue with | 465 scoped_refptr<ServiceWorkerVersion> current_version = |
436 // the job. If the same ResolvePromise with the current | 466 registration()->active_version(); |
437 // version and complete the job, throwing away the new version | 467 DCHECK(current_version); |
438 // since there's nothing new. | 468 int64 current_script_id = |
439 new_version()->embedded_worker()->RemoveListener(this); | 469 current_version->script_cache_map()->Lookup(script_url_); |
440 new_version()->embedded_worker()->ResumeAfterDownload(); | 470 int64 new_script_id = |
471 new_version()->script_cache_map()->Lookup(script_url_); | |
472 | |
473 // TODO(michaeln): It would be better to compare as the new resource | |
474 // is being downloaded and to avoid writing it to disk until we know | |
475 // its needed. | |
476 context_->storage()->CompareScriptResources( | |
477 current_script_id, new_script_id, | |
478 base::Bind(&ServiceWorkerRegisterJob::OnCompareScriptResourcesComplete, | |
479 weak_factory_.GetWeakPtr(), | |
480 current_version)); | |
441 } | 481 } |
442 | 482 |
443 bool ServiceWorkerRegisterJob::OnMessageReceived(const IPC::Message& message) { | 483 bool ServiceWorkerRegisterJob::OnMessageReceived(const IPC::Message& message) { |
444 return false; | 484 return false; |
445 } | 485 } |
446 | 486 |
487 void ServiceWorkerRegisterJob::OnCompareScriptResourcesComplete( | |
488 ServiceWorkerVersion* current_version, | |
489 ServiceWorkerStatusCode status, | |
490 int compare_result) { | |
491 if (compare_result == 0) { | |
492 new_version()->embedded_worker()->Stop(); | |
493 ResolvePromise( | |
494 SERVICE_WORKER_OK, registration(), current_version); | |
495 Complete(SERVICE_WORKER_ERROR_EXISTS); | |
496 return; | |
497 } | |
498 | |
499 // Proceed with really starting the worker. | |
500 new_version()->embedded_worker()->ResumeAfterDownload(); | |
501 new_version()->embedded_worker()->RemoveListener(this); | |
502 } | |
503 | |
447 // static | 504 // static |
448 void ServiceWorkerRegisterJob::AssociateInstallingVersionToDocuments( | 505 void ServiceWorkerRegisterJob::AssociateInstallingVersionToDocuments( |
449 base::WeakPtr<ServiceWorkerContextCore> context, | 506 base::WeakPtr<ServiceWorkerContextCore> context, |
450 ServiceWorkerVersion* version) { | 507 ServiceWorkerVersion* version) { |
451 DCHECK(context); | 508 DCHECK(context); |
452 DCHECK(version); | 509 DCHECK(version); |
453 | 510 |
454 for (scoped_ptr<ServiceWorkerContextCore::ProviderHostIterator> it = | 511 for (scoped_ptr<ServiceWorkerContextCore::ProviderHostIterator> it = |
455 context->GetProviderHostIterator(); | 512 context->GetProviderHostIterator(); |
456 !it->IsAtEnd(); it->Advance()) { | 513 !it->IsAtEnd(); it->Advance()) { |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
511 DCHECK(context); | 568 DCHECK(context); |
512 for (scoped_ptr<ServiceWorkerContextCore::ProviderHostIterator> it = | 569 for (scoped_ptr<ServiceWorkerContextCore::ProviderHostIterator> it = |
513 context->GetProviderHostIterator(); | 570 context->GetProviderHostIterator(); |
514 !it->IsAtEnd(); it->Advance()) { | 571 !it->IsAtEnd(); it->Advance()) { |
515 ServiceWorkerProviderHost* host = it->GetProviderHost(); | 572 ServiceWorkerProviderHost* host = it->GetProviderHost(); |
516 host->UnsetVersion(version); | 573 host->UnsetVersion(version); |
517 } | 574 } |
518 } | 575 } |
519 | 576 |
520 } // namespace content | 577 } // namespace content |
OLD | NEW |