OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |