Chromium Code Reviews

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

Issue 506043002: (Reland) Service Worker: Handle same-scope, new script registration (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: sync Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff |
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 122 matching lines...)
133 DCHECK(phase_ == UPDATE) << phase_; 133 DCHECK(phase_ == UPDATE) << phase_;
134 DCHECK(!internal_.new_version.get()); 134 DCHECK(!internal_.new_version.get());
135 internal_.new_version = version; 135 internal_.new_version = version;
136 } 136 }
137 137
138 ServiceWorkerVersion* ServiceWorkerRegisterJob::new_version() { 138 ServiceWorkerVersion* ServiceWorkerRegisterJob::new_version() {
139 DCHECK(phase_ >= UPDATE) << phase_; 139 DCHECK(phase_ >= UPDATE) << phase_;
140 return internal_.new_version.get(); 140 return internal_.new_version.get();
141 } 141 }
142 142
143 void ServiceWorkerRegisterJob::set_uninstalling_registration(
144 ServiceWorkerRegistration* registration) {
145 DCHECK_EQ(phase_, WAIT_FOR_UNINSTALL);
146 internal_.uninstalling_registration = registration;
147 }
148
149 ServiceWorkerRegistration*
150 ServiceWorkerRegisterJob::uninstalling_registration() {
151 DCHECK_EQ(phase_, WAIT_FOR_UNINSTALL);
152 return internal_.uninstalling_registration;
153 }
154
143 void ServiceWorkerRegisterJob::SetPhase(Phase phase) { 155 void ServiceWorkerRegisterJob::SetPhase(Phase phase) {
144 switch (phase) { 156 switch (phase) {
145 case INITIAL: 157 case INITIAL:
146 NOTREACHED(); 158 NOTREACHED();
147 break; 159 break;
148 case START: 160 case START:
149 DCHECK(phase_ == INITIAL) << phase_; 161 DCHECK(phase_ == INITIAL) << phase_;
150 break; 162 break;
163 case WAIT_FOR_UNINSTALL:
164 DCHECK(phase_ == START) << phase_;
165 break;
151 case REGISTER: 166 case REGISTER:
152 DCHECK(phase_ == START) << phase_; 167 DCHECK(phase_ == START || phase_ == WAIT_FOR_UNINSTALL) << phase_;
153 break; 168 break;
154 case UPDATE: 169 case UPDATE:
155 DCHECK(phase_ == START || phase_ == REGISTER) << phase_; 170 DCHECK(phase_ == START || phase_ == REGISTER) << phase_;
156 break; 171 break;
157 case INSTALL: 172 case INSTALL:
158 DCHECK(phase_ == UPDATE) << phase_; 173 DCHECK(phase_ == UPDATE) << phase_;
159 break; 174 break;
160 case STORE: 175 case STORE:
161 DCHECK(phase_ == INSTALL) << phase_; 176 DCHECK(phase_ == INSTALL) << phase_;
162 break; 177 break;
(...skipping 16 matching lines...)
179 if (status != SERVICE_WORKER_ERROR_NOT_FOUND && status != SERVICE_WORKER_OK) { 194 if (status != SERVICE_WORKER_ERROR_NOT_FOUND && status != SERVICE_WORKER_OK) {
180 Complete(status); 195 Complete(status);
181 return; 196 return;
182 } 197 }
183 198
184 if (!existing_registration.get()) { 199 if (!existing_registration.get()) {
185 RegisterAndContinue(SERVICE_WORKER_OK); 200 RegisterAndContinue(SERVICE_WORKER_OK);
186 return; 201 return;
187 } 202 }
188 203
204 // "If scriptURL is equal to registration.[[ScriptURL]], then:"
205 if (existing_registration->GetNewestVersion()->script_url() == script_url_) {
206 // "Set registration.[[Uninstalling]] to false."
207 existing_registration->AbortPendingClear(base::Bind(
208 &ServiceWorkerRegisterJob::ContinueWithRegistrationForSameScriptUrl,
209 weak_factory_.GetWeakPtr(),
210 existing_registration));
211 return;
212 }
213
214 if (existing_registration->is_uninstalling()) {
215 // "Wait until the Record {[[key]], [[value]]} entry of its
216 // [[ScopeToRegistrationMap]] where registation.scope matches entry.[[key]]
217 // is deleted."
218 WaitForUninstall(existing_registration);
219 return;
220 }
221
189 // "Set registration.[[Uninstalling]] to false." 222 // "Set registration.[[Uninstalling]] to false."
190 existing_registration->AbortPendingClear(); 223 DCHECK(!existing_registration->is_uninstalling());
191 224
192 // "If scriptURL is equal to registration.[[ScriptURL]], then:" 225 // "Return the result of running the [[Update]] algorithm, or its equivalent,
193 if (existing_registration->GetNewestVersion()->script_url() == script_url_) { 226 // passing registration as the argument."
194 // Spec says to resolve with registration.[[GetNewestWorker]]. We come close 227 set_registration(existing_registration);
195 // by resolving with the active version. 228 UpdateAndContinue();
196 set_registration(existing_registration.get());
197
198 if (!existing_registration->active_version()) {
199 UpdateAndContinue();
200 return;
201 }
202
203 ResolvePromise(status,
204 existing_registration.get(),
205 existing_registration->active_version());
206 Complete(SERVICE_WORKER_OK);
207 return;
208 }
209
210 // "Set registration.[[ScriptURL]] to scriptURL." We accomplish this by
211 // deleting the existing registration and registering a new one.
212 // TODO(michaeln): Deactivate the live existing_registration object and
213 // eventually call storage->DeleteVersionResources() when it no longer has any
214 // controllees.
215 context_->storage()->DeleteRegistration(
216 existing_registration->id(),
217 existing_registration->pattern().GetOrigin(),
218 base::Bind(&ServiceWorkerRegisterJob::RegisterAndContinue,
219 weak_factory_.GetWeakPtr()));
220 } 229 }
221 230
222 void ServiceWorkerRegisterJob::ContinueWithUpdate( 231 void ServiceWorkerRegisterJob::ContinueWithUpdate(
223 ServiceWorkerStatusCode status, 232 ServiceWorkerStatusCode status,
224 const scoped_refptr<ServiceWorkerRegistration>& existing_registration) { 233 const scoped_refptr<ServiceWorkerRegistration>& existing_registration) {
225 DCHECK_EQ(UPDATE_JOB, job_type_); 234 DCHECK_EQ(UPDATE_JOB, job_type_);
226 if (status != SERVICE_WORKER_OK) { 235 if (status != SERVICE_WORKER_OK) {
227 Complete(status); 236 Complete(status);
228 return; 237 return;
229 } 238 }
(...skipping 27 matching lines...)
257 Complete(status); 266 Complete(status);
258 return; 267 return;
259 } 268 }
260 269
261 set_registration(new ServiceWorkerRegistration( 270 set_registration(new ServiceWorkerRegistration(
262 pattern_, context_->storage()->NewRegistrationId(), context_)); 271 pattern_, context_->storage()->NewRegistrationId(), context_));
263 AssociateProviderHostsToRegistration(registration()); 272 AssociateProviderHostsToRegistration(registration());
264 UpdateAndContinue(); 273 UpdateAndContinue();
265 } 274 }
266 275
276 void ServiceWorkerRegisterJob::WaitForUninstall(
277 const scoped_refptr<ServiceWorkerRegistration>& existing_registration) {
278 SetPhase(WAIT_FOR_UNINSTALL);
279 set_uninstalling_registration(existing_registration);
280 uninstalling_registration()->AddListener(this);
281 }
282
283 void ServiceWorkerRegisterJob::ContinueWithRegistrationForSameScriptUrl(
284 const scoped_refptr<ServiceWorkerRegistration>& existing_registration,
285 ServiceWorkerStatusCode status) {
286 if (status != SERVICE_WORKER_OK) {
287 Complete(status);
288 return;
289 }
290 set_registration(existing_registration);
291
292 // TODO(falken): Follow the spec: resolve the promise
293 // with the newest version.
294
295 if (!existing_registration->active_version()) {
296 UpdateAndContinue();
297 return;
298 }
299
300 ResolvePromise(
301 status, existing_registration, existing_registration->active_version());
302 Complete(SERVICE_WORKER_OK);
303 }
304
267 // This function corresponds to the spec's [[Update]] algorithm. 305 // This function corresponds to the spec's [[Update]] algorithm.
268 void ServiceWorkerRegisterJob::UpdateAndContinue() { 306 void ServiceWorkerRegisterJob::UpdateAndContinue() {
269 SetPhase(UPDATE); 307 SetPhase(UPDATE);
270 context_->storage()->NotifyInstallingRegistration(registration()); 308 context_->storage()->NotifyInstallingRegistration(registration());
271 309
272 // TODO(falken): "If serviceWorkerRegistration.installingWorker is not null.." 310 // TODO(falken): "If serviceWorkerRegistration.installingWorker is not null.."
273 // then terminate the installing worker. It doesn't make sense to implement 311 // then terminate the installing worker. It doesn't make sense to implement
274 // yet since we always activate the worker if install completed, so there can 312 // yet since we always activate the worker if install completed, so there can
275 // be no installing worker at this point. 313 // be no installing worker at this point.
276 314
(...skipping 171 matching lines...)
448 most_recent_script_id, new_script_id, 486 most_recent_script_id, new_script_id,
449 base::Bind(&ServiceWorkerRegisterJob::OnCompareScriptResourcesComplete, 487 base::Bind(&ServiceWorkerRegisterJob::OnCompareScriptResourcesComplete,
450 weak_factory_.GetWeakPtr(), 488 weak_factory_.GetWeakPtr(),
451 most_recent_version)); 489 most_recent_version));
452 } 490 }
453 491
454 bool ServiceWorkerRegisterJob::OnMessageReceived(const IPC::Message& message) { 492 bool ServiceWorkerRegisterJob::OnMessageReceived(const IPC::Message& message) {
455 return false; 493 return false;
456 } 494 }
457 495
496 void ServiceWorkerRegisterJob::OnRegistrationFinishedUninstalling(
497 ServiceWorkerRegistration* existing_registration) {
498 DCHECK_EQ(phase_, WAIT_FOR_UNINSTALL);
499 DCHECK_EQ(existing_registration, uninstalling_registration());
500 existing_registration->RemoveListener(this);
501 set_uninstalling_registration(NULL);
502 RegisterAndContinue(SERVICE_WORKER_OK);
503 }
504
458 void ServiceWorkerRegisterJob::OnCompareScriptResourcesComplete( 505 void ServiceWorkerRegisterJob::OnCompareScriptResourcesComplete(
459 ServiceWorkerVersion* most_recent_version, 506 ServiceWorkerVersion* most_recent_version,
460 ServiceWorkerStatusCode status, 507 ServiceWorkerStatusCode status,
461 bool are_equal) { 508 bool are_equal) {
462 if (are_equal) { 509 if (are_equal) {
463 // Only bump the last check time when we've bypassed the browser cache. 510 // Only bump the last check time when we've bypassed the browser cache.
464 base::TimeDelta time_since_last_check = 511 base::TimeDelta time_since_last_check =
465 base::Time::Now() - registration()->last_update_check(); 512 base::Time::Now() - registration()->last_update_check();
466 if (time_since_last_check > base::TimeDelta::FromHours(24)) { 513 if (time_since_last_check > base::TimeDelta::FromHours(24)) {
467 registration()->set_last_update_check(base::Time::Now()); 514 registration()->set_last_update_check(base::Time::Now());
(...skipping 19 matching lines...)
487 ServiceWorkerProviderHost* host = it->GetProviderHost(); 534 ServiceWorkerProviderHost* host = it->GetProviderHost();
488 if (ServiceWorkerUtils::ScopeMatches(registration->pattern(), 535 if (ServiceWorkerUtils::ScopeMatches(registration->pattern(),
489 host->document_url())) { 536 host->document_url())) {
490 if (host->CanAssociateRegistration(registration)) 537 if (host->CanAssociateRegistration(registration))
491 host->AssociateRegistration(registration); 538 host->AssociateRegistration(registration);
492 } 539 }
493 } 540 }
494 } 541 }
495 542
496 } // namespace content 543 } // namespace content
OLDNEW

Powered by Google App Engine