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

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: address comments 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 DCHECK(!listeners_.might_have_observers()); 44 DCHECK(!listeners_.might_have_observers());
44 if (context_) 45 if (context_)
45 context_->RemoveLiveRegistration(registration_id_); 46 context_->RemoveLiveRegistration(registration_id_);
46 ResetShouldActivateWhenReady(); 47 if (active_version())
48 active_version()->RemoveListener(this);
47 } 49 }
48 50
49 void ServiceWorkerRegistration::AddListener(Listener* listener) { 51 void ServiceWorkerRegistration::AddListener(Listener* listener) {
50 listeners_.AddObserver(listener); 52 listeners_.AddObserver(listener);
51 } 53 }
52 54
53 void ServiceWorkerRegistration::RemoveListener(Listener* listener) { 55 void ServiceWorkerRegistration::RemoveListener(Listener* listener) {
54 listeners_.RemoveObserver(listener); 56 listeners_.RemoveObserver(listener);
55 } 57 }
56 58
57 void ServiceWorkerRegistration::NotifyRegistrationFailed() { 59 void ServiceWorkerRegistration::NotifyRegistrationFailed() {
58 FOR_EACH_OBSERVER(Listener, listeners_, OnRegistrationFailed(this)); 60 FOR_EACH_OBSERVER(Listener, listeners_, OnRegistrationFailed(this));
59 } 61 }
60 62
61 ServiceWorkerRegistrationInfo ServiceWorkerRegistration::GetInfo() { 63 ServiceWorkerRegistrationInfo ServiceWorkerRegistration::GetInfo() {
62 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 64 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
63 return ServiceWorkerRegistrationInfo( 65 return ServiceWorkerRegistrationInfo(
64 script_url(), 66 script_url(),
65 pattern(), 67 pattern(),
66 registration_id_, 68 registration_id_,
67 GetVersionInfo(active_version_), 69 GetVersionInfo(active_version_),
68 GetVersionInfo(waiting_version_), 70 GetVersionInfo(waiting_version_),
69 GetVersionInfo(installing_version_)); 71 GetVersionInfo(installing_version_));
70 } 72 }
71 73
72 void ServiceWorkerRegistration::SetActiveVersion( 74 void ServiceWorkerRegistration::SetActiveVersion(
73 ServiceWorkerVersion* version) { 75 ServiceWorkerVersion* version) {
74 ResetShouldActivateWhenReady(); 76 should_activate_when_ready_ = false;
75 SetVersionInternal(version, &active_version_, 77 SetVersionInternal(version, &active_version_,
76 ChangedVersionAttributesMask::ACTIVE_VERSION); 78 ChangedVersionAttributesMask::ACTIVE_VERSION);
77 } 79 }
78 80
79 void ServiceWorkerRegistration::SetWaitingVersion( 81 void ServiceWorkerRegistration::SetWaitingVersion(
80 ServiceWorkerVersion* version) { 82 ServiceWorkerVersion* version) {
81 ResetShouldActivateWhenReady(); 83 should_activate_when_ready_ = false;
82 SetVersionInternal(version, &waiting_version_, 84 SetVersionInternal(version, &waiting_version_,
83 ChangedVersionAttributesMask::WAITING_VERSION); 85 ChangedVersionAttributesMask::WAITING_VERSION);
84 } 86 }
85 87
86 void ServiceWorkerRegistration::SetInstallingVersion( 88 void ServiceWorkerRegistration::SetInstallingVersion(
87 ServiceWorkerVersion* version) { 89 ServiceWorkerVersion* version) {
88 SetVersionInternal(version, &installing_version_, 90 SetVersionInternal(version, &installing_version_,
89 ChangedVersionAttributesMask::INSTALLING_VERSION); 91 ChangedVersionAttributesMask::INSTALLING_VERSION);
90 } 92 }
91 93
(...skipping 13 matching lines...) Expand all
105 ServiceWorkerVersion* version, 107 ServiceWorkerVersion* version,
106 scoped_refptr<ServiceWorkerVersion>* data_member, 108 scoped_refptr<ServiceWorkerVersion>* data_member,
107 int change_flag) { 109 int change_flag) {
108 if (version == data_member->get()) 110 if (version == data_member->get())
109 return; 111 return;
110 scoped_refptr<ServiceWorkerVersion> protect(version); 112 scoped_refptr<ServiceWorkerVersion> protect(version);
111 ChangedVersionAttributesMask mask; 113 ChangedVersionAttributesMask mask;
112 if (version) 114 if (version)
113 UnsetVersionInternal(version, &mask); 115 UnsetVersionInternal(version, &mask);
114 *data_member = version; 116 *data_member = version;
117 if (active_version_ && active_version_ == version)
118 active_version_->AddListener(this);
115 mask.add(change_flag); 119 mask.add(change_flag);
116 ServiceWorkerRegistrationInfo info = GetInfo(); 120 ServiceWorkerRegistrationInfo info = GetInfo();
117 FOR_EACH_OBSERVER(Listener, listeners_, 121 FOR_EACH_OBSERVER(Listener, listeners_,
118 OnVersionAttributesChanged(this, mask, info)); 122 OnVersionAttributesChanged(this, mask, info));
119 } 123 }
120 124
121 void ServiceWorkerRegistration::UnsetVersionInternal( 125 void ServiceWorkerRegistration::UnsetVersionInternal(
122 ServiceWorkerVersion* version, 126 ServiceWorkerVersion* version,
123 ChangedVersionAttributesMask* mask) { 127 ChangedVersionAttributesMask* mask) {
124 DCHECK(version); 128 DCHECK(version);
125 if (installing_version_ == version) { 129 if (installing_version_ == version) {
126 installing_version_ = NULL; 130 installing_version_ = NULL;
127 mask->add(ChangedVersionAttributesMask::INSTALLING_VERSION); 131 mask->add(ChangedVersionAttributesMask::INSTALLING_VERSION);
128 } else if (waiting_version_ == version) { 132 } else if (waiting_version_ == version) {
129 waiting_version_ = NULL; 133 waiting_version_ = NULL;
130 mask->add(ChangedVersionAttributesMask::WAITING_VERSION); 134 mask->add(ChangedVersionAttributesMask::WAITING_VERSION);
131 } else if (active_version_ == version) { 135 } else if (active_version_ == version) {
136 active_version_->RemoveListener(this);
132 active_version_ = NULL; 137 active_version_ = NULL;
133 mask->add(ChangedVersionAttributesMask::ACTIVE_VERSION); 138 mask->add(ChangedVersionAttributesMask::ACTIVE_VERSION);
134 } 139 }
135 } 140 }
136 141
137 void ServiceWorkerRegistration::ActivateWaitingVersionWhenReady() { 142 void ServiceWorkerRegistration::ActivateWaitingVersionWhenReady() {
138 DCHECK(waiting_version()); 143 DCHECK(waiting_version());
139 if (should_activate_when_ready_) 144 should_activate_when_ready_ = true;
145 if (!active_version() || !active_version()->HasControllee())
146 ActivateWaitingVersion();
147 }
148
149 void ServiceWorkerRegistration::ClearWhenReady() {
150 DCHECK(context_);
151 if (is_uninstalling_)
140 return; 152 return;
141 if (active_version() && active_version()->HasControllee()) { 153 is_uninstalling_ = true;
142 active_version()->AddListener(this); 154
143 should_activate_when_ready_ = true; 155 context_->storage()->NotifyUninstallingRegistration(this);
156 context_->storage()->DeleteRegistration(
157 id(),
158 script_url().GetOrigin(),
159 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback));
160
161 if (!active_version() || !active_version()->HasControllee())
162 Clear();
163 }
164
165 void ServiceWorkerRegistration::AbortPendingClear() {
166 DCHECK(context_);
167 if (!is_uninstalling())
144 return; 168 return;
145 } 169 is_uninstalling_ = false;
146 ActivateWaitingVersion(); 170 context_->storage()->NotifyDoneUninstallingRegistration(this);
171
172 scoped_refptr<ServiceWorkerVersion> most_recent_version =
173 waiting_version() ? waiting_version() : active_version();
174 DCHECK(most_recent_version);
falken 2014/08/12 09:06:06 My earlier patches handled the case where there is
175 context_->storage()->NotifyInstallingRegistration(this);
176 context_->storage()->StoreRegistration(
177 this,
178 most_recent_version,
179 base::Bind(&ServiceWorkerRegistration::OnStoreFinished,
180 this,
181 most_recent_version));
147 } 182 }
148 183
149 void ServiceWorkerRegistration::OnNoControllees(ServiceWorkerVersion* version) { 184 void ServiceWorkerRegistration::OnNoControllees(ServiceWorkerVersion* version) {
150 DCHECK_EQ(active_version(), version); 185 DCHECK_EQ(active_version(), version);
151 DCHECK(should_activate_when_ready_); 186 if (is_uninstalling_)
152 active_version_->RemoveListener(this); 187 Clear();
188 else if (should_activate_when_ready_)
189 ActivateWaitingVersion();
190 is_uninstalling_ = false;
153 should_activate_when_ready_ = false; 191 should_activate_when_ready_ = false;
154 ActivateWaitingVersion();
155 } 192 }
156 193
157 void ServiceWorkerRegistration::ActivateWaitingVersion() { 194 void ServiceWorkerRegistration::ActivateWaitingVersion() {
158 DCHECK(context_); 195 DCHECK(context_);
159 DCHECK(waiting_version()); 196 DCHECK(waiting_version());
197 DCHECK(should_activate_when_ready_);
198 should_activate_when_ready_ = false;
160 scoped_refptr<ServiceWorkerVersion> activating_version = waiting_version(); 199 scoped_refptr<ServiceWorkerVersion> activating_version = waiting_version();
161 scoped_refptr<ServiceWorkerVersion> exiting_version = active_version(); 200 scoped_refptr<ServiceWorkerVersion> exiting_version = active_version();
162 201
163 if (activating_version->is_doomed() || 202 if (activating_version->is_doomed() ||
164 activating_version->status() == ServiceWorkerVersion::REDUNDANT) { 203 activating_version->status() == ServiceWorkerVersion::REDUNDANT) {
165 return; // Activation is no longer relevant. 204 return; // Activation is no longer relevant.
166 } 205 }
167 206
168 // "4. If exitingWorker is not null, 207 // "4. If exitingWorker is not null,
169 if (exiting_version) { 208 if (exiting_version) {
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
220 // "12. Run the [[UpdateState]] algorithm passing registration.activeWorker 259 // "12. Run the [[UpdateState]] algorithm passing registration.activeWorker
221 // and "activated" as the arguments." 260 // and "activated" as the arguments."
222 activating_version->SetStatus(ServiceWorkerVersion::ACTIVATED); 261 activating_version->SetStatus(ServiceWorkerVersion::ACTIVATED);
223 if (context_) { 262 if (context_) {
224 context_->storage()->UpdateToActiveState( 263 context_->storage()->UpdateToActiveState(
225 this, 264 this,
226 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback)); 265 base::Bind(&ServiceWorkerUtils::NoOpStatusCallback));
227 } 266 }
228 } 267 }
229 268
230 void ServiceWorkerRegistration::ResetShouldActivateWhenReady() {
231 if (should_activate_when_ready_) {
232 active_version()->RemoveListener(this);
233 should_activate_when_ready_ = false;
234 }
235 }
236
237 void ServiceWorkerRegistration::OnDeleteFinished( 269 void ServiceWorkerRegistration::OnDeleteFinished(
238 ServiceWorkerStatusCode status) { 270 ServiceWorkerStatusCode status) {
239 // Intentionally empty completion callback, used to prevent 271 // Intentionally empty completion callback, used to prevent
240 // |this| from being deleted until the storage method completes. 272 // |this| from being deleted until the storage method completes.
241 } 273 }
242 274
275 void ServiceWorkerRegistration::Clear() {
276 context_->storage()->NotifyDoneUninstallingRegistration(this);
277
278 if (installing_version()) {
279 installing_version()->Doom();
280 UnsetVersion(installing_version());
281 }
282
283 if (waiting_version()) {
284 waiting_version()->Doom();
285 UnsetVersion(waiting_version());
286 }
287
288 if (active_version()) {
289 active_version()->Doom();
290 UnsetVersion(active_version());
291 }
292 }
293
294 void ServiceWorkerRegistration::OnStoreFinished(
295 scoped_refptr<ServiceWorkerVersion> version,
296 ServiceWorkerStatusCode status) {
297 if (!context_)
298 return;
299 context_->storage()->NotifyDoneInstallingRegistration(
300 this, version.get(), status);
301 }
302
243 } // namespace content 303 } // 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