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

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"
(...skipping 12 matching lines...) Expand all
23 23
24 } 24 }
25 25
26 typedef ServiceWorkerRegisterJobBase::RegistrationJobType RegistrationJobType; 26 typedef ServiceWorkerRegisterJobBase::RegistrationJobType RegistrationJobType;
27 27
28 ServiceWorkerRegisterJob::ServiceWorkerRegisterJob( 28 ServiceWorkerRegisterJob::ServiceWorkerRegisterJob(
29 base::WeakPtr<ServiceWorkerContextCore> context, 29 base::WeakPtr<ServiceWorkerContextCore> context,
30 const GURL& pattern, 30 const GURL& pattern,
31 const GURL& script_url) 31 const GURL& script_url)
32 : context_(context), 32 : context_(context),
33 job_type_(REGISTRATION),
33 pattern_(pattern), 34 pattern_(pattern),
34 script_url_(script_url), 35 script_url_(script_url),
35 phase_(INITIAL), 36 phase_(INITIAL),
36 is_promise_resolved_(false), 37 is_promise_resolved_(false),
37 promise_resolved_status_(SERVICE_WORKER_OK), 38 promise_resolved_status_(SERVICE_WORKER_OK),
38 weak_factory_(this) {} 39 weak_factory_(this) {}
39 40
41 ServiceWorkerRegisterJob::ServiceWorkerRegisterJob(
42 base::WeakPtr<ServiceWorkerContextCore> context,
43 ServiceWorkerRegistration* registration)
44 : context_(context),
45 job_type_(UPDATE_JOB),
46 pattern_(registration->pattern()),
47 script_url_(registration->script_url()),
48 phase_(INITIAL),
49 is_promise_resolved_(false),
50 promise_resolved_status_(SERVICE_WORKER_OK),
51 weak_factory_(this) {
52 internal_.registration = registration;
53 }
54
40 ServiceWorkerRegisterJob::~ServiceWorkerRegisterJob() { 55 ServiceWorkerRegisterJob::~ServiceWorkerRegisterJob() {
41 DCHECK(!context_ || 56 DCHECK(!context_ ||
42 phase_ == INITIAL || phase_ == COMPLETE || phase_ == ABORT) 57 phase_ == INITIAL || phase_ == COMPLETE || phase_ == ABORT)
43 << "Jobs should only be interrupted during shutdown."; 58 << "Jobs should only be interrupted during shutdown.";
44 } 59 }
45 60
46 void ServiceWorkerRegisterJob::AddCallback(const RegistrationCallback& callback, 61 void ServiceWorkerRegisterJob::AddCallback(const RegistrationCallback& callback,
47 int process_id) { 62 int process_id) {
48 if (!is_promise_resolved_) { 63 if (!is_promise_resolved_) {
49 callbacks_.push_back(callback); 64 callbacks_.push_back(callback);
50 if (process_id != -1 && (phase_ < UPDATE || !new_version())) 65 if (process_id != -1 && (phase_ < UPDATE || !new_version()))
51 pending_process_ids_.push_back(process_id); 66 pending_process_ids_.push_back(process_id);
52 return; 67 return;
53 } 68 }
54 RunSoon(base::Bind( 69 RunSoon(base::Bind(
55 callback, promise_resolved_status_, 70 callback, promise_resolved_status_,
56 promise_resolved_registration_, promise_resolved_version_)); 71 promise_resolved_registration_, promise_resolved_version_));
57 } 72 }
58 73
59 void ServiceWorkerRegisterJob::Start() { 74 void ServiceWorkerRegisterJob::Start() {
60 SetPhase(START); 75 SetPhase(START);
76 ServiceWorkerStorage::FindRegistrationCallback next_step;
77 if (job_type_ == REGISTRATION) {
78 next_step = base::Bind(
79 &ServiceWorkerRegisterJob::ContinueWithRegistration,
80 weak_factory_.GetWeakPtr());
81 } else {
nhiroki 2014/07/10 09:14:14 You may want to add "DCHECK_EQ(UPDATE_JOB, job_typ
82 next_step = base::Bind(
83 &ServiceWorkerRegisterJob::ContinueWithUpdate,
84 weak_factory_.GetWeakPtr());
85 }
61 context_->storage()->FindRegistrationForPattern( 86 context_->storage()->FindRegistrationForPattern(
62 pattern_, 87 pattern_, next_step);
63 base::Bind(
64 &ServiceWorkerRegisterJob::HandleExistingRegistrationAndContinue,
65 weak_factory_.GetWeakPtr()));
66 } 88 }
67 89
68 void ServiceWorkerRegisterJob::Abort() { 90 void ServiceWorkerRegisterJob::Abort() {
69 SetPhase(ABORT); 91 SetPhase(ABORT);
70 CompleteInternal(SERVICE_WORKER_ERROR_ABORT); 92 CompleteInternal(SERVICE_WORKER_ERROR_ABORT);
71 // Don't have to call FinishJob() because the caller takes care of removing 93 // Don't have to call FinishJob() because the caller takes care of removing
72 // the jobs from the queue. 94 // the jobs from the queue.
73 } 95 }
74 96
75 bool ServiceWorkerRegisterJob::Equals(ServiceWorkerRegisterJobBase* job) { 97 bool ServiceWorkerRegisterJob::Equals(ServiceWorkerRegisterJobBase* job) {
76 if (job->GetType() != GetType()) 98 if (job->GetType() != GetType())
77 return false; 99 return false;
78 ServiceWorkerRegisterJob* register_job = 100 ServiceWorkerRegisterJob* register_job =
79 static_cast<ServiceWorkerRegisterJob*>(job); 101 static_cast<ServiceWorkerRegisterJob*>(job);
80 return register_job->pattern_ == pattern_ && 102 return register_job->pattern_ == pattern_ &&
81 register_job->script_url_ == script_url_; 103 register_job->script_url_ == script_url_;
82 } 104 }
83 105
84 RegistrationJobType ServiceWorkerRegisterJob::GetType() { 106 RegistrationJobType ServiceWorkerRegisterJob::GetType() {
85 return REGISTRATION; 107 return job_type_;
86 } 108 }
87 109
88 ServiceWorkerRegisterJob::Internal::Internal() {} 110 ServiceWorkerRegisterJob::Internal::Internal() {}
89 111
90 ServiceWorkerRegisterJob::Internal::~Internal() {} 112 ServiceWorkerRegisterJob::Internal::~Internal() {}
91 113
92 void ServiceWorkerRegisterJob::set_registration( 114 void ServiceWorkerRegisterJob::set_registration(
93 ServiceWorkerRegistration* registration) { 115 ServiceWorkerRegistration* registration) {
94 DCHECK(phase_ == START || phase_ == REGISTER) << phase_; 116 DCHECK(phase_ == START || phase_ == REGISTER) << phase_;
95 DCHECK(!internal_.registration); 117 DCHECK(!internal_.registration);
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
142 case ABORT: 164 case ABORT:
143 break; 165 break;
144 } 166 }
145 phase_ = phase; 167 phase_ = phase;
146 } 168 }
147 169
148 // This function corresponds to the steps in Register following 170 // This function corresponds to the steps in Register following
149 // "Let serviceWorkerRegistration be _GetRegistration(scope)" 171 // "Let serviceWorkerRegistration be _GetRegistration(scope)"
150 // |existing_registration| corresponds to serviceWorkerRegistration. 172 // |existing_registration| corresponds to serviceWorkerRegistration.
151 // Throughout this file, comments in quotes are excerpts from the spec. 173 // Throughout this file, comments in quotes are excerpts from the spec.
152 void ServiceWorkerRegisterJob::HandleExistingRegistrationAndContinue( 174 void ServiceWorkerRegisterJob::ContinueWithRegistration(
153 ServiceWorkerStatusCode status, 175 ServiceWorkerStatusCode status,
154 const scoped_refptr<ServiceWorkerRegistration>& existing_registration) { 176 const scoped_refptr<ServiceWorkerRegistration>& existing_registration) {
177 DCHECK_EQ(REGISTRATION, job_type_);
155 // On unexpected error, abort this registration job. 178 // On unexpected error, abort this registration job.
156 if (status != SERVICE_WORKER_ERROR_NOT_FOUND && status != SERVICE_WORKER_OK) { 179 if (status != SERVICE_WORKER_ERROR_NOT_FOUND && status != SERVICE_WORKER_OK) {
157 Complete(status); 180 Complete(status);
158 return; 181 return;
159 } 182 }
160 183
161 // "If serviceWorkerRegistration is not null and script is equal to 184 // "If serviceWorkerRegistration is not null and script is equal to
162 // serviceWorkerRegistration.scriptUrl..." resolve with the existing 185 // serviceWorkerRegistration.scriptUrl..." resolve with the existing
163 // registration and abort. 186 // registration and abort.
164 if (existing_registration.get() && 187 if (existing_registration.get() &&
165 existing_registration->script_url() == script_url_) { 188 existing_registration->script_url() == script_url_) {
166 set_registration(existing_registration); 189 set_registration(existing_registration);
167 // 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
169 // Update otherwise).
170 if (!existing_registration->active_version()) {
171 UpdateAndContinue(status);
172 return;
173 }
174 ResolvePromise( 190 ResolvePromise(
175 status, existing_registration, existing_registration->active_version()); 191 status, existing_registration, existing_registration->active_version());
176 Complete(SERVICE_WORKER_OK); 192 Complete(SERVICE_WORKER_OK);
177 return; 193 return;
178 } 194 }
179 195
180 // "If serviceWorkerRegistration is null..." create a new registration. 196 // "If serviceWorkerRegistration is null..." create a new registration.
181 if (!existing_registration.get()) { 197 if (!existing_registration.get()) {
182 RegisterAndContinue(SERVICE_WORKER_OK); 198 RegisterAndContinue(SERVICE_WORKER_OK);
183 return; 199 return;
184 } 200 }
185 201
186 // On script URL mismatch, "set serviceWorkerRegistration.scriptUrl to 202 // On script URL mismatch, "set serviceWorkerRegistration.scriptUrl to
187 // script." We accomplish this by deleting the existing registration and 203 // script." We accomplish this by deleting the existing registration and
188 // registering a new one. 204 // registering a new one.
189 // TODO(falken): Match the spec. We now throw away the active_version_ and 205 // 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. 206 // waiting_version_ of the existing registration, which isn't in the spec.
191 // TODO(michaeln): Deactivate the live existing_registration object and 207 // TODO(michaeln): Deactivate the live existing_registration object and
192 // eventually call storage->DeleteVersionResources() 208 // eventually call storage->DeleteVersionResources()
193 // when it no longer has any controllees. 209 // when it no longer has any controllees.
194 context_->storage()->DeleteRegistration( 210 context_->storage()->DeleteRegistration(
195 existing_registration->id(), 211 existing_registration->id(),
196 existing_registration->script_url().GetOrigin(), 212 existing_registration->script_url().GetOrigin(),
197 base::Bind(&ServiceWorkerRegisterJob::RegisterAndContinue, 213 base::Bind(&ServiceWorkerRegisterJob::RegisterAndContinue,
198 weak_factory_.GetWeakPtr())); 214 weak_factory_.GetWeakPtr()));
199 } 215 }
200 216
217 void ServiceWorkerRegisterJob::ContinueWithUpdate(
218 ServiceWorkerStatusCode status,
219 const scoped_refptr<ServiceWorkerRegistration>& existing_registration) {
220 DCHECK_EQ(UPDATE, job_type_);
221 if (status != SERVICE_WORKER_OK) {
222 Complete(status);
223 return;
224 }
225
226 if (existing_registration != registration()) {
227 Complete(SERVICE_WORKER_ERROR_NOT_FOUND);
228 return;
229 }
230
231 DCHECK(registration()->active_version());
232 UpdateAndContinue(status);
233 }
234
201 // Creates a new ServiceWorkerRegistration. 235 // Creates a new ServiceWorkerRegistration.
202 void ServiceWorkerRegisterJob::RegisterAndContinue( 236 void ServiceWorkerRegisterJob::RegisterAndContinue(
203 ServiceWorkerStatusCode status) { 237 ServiceWorkerStatusCode status) {
204 SetPhase(REGISTER); 238 SetPhase(REGISTER);
205 if (status != SERVICE_WORKER_OK) { 239 if (status != SERVICE_WORKER_OK) {
206 // Abort this registration job. 240 // Abort this registration job.
207 Complete(status); 241 Complete(status);
208 return; 242 return;
209 } 243 }
210 244
211 set_registration(new ServiceWorkerRegistration( 245 set_registration(new ServiceWorkerRegistration(
212 pattern_, script_url_, context_->storage()->NewRegistrationId(), 246 pattern_, script_url_, context_->storage()->NewRegistrationId(),
213 context_)); 247 context_));
214 context_->storage()->NotifyInstallingRegistration(registration());
215 UpdateAndContinue(SERVICE_WORKER_OK); 248 UpdateAndContinue(SERVICE_WORKER_OK);
216 } 249 }
217 250
218 // This function corresponds to the spec's _Update algorithm. 251 // This function corresponds to the spec's _Update algorithm.
219 void ServiceWorkerRegisterJob::UpdateAndContinue( 252 void ServiceWorkerRegisterJob::UpdateAndContinue(
220 ServiceWorkerStatusCode status) { 253 ServiceWorkerStatusCode status) {
nhiroki 2014/07/10 09:14:14 This may not have to receive |status| since the ca
michaeln 2014/07/14 23:02:30 Done.
221 SetPhase(UPDATE); 254 SetPhase(UPDATE);
222 if (status != SERVICE_WORKER_OK) { 255 if (status != SERVICE_WORKER_OK) {
223 // Abort this registration job. 256 // Abort this registration job.
224 Complete(status); 257 Complete(status);
225 return; 258 return;
226 } 259 }
260 context_->storage()->NotifyInstallingRegistration(registration());
227 261
228 // TODO(falken): "If serviceWorkerRegistration.installingWorker is not null.." 262 // TODO(falken): "If serviceWorkerRegistration.installingWorker is not null.."
229 // then terminate the installing worker. It doesn't make sense to implement 263 // 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 264 // yet since we always activate the worker if install completed, so there can
231 // be no installing worker at this point. 265 // be no installing worker at this point.
232 266
233 // "Let serviceWorker be a newly-created ServiceWorker object..." and start 267 // "Let serviceWorker be a newly-created ServiceWorker object..." and start
234 // the worker. 268 // the worker.
235 set_new_version(new ServiceWorkerVersion( 269 set_new_version(new ServiceWorkerVersion(
236 registration(), context_->storage()->NewVersionId(), context_)); 270 registration(), context_->storage()->NewVersionId(), context_));
237 271
238 // TODO(michaeln): Pause after downloading when performing an update. 272 bool pause_after_download = job_type_ == UPDATE_JOB;
239 bool pause_after_download = false;
240 if (pause_after_download) 273 if (pause_after_download)
241 new_version()->embedded_worker()->AddListener(this); 274 new_version()->embedded_worker()->AddListener(this);
242 new_version()->StartWorkerWithCandidateProcesses( 275 new_version()->StartWorkerWithCandidateProcesses(
243 pending_process_ids_, 276 pending_process_ids_,
244 pause_after_download, 277 pause_after_download,
245 base::Bind(&ServiceWorkerRegisterJob::OnStartWorkerFinished, 278 base::Bind(&ServiceWorkerRegisterJob::OnStartWorkerFinished,
246 weak_factory_.GetWeakPtr())); 279 weak_factory_.GetWeakPtr()));
247 } 280 }
248 281
249 void ServiceWorkerRegisterJob::OnStartWorkerFinished( 282 void ServiceWorkerRegisterJob::OnStartWorkerFinished(
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
424 promise_resolved_version_ = version; 457 promise_resolved_version_ = version;
425 for (std::vector<RegistrationCallback>::iterator it = callbacks_.begin(); 458 for (std::vector<RegistrationCallback>::iterator it = callbacks_.begin();
426 it != callbacks_.end(); 459 it != callbacks_.end();
427 ++it) { 460 ++it) {
428 it->Run(status, registration, version); 461 it->Run(status, registration, version);
429 } 462 }
430 callbacks_.clear(); 463 callbacks_.clear();
431 } 464 }
432 465
433 void ServiceWorkerRegisterJob::OnPausedAfterDownload() { 466 void ServiceWorkerRegisterJob::OnPausedAfterDownload() {
434 // TODO(michaeln): Compare the old and new script. 467 // This happens prior to OnStartWorkerFinished time.
435 // If different unpause the worker and continue with 468 scoped_refptr<ServiceWorkerVersion> current_version =
436 // the job. If the same ResolvePromise with the current 469 registration()->active_version();
437 // version and complete the job, throwing away the new version 470 DCHECK(current_version);
438 // since there's nothing new. 471 int64 current_script_id =
439 new_version()->embedded_worker()->RemoveListener(this); 472 current_version->script_cache_map()->Lookup(script_url_);
440 new_version()->embedded_worker()->ResumeAfterDownload(); 473 int64 new_script_id =
474 new_version()->script_cache_map()->Lookup(script_url_);
475
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698