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