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
3 // found in the LICENSE file.
5 #include "content/browser/service_worker/service_worker_register_job.h"
9 #include "content/browser/service_worker/service_worker_job_coordinator.h"
10 #include "content/browser/service_worker/service_worker_registration.h"
11 #include "content/public/browser/browser_thread.h"
16 ServiceWorkerRegisterJob::ServiceWorkerRegisterJob(
17 ServiceWorkerStorage* storage,
18 ServiceWorkerJobCoordinator* coordinator,
20 const GURL& script_url,
21 RegistrationType type)
23 coordinator_(coordinator),
25 script_url_(script_url),
27 weak_factory_(this) {}
29 ServiceWorkerRegisterJob::~ServiceWorkerRegisterJob() {}
31 void ServiceWorkerRegisterJob::AddCallback(
32 const RegistrationCallback& callback) {
33 callbacks_.push_back(callback);
36 void ServiceWorkerRegisterJob::Start() {
37 if (type_ == REGISTER)
43 bool ServiceWorkerRegisterJob::Equals(ServiceWorkerRegisterJob* job) {
44 return job->type_ == type_ &&
45 (type_ == ServiceWorkerRegisterJob::UNREGISTER ||
46 job->script_url_ == script_url_);
49 void ServiceWorkerRegisterJob::StartRegister() {
50 // Set up a chain of callbacks, in reverse order. Each of these
51 // callbacks may be called asynchronously by the previous callback.
52 RegistrationCallback finish_registration(base::Bind(
53 &ServiceWorkerRegisterJob::RegisterComplete, weak_factory_.GetWeakPtr()));
55 UnregistrationCallback register_new(
56 base::Bind(&ServiceWorkerRegisterJob::RegisterPatternAndContinue,
57 weak_factory_.GetWeakPtr(),
58 finish_registration));
60 ServiceWorkerStorage::FindRegistrationCallback unregister_old(
61 base::Bind(&ServiceWorkerRegisterJob::UnregisterPatternAndContinue,
62 weak_factory_.GetWeakPtr(),
65 storage_->FindRegistrationForPattern(pattern_, unregister_old);
68 void ServiceWorkerRegisterJob::StartUnregister() {
69 // Set up a chain of callbacks, in reverse order. Each of these
70 // callbacks may be called asynchronously by the previous callback.
71 UnregistrationCallback finish_unregistration(
72 base::Bind(&ServiceWorkerRegisterJob::UnregisterComplete,
73 weak_factory_.GetWeakPtr()));
75 ServiceWorkerStorage::FindRegistrationCallback unregister(
76 base::Bind(&ServiceWorkerRegisterJob::UnregisterPatternAndContinue,
77 weak_factory_.GetWeakPtr(),
78 finish_unregistration));
80 storage_->FindRegistrationForPattern(pattern_, unregister);
83 void ServiceWorkerRegisterJob::RegisterPatternAndContinue(
84 const RegistrationCallback& callback,
85 ServiceWorkerStatusCode previous_status) {
86 if (previous_status != SERVICE_WORKER_OK) {
87 BrowserThread::PostTask(
92 scoped_refptr<ServiceWorkerRegistration>()));
96 // TODO: Eventually RegisterInternal will be replaced by an asynchronous
97 // operation. Pass its resulting status through 'callback'.
98 scoped_refptr<ServiceWorkerRegistration> registration =
99 storage_->RegisterInternal(pattern_, script_url_);
100 BrowserThread::PostTask(BrowserThread::IO,
102 base::Bind(callback, SERVICE_WORKER_OK,
106 void ServiceWorkerRegisterJob::UnregisterPatternAndContinue(
107 const UnregistrationCallback& callback,
109 ServiceWorkerStatusCode previous_status,
110 const scoped_refptr<ServiceWorkerRegistration>& previous_registration) {
112 // The previous registration may not exist, which is ok.
113 if (previous_status == SERVICE_WORKER_OK && found &&
114 (script_url_.is_empty() ||
115 previous_registration->script_url() != script_url_)) {
116 // TODO: Eventually UnregisterInternal will be replaced by an
117 // asynchronous operation. Pass its resulting status though
119 storage_->UnregisterInternal(pattern_);
120 DCHECK(previous_registration->is_shutdown());
122 BrowserThread::PostTask(
123 BrowserThread::IO, FROM_HERE, base::Bind(callback, previous_status));
126 void ServiceWorkerRegisterJob::RunCallbacks(
127 ServiceWorkerStatusCode status,
128 const scoped_refptr<ServiceWorkerRegistration>& registration) {
129 for (std::vector<RegistrationCallback>::iterator it = callbacks_.begin();
130 it != callbacks_.end();
132 it->Run(status, registration);
135 void ServiceWorkerRegisterJob::RegisterComplete(
136 ServiceWorkerStatusCode status,
137 const scoped_refptr<ServiceWorkerRegistration>& registration) {
138 RunCallbacks(status, registration);
139 coordinator_->FinishJob(pattern_, this);
142 void ServiceWorkerRegisterJob::UnregisterComplete(
143 ServiceWorkerStatusCode status) {
144 RunCallbacks(status, NULL);
145 coordinator_->FinishJob(pattern_, this);
148 } // namespace content