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

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

Issue 413063004: Service Worker: in Unregister, wait until after the active worker no longer controls a document (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase and merge Created 6 years, 4 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_registration.h" 5 #include "content/browser/service_worker/service_worker_registration.h"
6 6
7 #include "content/browser/service_worker/service_worker_context_core.h" 7 #include "content/browser/service_worker/service_worker_context_core.h"
8 #include "content/browser/service_worker/service_worker_info.h" 8 #include "content/browser/service_worker/service_worker_info.h"
9 #include "content/browser/service_worker/service_worker_register_job.h" 9 #include "content/browser/service_worker/service_worker_register_job.h"
10 #include "content/browser/service_worker/service_worker_utils.h" 10 #include "content/browser/service_worker/service_worker_utils.h"
(...skipping 13 matching lines...) Expand all
24 24
25 ServiceWorkerRegistration::ServiceWorkerRegistration( 25 ServiceWorkerRegistration::ServiceWorkerRegistration(
26 const GURL& pattern, 26 const GURL& pattern,
27 const GURL& script_url, 27 const GURL& script_url,
28 int64 registration_id, 28 int64 registration_id,
29 base::WeakPtr<ServiceWorkerContextCore> context) 29 base::WeakPtr<ServiceWorkerContextCore> context)
30 : pattern_(pattern), 30 : pattern_(pattern),
31 script_url_(script_url), 31 script_url_(script_url),
32 registration_id_(registration_id), 32 registration_id_(registration_id),
33 is_deleted_(false), 33 is_deleted_(false),
34 is_uninstalling_(false),
34 should_activate_when_ready_(false), 35 should_activate_when_ready_(false),
35 context_(context) { 36 context_(context) {
36 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 37 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
37 DCHECK(context_); 38 DCHECK(context_);
38 context_->AddLiveRegistration(this); 39 context_->AddLiveRegistration(this);
39 } 40 }
40 41
41 ServiceWorkerRegistration::~ServiceWorkerRegistration() { 42 ServiceWorkerRegistration::~ServiceWorkerRegistration() {
42 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 43 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
43 if (context_) 44 if (context_)
44 context_->RemoveLiveRegistration(registration_id_); 45 context_->RemoveLiveRegistration(registration_id_);
45 ResetShouldActivateWhenReady(); 46 if (should_activate_when_ready_ || is_uninstalling())
47 active_version()->RemoveListener(this);
46 } 48 }
47 49
48 void ServiceWorkerRegistration::AddListener(Listener* listener) { 50 void ServiceWorkerRegistration::AddListener(Listener* listener) {
49 listeners_.AddObserver(listener); 51 listeners_.AddObserver(listener);
50 } 52 }
51 53
52 void ServiceWorkerRegistration::RemoveListener(Listener* listener) { 54 void ServiceWorkerRegistration::RemoveListener(Listener* listener) {
53 listeners_.RemoveObserver(listener); 55 listeners_.RemoveObserver(listener);
54 } 56 }
55 57
56 ServiceWorkerRegistrationInfo ServiceWorkerRegistration::GetInfo() { 58 ServiceWorkerRegistrationInfo ServiceWorkerRegistration::GetInfo() {
57 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 59 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
58 return ServiceWorkerRegistrationInfo( 60 return ServiceWorkerRegistrationInfo(
59 script_url(), 61 script_url(),
60 pattern(), 62 pattern(),
61 registration_id_, 63 registration_id_,
62 GetVersionInfo(active_version_), 64 GetVersionInfo(active_version_),
63 GetVersionInfo(waiting_version_), 65 GetVersionInfo(waiting_version_),
64 GetVersionInfo(installing_version_)); 66 GetVersionInfo(installing_version_));
65 } 67 }
66 68
67 void ServiceWorkerRegistration::SetActiveVersion( 69 void ServiceWorkerRegistration::SetActiveVersion(
68 ServiceWorkerVersion* version) { 70 ServiceWorkerVersion* version) {
69 ResetShouldActivateWhenReady(); 71 SetShouldActivateWhenReady(false);
70 SetVersionInternal(version, &active_version_, 72 SetVersionInternal(version, &active_version_,
71 ChangedVersionAttributesMask::ACTIVE_VERSION); 73 ChangedVersionAttributesMask::ACTIVE_VERSION);
72 } 74 }
73 75
74 void ServiceWorkerRegistration::SetWaitingVersion( 76 void ServiceWorkerRegistration::SetWaitingVersion(
75 ServiceWorkerVersion* version) { 77 ServiceWorkerVersion* version) {
76 ResetShouldActivateWhenReady(); 78 SetShouldActivateWhenReady(false);
77 SetVersionInternal(version, &waiting_version_, 79 SetVersionInternal(version, &waiting_version_,
78 ChangedVersionAttributesMask::WAITING_VERSION); 80 ChangedVersionAttributesMask::WAITING_VERSION);
79 } 81 }
80 82
81 void ServiceWorkerRegistration::SetInstallingVersion( 83 void ServiceWorkerRegistration::SetInstallingVersion(
82 ServiceWorkerVersion* version) { 84 ServiceWorkerVersion* version) {
83 SetVersionInternal(version, &installing_version_, 85 SetVersionInternal(version, &installing_version_,
84 ChangedVersionAttributesMask::INSTALLING_VERSION); 86 ChangedVersionAttributesMask::INSTALLING_VERSION);
85 } 87 }
86 88
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
126 } else if (active_version_ == version) { 128 } else if (active_version_ == version) {
127 active_version_ = NULL; 129 active_version_ = NULL;
128 mask->add(ChangedVersionAttributesMask::ACTIVE_VERSION); 130 mask->add(ChangedVersionAttributesMask::ACTIVE_VERSION);
129 } 131 }
130 } 132 }
131 133
132 void ServiceWorkerRegistration::ActivateWaitingVersionWhenReady() { 134 void ServiceWorkerRegistration::ActivateWaitingVersionWhenReady() {
133 DCHECK(waiting_version()); 135 DCHECK(waiting_version());
134 if (should_activate_when_ready_) 136 if (should_activate_when_ready_)
135 return; 137 return;
136 if (active_version() && active_version()->HasControllee()) { 138 if (active_version() && active_version()->HasControllee())
139 SetShouldActivateWhenReady(true);
140 else
141 ActivateWaitingVersion();
142 }
143
144 bool ServiceWorkerRegistration::IsListeningForNoControllees() {
145 return active_version() && (should_activate_when_ready_ || is_uninstalling_);
146 }
147
148 void ServiceWorkerRegistration::SetShouldActivateWhenReady(
149 bool should_activate) {
150 if (should_activate_when_ready_ == should_activate)
151 return;
152 bool listening = IsListeningForNoControllees();
153 should_activate_when_ready_ = should_activate;
154 if (listening == IsListeningForNoControllees())
155 return;
156 if (IsListeningForNoControllees())
137 active_version()->AddListener(this); 157 active_version()->AddListener(this);
138 should_activate_when_ready_ = true; 158 else
159 active_version()->RemoveListener(this);
160 }
falken 2014/07/29 14:04:05 It may be better for Registration to always listen
michaeln 2014/07/31 00:08:07 sgtm
161
162 void ServiceWorkerRegistration::SetUninstalling(bool is_uninstalling) {
163 if (is_uninstalling_ == is_uninstalling)
139 return; 164 return;
140 } 165 bool listening = IsListeningForNoControllees();
141 ActivateWaitingVersion(); 166 is_uninstalling_ = is_uninstalling;
167 if (listening == IsListeningForNoControllees())
168 return;
169 if (IsListeningForNoControllees())
170 active_version()->AddListener(this);
171 else
172 active_version()->RemoveListener(this);
142 } 173 }
143 174
144 void ServiceWorkerRegistration::OnNoControllees(ServiceWorkerVersion* version) { 175 void ServiceWorkerRegistration::OnNoControllees(ServiceWorkerVersion* version) {
145 DCHECK_EQ(active_version(), version); 176 DCHECK_EQ(active_version(), version);
146 DCHECK(should_activate_when_ready_); 177 active_version()->RemoveListener(this);
147 active_version_->RemoveListener(this); 178 if (is_uninstalling())
179 Clear();
180 else if (should_activate_when_ready_)
181 ActivateWaitingVersion();
182 is_uninstalling_ = false;
148 should_activate_when_ready_ = false; 183 should_activate_when_ready_ = false;
149 ActivateWaitingVersion();
150 } 184 }
151 185
152 void ServiceWorkerRegistration::ActivateWaitingVersion() { 186 void ServiceWorkerRegistration::ActivateWaitingVersion() {
153 DCHECK(context_); 187 DCHECK(context_);
154 DCHECK(waiting_version()); 188 DCHECK(waiting_version());
155 scoped_refptr<ServiceWorkerVersion> activating_version = waiting_version(); 189 scoped_refptr<ServiceWorkerVersion> activating_version = waiting_version();
156 scoped_refptr<ServiceWorkerVersion> exiting_version = active_version(); 190 scoped_refptr<ServiceWorkerVersion> exiting_version = active_version();
157 191
158 if (activating_version->is_doomed() || 192 if (activating_version->is_doomed() ||
159 activating_version->status() == ServiceWorkerVersion::REDUNDANT) { 193 activating_version->status() == ServiceWorkerVersion::REDUNDANT) {
(...skipping 26 matching lines...) Expand all
186 activating_version->SetStatus(ServiceWorkerVersion::ACTIVATING); 220 activating_version->SetStatus(ServiceWorkerVersion::ACTIVATING);
187 221
188 // TODO(nhiroki): "8. Fire a simple event named controllerchange..." 222 // TODO(nhiroki): "8. Fire a simple event named controllerchange..."
189 223
190 // "9. Queue a task to fire an event named activate..." 224 // "9. Queue a task to fire an event named activate..."
191 activating_version->DispatchActivateEvent( 225 activating_version->DispatchActivateEvent(
192 base::Bind(&ServiceWorkerRegistration::OnActivateEventFinished, 226 base::Bind(&ServiceWorkerRegistration::OnActivateEventFinished,
193 this, activating_version)); 227 this, activating_version));
194 } 228 }
195 229
230 void ServiceWorkerRegistration::ClearWhenReady() {
231 DCHECK(context_);
232 if (is_uninstalling())
233 return;
234 context_->storage()->NotifyUninstallingRegistration(this);
235
236 // Delete from DB in case browser dies before we're ready.
237 context_->storage()->DeleteRegistration(
238 id(),
239 script_url().GetOrigin(),
240 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback));
241
242 if (active_version() && active_version()->HasControllee())
243 SetUninstalling(true);
244 else
245 Clear();
246 }
247
248 void ServiceWorkerRegistration::AbortPendingClear() {
249 DCHECK(context_);
250 if (!is_uninstalling())
251 return;
252 SetUninstalling(false);
253 context_->storage()->NotifyDoneUninstallingRegistration(this);
254
255 if (waiting_version()) {
256 context_->storage()->StoreRegistration(
257 this,
258 waiting_version(),
259 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback));
260 return;
261 }
262 if (active_version()) {
263 context_->storage()->StoreRegistration(
264 this,
265 active_version(),
266 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback));
267 }
268 }
269
196 void ServiceWorkerRegistration::OnActivateEventFinished( 270 void ServiceWorkerRegistration::OnActivateEventFinished(
197 ServiceWorkerVersion* activating_version, 271 ServiceWorkerVersion* activating_version,
198 ServiceWorkerStatusCode status) { 272 ServiceWorkerStatusCode status) {
199 if (!context_ || activating_version != active_version()) 273 if (!context_ || activating_version != active_version())
200 return; 274 return;
201 // TODO(kinuko,falken): For some error cases (e.g. ServiceWorker is 275 // TODO(kinuko,falken): For some error cases (e.g. ServiceWorker is
202 // unexpectedly terminated) we may want to retry sending the event again. 276 // unexpectedly terminated) we may want to retry sending the event again.
203 if (status != SERVICE_WORKER_OK) { 277 if (status != SERVICE_WORKER_OK) {
204 // "11. If activateFailed is true, then:..." 278 // "11. If activateFailed is true, then:..."
205 ServiceWorkerRegisterJob::DisassociateVersionFromDocuments( 279 ServiceWorkerRegisterJob::DisassociateVersionFromDocuments(
(...skipping 15 matching lines...) Expand all
221 // "12. Run the [[UpdateState]] algorithm passing registration.activeWorker 295 // "12. Run the [[UpdateState]] algorithm passing registration.activeWorker
222 // and "activated" as the arguments." 296 // and "activated" as the arguments."
223 activating_version->SetStatus(ServiceWorkerVersion::ACTIVATED); 297 activating_version->SetStatus(ServiceWorkerVersion::ACTIVATED);
224 if (context_) { 298 if (context_) {
225 context_->storage()->UpdateToActiveState( 299 context_->storage()->UpdateToActiveState(
226 this, 300 this,
227 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback)); 301 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback));
228 } 302 }
229 } 303 }
230 304
231 void ServiceWorkerRegistration::ResetShouldActivateWhenReady() {
232 if (should_activate_when_ready_) {
233 active_version()->RemoveListener(this);
234 should_activate_when_ready_ = false;
235 }
236 }
237
238 void ServiceWorkerRegistration::OnDeleteFinished( 305 void ServiceWorkerRegistration::OnDeleteFinished(
239 ServiceWorkerStatusCode status) { 306 ServiceWorkerStatusCode status) {
240 // Intentionally empty completion callback, used to prevent 307 // Intentionally empty completion callback, used to prevent
241 // |this| from being deleted until the storage method completes. 308 // |this| from being deleted until the storage method completes.
242 } 309 }
243 310
311 void ServiceWorkerRegistration::Clear() {
312 context_->storage()->NotifyDoneUninstallingRegistration(this);
313
314 if (installing_version()) {
315 installing_version()->Doom();
316 UnsetVersion(installing_version());
317 }
318
319 if (waiting_version()) {
320 waiting_version()->Doom();
321 UnsetVersion(waiting_version());
322 }
323
324 if (active_version()) {
325 active_version()->Doom();
326 UnsetVersion(active_version());
327 }
328 }
329
244 } // namespace content 330 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/service_worker/service_worker_registration.h ('k') | content/browser/service_worker/service_worker_storage.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698