Chromium Code Reviews| Index: content/browser/service_worker/service_worker_provider_host.cc |
| diff --git a/content/browser/service_worker/service_worker_provider_host.cc b/content/browser/service_worker/service_worker_provider_host.cc |
| index 2926c75032d6893c2f084cb24acb59d0cd3bd7b3..42b024a82ce1a8c835994b89d485a395bc6c9305 100644 |
| --- a/content/browser/service_worker/service_worker_provider_host.cc |
| +++ b/content/browser/service_worker/service_worker_provider_host.cc |
| @@ -114,24 +114,40 @@ ServiceWorkerProviderHost::~ServiceWorkerProviderHost() { |
| document_url_ = GURL(); |
| if (controlling_version_.get()) |
| controlling_version_->RemoveControllee(this); |
| - if (associated_registration_.get()) { |
| - DecreaseProcessReference(associated_registration_->pattern()); |
| - associated_registration_->RemoveListener(this); |
| + |
| + for (auto& key_registration : matching_registrations_) { |
| + DecreaseProcessReference(key_registration.second->pattern()); |
| + key_registration.second->RemoveListener(this); |
| } |
| for (const GURL& pattern : associated_patterns_) |
| DecreaseProcessReference(pattern); |
| } |
| +void ServiceWorkerProviderHost::OnVersionAttributesChanged( |
| + ServiceWorkerRegistration* registration, |
| + ChangedVersionAttributesMask changed_mask, |
| + const ServiceWorkerRegistrationInfo& info) { |
| + ReturnRegistrationForReadyIfNeeded(); |
| +} |
| + |
| void ServiceWorkerProviderHost::OnRegistrationFailed( |
| ServiceWorkerRegistration* registration) { |
| - DCHECK_EQ(associated_registration_.get(), registration); |
| - DisassociateRegistration(); |
| + if (associated_registration_ == registration) |
| + 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.
|
| + else |
| + RemoveMatchingRegistration(registration); |
| +} |
| + |
| +void ServiceWorkerProviderHost::OnRegistrationFinishedUninstalling( |
| + ServiceWorkerRegistration* registration) { |
| + RemoveMatchingRegistration(registration); |
| } |
| void ServiceWorkerProviderHost::OnSkippedWaiting( |
| ServiceWorkerRegistration* registration) { |
| - DCHECK_EQ(associated_registration_.get(), registration); |
| + if (associated_registration_ != registration) |
| + return; |
| // A client is "using" a registration if it is controlled by the active |
| // worker of the registration. skipWaiting doesn't cause a client to start |
| // using the registration. |
| @@ -202,9 +218,8 @@ bool ServiceWorkerProviderHost::SetHostedVersionId(int64 version_id) { |
| void ServiceWorkerProviderHost::AssociateRegistration( |
| ServiceWorkerRegistration* registration) { |
| DCHECK(CanAssociateRegistration(registration)); |
| - IncreaseProcessReference(registration->pattern()); |
| associated_registration_ = registration; |
| - associated_registration_->AddListener(this); |
| + AddMatchingRegistration(registration); |
| SendAssociateRegistrationMessage(); |
| SetControllerVersionAttribute(registration->active_version()); |
| } |
| @@ -213,8 +228,6 @@ void ServiceWorkerProviderHost::DisassociateRegistration() { |
| queued_events_.clear(); |
| if (!associated_registration_.get()) |
| return; |
| - DecreaseProcessReference(associated_registration_->pattern()); |
| - associated_registration_->RemoveListener(this); |
| associated_registration_ = NULL; |
| SetControllerVersionAttribute(NULL); |
| @@ -227,6 +240,42 @@ void ServiceWorkerProviderHost::DisassociateRegistration() { |
| render_thread_id_, provider_id())); |
| } |
| +void ServiceWorkerProviderHost::AddMatchingRegistration( |
| + ServiceWorkerRegistration* registration) { |
| + DCHECK(ServiceWorkerUtils::ScopeMatches( |
| + registration->pattern(), document_url_)); |
| + size_t key = registration->pattern().spec().size(); |
| + if (ContainsKey(matching_registrations_, key)) |
| + return; |
| + IncreaseProcessReference(registration->pattern()); |
| + registration->AddListener(this); |
| + matching_registrations_[key] = registration; |
| + ReturnRegistrationForReadyIfNeeded(); |
| +} |
| + |
| +void ServiceWorkerProviderHost::RemoveMatchingRegistration( |
| + ServiceWorkerRegistration* registration) { |
| + size_t key = registration->pattern().spec().size(); |
| + DCHECK(ContainsKey(matching_registrations_, key)); |
| + DecreaseProcessReference(registration->pattern()); |
| + registration->RemoveListener(this); |
| + matching_registrations_.erase(key); |
| +} |
| + |
| +ServiceWorkerRegistration* |
| +ServiceWorkerProviderHost::MatchRegistration() const { |
| + ServiceWorkerRegistrationMap::const_reverse_iterator it = |
| + matching_registrations_.rbegin(); |
| + for (; it != matching_registrations_.rend(); ++it) { |
| + if (it->second->is_uninstalled()) |
| + continue; |
| + if (it->second->is_uninstalling()) |
| + return nullptr; |
| + 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.
|
| + } |
| + return it == matching_registrations_.rend() ? nullptr : it->second.get(); |
| +} |
| + |
| scoped_ptr<ServiceWorkerRequestHandler> |
| ServiceWorkerProviderHost::CreateRequestHandler( |
| FetchRequestMode request_mode, |
| @@ -337,6 +386,13 @@ void ServiceWorkerProviderHost::ClaimedByRegistration( |
| is_claiming_ = false; |
| } |
| +void ServiceWorkerProviderHost::GetRegistrationForReady( |
| + const GetRegistrationForReadyCallback& callback) { |
| + 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.
|
| + get_ready_callback_ = callback; |
| + ReturnRegistrationForReadyIfNeeded(); |
| +} |
| + |
| void ServiceWorkerProviderHost::PrepareForCrossSiteTransfer() { |
| DCHECK_NE(ChildProcessHost::kInvalidUniqueID, render_process_id_); |
| DCHECK_NE(MSG_ROUTING_NONE, render_frame_id_); |
| @@ -345,8 +401,10 @@ void ServiceWorkerProviderHost::PrepareForCrossSiteTransfer() { |
| for (const GURL& pattern : associated_patterns_) |
| DecreaseProcessReference(pattern); |
| + for (auto& key_registration : matching_registrations_) |
| + DecreaseProcessReference(key_registration.second->pattern()); |
| + |
| if (associated_registration_.get()) { |
| - DecreaseProcessReference(associated_registration_->pattern()); |
| if (dispatcher_host_) { |
| Send(new ServiceWorkerMsg_DisassociateRegistration( |
| render_thread_id_, provider_id())); |
| @@ -378,8 +436,10 @@ void ServiceWorkerProviderHost::CompleteCrossSiteTransfer( |
| for (const GURL& pattern : associated_patterns_) |
| IncreaseProcessReference(pattern); |
| + for (auto& key_registration : matching_registrations_) |
| + IncreaseProcessReference(key_registration.second->pattern()); |
| + |
| if (associated_registration_.get()) { |
| - IncreaseProcessReference(associated_registration_->pattern()); |
| SendAssociateRegistrationMessage(); |
| if (dispatcher_host_ && associated_registration_->active_version()) { |
| Send(new ServiceWorkerMsg_SetControllerServiceWorker( |
| @@ -505,6 +565,19 @@ void ServiceWorkerProviderHost::DecreaseProcessReference( |
| } |
| } |
| +void ServiceWorkerProviderHost::ReturnRegistrationForReadyIfNeeded() { |
| + if (get_ready_callback_.is_null()) |
| + return; |
| + ServiceWorkerRegistration* registration = MatchRegistration(); |
| + if (!registration) |
| + return; |
| + if (registration->active_version()) { |
| + get_ready_callback_.Run(registration); |
| + 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
|
| + return; |
| + } |
| +} |
| + |
| bool ServiceWorkerProviderHost::IsReadyToSendMessages() const { |
| return render_thread_id_ != kInvalidEmbeddedWorkerThreadId; |
| } |