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_provider_host.h" | 5 #include "content/browser/service_worker/service_worker_provider_host.h" |
| 6 | 6 |
| 7 #include "base/stl_util.h" | 7 #include "base/stl_util.h" |
| 8 #include "content/browser/frame_host/frame_tree.h" | 8 #include "content/browser/frame_host/frame_tree.h" |
| 9 #include "content/browser/frame_host/frame_tree_node.h" | 9 #include "content/browser/frame_host/frame_tree_node.h" |
| 10 #include "content/browser/frame_host/render_frame_host_impl.h" | 10 #include "content/browser/frame_host/render_frame_host_impl.h" |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 107 render_thread_id_ = kInvalidEmbeddedWorkerThreadId; | 107 render_thread_id_ = kInvalidEmbeddedWorkerThreadId; |
| 108 } | 108 } |
| 109 } | 109 } |
| 110 | 110 |
| 111 ServiceWorkerProviderHost::~ServiceWorkerProviderHost() { | 111 ServiceWorkerProviderHost::~ServiceWorkerProviderHost() { |
| 112 // Clear docurl so the deferred activation of a waiting worker | 112 // Clear docurl so the deferred activation of a waiting worker |
| 113 // won't associate the new version with a provider being destroyed. | 113 // won't associate the new version with a provider being destroyed. |
| 114 document_url_ = GURL(); | 114 document_url_ = GURL(); |
| 115 if (controlling_version_.get()) | 115 if (controlling_version_.get()) |
| 116 controlling_version_->RemoveControllee(this); | 116 controlling_version_->RemoveControllee(this); |
| 117 if (associated_registration_.get()) { | 117 |
| 118 DecreaseProcessReference(associated_registration_->pattern()); | 118 for (auto& key_registration : matching_registrations_) { |
| 119 associated_registration_->RemoveListener(this); | 119 DecreaseProcessReference(key_registration.second->pattern()); |
| 120 key_registration.second->RemoveListener(this); | |
| 120 } | 121 } |
| 121 | 122 |
| 122 for (const GURL& pattern : associated_patterns_) | 123 for (const GURL& pattern : associated_patterns_) |
| 123 DecreaseProcessReference(pattern); | 124 DecreaseProcessReference(pattern); |
| 124 } | 125 } |
| 125 | 126 |
| 127 void ServiceWorkerProviderHost::OnVersionAttributesChanged( | |
| 128 ServiceWorkerRegistration* registration, | |
| 129 ChangedVersionAttributesMask changed_mask, | |
| 130 const ServiceWorkerRegistrationInfo& info) { | |
| 131 ReturnRegistrationForReadyIfNeeded(); | |
| 132 } | |
| 133 | |
| 126 void ServiceWorkerProviderHost::OnRegistrationFailed( | 134 void ServiceWorkerProviderHost::OnRegistrationFailed( |
| 127 ServiceWorkerRegistration* registration) { | 135 ServiceWorkerRegistration* registration) { |
| 128 DCHECK_EQ(associated_registration_.get(), registration); | 136 if (associated_registration_ == registration) |
| 129 DisassociateRegistration(); | 137 DisassociateRegistration(); |
|
falken
2015/02/16 09:18:29
Shouldn't you RemoveMatchingRegistration in this c
xiang
2015/02/26 06:52:14
You're right, done.
| |
| 138 else | |
| 139 RemoveMatchingRegistration(registration); | |
| 140 } | |
| 141 | |
| 142 void ServiceWorkerProviderHost::OnRegistrationFinishedUninstalling( | |
| 143 ServiceWorkerRegistration* registration) { | |
| 144 RemoveMatchingRegistration(registration); | |
| 130 } | 145 } |
| 131 | 146 |
| 132 void ServiceWorkerProviderHost::OnSkippedWaiting( | 147 void ServiceWorkerProviderHost::OnSkippedWaiting( |
| 133 ServiceWorkerRegistration* registration) { | 148 ServiceWorkerRegistration* registration) { |
| 134 DCHECK_EQ(associated_registration_.get(), registration); | 149 if (associated_registration_ != registration) |
| 150 return; | |
| 135 // A client is "using" a registration if it is controlled by the active | 151 // A client is "using" a registration if it is controlled by the active |
| 136 // worker of the registration. skipWaiting doesn't cause a client to start | 152 // worker of the registration. skipWaiting doesn't cause a client to start |
| 137 // using the registration. | 153 // using the registration. |
| 138 if (!controlling_version_) | 154 if (!controlling_version_) |
| 139 return; | 155 return; |
| 140 ServiceWorkerVersion* active_version = registration->active_version(); | 156 ServiceWorkerVersion* active_version = registration->active_version(); |
| 141 DCHECK_EQ(active_version->status(), ServiceWorkerVersion::ACTIVATING); | 157 DCHECK_EQ(active_version->status(), ServiceWorkerVersion::ACTIVATING); |
| 142 SetControllerVersionAttribute(active_version); | 158 SetControllerVersionAttribute(active_version); |
| 143 } | 159 } |
| 144 | 160 |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 195 return false; | 211 return false; |
| 196 } | 212 } |
| 197 | 213 |
| 198 running_hosted_version_ = live_version; | 214 running_hosted_version_ = live_version; |
| 199 return true; | 215 return true; |
| 200 } | 216 } |
| 201 | 217 |
| 202 void ServiceWorkerProviderHost::AssociateRegistration( | 218 void ServiceWorkerProviderHost::AssociateRegistration( |
| 203 ServiceWorkerRegistration* registration) { | 219 ServiceWorkerRegistration* registration) { |
| 204 DCHECK(CanAssociateRegistration(registration)); | 220 DCHECK(CanAssociateRegistration(registration)); |
| 205 IncreaseProcessReference(registration->pattern()); | |
| 206 associated_registration_ = registration; | 221 associated_registration_ = registration; |
| 207 associated_registration_->AddListener(this); | 222 AddMatchingRegistration(registration); |
| 208 SendAssociateRegistrationMessage(); | 223 SendAssociateRegistrationMessage(); |
| 209 SetControllerVersionAttribute(registration->active_version()); | 224 SetControllerVersionAttribute(registration->active_version()); |
| 210 } | 225 } |
| 211 | 226 |
| 212 void ServiceWorkerProviderHost::DisassociateRegistration() { | 227 void ServiceWorkerProviderHost::DisassociateRegistration() { |
| 213 queued_events_.clear(); | 228 queued_events_.clear(); |
| 214 if (!associated_registration_.get()) | 229 if (!associated_registration_.get()) |
| 215 return; | 230 return; |
| 216 DecreaseProcessReference(associated_registration_->pattern()); | |
| 217 associated_registration_->RemoveListener(this); | |
| 218 associated_registration_ = NULL; | 231 associated_registration_ = NULL; |
| 219 SetControllerVersionAttribute(NULL); | 232 SetControllerVersionAttribute(NULL); |
| 220 | 233 |
| 221 if (!dispatcher_host_) | 234 if (!dispatcher_host_) |
| 222 return; | 235 return; |
| 223 | 236 |
| 224 // Disassociation message should be sent only for the document context. | 237 // Disassociation message should be sent only for the document context. |
| 225 DCHECK_EQ(kDocumentMainThreadId, render_thread_id_); | 238 DCHECK_EQ(kDocumentMainThreadId, render_thread_id_); |
| 226 Send(new ServiceWorkerMsg_DisassociateRegistration( | 239 Send(new ServiceWorkerMsg_DisassociateRegistration( |
| 227 render_thread_id_, provider_id())); | 240 render_thread_id_, provider_id())); |
| 228 } | 241 } |
| 229 | 242 |
| 243 void ServiceWorkerProviderHost::AddMatchingRegistration( | |
| 244 ServiceWorkerRegistration* registration) { | |
| 245 DCHECK(ServiceWorkerUtils::ScopeMatches( | |
| 246 registration->pattern(), document_url_)); | |
| 247 size_t key = registration->pattern().spec().size(); | |
| 248 if (ContainsKey(matching_registrations_, key)) | |
| 249 return; | |
| 250 IncreaseProcessReference(registration->pattern()); | |
| 251 registration->AddListener(this); | |
| 252 matching_registrations_[key] = registration; | |
| 253 ReturnRegistrationForReadyIfNeeded(); | |
| 254 } | |
| 255 | |
| 256 void ServiceWorkerProviderHost::RemoveMatchingRegistration( | |
| 257 ServiceWorkerRegistration* registration) { | |
| 258 size_t key = registration->pattern().spec().size(); | |
| 259 DCHECK(ContainsKey(matching_registrations_, key)); | |
| 260 DecreaseProcessReference(registration->pattern()); | |
| 261 registration->RemoveListener(this); | |
| 262 matching_registrations_.erase(key); | |
| 263 } | |
| 264 | |
| 265 ServiceWorkerRegistration* | |
| 266 ServiceWorkerProviderHost::MatchRegistration() const { | |
| 267 ServiceWorkerRegistrationMap::const_reverse_iterator it = | |
| 268 matching_registrations_.rbegin(); | |
| 269 for (; it != matching_registrations_.rend(); ++it) { | |
| 270 if (it->second->is_uninstalled()) | |
| 271 continue; | |
| 272 if (it->second->is_uninstalling()) | |
| 273 return nullptr; | |
| 274 break; | |
|
falken
2015/02/16 09:18:29
nit: maybe just return it->second.get() here? then
xiang
2015/02/26 06:52:14
Done.
| |
| 275 } | |
| 276 return it == matching_registrations_.rend() ? nullptr : it->second.get(); | |
| 277 } | |
| 278 | |
| 230 scoped_ptr<ServiceWorkerRequestHandler> | 279 scoped_ptr<ServiceWorkerRequestHandler> |
| 231 ServiceWorkerProviderHost::CreateRequestHandler( | 280 ServiceWorkerProviderHost::CreateRequestHandler( |
| 232 FetchRequestMode request_mode, | 281 FetchRequestMode request_mode, |
| 233 FetchCredentialsMode credentials_mode, | 282 FetchCredentialsMode credentials_mode, |
| 234 ResourceType resource_type, | 283 ResourceType resource_type, |
| 235 RequestContextType request_context_type, | 284 RequestContextType request_context_type, |
| 236 RequestContextFrameType frame_type, | 285 RequestContextFrameType frame_type, |
| 237 base::WeakPtr<storage::BlobStorageContext> blob_storage_context, | 286 base::WeakPtr<storage::BlobStorageContext> blob_storage_context, |
| 238 scoped_refptr<ResourceRequestBody> body) { | 287 scoped_refptr<ResourceRequestBody> body) { |
| 239 if (IsHostToRunningServiceWorker()) { | 288 if (IsHostToRunningServiceWorker()) { |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 330 is_claiming_ = true; | 379 is_claiming_ = true; |
| 331 if (registration == associated_registration_) { | 380 if (registration == associated_registration_) { |
| 332 SetControllerVersionAttribute(registration->active_version()); | 381 SetControllerVersionAttribute(registration->active_version()); |
| 333 } else if (allow_association_) { | 382 } else if (allow_association_) { |
| 334 DisassociateRegistration(); | 383 DisassociateRegistration(); |
| 335 AssociateRegistration(registration); | 384 AssociateRegistration(registration); |
| 336 } | 385 } |
| 337 is_claiming_ = false; | 386 is_claiming_ = false; |
| 338 } | 387 } |
| 339 | 388 |
| 389 void ServiceWorkerProviderHost::GetRegistrationForReady( | |
| 390 const GetRegistrationForReadyCallback& callback) { | |
| 391 DCHECK(get_ready_callback_.is_null()); | |
|
falken
2015/02/16 09:18:29
As in my other comment, this DCHECK can be violate
xiang
2015/02/26 06:52:14
Done.
| |
| 392 get_ready_callback_ = callback; | |
| 393 ReturnRegistrationForReadyIfNeeded(); | |
| 394 } | |
| 395 | |
| 340 void ServiceWorkerProviderHost::PrepareForCrossSiteTransfer() { | 396 void ServiceWorkerProviderHost::PrepareForCrossSiteTransfer() { |
| 341 DCHECK_NE(ChildProcessHost::kInvalidUniqueID, render_process_id_); | 397 DCHECK_NE(ChildProcessHost::kInvalidUniqueID, render_process_id_); |
| 342 DCHECK_NE(MSG_ROUTING_NONE, render_frame_id_); | 398 DCHECK_NE(MSG_ROUTING_NONE, render_frame_id_); |
| 343 DCHECK_EQ(kDocumentMainThreadId, render_thread_id_); | 399 DCHECK_EQ(kDocumentMainThreadId, render_thread_id_); |
| 344 | 400 |
| 345 for (const GURL& pattern : associated_patterns_) | 401 for (const GURL& pattern : associated_patterns_) |
| 346 DecreaseProcessReference(pattern); | 402 DecreaseProcessReference(pattern); |
| 347 | 403 |
| 404 for (auto& key_registration : matching_registrations_) | |
| 405 DecreaseProcessReference(key_registration.second->pattern()); | |
| 406 | |
| 348 if (associated_registration_.get()) { | 407 if (associated_registration_.get()) { |
| 349 DecreaseProcessReference(associated_registration_->pattern()); | |
| 350 if (dispatcher_host_) { | 408 if (dispatcher_host_) { |
| 351 Send(new ServiceWorkerMsg_DisassociateRegistration( | 409 Send(new ServiceWorkerMsg_DisassociateRegistration( |
| 352 render_thread_id_, provider_id())); | 410 render_thread_id_, provider_id())); |
| 353 } | 411 } |
| 354 } | 412 } |
| 355 | 413 |
| 356 render_process_id_ = ChildProcessHost::kInvalidUniqueID; | 414 render_process_id_ = ChildProcessHost::kInvalidUniqueID; |
| 357 render_frame_id_ = MSG_ROUTING_NONE; | 415 render_frame_id_ = MSG_ROUTING_NONE; |
| 358 render_thread_id_ = kInvalidEmbeddedWorkerThreadId; | 416 render_thread_id_ = kInvalidEmbeddedWorkerThreadId; |
| 359 provider_id_ = kInvalidServiceWorkerProviderId; | 417 provider_id_ = kInvalidServiceWorkerProviderId; |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 371 | 429 |
| 372 render_process_id_ = new_process_id; | 430 render_process_id_ = new_process_id; |
| 373 render_frame_id_ = new_frame_id; | 431 render_frame_id_ = new_frame_id; |
| 374 render_thread_id_ = kDocumentMainThreadId; | 432 render_thread_id_ = kDocumentMainThreadId; |
| 375 provider_id_ = new_provider_id; | 433 provider_id_ = new_provider_id; |
| 376 dispatcher_host_ = new_dispatcher_host; | 434 dispatcher_host_ = new_dispatcher_host; |
| 377 | 435 |
| 378 for (const GURL& pattern : associated_patterns_) | 436 for (const GURL& pattern : associated_patterns_) |
| 379 IncreaseProcessReference(pattern); | 437 IncreaseProcessReference(pattern); |
| 380 | 438 |
| 439 for (auto& key_registration : matching_registrations_) | |
| 440 IncreaseProcessReference(key_registration.second->pattern()); | |
| 441 | |
| 381 if (associated_registration_.get()) { | 442 if (associated_registration_.get()) { |
| 382 IncreaseProcessReference(associated_registration_->pattern()); | |
| 383 SendAssociateRegistrationMessage(); | 443 SendAssociateRegistrationMessage(); |
| 384 if (dispatcher_host_ && associated_registration_->active_version()) { | 444 if (dispatcher_host_ && associated_registration_->active_version()) { |
| 385 Send(new ServiceWorkerMsg_SetControllerServiceWorker( | 445 Send(new ServiceWorkerMsg_SetControllerServiceWorker( |
| 386 render_thread_id_, provider_id(), | 446 render_thread_id_, provider_id(), |
| 387 CreateAndRegisterServiceWorkerHandle( | 447 CreateAndRegisterServiceWorkerHandle( |
| 388 associated_registration_->active_version()), | 448 associated_registration_->active_version()), |
| 389 false /* shouldNotifyControllerChange */)); | 449 false /* shouldNotifyControllerChange */)); |
| 390 } | 450 } |
| 391 } | 451 } |
| 392 } | 452 } |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 498 } | 558 } |
| 499 | 559 |
| 500 void ServiceWorkerProviderHost::DecreaseProcessReference( | 560 void ServiceWorkerProviderHost::DecreaseProcessReference( |
| 501 const GURL& pattern) { | 561 const GURL& pattern) { |
| 502 if (context_ && context_->process_manager()) { | 562 if (context_ && context_->process_manager()) { |
| 503 context_->process_manager()->RemoveProcessReferenceFromPattern( | 563 context_->process_manager()->RemoveProcessReferenceFromPattern( |
| 504 pattern, render_process_id_); | 564 pattern, render_process_id_); |
| 505 } | 565 } |
| 506 } | 566 } |
| 507 | 567 |
| 568 void ServiceWorkerProviderHost::ReturnRegistrationForReadyIfNeeded() { | |
| 569 if (get_ready_callback_.is_null()) | |
| 570 return; | |
| 571 ServiceWorkerRegistration* registration = MatchRegistration(); | |
| 572 if (!registration) | |
| 573 return; | |
| 574 if (registration->active_version()) { | |
| 575 get_ready_callback_.Run(registration); | |
| 576 get_ready_callback_.Reset(); | |
|
falken
2015/02/16 09:18:29
Are you sure we should reset it here? I think the
xiang
2015/02/26 06:52:14
Yes, but I thought we already made Blink can only
| |
| 577 return; | |
| 578 } | |
| 579 } | |
| 580 | |
| 508 bool ServiceWorkerProviderHost::IsReadyToSendMessages() const { | 581 bool ServiceWorkerProviderHost::IsReadyToSendMessages() const { |
| 509 return render_thread_id_ != kInvalidEmbeddedWorkerThreadId; | 582 return render_thread_id_ != kInvalidEmbeddedWorkerThreadId; |
| 510 } | 583 } |
| 511 | 584 |
| 512 bool ServiceWorkerProviderHost::IsContextAlive() { | 585 bool ServiceWorkerProviderHost::IsContextAlive() { |
| 513 return context_ != NULL; | 586 return context_ != NULL; |
| 514 } | 587 } |
| 515 | 588 |
| 516 void ServiceWorkerProviderHost::Send(IPC::Message* message) const { | 589 void ServiceWorkerProviderHost::Send(IPC::Message* message) const { |
| 517 DCHECK(dispatcher_host_); | 590 DCHECK(dispatcher_host_); |
| 518 DCHECK(IsReadyToSendMessages()); | 591 DCHECK(IsReadyToSendMessages()); |
| 519 dispatcher_host_->Send(message); | 592 dispatcher_host_->Send(message); |
| 520 } | 593 } |
| 521 | 594 |
| 522 } // namespace content | 595 } // namespace content |
| OLD | NEW |