Index: content/browser/service_worker/service_worker_register_job.cc |
diff --git a/content/browser/service_worker/service_worker_register_job.cc b/content/browser/service_worker/service_worker_register_job.cc |
index 0903cdb8f15ff818a3622e8e5dfdc70d6fae1236..cd9bab0255442a1cf4883d64ad8df62b5dc01af7 100644 |
--- a/content/browser/service_worker/service_worker_register_job.cc |
+++ b/content/browser/service_worker/service_worker_register_job.cc |
@@ -30,6 +30,7 @@ ServiceWorkerRegisterJob::ServiceWorkerRegisterJob( |
const GURL& pattern, |
const GURL& script_url) |
: context_(context), |
+ job_type_(REGISTRATION), |
pattern_(pattern), |
script_url_(script_url), |
phase_(INITIAL), |
@@ -37,6 +38,20 @@ ServiceWorkerRegisterJob::ServiceWorkerRegisterJob( |
promise_resolved_status_(SERVICE_WORKER_OK), |
weak_factory_(this) {} |
+ServiceWorkerRegisterJob::ServiceWorkerRegisterJob( |
+ base::WeakPtr<ServiceWorkerContextCore> context, |
+ ServiceWorkerRegistration* registration) |
+ : context_(context), |
+ job_type_(UPDATE_JOB), |
+ pattern_(registration->pattern()), |
+ script_url_(registration->script_url()), |
+ phase_(INITIAL), |
+ is_promise_resolved_(false), |
+ promise_resolved_status_(SERVICE_WORKER_OK), |
+ weak_factory_(this) { |
+ internal_.registration = registration; |
+} |
+ |
ServiceWorkerRegisterJob::~ServiceWorkerRegisterJob() { |
DCHECK(!context_ || |
phase_ == INITIAL || phase_ == COMPLETE || phase_ == ABORT) |
@@ -58,11 +73,18 @@ void ServiceWorkerRegisterJob::AddCallback(const RegistrationCallback& callback, |
void ServiceWorkerRegisterJob::Start() { |
SetPhase(START); |
+ ServiceWorkerStorage::FindRegistrationCallback next_step; |
+ if (job_type_ == REGISTRATION) { |
+ next_step = base::Bind( |
+ &ServiceWorkerRegisterJob::ContinueWithRegistration, |
+ weak_factory_.GetWeakPtr()); |
+ } else { |
nhiroki
2014/07/10 09:14:14
You may want to add "DCHECK_EQ(UPDATE_JOB, job_typ
|
+ next_step = base::Bind( |
+ &ServiceWorkerRegisterJob::ContinueWithUpdate, |
+ weak_factory_.GetWeakPtr()); |
+ } |
context_->storage()->FindRegistrationForPattern( |
- pattern_, |
- base::Bind( |
- &ServiceWorkerRegisterJob::HandleExistingRegistrationAndContinue, |
- weak_factory_.GetWeakPtr())); |
+ pattern_, next_step); |
} |
void ServiceWorkerRegisterJob::Abort() { |
@@ -82,7 +104,7 @@ bool ServiceWorkerRegisterJob::Equals(ServiceWorkerRegisterJobBase* job) { |
} |
RegistrationJobType ServiceWorkerRegisterJob::GetType() { |
- return REGISTRATION; |
+ return job_type_; |
} |
ServiceWorkerRegisterJob::Internal::Internal() {} |
@@ -149,9 +171,10 @@ void ServiceWorkerRegisterJob::SetPhase(Phase phase) { |
// "Let serviceWorkerRegistration be _GetRegistration(scope)" |
// |existing_registration| corresponds to serviceWorkerRegistration. |
// Throughout this file, comments in quotes are excerpts from the spec. |
-void ServiceWorkerRegisterJob::HandleExistingRegistrationAndContinue( |
+void ServiceWorkerRegisterJob::ContinueWithRegistration( |
ServiceWorkerStatusCode status, |
const scoped_refptr<ServiceWorkerRegistration>& existing_registration) { |
+ DCHECK_EQ(REGISTRATION, job_type_); |
// On unexpected error, abort this registration job. |
if (status != SERVICE_WORKER_ERROR_NOT_FOUND && status != SERVICE_WORKER_OK) { |
Complete(status); |
@@ -164,13 +187,6 @@ void ServiceWorkerRegisterJob::HandleExistingRegistrationAndContinue( |
if (existing_registration.get() && |
existing_registration->script_url() == script_url_) { |
set_registration(existing_registration); |
- // If there's no active version, go ahead to Update (this isn't in the spec |
- // but seems reasonable, and without SoftUpdate implemented we can never |
- // Update otherwise). |
- if (!existing_registration->active_version()) { |
- UpdateAndContinue(status); |
- return; |
- } |
ResolvePromise( |
status, existing_registration, existing_registration->active_version()); |
Complete(SERVICE_WORKER_OK); |
@@ -198,6 +214,24 @@ void ServiceWorkerRegisterJob::HandleExistingRegistrationAndContinue( |
weak_factory_.GetWeakPtr())); |
} |
+void ServiceWorkerRegisterJob::ContinueWithUpdate( |
+ ServiceWorkerStatusCode status, |
+ const scoped_refptr<ServiceWorkerRegistration>& existing_registration) { |
+ DCHECK_EQ(UPDATE, job_type_); |
+ if (status != SERVICE_WORKER_OK) { |
+ Complete(status); |
+ return; |
+ } |
+ |
+ if (existing_registration != registration()) { |
+ Complete(SERVICE_WORKER_ERROR_NOT_FOUND); |
+ return; |
+ } |
+ |
+ DCHECK(registration()->active_version()); |
+ UpdateAndContinue(status); |
+} |
+ |
// Creates a new ServiceWorkerRegistration. |
void ServiceWorkerRegisterJob::RegisterAndContinue( |
ServiceWorkerStatusCode status) { |
@@ -211,7 +245,6 @@ void ServiceWorkerRegisterJob::RegisterAndContinue( |
set_registration(new ServiceWorkerRegistration( |
pattern_, script_url_, context_->storage()->NewRegistrationId(), |
context_)); |
- context_->storage()->NotifyInstallingRegistration(registration()); |
UpdateAndContinue(SERVICE_WORKER_OK); |
} |
@@ -224,6 +257,7 @@ void ServiceWorkerRegisterJob::UpdateAndContinue( |
Complete(status); |
return; |
} |
+ context_->storage()->NotifyInstallingRegistration(registration()); |
// TODO(falken): "If serviceWorkerRegistration.installingWorker is not null.." |
// then terminate the installing worker. It doesn't make sense to implement |
@@ -235,8 +269,7 @@ void ServiceWorkerRegisterJob::UpdateAndContinue( |
set_new_version(new ServiceWorkerVersion( |
registration(), context_->storage()->NewVersionId(), context_)); |
- // TODO(michaeln): Pause after downloading when performing an update. |
- bool pause_after_download = false; |
+ bool pause_after_download = job_type_ == UPDATE_JOB; |
if (pause_after_download) |
new_version()->embedded_worker()->AddListener(this); |
new_version()->StartWorkerWithCandidateProcesses( |
@@ -431,19 +464,43 @@ void ServiceWorkerRegisterJob::ResolvePromise( |
} |
void ServiceWorkerRegisterJob::OnPausedAfterDownload() { |
- // TODO(michaeln): Compare the old and new script. |
- // If different unpause the worker and continue with |
- // the job. If the same ResolvePromise with the current |
- // version and complete the job, throwing away the new version |
- // since there's nothing new. |
- new_version()->embedded_worker()->RemoveListener(this); |
- new_version()->embedded_worker()->ResumeAfterDownload(); |
+ // This happens prior to OnStartWorkerFinished time. |
+ scoped_refptr<ServiceWorkerVersion> current_version = |
+ registration()->active_version(); |
+ DCHECK(current_version); |
+ int64 current_script_id = |
+ current_version->script_cache_map()->Lookup(script_url_); |
+ int64 new_script_id = |
+ new_version()->script_cache_map()->Lookup(script_url_); |
+ |
+ context_->storage()->CompareScriptResources( |
+ current_script_id, new_script_id, |
+ base::Bind(&ServiceWorkerRegisterJob::OnCompareScriptResourcesComplete, |
+ weak_factory_.GetWeakPtr(), |
+ current_version)); |
} |
bool ServiceWorkerRegisterJob::OnMessageReceived(const IPC::Message& message) { |
return false; |
} |
+void ServiceWorkerRegisterJob::OnCompareScriptResourcesComplete( |
+ ServiceWorkerVersion* current_version, |
+ ServiceWorkerStatusCode status, |
+ int compare_result) { |
+ if (compare_result == 0) { |
+ new_version()->embedded_worker()->Stop(); |
+ ResolvePromise( |
+ SERVICE_WORKER_OK, registration(), current_version); |
+ Complete(SERVICE_WORKER_ERROR_EXISTS); |
+ return; |
+ } |
+ |
+ // Proceed with really starting the worker. |
+ new_version()->embedded_worker()->ResumeAfterDownload(); |
+ new_version()->embedded_worker()->RemoveListener(this); |
+} |
+ |
// static |
void ServiceWorkerRegisterJob::AssociateInstallingVersionToDocuments( |
base::WeakPtr<ServiceWorkerContextCore> context, |