1a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 2a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// found in the LICENSE file. 4a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 5a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "content/browser/service_worker/service_worker_register_job.h" 6a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <vector> 85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 90529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "base/message_loop/message_loop.h" 10c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "content/browser/service_worker/service_worker_context_core.h" 115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/browser/service_worker/service_worker_job_coordinator.h" 12a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "content/browser/service_worker/service_worker_registration.h" 13e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "content/browser/service_worker/service_worker_storage.h" 140529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "content/browser/service_worker/service_worker_utils.h" 151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "net/base/net_errors.h" 16a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 17a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)namespace content { 18a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 190529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochnamespace { 200529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 210529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid RunSoon(const base::Closure& closure) { 220529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch base::MessageLoop::current()->PostTask(FROM_HERE, closure); 230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} // namespace 260529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 27e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochtypedef ServiceWorkerRegisterJobBase::RegistrationJobType RegistrationJobType; 28a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 29a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)ServiceWorkerRegisterJob::ServiceWorkerRegisterJob( 30c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch base::WeakPtr<ServiceWorkerContextCore> context, 315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const GURL& pattern, 32e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch const GURL& script_url) 33c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch : context_(context), 345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) job_type_(REGISTRATION_JOB), 355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pattern_(pattern), 365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) script_url_(script_url), 37c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch phase_(INITIAL), 380529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch is_promise_resolved_(false), 390529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch promise_resolved_status_(SERVICE_WORKER_OK), 405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) weak_factory_(this) {} 41a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)ServiceWorkerRegisterJob::ServiceWorkerRegisterJob( 435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::WeakPtr<ServiceWorkerContextCore> context, 445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ServiceWorkerRegistration* registration) 455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) : context_(context), 465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) job_type_(UPDATE_JOB), 475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pattern_(registration->pattern()), 481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci script_url_(registration->GetNewestVersion()->script_url()), 495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) phase_(INITIAL), 505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) is_promise_resolved_(false), 515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) promise_resolved_status_(SERVICE_WORKER_OK), 525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) weak_factory_(this) { 535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) internal_.registration = registration; 545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 560529e5d033099cbfc42635f6f6183833b09dff6eBen MurdochServiceWorkerRegisterJob::~ServiceWorkerRegisterJob() { 576d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) DCHECK(!context_ || 586d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) phase_ == INITIAL || phase_ == COMPLETE || phase_ == ABORT) 59cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) << "Jobs should only be interrupted during shutdown."; 600529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 61a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid ServiceWorkerRegisterJob::AddCallback( 631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const RegistrationCallback& callback, 641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ServiceWorkerProviderHost* provider_host) { 650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (!is_promise_resolved_) { 660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch callbacks_.push_back(callback); 671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (provider_host) 681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci provider_host->AddScopedProcessReferenceToPattern(pattern_); 690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return; 705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch RunSoon(base::Bind( 720529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch callback, promise_resolved_status_, 730529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch promise_resolved_registration_, promise_resolved_version_)); 745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ServiceWorkerRegisterJob::Start() { 77c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch SetPhase(START); 785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ServiceWorkerStorage::FindRegistrationCallback next_step; 795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (job_type_ == REGISTRATION_JOB) { 805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) next_step = base::Bind( 815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) &ServiceWorkerRegisterJob::ContinueWithRegistration, 825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) weak_factory_.GetWeakPtr()); 835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } else { 845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) next_step = base::Bind( 855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) &ServiceWorkerRegisterJob::ContinueWithUpdate, 865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) weak_factory_.GetWeakPtr()); 875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 886e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 896e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) scoped_refptr<ServiceWorkerRegistration> registration = 906e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) context_->storage()->GetUninstallingRegistration(pattern_); 911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (registration.get()) 926e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) RunSoon(base::Bind(next_step, SERVICE_WORKER_OK, registration)); 936e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) else 946e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) context_->storage()->FindRegistrationForPattern(pattern_, next_step); 955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 976d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)void ServiceWorkerRegisterJob::Abort() { 986d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) SetPhase(ABORT); 996d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) CompleteInternal(SERVICE_WORKER_ERROR_ABORT); 1006d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) // Don't have to call FinishJob() because the caller takes care of removing 1016d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) // the jobs from the queue. 1026d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)} 1036d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) 104e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochbool ServiceWorkerRegisterJob::Equals(ServiceWorkerRegisterJobBase* job) { 105e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch if (job->GetType() != GetType()) 106e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch return false; 107e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch ServiceWorkerRegisterJob* register_job = 108e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch static_cast<ServiceWorkerRegisterJob*>(job); 109e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch return register_job->pattern_ == pattern_ && 110e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch register_job->script_url_ == script_url_; 1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 113e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen MurdochRegistrationJobType ServiceWorkerRegisterJob::GetType() { 1145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return job_type_; 115e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch} 116a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 117c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochServiceWorkerRegisterJob::Internal::Internal() {} 118c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 119c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochServiceWorkerRegisterJob::Internal::~Internal() {} 120c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 121c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid ServiceWorkerRegisterJob::set_registration( 1221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const scoped_refptr<ServiceWorkerRegistration>& registration) { 123c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DCHECK(phase_ == START || phase_ == REGISTER) << phase_; 1241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(!internal_.registration.get()); 125c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch internal_.registration = registration; 126c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 127c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 128c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochServiceWorkerRegistration* ServiceWorkerRegisterJob::registration() { 1295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(phase_ >= REGISTER || job_type_ == UPDATE_JOB) << phase_; 1301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return internal_.registration.get(); 131c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 132c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 133116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid ServiceWorkerRegisterJob::set_new_version( 134c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ServiceWorkerVersion* version) { 135cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK(phase_ == UPDATE) << phase_; 1361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(!internal_.new_version.get()); 137116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch internal_.new_version = version; 138c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 139c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 140116680a4aac90f2aa7413d9095a592090648e557Ben MurdochServiceWorkerVersion* ServiceWorkerRegisterJob::new_version() { 141c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DCHECK(phase_ >= UPDATE) << phase_; 1421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return internal_.new_version.get(); 1431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid ServiceWorkerRegisterJob::set_uninstalling_registration( 1461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const scoped_refptr<ServiceWorkerRegistration>& registration) { 1471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK_EQ(phase_, WAIT_FOR_UNINSTALL); 1481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci internal_.uninstalling_registration = registration; 1491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciServiceWorkerRegistration* 1521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciServiceWorkerRegisterJob::uninstalling_registration() { 1531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK_EQ(phase_, WAIT_FOR_UNINSTALL); 1541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return internal_.uninstalling_registration.get(); 155c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 156c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 157c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid ServiceWorkerRegisterJob::SetPhase(Phase phase) { 158c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch switch (phase) { 159c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch case INITIAL: 160c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch NOTREACHED(); 161c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch break; 162c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch case START: 163c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DCHECK(phase_ == INITIAL) << phase_; 164c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch break; 1651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case WAIT_FOR_UNINSTALL: 166c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DCHECK(phase_ == START) << phase_; 167c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch break; 1681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case REGISTER: 1691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(phase_ == START || phase_ == WAIT_FOR_UNINSTALL) << phase_; 1701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci break; 171c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch case UPDATE: 172c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DCHECK(phase_ == START || phase_ == REGISTER) << phase_; 173c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch break; 174c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch case INSTALL: 175c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DCHECK(phase_ == UPDATE) << phase_; 176c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch break; 1770529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch case STORE: 178c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DCHECK(phase_ == INSTALL) << phase_; 179c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch break; 180c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch case COMPLETE: 181c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DCHECK(phase_ != INITIAL && phase_ != COMPLETE) << phase_; 182c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch break; 1836d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) case ABORT: 1846d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) break; 185c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 186c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch phase_ = phase; 187c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 188c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 1896e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// This function corresponds to the steps in [[Register]] following 1906e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// "Let registration be the result of running the [[GetRegistration]] algorithm. 191c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch// Throughout this file, comments in quotes are excerpts from the spec. 1925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void ServiceWorkerRegisterJob::ContinueWithRegistration( 193e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch ServiceWorkerStatusCode status, 194c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const scoped_refptr<ServiceWorkerRegistration>& existing_registration) { 1955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK_EQ(REGISTRATION_JOB, job_type_); 196c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (status != SERVICE_WORKER_ERROR_NOT_FOUND && status != SERVICE_WORKER_OK) { 197c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch Complete(status); 198e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch return; 199e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch } 200a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 2011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!existing_registration.get() || existing_registration->is_uninstalled()) { 2026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) RegisterAndContinue(SERVICE_WORKER_OK); 2036e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) return; 2046e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 2056e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 2061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(existing_registration->GetNewestVersion()); 2076e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // "If scriptURL is equal to registration.[[ScriptURL]], then:" 2081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (existing_registration->GetNewestVersion()->script_url() == script_url_) { 2091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // "Set registration.[[Uninstalling]] to false." 2101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci existing_registration->AbortPendingClear(base::Bind( 2111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci &ServiceWorkerRegisterJob::ContinueWithRegistrationForSameScriptUrl, 2121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci weak_factory_.GetWeakPtr(), 2131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci existing_registration)); 2141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 2151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 2166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 2171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (existing_registration->is_uninstalling()) { 2181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // "Wait until the Record {[[key]], [[value]]} entry of its 2191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // [[ScopeToRegistrationMap]] where registation.scope matches entry.[[key]] 2201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // is deleted." 2211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci WaitForUninstall(existing_registration); 222e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch return; 223e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch } 2245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // "Set registration.[[Uninstalling]] to false." 2261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(!existing_registration->is_uninstalling()); 2271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // "Return the result of running the [[Update]] algorithm, or its equivalent, 2291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // passing registration as the argument." 2301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci set_registration(existing_registration); 2311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci UpdateAndContinue(); 232a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 233a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 2345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void ServiceWorkerRegisterJob::ContinueWithUpdate( 2355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ServiceWorkerStatusCode status, 2365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const scoped_refptr<ServiceWorkerRegistration>& existing_registration) { 2375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK_EQ(UPDATE_JOB, job_type_); 2385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (status != SERVICE_WORKER_OK) { 2395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Complete(status); 2405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return; 2415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 2425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (existing_registration.get() != registration()) { 2441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Complete(SERVICE_WORKER_ERROR_NOT_FOUND); 2451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 2461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 2471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // A previous job may have unregistered or installed a new version to this 2491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // registration. 2501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (registration()->is_uninstalling() || 2511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci registration()->GetNewestVersion()->script_url() != script_url_) { 2525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Complete(SERVICE_WORKER_ERROR_NOT_FOUND); 2535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return; 2545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 2555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2566e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // TODO(michaeln): If the last update check was less than 24 hours 2576e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // ago, depending on the freshness of the cached worker script we 2586e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // may be able to complete the update job right here. 2596e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 2605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) UpdateAndContinue(); 2615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 2625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 2630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch// Creates a new ServiceWorkerRegistration. 264e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochvoid ServiceWorkerRegisterJob::RegisterAndContinue( 265e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch ServiceWorkerStatusCode status) { 266c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch SetPhase(REGISTER); 267e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch if (status != SERVICE_WORKER_OK) { 268e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch // Abort this registration job. 269e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch Complete(status); 270e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch return; 271e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch } 272a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 273c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch set_registration(new ServiceWorkerRegistration( 2741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci pattern_, context_->storage()->NewRegistrationId(), context_)); 2756e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) AssociateProviderHostsToRegistration(registration()); 2765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) UpdateAndContinue(); 2775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid ServiceWorkerRegisterJob::WaitForUninstall( 2801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const scoped_refptr<ServiceWorkerRegistration>& existing_registration) { 2811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci SetPhase(WAIT_FOR_UNINSTALL); 2821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci set_uninstalling_registration(existing_registration); 2831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci uninstalling_registration()->AddListener(this); 2841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 2851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid ServiceWorkerRegisterJob::ContinueWithRegistrationForSameScriptUrl( 2871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const scoped_refptr<ServiceWorkerRegistration>& existing_registration, 2881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ServiceWorkerStatusCode status) { 2891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (status != SERVICE_WORKER_OK) { 2901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Complete(status); 2911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 2921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 2931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci set_registration(existing_registration); 2941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // TODO(falken): Follow the spec: resolve the promise 2961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // with the newest version. 2971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 2981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!existing_registration->active_version()) { 2991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci UpdateAndContinue(); 3001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 3011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 3021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ResolvePromise(status, 3041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci existing_registration.get(), 3051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci existing_registration->active_version()); 3061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Complete(SERVICE_WORKER_OK); 3071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 3081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 3095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// This function corresponds to the spec's [[Update]] algorithm. 3105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void ServiceWorkerRegisterJob::UpdateAndContinue() { 311c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch SetPhase(UPDATE); 3125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) context_->storage()->NotifyInstallingRegistration(registration()); 3135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 314cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // TODO(falken): "If serviceWorkerRegistration.installingWorker is not null.." 315cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // then terminate the installing worker. It doesn't make sense to implement 316cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // yet since we always activate the worker if install completed, so there can 317cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // be no installing worker at this point. 318c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 319c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // "Let serviceWorker be a newly-created ServiceWorker object..." and start 320c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // the worker. 3211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci set_new_version(new ServiceWorkerVersion(registration(), 3221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci script_url_, 3231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci context_->storage()->NewVersionId(), 3241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci context_)); 3255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) bool pause_after_download = job_type_ == UPDATE_JOB; 327116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (pause_after_download) 328116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch new_version()->embedded_worker()->AddListener(this); 3291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci new_version()->StartWorker( 330116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch pause_after_download, 331c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch base::Bind(&ServiceWorkerRegisterJob::OnStartWorkerFinished, 332c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch weak_factory_.GetWeakPtr())); 333c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 334c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 335c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid ServiceWorkerRegisterJob::OnStartWorkerFinished( 336c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ServiceWorkerStatusCode status) { 3371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (status == SERVICE_WORKER_OK) { 3381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci InstallAndContinue(); 339c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return; 340c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 341c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 3421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // "If serviceWorker fails to start up..." then reject the promise with an 3431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // error and abort. When there is a main script network error, the status will 3441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // be updated to a more specific one. 3451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const net::URLRequestStatus& main_script_status = 3461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci new_version()->script_cache_map()->main_script_status(); 3471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (main_script_status.status() != net::URLRequestStatus::SUCCESS) { 3481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci switch (main_script_status.error()) { 3491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case net::ERR_INSECURE_RESPONSE: 3501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case net::ERR_UNSAFE_REDIRECT: 3511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci status = SERVICE_WORKER_ERROR_SECURITY; 3521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci break; 3531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case net::ERR_ABORTED: 3541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci status = SERVICE_WORKER_ERROR_ABORT; 3551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci break; 3561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci case net::ERR_FAILED: 3571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci status = SERVICE_WORKER_ERROR_NETWORK; 3581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci break; 3591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci default: 3601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci NOTREACHED(); 3611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 3621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 3631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci Complete(status); 364c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 365c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 3661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// This function corresponds to the spec's [[Install]] algorithm. 367c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid ServiceWorkerRegisterJob::InstallAndContinue() { 368c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch SetPhase(INSTALL); 369116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 3701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // "2. Set registration.installingWorker to worker." 371116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch registration()->SetInstallingVersion(new_version()); 372116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 3731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // "3. Resolve promise with registration." 3741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ResolvePromise(SERVICE_WORKER_OK, registration(), new_version()); 3751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 376116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // "4. Run the [[UpdateState]] algorithm passing registration.installingWorker 377116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // and "installing" as the arguments." 378116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch new_version()->SetStatus(ServiceWorkerVersion::INSTALLING); 379116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 3801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // "5. Fire a simple event named updatefound..." 3811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci registration()->NotifyUpdateFound(); 382116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 383116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // "6. Fire an event named install..." 384116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch new_version()->DispatchInstallEvent( 385c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch -1, 386c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch base::Bind(&ServiceWorkerRegisterJob::OnInstallFinished, 387c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch weak_factory_.GetWeakPtr())); 388c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 389c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 390c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochvoid ServiceWorkerRegisterJob::OnInstallFinished( 391c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ServiceWorkerStatusCode status) { 392a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // TODO(kinuko,falken): For some error cases (e.g. ServiceWorker is 393a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch // unexpectedly terminated) we may want to retry sending the event again. 394c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (status != SERVICE_WORKER_OK) { 395116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // "8. If installFailed is true, then:..." 3960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch Complete(status); 3970529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return; 3980529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 3990529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 4000529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch SetPhase(STORE); 4016e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) registration()->set_last_update_check(base::Time::Now()); 4020529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch context_->storage()->StoreRegistration( 4030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch registration(), 404116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch new_version(), 4050529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch base::Bind(&ServiceWorkerRegisterJob::OnStoreRegistrationComplete, 4060529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch weak_factory_.GetWeakPtr())); 4070529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 4080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 4090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid ServiceWorkerRegisterJob::OnStoreRegistrationComplete( 4100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ServiceWorkerStatusCode status) { 4110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (status != SERVICE_WORKER_OK) { 412c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch Complete(status); 413c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return; 414c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 4155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // "9. If registration.waitingWorker is not null, then:..." 4175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (registration()->waiting_version()) { 4185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // "1. Run the [[UpdateState]] algorithm passing registration.waitingWorker 4195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // and "redundant" as the arguments." 4205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) registration()->waiting_version()->SetStatus( 4215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ServiceWorkerVersion::REDUNDANT); 4225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 423116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 424116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // "10. Set registration.waitingWorker to registration.installingWorker." 425116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // "11. Set registration.installingWorker to null." 426116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch registration()->SetWaitingVersion(new_version()); 427116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 428116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // "12. Run the [[UpdateState]] algorithm passing registration.waitingWorker 429116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // and "installed" as the arguments." 430116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch new_version()->SetStatus(ServiceWorkerVersion::INSTALLED); 431116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 4325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // TODO(michaeln): "13. If activateImmediate is true, then..." 433116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 4345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // "14. Wait until no document is using registration as their 4355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Service Worker registration." 4365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) registration()->ActivateWaitingVersionWhenReady(); 437a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch 438c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch Complete(SERVICE_WORKER_OK); 439a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 440a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 441a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void ServiceWorkerRegisterJob::Complete(ServiceWorkerStatusCode status) { 4426d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) CompleteInternal(status); 4436d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) context_->job_coordinator()->FinishJob(pattern_, this); 4446d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)} 4456d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) 4466d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)void ServiceWorkerRegisterJob::CompleteInternal( 4476d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) ServiceWorkerStatusCode status) { 448c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch SetPhase(COMPLETE); 4490529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (status != SERVICE_WORKER_OK) { 450116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (registration()) { 451116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (new_version()) { 452116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch registration()->UnsetVersion(new_version()); 453116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch new_version()->Doom(); 454116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 4556e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (!registration()->waiting_version() && 4566e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) !registration()->active_version()) { 4576e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) registration()->NotifyRegistrationFailed(); 458116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch context_->storage()->DeleteRegistration( 459116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch registration()->id(), 4601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci registration()->pattern().GetOrigin(), 461116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::Bind(&ServiceWorkerUtils::NoOpStatusCallback)); 462116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 4630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 4640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (!is_promise_resolved_) 4650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch ResolvePromise(status, NULL, NULL); 4660529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 4670529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch DCHECK(callbacks_.empty()); 468cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (registration()) { 469cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) context_->storage()->NotifyDoneInstallingRegistration( 470116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch registration(), new_version(), status); 471cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 472116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (new_version()) 473116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch new_version()->embedded_worker()->RemoveListener(this); 474c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 475c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 4760529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid ServiceWorkerRegisterJob::ResolvePromise( 477c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ServiceWorkerStatusCode status, 478c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ServiceWorkerRegistration* registration, 479c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ServiceWorkerVersion* version) { 4800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch DCHECK(!is_promise_resolved_); 4810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch is_promise_resolved_ = true; 4820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch promise_resolved_status_ = status; 4830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch promise_resolved_registration_ = registration; 4840529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch promise_resolved_version_ = version; 4855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (std::vector<RegistrationCallback>::iterator it = callbacks_.begin(); 4865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) it != callbacks_.end(); 4875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ++it) { 488c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch it->Run(status, registration, version); 4895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 490c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch callbacks_.clear(); 491a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 492a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 493116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid ServiceWorkerRegisterJob::OnPausedAfterDownload() { 4945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // This happens prior to OnStartWorkerFinished time. 4956e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) scoped_refptr<ServiceWorkerVersion> most_recent_version = 4966e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) registration()->waiting_version() ? 4976e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) registration()->waiting_version() : 4986e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) registration()->active_version(); 4991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(most_recent_version.get()); 5006e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) int64 most_recent_script_id = 5016e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) most_recent_version->script_cache_map()->Lookup(script_url_); 5025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int64 new_script_id = 5035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) new_version()->script_cache_map()->Lookup(script_url_); 5045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 5055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // TODO(michaeln): It would be better to compare as the new resource 5065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // is being downloaded and to avoid writing it to disk until we know 5075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // its needed. 5085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) context_->storage()->CompareScriptResources( 5096e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) most_recent_script_id, new_script_id, 5105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::Bind(&ServiceWorkerRegisterJob::OnCompareScriptResourcesComplete, 5115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) weak_factory_.GetWeakPtr(), 5126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) most_recent_version)); 513116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 514116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 515116680a4aac90f2aa7413d9095a592090648e557Ben Murdochbool ServiceWorkerRegisterJob::OnMessageReceived(const IPC::Message& message) { 516116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 517116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 518116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 5191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid ServiceWorkerRegisterJob::OnRegistrationFinishedUninstalling( 5201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ServiceWorkerRegistration* existing_registration) { 5211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK_EQ(phase_, WAIT_FOR_UNINSTALL); 5221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK_EQ(existing_registration, uninstalling_registration()); 5231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci existing_registration->RemoveListener(this); 5241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci set_uninstalling_registration(NULL); 5251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci RegisterAndContinue(SERVICE_WORKER_OK); 5261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 5271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 5285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void ServiceWorkerRegisterJob::OnCompareScriptResourcesComplete( 5296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) ServiceWorkerVersion* most_recent_version, 5305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ServiceWorkerStatusCode status, 5315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) bool are_equal) { 5325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (are_equal) { 5336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // Only bump the last check time when we've bypassed the browser cache. 5346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) base::TimeDelta time_since_last_check = 5356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) base::Time::Now() - registration()->last_update_check(); 5366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (time_since_last_check > base::TimeDelta::FromHours(24)) { 5376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) registration()->set_last_update_check(base::Time::Now()); 5386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) context_->storage()->UpdateLastUpdateCheckTime(registration()); 5396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) } 5406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 5416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) ResolvePromise(SERVICE_WORKER_OK, registration(), most_recent_version); 5425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) Complete(SERVICE_WORKER_ERROR_EXISTS); 5435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return; 5445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 5455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 5465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Proceed with really starting the worker. 5475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) new_version()->embedded_worker()->ResumeAfterDownload(); 5485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) new_version()->embedded_worker()->RemoveListener(this); 5495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 5505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 5516e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void ServiceWorkerRegisterJob::AssociateProviderHostsToRegistration( 5526e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) ServiceWorkerRegistration* registration) { 5536e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) DCHECK(registration); 554cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) for (scoped_ptr<ServiceWorkerContextCore::ProviderHostIterator> it = 5556e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) context_->GetProviderHostIterator(); 556116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch !it->IsAtEnd(); it->Advance()) { 557cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ServiceWorkerProviderHost* host = it->GetProviderHost(); 5586e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (ServiceWorkerUtils::ScopeMatches(registration->pattern(), 559116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch host->document_url())) { 5606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (host->CanAssociateRegistration(registration)) 5616e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) host->AssociateRegistration(registration); 562cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 5630529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch } 5640529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 5650529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 566a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} // namespace content 567