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

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: more cleanup 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 (active_version())
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 should_activate_when_ready_ = 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 should_activate_when_ready_ = 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 13 matching lines...) Expand all
100 ServiceWorkerVersion* version, 102 ServiceWorkerVersion* version,
101 scoped_refptr<ServiceWorkerVersion>* data_member, 103 scoped_refptr<ServiceWorkerVersion>* data_member,
102 int change_flag) { 104 int change_flag) {
103 if (version == data_member->get()) 105 if (version == data_member->get())
104 return; 106 return;
105 scoped_refptr<ServiceWorkerVersion> protect(version); 107 scoped_refptr<ServiceWorkerVersion> protect(version);
106 ChangedVersionAttributesMask mask; 108 ChangedVersionAttributesMask mask;
107 if (version) 109 if (version)
108 UnsetVersionInternal(version, &mask); 110 UnsetVersionInternal(version, &mask);
109 *data_member = version; 111 *data_member = version;
112 if (active_version_ && active_version_ == version)
113 active_version_->AddListener(this);
110 mask.add(change_flag); 114 mask.add(change_flag);
111 ServiceWorkerRegistrationInfo info = GetInfo(); 115 ServiceWorkerRegistrationInfo info = GetInfo();
112 FOR_EACH_OBSERVER(Listener, listeners_, 116 FOR_EACH_OBSERVER(Listener, listeners_,
113 OnVersionAttributesChanged(this, mask, info)); 117 OnVersionAttributesChanged(this, mask, info));
114 } 118 }
115 119
116 void ServiceWorkerRegistration::UnsetVersionInternal( 120 void ServiceWorkerRegistration::UnsetVersionInternal(
117 ServiceWorkerVersion* version, 121 ServiceWorkerVersion* version,
118 ChangedVersionAttributesMask* mask) { 122 ChangedVersionAttributesMask* mask) {
119 DCHECK(version); 123 DCHECK(version);
120 if (installing_version_ == version) { 124 if (installing_version_ == version) {
121 installing_version_ = NULL; 125 installing_version_ = NULL;
122 mask->add(ChangedVersionAttributesMask::INSTALLING_VERSION); 126 mask->add(ChangedVersionAttributesMask::INSTALLING_VERSION);
123 } else if (waiting_version_ == version) { 127 } else if (waiting_version_ == version) {
124 waiting_version_ = NULL; 128 waiting_version_ = NULL;
125 mask->add(ChangedVersionAttributesMask::WAITING_VERSION); 129 mask->add(ChangedVersionAttributesMask::WAITING_VERSION);
126 } else if (active_version_ == version) { 130 } else if (active_version_ == version) {
131 active_version_->RemoveListener(this);
127 active_version_ = NULL; 132 active_version_ = NULL;
128 mask->add(ChangedVersionAttributesMask::ACTIVE_VERSION); 133 mask->add(ChangedVersionAttributesMask::ACTIVE_VERSION);
129 } 134 }
130 } 135 }
131 136
132 void ServiceWorkerRegistration::ActivateWaitingVersionWhenReady() { 137 void ServiceWorkerRegistration::ActivateWaitingVersionWhenReady() {
133 DCHECK(waiting_version()); 138 DCHECK(waiting_version());
134 if (should_activate_when_ready_) 139 should_activate_when_ready_ = true;
135 return; 140 if (!active_version() || !active_version()->HasControllee())
136 if (active_version() && active_version()->HasControllee()) { 141 ActivateWaitingVersion();
137 active_version()->AddListener(this);
138 should_activate_when_ready_ = true;
139 return;
140 }
141 ActivateWaitingVersion();
142 } 142 }
143 143
144 void ServiceWorkerRegistration::OnNoControllees(ServiceWorkerVersion* version) { 144 void ServiceWorkerRegistration::OnNoControllees(ServiceWorkerVersion* version) {
145 DCHECK_EQ(active_version(), version); 145 DCHECK_EQ(active_version(), version);
146 DCHECK(should_activate_when_ready_); 146 if (is_uninstalling_)
147 active_version_->RemoveListener(this); 147 Clear();
148 else if (should_activate_when_ready_)
149 ActivateWaitingVersion();
150 is_uninstalling_ = false;
148 should_activate_when_ready_ = false; 151 should_activate_when_ready_ = false;
149 ActivateWaitingVersion();
150 } 152 }
151 153
152 void ServiceWorkerRegistration::ActivateWaitingVersion() { 154 void ServiceWorkerRegistration::ActivateWaitingVersion() {
153 DCHECK(context_); 155 DCHECK(context_);
154 DCHECK(waiting_version()); 156 DCHECK(waiting_version());
157 DCHECK(should_activate_when_ready_);
158 should_activate_when_ready_ = false;
155 scoped_refptr<ServiceWorkerVersion> activating_version = waiting_version(); 159 scoped_refptr<ServiceWorkerVersion> activating_version = waiting_version();
156 scoped_refptr<ServiceWorkerVersion> exiting_version = active_version(); 160 scoped_refptr<ServiceWorkerVersion> exiting_version = active_version();
157 161
158 if (activating_version->is_doomed() || 162 if (activating_version->is_doomed() ||
159 activating_version->status() == ServiceWorkerVersion::REDUNDANT) { 163 activating_version->status() == ServiceWorkerVersion::REDUNDANT) {
160 return; // Activation is no longer relevant. 164 return; // Activation is no longer relevant.
161 } 165 }
162 166
163 // "4. If exitingWorker is not null, 167 // "4. If exitingWorker is not null,
164 if (exiting_version) { 168 if (exiting_version) {
(...skipping 21 matching lines...) Expand all
186 activating_version->SetStatus(ServiceWorkerVersion::ACTIVATING); 190 activating_version->SetStatus(ServiceWorkerVersion::ACTIVATING);
187 191
188 // TODO(nhiroki): "8. Fire a simple event named controllerchange..." 192 // TODO(nhiroki): "8. Fire a simple event named controllerchange..."
189 193
190 // "9. Queue a task to fire an event named activate..." 194 // "9. Queue a task to fire an event named activate..."
191 activating_version->DispatchActivateEvent( 195 activating_version->DispatchActivateEvent(
192 base::Bind(&ServiceWorkerRegistration::OnActivateEventFinished, 196 base::Bind(&ServiceWorkerRegistration::OnActivateEventFinished,
193 this, activating_version)); 197 this, activating_version));
194 } 198 }
195 199
200 void ServiceWorkerRegistration::ClearWhenReady() {
201 DCHECK(context_);
202 if (is_uninstalling_)
203 return;
204 is_uninstalling_ = true;
205 context_->storage()->NotifyUninstallingRegistration(this);
michaeln 2014/08/12 02:15:35 I think the call to DeleteRegistration(id()) shoul
falken 2014/08/12 09:06:06 I see your point. Done.
206
207 if (!active_version() || !active_version()->HasControllee())
208 Clear();
209 }
210
211 void ServiceWorkerRegistration::AbortPendingClear() {
212 DCHECK(context_);
213 if (!is_uninstalling())
214 return;
215 is_uninstalling_ = false;
216 context_->storage()->NotifyAbortedUninstallingRegistration(this);
michaeln 2014/08/12 02:15:35 Ditto the call to (re) StoreRegistration() should
falken 2014/08/12 09:06:06 Done.
217 }
218
196 void ServiceWorkerRegistration::OnActivateEventFinished( 219 void ServiceWorkerRegistration::OnActivateEventFinished(
197 ServiceWorkerVersion* activating_version, 220 ServiceWorkerVersion* activating_version,
198 ServiceWorkerStatusCode status) { 221 ServiceWorkerStatusCode status) {
199 if (!context_ || activating_version != active_version()) 222 if (!context_ || activating_version != active_version())
200 return; 223 return;
201 // TODO(kinuko,falken): For some error cases (e.g. ServiceWorker is 224 // TODO(kinuko,falken): For some error cases (e.g. ServiceWorker is
202 // unexpectedly terminated) we may want to retry sending the event again. 225 // unexpectedly terminated) we may want to retry sending the event again.
203 if (status != SERVICE_WORKER_OK) { 226 if (status != SERVICE_WORKER_OK) {
204 // "11. If activateFailed is true, then:..." 227 // "11. If activateFailed is true, then:..."
205 ServiceWorkerRegisterJob::DisassociateVersionFromDocuments( 228 ServiceWorkerRegisterJob::DisassociateVersionFromDocuments(
(...skipping 15 matching lines...) Expand all
221 // "12. Run the [[UpdateState]] algorithm passing registration.activeWorker 244 // "12. Run the [[UpdateState]] algorithm passing registration.activeWorker
222 // and "activated" as the arguments." 245 // and "activated" as the arguments."
223 activating_version->SetStatus(ServiceWorkerVersion::ACTIVATED); 246 activating_version->SetStatus(ServiceWorkerVersion::ACTIVATED);
224 if (context_) { 247 if (context_) {
225 context_->storage()->UpdateToActiveState( 248 context_->storage()->UpdateToActiveState(
226 this, 249 this,
227 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback)); 250 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback));
228 } 251 }
229 } 252 }
230 253
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( 254 void ServiceWorkerRegistration::OnDeleteFinished(
239 ServiceWorkerStatusCode status) { 255 ServiceWorkerStatusCode status) {
240 // Intentionally empty completion callback, used to prevent 256 // Intentionally empty completion callback, used to prevent
241 // |this| from being deleted until the storage method completes. 257 // |this| from being deleted until the storage method completes.
242 } 258 }
243 259
260 void ServiceWorkerRegistration::Clear() {
261 context_->storage()->NotifyUninstalledRegistration(this);
262
263 if (installing_version()) {
264 installing_version()->Doom();
265 UnsetVersion(installing_version());
266 }
267
268 if (waiting_version()) {
269 waiting_version()->Doom();
270 UnsetVersion(waiting_version());
271 }
272
273 if (active_version()) {
274 active_version()->Doom();
275 UnsetVersion(active_version());
276 }
277 }
278
244 } // namespace content 279 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698