Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1083)

Side by Side Diff: content/browser/service_worker/service_worker_register_job.cc

Issue 380093002: Update installed ServiceWorkers. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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_JOB),
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);
61 context_->storage()->FindRegistrationForPattern( 107 ServiceWorkerStorage::FindRegistrationCallback next_step;
62 pattern_, 108 if (job_type_ == REGISTRATION_JOB) {
63 base::Bind( 109 next_step = base::Bind(
64 &ServiceWorkerRegisterJob::HandleExistingRegistrationAndContinue, 110 &ServiceWorkerRegisterJob::ContinueWithRegistration,
65 weak_factory_.GetWeakPtr())); 111 weak_factory_.GetWeakPtr());
112 } else {
113 next_step = base::Bind(
114 &ServiceWorkerRegisterJob::ContinueWithUpdate,
115 weak_factory_.GetWeakPtr());
116 }
117 context_->storage()->FindRegistrationForPattern(pattern_, next_step);
66 } 118 }
67 119
68 void ServiceWorkerRegisterJob::Abort() { 120 void ServiceWorkerRegisterJob::Abort() {
69 SetPhase(ABORT); 121 SetPhase(ABORT);
70 CompleteInternal(SERVICE_WORKER_ERROR_ABORT); 122 CompleteInternal(SERVICE_WORKER_ERROR_ABORT);
71 // Don't have to call FinishJob() because the caller takes care of removing 123 // Don't have to call FinishJob() because the caller takes care of removing
72 // the jobs from the queue. 124 // the jobs from the queue.
73 } 125 }
74 126
75 bool ServiceWorkerRegisterJob::Equals(ServiceWorkerRegisterJobBase* job) { 127 bool ServiceWorkerRegisterJob::Equals(ServiceWorkerRegisterJobBase* job) {
76 if (job->GetType() != GetType()) 128 if (job->GetType() != GetType())
77 return false; 129 return false;
78 ServiceWorkerRegisterJob* register_job = 130 ServiceWorkerRegisterJob* register_job =
79 static_cast<ServiceWorkerRegisterJob*>(job); 131 static_cast<ServiceWorkerRegisterJob*>(job);
80 return register_job->pattern_ == pattern_ && 132 return register_job->pattern_ == pattern_ &&
81 register_job->script_url_ == script_url_; 133 register_job->script_url_ == script_url_;
82 } 134 }
83 135
84 RegistrationJobType ServiceWorkerRegisterJob::GetType() { 136 RegistrationJobType ServiceWorkerRegisterJob::GetType() {
85 return REGISTRATION; 137 return job_type_;
86 } 138 }
87 139
88 ServiceWorkerRegisterJob::Internal::Internal() {} 140 ServiceWorkerRegisterJob::Internal::Internal() {}
89 141
90 ServiceWorkerRegisterJob::Internal::~Internal() {} 142 ServiceWorkerRegisterJob::Internal::~Internal() {}
91 143
92 void ServiceWorkerRegisterJob::set_registration( 144 void ServiceWorkerRegisterJob::set_registration(
93 ServiceWorkerRegistration* registration) { 145 ServiceWorkerRegistration* registration) {
94 DCHECK(phase_ == START || phase_ == REGISTER) << phase_; 146 DCHECK(phase_ == START || phase_ == REGISTER) << phase_;
95 DCHECK(!internal_.registration); 147 DCHECK(!internal_.registration);
96 internal_.registration = registration; 148 internal_.registration = registration;
97 } 149 }
98 150
99 ServiceWorkerRegistration* ServiceWorkerRegisterJob::registration() { 151 ServiceWorkerRegistration* ServiceWorkerRegisterJob::registration() {
100 DCHECK(phase_ >= REGISTER) << phase_; 152 DCHECK(phase_ >= REGISTER || job_type_ == UPDATE_JOB) << phase_;
101 return internal_.registration; 153 return internal_.registration;
102 } 154 }
103 155
104 void ServiceWorkerRegisterJob::set_new_version( 156 void ServiceWorkerRegisterJob::set_new_version(
105 ServiceWorkerVersion* version) { 157 ServiceWorkerVersion* version) {
106 DCHECK(phase_ == UPDATE) << phase_; 158 DCHECK(phase_ == UPDATE) << phase_;
107 DCHECK(!internal_.new_version); 159 DCHECK(!internal_.new_version);
108 internal_.new_version = version; 160 internal_.new_version = version;
109 } 161 }
110 162
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
142 case ABORT: 194 case ABORT:
143 break; 195 break;
144 } 196 }
145 phase_ = phase; 197 phase_ = phase;
146 } 198 }
147 199
148 // This function corresponds to the steps in Register following 200 // This function corresponds to the steps in Register following
149 // "Let serviceWorkerRegistration be _GetRegistration(scope)" 201 // "Let serviceWorkerRegistration be _GetRegistration(scope)"
150 // |existing_registration| corresponds to serviceWorkerRegistration. 202 // |existing_registration| corresponds to serviceWorkerRegistration.
151 // Throughout this file, comments in quotes are excerpts from the spec. 203 // Throughout this file, comments in quotes are excerpts from the spec.
152 void ServiceWorkerRegisterJob::HandleExistingRegistrationAndContinue( 204 void ServiceWorkerRegisterJob::ContinueWithRegistration(
153 ServiceWorkerStatusCode status, 205 ServiceWorkerStatusCode status,
154 const scoped_refptr<ServiceWorkerRegistration>& existing_registration) { 206 const scoped_refptr<ServiceWorkerRegistration>& existing_registration) {
207 DCHECK_EQ(REGISTRATION_JOB, job_type_);
155 // On unexpected error, abort this registration job. 208 // On unexpected error, abort this registration job.
156 if (status != SERVICE_WORKER_ERROR_NOT_FOUND && status != SERVICE_WORKER_OK) { 209 if (status != SERVICE_WORKER_ERROR_NOT_FOUND && status != SERVICE_WORKER_OK) {
157 Complete(status); 210 Complete(status);
158 return; 211 return;
159 } 212 }
160 213
161 // "If serviceWorkerRegistration is not null and script is equal to 214 // "If serviceWorkerRegistration is not null and script is equal to
162 // serviceWorkerRegistration.scriptUrl..." resolve with the existing 215 // serviceWorkerRegistration.scriptUrl..." resolve with the existing
163 // registration and abort. 216 // registration and abort.
164 if (existing_registration.get() && 217 if (existing_registration.get() &&
165 existing_registration->script_url() == script_url_) { 218 existing_registration->script_url() == script_url_) {
166 set_registration(existing_registration); 219 set_registration(existing_registration);
167 // If there's no active version, go ahead to Update (this isn't in the spec 220 // 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 221 // but seems reasonable, and without SoftUpdate implemented we can never
169 // Update otherwise). 222 // Update otherwise).
170 if (!existing_registration->active_version()) { 223 if (!existing_registration->active_version()) {
171 UpdateAndContinue(status); 224 UpdateAndContinue();
172 return; 225 return;
173 } 226 }
174 ResolvePromise( 227 ResolvePromise(
175 status, existing_registration, existing_registration->active_version()); 228 status, existing_registration, existing_registration->active_version());
176 Complete(SERVICE_WORKER_OK); 229 Complete(SERVICE_WORKER_OK);
177 return; 230 return;
178 } 231 }
179 232
180 // "If serviceWorkerRegistration is null..." create a new registration. 233 // "If serviceWorkerRegistration is null..." create a new registration.
181 if (!existing_registration.get()) { 234 if (!existing_registration.get()) {
182 RegisterAndContinue(SERVICE_WORKER_OK); 235 RegisterAndContinue(SERVICE_WORKER_OK);
183 return; 236 return;
184 } 237 }
185 238
186 // On script URL mismatch, "set serviceWorkerRegistration.scriptUrl to 239 // On script URL mismatch, "set serviceWorkerRegistration.scriptUrl to
187 // script." We accomplish this by deleting the existing registration and 240 // script." We accomplish this by deleting the existing registration and
188 // registering a new one. 241 // registering a new one.
189 // TODO(falken): Match the spec. We now throw away the active_version_ and 242 // 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. 243 // waiting_version_ of the existing registration, which isn't in the spec.
191 // TODO(michaeln): Deactivate the live existing_registration object and 244 // TODO(michaeln): Deactivate the live existing_registration object and
192 // eventually call storage->DeleteVersionResources() 245 // eventually call storage->DeleteVersionResources()
193 // when it no longer has any controllees. 246 // when it no longer has any controllees.
194 context_->storage()->DeleteRegistration( 247 context_->storage()->DeleteRegistration(
195 existing_registration->id(), 248 existing_registration->id(),
196 existing_registration->script_url().GetOrigin(), 249 existing_registration->script_url().GetOrigin(),
197 base::Bind(&ServiceWorkerRegisterJob::RegisterAndContinue, 250 base::Bind(&ServiceWorkerRegisterJob::RegisterAndContinue,
198 weak_factory_.GetWeakPtr())); 251 weak_factory_.GetWeakPtr()));
199 } 252 }
200 253
254 void ServiceWorkerRegisterJob::ContinueWithUpdate(
255 ServiceWorkerStatusCode status,
256 const scoped_refptr<ServiceWorkerRegistration>& existing_registration) {
257 DCHECK_EQ(UPDATE_JOB, job_type_);
258 if (status != SERVICE_WORKER_OK) {
259 Complete(status);
260 return;
261 }
262
263 if (existing_registration != registration()) {
264 Complete(SERVICE_WORKER_ERROR_NOT_FOUND);
265 return;
266 }
267
268 UpdateAndContinue();
269 }
270
201 // Creates a new ServiceWorkerRegistration. 271 // Creates a new ServiceWorkerRegistration.
202 void ServiceWorkerRegisterJob::RegisterAndContinue( 272 void ServiceWorkerRegisterJob::RegisterAndContinue(
203 ServiceWorkerStatusCode status) { 273 ServiceWorkerStatusCode status) {
204 SetPhase(REGISTER); 274 SetPhase(REGISTER);
205 if (status != SERVICE_WORKER_OK) { 275 if (status != SERVICE_WORKER_OK) {
206 // Abort this registration job. 276 // Abort this registration job.
207 Complete(status); 277 Complete(status);
208 return; 278 return;
209 } 279 }
210 280
211 set_registration(new ServiceWorkerRegistration( 281 set_registration(new ServiceWorkerRegistration(
212 pattern_, script_url_, context_->storage()->NewRegistrationId(), 282 pattern_, script_url_, context_->storage()->NewRegistrationId(),
213 context_)); 283 context_));
214 context_->storage()->NotifyInstallingRegistration(registration()); 284 UpdateAndContinue();
215 UpdateAndContinue(SERVICE_WORKER_OK);
216 } 285 }
217 286
218 // This function corresponds to the spec's _Update algorithm. 287 // This function corresponds to the spec's [[Update]] algorithm.
219 void ServiceWorkerRegisterJob::UpdateAndContinue( 288 void ServiceWorkerRegisterJob::UpdateAndContinue() {
220 ServiceWorkerStatusCode status) {
221 SetPhase(UPDATE); 289 SetPhase(UPDATE);
222 if (status != SERVICE_WORKER_OK) { 290 context_->storage()->NotifyInstallingRegistration(registration());
223 // Abort this registration job.
224 Complete(status);
225 return;
226 }
227 291
228 // TODO(falken): "If serviceWorkerRegistration.installingWorker is not null.." 292 // TODO(falken): "If serviceWorkerRegistration.installingWorker is not null.."
229 // then terminate the installing worker. It doesn't make sense to implement 293 // 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 294 // yet since we always activate the worker if install completed, so there can
231 // be no installing worker at this point. 295 // be no installing worker at this point.
232 296
233 // "Let serviceWorker be a newly-created ServiceWorker object..." and start 297 // "Let serviceWorker be a newly-created ServiceWorker object..." and start
234 // the worker. 298 // the worker.
235 set_new_version(new ServiceWorkerVersion( 299 set_new_version(new ServiceWorkerVersion(
236 registration(), context_->storage()->NewVersionId(), context_)); 300 registration(), context_->storage()->NewVersionId(), context_));
237 301
238 // TODO(michaeln): Pause after downloading when performing an update. 302 bool pause_after_download = job_type_ == UPDATE_JOB;
239 bool pause_after_download = false;
240 if (pause_after_download) 303 if (pause_after_download)
241 new_version()->embedded_worker()->AddListener(this); 304 new_version()->embedded_worker()->AddListener(this);
242 new_version()->StartWorkerWithCandidateProcesses( 305 new_version()->StartWorkerWithCandidateProcesses(
243 pending_process_ids_, 306 pending_process_ids_,
244 pause_after_download, 307 pause_after_download,
245 base::Bind(&ServiceWorkerRegisterJob::OnStartWorkerFinished, 308 base::Bind(&ServiceWorkerRegisterJob::OnStartWorkerFinished,
246 weak_factory_.GetWeakPtr())); 309 weak_factory_.GetWeakPtr()));
247 } 310 }
248 311
249 void ServiceWorkerRegisterJob::OnStartWorkerFinished( 312 void ServiceWorkerRegisterJob::OnStartWorkerFinished(
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
300 weak_factory_.GetWeakPtr())); 363 weak_factory_.GetWeakPtr()));
301 } 364 }
302 365
303 void ServiceWorkerRegisterJob::OnStoreRegistrationComplete( 366 void ServiceWorkerRegisterJob::OnStoreRegistrationComplete(
304 ServiceWorkerStatusCode status) { 367 ServiceWorkerStatusCode status) {
305 if (status != SERVICE_WORKER_OK) { 368 if (status != SERVICE_WORKER_OK) {
306 Complete(status); 369 Complete(status);
307 return; 370 return;
308 } 371 }
309 372
310 // TODO(nhiroki): "9. If registration.waitingWorker is not null, then:..." 373 // "9. If registration.waitingWorker is not null, then:..."
374 if (registration()->waiting_version()) {
375 // "1. Run the [[UpdateState]] algorithm passing registration.waitingWorker
376 // and "redundant" as the arguments."
377 registration()->waiting_version()->SetStatus(
378 ServiceWorkerVersion::REDUNDANT);
379 }
311 380
312 // "10. Set registration.waitingWorker to registration.installingWorker." 381 // "10. Set registration.waitingWorker to registration.installingWorker."
313 // "11. Set registration.installingWorker to null." 382 // "11. Set registration.installingWorker to null."
314 DisassociateVersionFromDocuments(context_, new_version()); 383 DisassociateVersionFromDocuments(context_, new_version());
315 registration()->SetWaitingVersion(new_version()); 384 registration()->SetWaitingVersion(new_version());
316 AssociateWaitingVersionToDocuments(context_, new_version()); 385 AssociateWaitingVersionToDocuments(context_, new_version());
317 386
318 // "12. Run the [[UpdateState]] algorithm passing registration.waitingWorker 387 // "12. Run the [[UpdateState]] algorithm passing registration.waitingWorker
319 // and "installed" as the arguments." 388 // and "installed" as the arguments."
320 new_version()->SetStatus(ServiceWorkerVersion::INSTALLED); 389 new_version()->SetStatus(ServiceWorkerVersion::INSTALLED);
321 ActivateAndContinue();
322 }
323 390
324 // This function corresponds to the spec's _Activate algorithm. 391 // TODO(michaeln): "13. If activateImmediate is true, then..."
325 void ServiceWorkerRegisterJob::ActivateAndContinue() {
326 SetPhase(ACTIVATE);
327 392
328 // "4. If existingWorker is not null, then: wait for exitingWorker to finish 393 // "14. Wait until no document is using registration as their
329 // handling any in-progress requests." 394 // 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() && 395 if (registration()->active_version() &&
334 registration()->active_version()->HasControllee()) { 396 registration()->active_version()->HasControllee()) {
335 // TODO(kinuko,falken): Currently we immediately return if the existing 397 scoped_ptr<DeferredActivationHelper> deferred_activation(
336 // registration already has an active version, so we shouldn't come 398 new DeferredActivationHelper(registration()));
337 // this way. 399 // It will delete itself when done.
338 NOTREACHED(); 400 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); 401 Complete(SERVICE_WORKER_OK);
342 return; 402 return;
343 } 403 }
344 404
345 // "5. Set serviceWorkerRegistration.activeWorker to activatingWorker." 405 SetPhase(ACTIVATE);
346 // "6. Set serviceWorkerRegistration.waitingWorker to null." 406 registration()->ActivateWaitingVersion(
347 DisassociateVersionFromDocuments(context_, new_version()); 407 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())); 408 weak_factory_.GetWeakPtr()));
361 } 409 }
362 410
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) { 411 void ServiceWorkerRegisterJob::Complete(ServiceWorkerStatusCode status) {
383 CompleteInternal(status); 412 CompleteInternal(status);
384 context_->job_coordinator()->FinishJob(pattern_, this); 413 context_->job_coordinator()->FinishJob(pattern_, this);
385 } 414 }
386 415
387 void ServiceWorkerRegisterJob::CompleteInternal( 416 void ServiceWorkerRegisterJob::CompleteInternal(
388 ServiceWorkerStatusCode status) { 417 ServiceWorkerStatusCode status) {
389 SetPhase(COMPLETE); 418 SetPhase(COMPLETE);
390 if (status != SERVICE_WORKER_OK) { 419 if (status != SERVICE_WORKER_OK) {
391 if (registration()) { 420 if (registration()) {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
424 promise_resolved_version_ = version; 453 promise_resolved_version_ = version;
425 for (std::vector<RegistrationCallback>::iterator it = callbacks_.begin(); 454 for (std::vector<RegistrationCallback>::iterator it = callbacks_.begin();
426 it != callbacks_.end(); 455 it != callbacks_.end();
427 ++it) { 456 ++it) {
428 it->Run(status, registration, version); 457 it->Run(status, registration, version);
429 } 458 }
430 callbacks_.clear(); 459 callbacks_.clear();
431 } 460 }
432 461
433 void ServiceWorkerRegisterJob::OnPausedAfterDownload() { 462 void ServiceWorkerRegisterJob::OnPausedAfterDownload() {
434 // TODO(michaeln): Compare the old and new script. 463 // This happens prior to OnStartWorkerFinished time.
435 // If different unpause the worker and continue with 464 scoped_refptr<ServiceWorkerVersion> current_version =
436 // the job. If the same ResolvePromise with the current 465 registration()->active_version();
437 // version and complete the job, throwing away the new version 466 DCHECK(current_version);
438 // since there's nothing new. 467 int64 current_script_id =
439 new_version()->embedded_worker()->RemoveListener(this); 468 current_version->script_cache_map()->Lookup(script_url_);
440 new_version()->embedded_worker()->ResumeAfterDownload(); 469 int64 new_script_id =
470 new_version()->script_cache_map()->Lookup(script_url_);
471
472 // TODO(michaeln): It would be better to compare as the new resource
473 // is being downloaded and to avoid writing it to disk until we know
474 // its needed.
475 context_->storage()->CompareScriptResources(
476 current_script_id, new_script_id,
477 base::Bind(&ServiceWorkerRegisterJob::OnCompareScriptResourcesComplete,
478 weak_factory_.GetWeakPtr(),
479 current_version));
441 } 480 }
442 481
443 bool ServiceWorkerRegisterJob::OnMessageReceived(const IPC::Message& message) { 482 bool ServiceWorkerRegisterJob::OnMessageReceived(const IPC::Message& message) {
444 return false; 483 return false;
445 } 484 }
446 485
486 void ServiceWorkerRegisterJob::OnCompareScriptResourcesComplete(
487 ServiceWorkerVersion* current_version,
488 ServiceWorkerStatusCode status,
489 bool are_equal) {
490 if (are_equal) {
491 ResolvePromise(SERVICE_WORKER_OK, registration(), current_version);
492 Complete(SERVICE_WORKER_ERROR_EXISTS);
493 return;
494 }
495
496 // Proceed with really starting the worker.
497 new_version()->embedded_worker()->ResumeAfterDownload();
498 new_version()->embedded_worker()->RemoveListener(this);
499 }
500
447 // static 501 // static
448 void ServiceWorkerRegisterJob::AssociateInstallingVersionToDocuments( 502 void ServiceWorkerRegisterJob::AssociateInstallingVersionToDocuments(
449 base::WeakPtr<ServiceWorkerContextCore> context, 503 base::WeakPtr<ServiceWorkerContextCore> context,
450 ServiceWorkerVersion* version) { 504 ServiceWorkerVersion* version) {
451 DCHECK(context); 505 DCHECK(context);
452 DCHECK(version); 506 DCHECK(version);
453 507
454 for (scoped_ptr<ServiceWorkerContextCore::ProviderHostIterator> it = 508 for (scoped_ptr<ServiceWorkerContextCore::ProviderHostIterator> it =
455 context->GetProviderHostIterator(); 509 context->GetProviderHostIterator();
456 !it->IsAtEnd(); it->Advance()) { 510 !it->IsAtEnd(); it->Advance()) {
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
511 DCHECK(context); 565 DCHECK(context);
512 for (scoped_ptr<ServiceWorkerContextCore::ProviderHostIterator> it = 566 for (scoped_ptr<ServiceWorkerContextCore::ProviderHostIterator> it =
513 context->GetProviderHostIterator(); 567 context->GetProviderHostIterator();
514 !it->IsAtEnd(); it->Advance()) { 568 !it->IsAtEnd(); it->Advance()) {
515 ServiceWorkerProviderHost* host = it->GetProviderHost(); 569 ServiceWorkerProviderHost* host = it->GetProviderHost();
516 host->UnsetVersion(version); 570 host->UnsetVersion(version);
517 } 571 }
518 } 572 }
519 573
520 } // namespace content 574 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698