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/render_frame_host_impl.h" | 8 #include "content/browser/frame_host/render_frame_host_impl.h" |
9 #include "content/browser/message_port_message_filter.h" | 9 #include "content/browser/message_port_message_filter.h" |
10 #include "content/browser/service_worker/service_worker_context_core.h" | 10 #include "content/browser/service_worker/service_worker_context_core.h" |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
77 int render_frame_id, | 77 int render_frame_id, |
78 int provider_id, | 78 int provider_id, |
79 base::WeakPtr<ServiceWorkerContextCore> context, | 79 base::WeakPtr<ServiceWorkerContextCore> context, |
80 ServiceWorkerDispatcherHost* dispatcher_host) | 80 ServiceWorkerDispatcherHost* dispatcher_host) |
81 : render_process_id_(render_process_id), | 81 : render_process_id_(render_process_id), |
82 render_frame_id_(render_frame_id), | 82 render_frame_id_(render_frame_id), |
83 render_thread_id_(kDocumentMainThreadId), | 83 render_thread_id_(kDocumentMainThreadId), |
84 provider_id_(provider_id), | 84 provider_id_(provider_id), |
85 context_(context), | 85 context_(context), |
86 dispatcher_host_(dispatcher_host), | 86 dispatcher_host_(dispatcher_host), |
87 allow_association_(true), | |
88 is_claiming_(false) { | 87 is_claiming_(false) { |
89 DCHECK_NE(ChildProcessHost::kInvalidUniqueID, render_process_id_); | 88 DCHECK_NE(ChildProcessHost::kInvalidUniqueID, render_process_id_); |
90 if (render_frame_id == MSG_ROUTING_NONE) { | 89 if (render_frame_id == MSG_ROUTING_NONE) { |
91 // Actual thread id is set when the worker context gets started. | 90 // Actual thread id is set when the worker context gets started. |
92 render_thread_id_ = kInvalidEmbeddedWorkerThreadId; | 91 render_thread_id_ = kInvalidEmbeddedWorkerThreadId; |
93 } | 92 } |
94 } | 93 } |
95 | 94 |
96 ServiceWorkerProviderHost::~ServiceWorkerProviderHost() { | 95 ServiceWorkerProviderHost::~ServiceWorkerProviderHost() { |
97 // Clear docurl so the deferred activation of a waiting worker | 96 // Clear docurl so the deferred activation of a waiting worker |
98 // won't associate the new version with a provider being destroyed. | 97 // won't associate the new version with a provider being destroyed. |
99 document_url_ = GURL(); | 98 document_url_ = GURL(); |
100 if (controlling_version_.get()) | 99 if (controlling_version_.get()) |
101 controlling_version_->RemoveControllee(this); | 100 controlling_version_->RemoveControllee(this); |
102 if (associated_registration_.get()) { | 101 |
103 DecreaseProcessReference(associated_registration_->pattern()); | 102 for (auto& key_registration : potential_registrations_) { |
104 associated_registration_->RemoveListener(this); | 103 DecreaseProcessReference(key_registration.second->pattern()); |
| 104 key_registration.second->RemoveListener(this); |
105 } | 105 } |
106 | 106 |
107 for (const GURL& pattern : associated_patterns_) | 107 for (const GURL& pattern : associated_patterns_) |
108 DecreaseProcessReference(pattern); | 108 DecreaseProcessReference(pattern); |
109 } | 109 } |
110 | 110 |
| 111 void ServiceWorkerProviderHost::OnVersionAttributesChanged( |
| 112 ServiceWorkerRegistration* registration, |
| 113 ChangedVersionAttributesMask changed_mask, |
| 114 const ServiceWorkerRegistrationInfo& info) { |
| 115 ReturnReadyRegistrationIfNeeded(); |
| 116 } |
| 117 |
111 void ServiceWorkerProviderHost::OnRegistrationFailed( | 118 void ServiceWorkerProviderHost::OnRegistrationFailed( |
112 ServiceWorkerRegistration* registration) { | 119 ServiceWorkerRegistration* registration) { |
113 DCHECK_EQ(associated_registration_.get(), registration); | 120 if (associated_registration_ == registration) |
114 DisassociateRegistration(); | 121 DisassociateRegistration(); |
| 122 else |
| 123 RemovePotentialRegistration(registration); |
| 124 } |
| 125 |
| 126 void ServiceWorkerProviderHost::OnRegistrationFinishedUninstalling( |
| 127 ServiceWorkerRegistration* registration) { |
| 128 RemovePotentialRegistration(registration); |
115 } | 129 } |
116 | 130 |
117 void ServiceWorkerProviderHost::OnSkippedWaiting( | 131 void ServiceWorkerProviderHost::OnSkippedWaiting( |
118 ServiceWorkerRegistration* registration) { | 132 ServiceWorkerRegistration* registration) { |
119 DCHECK_EQ(associated_registration_.get(), registration); | 133 if (associated_registration_ != registration) |
| 134 return; |
120 // A client is "using" a registration if it is controlled by the active | 135 // A client is "using" a registration if it is controlled by the active |
121 // worker of the registration. skipWaiting doesn't cause a client to start | 136 // worker of the registration. skipWaiting doesn't cause a client to start |
122 // using the registration. | 137 // using the registration. |
123 if (!controlling_version_) | 138 if (!controlling_version_) |
124 return; | 139 return; |
125 ServiceWorkerVersion* active_version = registration->active_version(); | 140 ServiceWorkerVersion* active_version = registration->active_version(); |
126 DCHECK_EQ(active_version->status(), ServiceWorkerVersion::ACTIVATING); | 141 DCHECK_EQ(active_version->status(), ServiceWorkerVersion::ACTIVATING); |
127 SetControllerVersionAttribute(active_version); | 142 SetControllerVersionAttribute(active_version); |
128 } | 143 } |
129 | 144 |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
180 return false; | 195 return false; |
181 } | 196 } |
182 | 197 |
183 running_hosted_version_ = live_version; | 198 running_hosted_version_ = live_version; |
184 return true; | 199 return true; |
185 } | 200 } |
186 | 201 |
187 void ServiceWorkerProviderHost::AssociateRegistration( | 202 void ServiceWorkerProviderHost::AssociateRegistration( |
188 ServiceWorkerRegistration* registration) { | 203 ServiceWorkerRegistration* registration) { |
189 DCHECK(CanAssociateRegistration(registration)); | 204 DCHECK(CanAssociateRegistration(registration)); |
190 IncreaseProcessReference(registration->pattern()); | |
191 associated_registration_ = registration; | 205 associated_registration_ = registration; |
192 associated_registration_->AddListener(this); | 206 AddPotentialRegistration(registration); |
193 SendAssociateRegistrationMessage(); | 207 SendAssociateRegistrationMessage(); |
194 SetControllerVersionAttribute(registration->active_version()); | 208 SetControllerVersionAttribute(registration->active_version()); |
195 } | 209 } |
196 | 210 |
197 void ServiceWorkerProviderHost::DisassociateRegistration() { | 211 void ServiceWorkerProviderHost::DisassociateRegistration() { |
198 queued_events_.clear(); | 212 queued_events_.clear(); |
199 if (!associated_registration_.get()) | 213 if (!associated_registration_.get()) |
200 return; | 214 return; |
201 DecreaseProcessReference(associated_registration_->pattern()); | |
202 associated_registration_->RemoveListener(this); | |
203 associated_registration_ = NULL; | 215 associated_registration_ = NULL; |
204 SetControllerVersionAttribute(NULL); | 216 SetControllerVersionAttribute(NULL); |
205 | 217 |
206 if (!dispatcher_host_) | 218 if (!dispatcher_host_) |
207 return; | 219 return; |
208 | 220 |
209 // Disassociation message should be sent only for the document context. | 221 // Disassociation message should be sent only for the document context. |
210 DCHECK_EQ(kDocumentMainThreadId, render_thread_id_); | 222 DCHECK_EQ(kDocumentMainThreadId, render_thread_id_); |
211 Send(new ServiceWorkerMsg_DisassociateRegistration( | 223 Send(new ServiceWorkerMsg_DisassociateRegistration( |
212 render_thread_id_, provider_id())); | 224 render_thread_id_, provider_id())); |
213 } | 225 } |
214 | 226 |
| 227 void ServiceWorkerProviderHost::AddPotentialRegistration( |
| 228 ServiceWorkerRegistration* registration) { |
| 229 size_t key = registration->pattern().spec().size(); |
| 230 if (ContainsKey(potential_registrations_, key)) |
| 231 return; |
| 232 IncreaseProcessReference(registration->pattern()); |
| 233 registration->AddListener(this); |
| 234 potential_registrations_[key] = registration; |
| 235 ReturnReadyRegistrationIfNeeded(); |
| 236 } |
| 237 |
| 238 void ServiceWorkerProviderHost::RemovePotentialRegistration( |
| 239 ServiceWorkerRegistration* registration) { |
| 240 size_t key = registration->pattern().spec().size(); |
| 241 DCHECK(ContainsKey(potential_registrations_, key)); |
| 242 DecreaseProcessReference(registration->pattern()); |
| 243 registration->RemoveListener(this); |
| 244 potential_registrations_.erase(key); |
| 245 } |
| 246 |
| 247 ServiceWorkerRegistration* |
| 248 ServiceWorkerProviderHost::GetMatchedRegistration() const { |
| 249 ServiceWorkerRegistrationMap::const_reverse_iterator it = |
| 250 potential_registrations_.rbegin(); |
| 251 for (; it != potential_registrations_.rend(); ++it) { |
| 252 if (it->second->is_uninstalled()) |
| 253 continue; |
| 254 if (it->second->is_uninstalling()) |
| 255 return nullptr; |
| 256 break; |
| 257 } |
| 258 return it == potential_registrations_.rend() ? nullptr : it->second.get(); |
| 259 } |
| 260 |
215 scoped_ptr<ServiceWorkerRequestHandler> | 261 scoped_ptr<ServiceWorkerRequestHandler> |
216 ServiceWorkerProviderHost::CreateRequestHandler( | 262 ServiceWorkerProviderHost::CreateRequestHandler( |
217 FetchRequestMode request_mode, | 263 FetchRequestMode request_mode, |
218 FetchCredentialsMode credentials_mode, | 264 FetchCredentialsMode credentials_mode, |
219 ResourceType resource_type, | 265 ResourceType resource_type, |
220 RequestContextType request_context_type, | 266 RequestContextType request_context_type, |
221 RequestContextFrameType frame_type, | 267 RequestContextFrameType frame_type, |
222 base::WeakPtr<storage::BlobStorageContext> blob_storage_context, | 268 base::WeakPtr<storage::BlobStorageContext> blob_storage_context, |
223 scoped_refptr<ResourceRequestBody> body) { | 269 scoped_refptr<ResourceRequestBody> body) { |
224 if (IsHostToRunningServiceWorker()) { | 270 if (IsHostToRunningServiceWorker()) { |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
315 is_claiming_ = true; | 361 is_claiming_ = true; |
316 if (registration == associated_registration_) { | 362 if (registration == associated_registration_) { |
317 SetControllerVersionAttribute(registration->active_version()); | 363 SetControllerVersionAttribute(registration->active_version()); |
318 } else if (allow_association_) { | 364 } else if (allow_association_) { |
319 DisassociateRegistration(); | 365 DisassociateRegistration(); |
320 AssociateRegistration(registration); | 366 AssociateRegistration(registration); |
321 } | 367 } |
322 is_claiming_ = false; | 368 is_claiming_ = false; |
323 } | 369 } |
324 | 370 |
| 371 void ServiceWorkerProviderHost::GetReadyRegistration( |
| 372 const GetReadyRegistrationCallback& callback) { |
| 373 registration_ready_callback_ = callback; |
| 374 ReturnReadyRegistrationIfNeeded(); |
| 375 } |
| 376 |
325 void ServiceWorkerProviderHost::PrepareForCrossSiteTransfer() { | 377 void ServiceWorkerProviderHost::PrepareForCrossSiteTransfer() { |
326 DCHECK_NE(ChildProcessHost::kInvalidUniqueID, render_process_id_); | 378 DCHECK_NE(ChildProcessHost::kInvalidUniqueID, render_process_id_); |
327 DCHECK_NE(MSG_ROUTING_NONE, render_frame_id_); | 379 DCHECK_NE(MSG_ROUTING_NONE, render_frame_id_); |
328 DCHECK_EQ(kDocumentMainThreadId, render_thread_id_); | 380 DCHECK_EQ(kDocumentMainThreadId, render_thread_id_); |
329 | 381 |
330 for (const GURL& pattern : associated_patterns_) | 382 for (const GURL& pattern : associated_patterns_) |
331 DecreaseProcessReference(pattern); | 383 DecreaseProcessReference(pattern); |
332 | 384 |
| 385 for (auto& key_registration : potential_registrations_) |
| 386 DecreaseProcessReference(key_registration.second->pattern()); |
| 387 |
333 if (associated_registration_.get()) { | 388 if (associated_registration_.get()) { |
334 DecreaseProcessReference(associated_registration_->pattern()); | |
335 if (dispatcher_host_) { | 389 if (dispatcher_host_) { |
336 Send(new ServiceWorkerMsg_DisassociateRegistration( | 390 Send(new ServiceWorkerMsg_DisassociateRegistration( |
337 render_thread_id_, provider_id())); | 391 render_thread_id_, provider_id())); |
338 } | 392 } |
339 } | 393 } |
340 | 394 |
341 render_process_id_ = ChildProcessHost::kInvalidUniqueID; | 395 render_process_id_ = ChildProcessHost::kInvalidUniqueID; |
342 render_frame_id_ = MSG_ROUTING_NONE; | 396 render_frame_id_ = MSG_ROUTING_NONE; |
343 render_thread_id_ = kInvalidEmbeddedWorkerThreadId; | 397 render_thread_id_ = kInvalidEmbeddedWorkerThreadId; |
344 provider_id_ = kInvalidServiceWorkerProviderId; | 398 provider_id_ = kInvalidServiceWorkerProviderId; |
(...skipping 11 matching lines...) Expand all Loading... |
356 | 410 |
357 render_process_id_ = new_process_id; | 411 render_process_id_ = new_process_id; |
358 render_frame_id_ = new_frame_id; | 412 render_frame_id_ = new_frame_id; |
359 render_thread_id_ = kDocumentMainThreadId; | 413 render_thread_id_ = kDocumentMainThreadId; |
360 provider_id_ = new_provider_id; | 414 provider_id_ = new_provider_id; |
361 dispatcher_host_ = new_dispatcher_host; | 415 dispatcher_host_ = new_dispatcher_host; |
362 | 416 |
363 for (const GURL& pattern : associated_patterns_) | 417 for (const GURL& pattern : associated_patterns_) |
364 IncreaseProcessReference(pattern); | 418 IncreaseProcessReference(pattern); |
365 | 419 |
| 420 for (auto& key_registration : potential_registrations_) |
| 421 IncreaseProcessReference(key_registration.second->pattern()); |
| 422 |
366 if (associated_registration_.get()) { | 423 if (associated_registration_.get()) { |
367 IncreaseProcessReference(associated_registration_->pattern()); | |
368 SendAssociateRegistrationMessage(); | 424 SendAssociateRegistrationMessage(); |
369 if (dispatcher_host_ && associated_registration_->active_version()) { | 425 if (dispatcher_host_ && associated_registration_->active_version()) { |
370 Send(new ServiceWorkerMsg_SetControllerServiceWorker( | 426 Send(new ServiceWorkerMsg_SetControllerServiceWorker( |
371 render_thread_id_, provider_id(), | 427 render_thread_id_, provider_id(), |
372 CreateAndRegisterServiceWorkerHandle( | 428 CreateAndRegisterServiceWorkerHandle( |
373 associated_registration_->active_version()), | 429 associated_registration_->active_version()), |
374 false /* shouldNotifyControllerChange */)); | 430 false /* shouldNotifyControllerChange */)); |
375 } | 431 } |
376 } | 432 } |
377 } | 433 } |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
483 } | 539 } |
484 | 540 |
485 void ServiceWorkerProviderHost::DecreaseProcessReference( | 541 void ServiceWorkerProviderHost::DecreaseProcessReference( |
486 const GURL& pattern) { | 542 const GURL& pattern) { |
487 if (context_ && context_->process_manager()) { | 543 if (context_ && context_->process_manager()) { |
488 context_->process_manager()->RemoveProcessReferenceFromPattern( | 544 context_->process_manager()->RemoveProcessReferenceFromPattern( |
489 pattern, render_process_id_); | 545 pattern, render_process_id_); |
490 } | 546 } |
491 } | 547 } |
492 | 548 |
| 549 void ServiceWorkerProviderHost::ReturnReadyRegistrationIfNeeded() { |
| 550 if (registration_ready_callback_.is_null()) |
| 551 return; |
| 552 ServiceWorkerRegistration* registration = GetMatchedRegistration(); |
| 553 if (!registration) |
| 554 return; |
| 555 if (registration->active_version()) { |
| 556 registration_ready_callback_.Run(registration); |
| 557 registration_ready_callback_.Reset(); |
| 558 return; |
| 559 } |
| 560 } |
| 561 |
493 bool ServiceWorkerProviderHost::IsReadyToSendMessages() const { | 562 bool ServiceWorkerProviderHost::IsReadyToSendMessages() const { |
494 return render_thread_id_ != kInvalidEmbeddedWorkerThreadId; | 563 return render_thread_id_ != kInvalidEmbeddedWorkerThreadId; |
495 } | 564 } |
496 | 565 |
497 bool ServiceWorkerProviderHost::IsContextAlive() { | 566 bool ServiceWorkerProviderHost::IsContextAlive() { |
498 return context_ != NULL; | 567 return context_ != NULL; |
499 } | 568 } |
500 | 569 |
501 void ServiceWorkerProviderHost::Send(IPC::Message* message) const { | 570 void ServiceWorkerProviderHost::Send(IPC::Message* message) const { |
502 DCHECK(dispatcher_host_); | 571 DCHECK(dispatcher_host_); |
503 DCHECK(IsReadyToSendMessages()); | 572 DCHECK(IsReadyToSendMessages()); |
504 dispatcher_host_->Send(message); | 573 dispatcher_host_->Send(message); |
505 } | 574 } |
506 | 575 |
507 } // namespace content | 576 } // namespace content |
OLD | NEW |