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 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
51 | 51 |
52 // Move the web contents to the foreground. | 52 // Move the web contents to the foreground. |
53 web_contents->Activate(); | 53 web_contents->Activate(); |
54 | 54 |
55 return ServiceWorkerProviderHost::GetClientInfoOnUI( | 55 return ServiceWorkerProviderHost::GetClientInfoOnUI( |
56 render_process_id, render_frame_id); | 56 render_process_id, render_frame_id); |
57 } | 57 } |
58 | 58 |
59 } // anonymous namespace | 59 } // anonymous namespace |
60 | 60 |
| 61 ServiceWorkerProviderHost::OneShotGetReadyCallback::OneShotGetReadyCallback( |
| 62 const GetRegistrationForReadyCallback& callback) |
| 63 : callback(callback), |
| 64 called(false) { |
| 65 } |
| 66 |
| 67 ServiceWorkerProviderHost::OneShotGetReadyCallback::~OneShotGetReadyCallback() { |
| 68 } |
| 69 |
61 ServiceWorkerProviderHost::ServiceWorkerProviderHost( | 70 ServiceWorkerProviderHost::ServiceWorkerProviderHost( |
62 int render_process_id, | 71 int render_process_id, |
63 int render_frame_id, | 72 int render_frame_id, |
64 int provider_id, | 73 int provider_id, |
65 ServiceWorkerProviderType provider_type, | 74 ServiceWorkerProviderType provider_type, |
66 base::WeakPtr<ServiceWorkerContextCore> context, | 75 base::WeakPtr<ServiceWorkerContextCore> context, |
67 ServiceWorkerDispatcherHost* dispatcher_host) | 76 ServiceWorkerDispatcherHost* dispatcher_host) |
68 : render_process_id_(render_process_id), | 77 : render_process_id_(render_process_id), |
69 render_frame_id_(render_frame_id), | 78 render_frame_id_(render_frame_id), |
70 render_thread_id_(kDocumentMainThreadId), | 79 render_thread_id_(kDocumentMainThreadId), |
(...skipping 10 matching lines...) Expand all Loading... |
81 render_thread_id_ = kInvalidEmbeddedWorkerThreadId; | 90 render_thread_id_ = kInvalidEmbeddedWorkerThreadId; |
82 } | 91 } |
83 } | 92 } |
84 | 93 |
85 ServiceWorkerProviderHost::~ServiceWorkerProviderHost() { | 94 ServiceWorkerProviderHost::~ServiceWorkerProviderHost() { |
86 // Clear docurl so the deferred activation of a waiting worker | 95 // Clear docurl so the deferred activation of a waiting worker |
87 // won't associate the new version with a provider being destroyed. | 96 // won't associate the new version with a provider being destroyed. |
88 document_url_ = GURL(); | 97 document_url_ = GURL(); |
89 if (controlling_version_.get()) | 98 if (controlling_version_.get()) |
90 controlling_version_->RemoveControllee(this); | 99 controlling_version_->RemoveControllee(this); |
91 if (associated_registration_.get()) { | 100 |
92 DecreaseProcessReference(associated_registration_->pattern()); | 101 for (auto& key_registration : matching_registrations_) { |
93 associated_registration_->RemoveListener(this); | 102 DecreaseProcessReference(key_registration.second->pattern()); |
| 103 key_registration.second->RemoveListener(this); |
94 } | 104 } |
95 | 105 |
96 for (const GURL& pattern : associated_patterns_) | 106 for (const GURL& pattern : associated_patterns_) |
97 DecreaseProcessReference(pattern); | 107 DecreaseProcessReference(pattern); |
98 } | 108 } |
99 | 109 |
| 110 void ServiceWorkerProviderHost::OnVersionAttributesChanged( |
| 111 ServiceWorkerRegistration* registration, |
| 112 ChangedVersionAttributesMask changed_mask, |
| 113 const ServiceWorkerRegistrationInfo& info) { |
| 114 if (!get_ready_callback_ || get_ready_callback_->called) |
| 115 return; |
| 116 if (changed_mask.active_changed() && registration->active_version()) { |
| 117 // Wait until the state change so we don't send the get for ready |
| 118 // registration complete message before set version attributes message. |
| 119 registration->active_version()->RegisterStatusChangeCallback(base::Bind( |
| 120 &ServiceWorkerProviderHost::ReturnRegistrationForReadyIfNeeded, |
| 121 AsWeakPtr())); |
| 122 } |
| 123 } |
| 124 |
100 void ServiceWorkerProviderHost::OnRegistrationFailed( | 125 void ServiceWorkerProviderHost::OnRegistrationFailed( |
101 ServiceWorkerRegistration* registration) { | 126 ServiceWorkerRegistration* registration) { |
102 DCHECK_EQ(associated_registration_.get(), registration); | 127 if (associated_registration_ == registration) |
103 DisassociateRegistration(); | 128 DisassociateRegistration(); |
| 129 RemoveMatchingRegistration(registration); |
| 130 } |
| 131 |
| 132 void ServiceWorkerProviderHost::OnRegistrationFinishedUninstalling( |
| 133 ServiceWorkerRegistration* registration) { |
| 134 RemoveMatchingRegistration(registration); |
104 } | 135 } |
105 | 136 |
106 void ServiceWorkerProviderHost::OnSkippedWaiting( | 137 void ServiceWorkerProviderHost::OnSkippedWaiting( |
107 ServiceWorkerRegistration* registration) { | 138 ServiceWorkerRegistration* registration) { |
108 DCHECK_EQ(associated_registration_.get(), registration); | 139 if (associated_registration_ != registration) |
| 140 return; |
109 // A client is "using" a registration if it is controlled by the active | 141 // A client is "using" a registration if it is controlled by the active |
110 // worker of the registration. skipWaiting doesn't cause a client to start | 142 // worker of the registration. skipWaiting doesn't cause a client to start |
111 // using the registration. | 143 // using the registration. |
112 if (!controlling_version_) | 144 if (!controlling_version_) |
113 return; | 145 return; |
114 ServiceWorkerVersion* active_version = registration->active_version(); | 146 ServiceWorkerVersion* active_version = registration->active_version(); |
115 DCHECK_EQ(active_version->status(), ServiceWorkerVersion::ACTIVATING); | 147 DCHECK_EQ(active_version->status(), ServiceWorkerVersion::ACTIVATING); |
116 SetControllerVersionAttribute(active_version); | 148 SetControllerVersionAttribute(active_version); |
117 } | 149 } |
118 | 150 |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
169 return false; | 201 return false; |
170 } | 202 } |
171 | 203 |
172 running_hosted_version_ = live_version; | 204 running_hosted_version_ = live_version; |
173 return true; | 205 return true; |
174 } | 206 } |
175 | 207 |
176 void ServiceWorkerProviderHost::AssociateRegistration( | 208 void ServiceWorkerProviderHost::AssociateRegistration( |
177 ServiceWorkerRegistration* registration) { | 209 ServiceWorkerRegistration* registration) { |
178 DCHECK(CanAssociateRegistration(registration)); | 210 DCHECK(CanAssociateRegistration(registration)); |
179 IncreaseProcessReference(registration->pattern()); | |
180 associated_registration_ = registration; | 211 associated_registration_ = registration; |
181 associated_registration_->AddListener(this); | 212 AddMatchingRegistration(registration); |
182 SendAssociateRegistrationMessage(); | 213 SendAssociateRegistrationMessage(); |
183 SetControllerVersionAttribute(registration->active_version()); | 214 SetControllerVersionAttribute(registration->active_version()); |
184 } | 215 } |
185 | 216 |
186 void ServiceWorkerProviderHost::DisassociateRegistration() { | 217 void ServiceWorkerProviderHost::DisassociateRegistration() { |
187 queued_events_.clear(); | 218 queued_events_.clear(); |
188 if (!associated_registration_.get()) | 219 if (!associated_registration_.get()) |
189 return; | 220 return; |
190 DecreaseProcessReference(associated_registration_->pattern()); | |
191 associated_registration_->RemoveListener(this); | |
192 associated_registration_ = NULL; | 221 associated_registration_ = NULL; |
193 SetControllerVersionAttribute(NULL); | 222 SetControllerVersionAttribute(NULL); |
194 | 223 |
195 if (!dispatcher_host_) | 224 if (!dispatcher_host_) |
196 return; | 225 return; |
197 | 226 |
198 // Disassociation message should be sent only for controllees. | 227 // Disassociation message should be sent only for controllees. |
199 DCHECK_EQ(SERVICE_WORKER_PROVIDER_FOR_CONTROLLEE, provider_type_); | 228 DCHECK_EQ(SERVICE_WORKER_PROVIDER_FOR_CONTROLLEE, provider_type_); |
200 Send(new ServiceWorkerMsg_DisassociateRegistration( | 229 Send(new ServiceWorkerMsg_DisassociateRegistration( |
201 render_thread_id_, provider_id())); | 230 render_thread_id_, provider_id())); |
202 } | 231 } |
203 | 232 |
| 233 void ServiceWorkerProviderHost::AddMatchingRegistration( |
| 234 ServiceWorkerRegistration* registration) { |
| 235 DCHECK(ServiceWorkerUtils::ScopeMatches( |
| 236 registration->pattern(), document_url_)); |
| 237 size_t key = registration->pattern().spec().size(); |
| 238 if (ContainsKey(matching_registrations_, key)) |
| 239 return; |
| 240 IncreaseProcessReference(registration->pattern()); |
| 241 registration->AddListener(this); |
| 242 matching_registrations_[key] = registration; |
| 243 ReturnRegistrationForReadyIfNeeded(); |
| 244 } |
| 245 |
| 246 void ServiceWorkerProviderHost::RemoveMatchingRegistration( |
| 247 ServiceWorkerRegistration* registration) { |
| 248 size_t key = registration->pattern().spec().size(); |
| 249 DCHECK(ContainsKey(matching_registrations_, key)); |
| 250 DecreaseProcessReference(registration->pattern()); |
| 251 registration->RemoveListener(this); |
| 252 matching_registrations_.erase(key); |
| 253 } |
| 254 |
| 255 ServiceWorkerRegistration* |
| 256 ServiceWorkerProviderHost::MatchRegistration() const { |
| 257 ServiceWorkerRegistrationMap::const_reverse_iterator it = |
| 258 matching_registrations_.rbegin(); |
| 259 for (; it != matching_registrations_.rend(); ++it) { |
| 260 if (it->second->is_uninstalled()) |
| 261 continue; |
| 262 if (it->second->is_uninstalling()) |
| 263 return nullptr; |
| 264 return it->second.get(); |
| 265 } |
| 266 return nullptr; |
| 267 } |
| 268 |
204 scoped_ptr<ServiceWorkerRequestHandler> | 269 scoped_ptr<ServiceWorkerRequestHandler> |
205 ServiceWorkerProviderHost::CreateRequestHandler( | 270 ServiceWorkerProviderHost::CreateRequestHandler( |
206 FetchRequestMode request_mode, | 271 FetchRequestMode request_mode, |
207 FetchCredentialsMode credentials_mode, | 272 FetchCredentialsMode credentials_mode, |
208 ResourceType resource_type, | 273 ResourceType resource_type, |
209 RequestContextType request_context_type, | 274 RequestContextType request_context_type, |
210 RequestContextFrameType frame_type, | 275 RequestContextFrameType frame_type, |
211 base::WeakPtr<storage::BlobStorageContext> blob_storage_context, | 276 base::WeakPtr<storage::BlobStorageContext> blob_storage_context, |
212 scoped_refptr<ResourceRequestBody> body) { | 277 scoped_refptr<ResourceRequestBody> body) { |
213 if (IsHostToRunningServiceWorker()) { | 278 if (IsHostToRunningServiceWorker()) { |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
325 is_claiming_ = true; | 390 is_claiming_ = true; |
326 if (registration == associated_registration_) { | 391 if (registration == associated_registration_) { |
327 SetControllerVersionAttribute(registration->active_version()); | 392 SetControllerVersionAttribute(registration->active_version()); |
328 } else if (allow_association_) { | 393 } else if (allow_association_) { |
329 DisassociateRegistration(); | 394 DisassociateRegistration(); |
330 AssociateRegistration(registration); | 395 AssociateRegistration(registration); |
331 } | 396 } |
332 is_claiming_ = false; | 397 is_claiming_ = false; |
333 } | 398 } |
334 | 399 |
| 400 bool ServiceWorkerProviderHost::GetRegistrationForReady( |
| 401 const GetRegistrationForReadyCallback& callback) { |
| 402 if (get_ready_callback_) |
| 403 return false; |
| 404 get_ready_callback_.reset(new OneShotGetReadyCallback(callback)); |
| 405 ReturnRegistrationForReadyIfNeeded(); |
| 406 return true; |
| 407 } |
| 408 |
335 void ServiceWorkerProviderHost::PrepareForCrossSiteTransfer() { | 409 void ServiceWorkerProviderHost::PrepareForCrossSiteTransfer() { |
336 DCHECK_NE(ChildProcessHost::kInvalidUniqueID, render_process_id_); | 410 DCHECK_NE(ChildProcessHost::kInvalidUniqueID, render_process_id_); |
337 DCHECK_NE(MSG_ROUTING_NONE, render_frame_id_); | 411 DCHECK_NE(MSG_ROUTING_NONE, render_frame_id_); |
338 DCHECK_EQ(kDocumentMainThreadId, render_thread_id_); | 412 DCHECK_EQ(kDocumentMainThreadId, render_thread_id_); |
339 DCHECK_NE(SERVICE_WORKER_PROVIDER_UNKNOWN, provider_type_); | 413 DCHECK_NE(SERVICE_WORKER_PROVIDER_UNKNOWN, provider_type_); |
340 | 414 |
341 for (const GURL& pattern : associated_patterns_) | 415 for (const GURL& pattern : associated_patterns_) |
342 DecreaseProcessReference(pattern); | 416 DecreaseProcessReference(pattern); |
343 | 417 |
| 418 for (auto& key_registration : matching_registrations_) |
| 419 DecreaseProcessReference(key_registration.second->pattern()); |
| 420 |
344 if (associated_registration_.get()) { | 421 if (associated_registration_.get()) { |
345 DecreaseProcessReference(associated_registration_->pattern()); | |
346 if (dispatcher_host_) { | 422 if (dispatcher_host_) { |
347 Send(new ServiceWorkerMsg_DisassociateRegistration( | 423 Send(new ServiceWorkerMsg_DisassociateRegistration( |
348 render_thread_id_, provider_id())); | 424 render_thread_id_, provider_id())); |
349 } | 425 } |
350 } | 426 } |
351 | 427 |
352 render_process_id_ = ChildProcessHost::kInvalidUniqueID; | 428 render_process_id_ = ChildProcessHost::kInvalidUniqueID; |
353 render_frame_id_ = MSG_ROUTING_NONE; | 429 render_frame_id_ = MSG_ROUTING_NONE; |
354 render_thread_id_ = kInvalidEmbeddedWorkerThreadId; | 430 render_thread_id_ = kInvalidEmbeddedWorkerThreadId; |
355 provider_id_ = kInvalidServiceWorkerProviderId; | 431 provider_id_ = kInvalidServiceWorkerProviderId; |
(...skipping 14 matching lines...) Expand all Loading... |
370 render_process_id_ = new_process_id; | 446 render_process_id_ = new_process_id; |
371 render_frame_id_ = new_frame_id; | 447 render_frame_id_ = new_frame_id; |
372 render_thread_id_ = kDocumentMainThreadId; | 448 render_thread_id_ = kDocumentMainThreadId; |
373 provider_id_ = new_provider_id; | 449 provider_id_ = new_provider_id; |
374 provider_type_ = new_provider_type; | 450 provider_type_ = new_provider_type; |
375 dispatcher_host_ = new_dispatcher_host; | 451 dispatcher_host_ = new_dispatcher_host; |
376 | 452 |
377 for (const GURL& pattern : associated_patterns_) | 453 for (const GURL& pattern : associated_patterns_) |
378 IncreaseProcessReference(pattern); | 454 IncreaseProcessReference(pattern); |
379 | 455 |
| 456 for (auto& key_registration : matching_registrations_) |
| 457 IncreaseProcessReference(key_registration.second->pattern()); |
| 458 |
380 if (associated_registration_.get()) { | 459 if (associated_registration_.get()) { |
381 IncreaseProcessReference(associated_registration_->pattern()); | |
382 SendAssociateRegistrationMessage(); | 460 SendAssociateRegistrationMessage(); |
383 if (dispatcher_host_ && associated_registration_->active_version()) { | 461 if (dispatcher_host_ && associated_registration_->active_version()) { |
384 Send(new ServiceWorkerMsg_SetControllerServiceWorker( | 462 Send(new ServiceWorkerMsg_SetControllerServiceWorker( |
385 render_thread_id_, provider_id(), | 463 render_thread_id_, provider_id(), |
386 CreateAndRegisterServiceWorkerHandle( | 464 CreateAndRegisterServiceWorkerHandle( |
387 associated_registration_->active_version()), | 465 associated_registration_->active_version()), |
388 false /* shouldNotifyControllerChange */)); | 466 false /* shouldNotifyControllerChange */)); |
389 } | 467 } |
390 } | 468 } |
391 } | 469 } |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
497 } | 575 } |
498 | 576 |
499 void ServiceWorkerProviderHost::DecreaseProcessReference( | 577 void ServiceWorkerProviderHost::DecreaseProcessReference( |
500 const GURL& pattern) { | 578 const GURL& pattern) { |
501 if (context_ && context_->process_manager()) { | 579 if (context_ && context_->process_manager()) { |
502 context_->process_manager()->RemoveProcessReferenceFromPattern( | 580 context_->process_manager()->RemoveProcessReferenceFromPattern( |
503 pattern, render_process_id_); | 581 pattern, render_process_id_); |
504 } | 582 } |
505 } | 583 } |
506 | 584 |
| 585 void ServiceWorkerProviderHost::ReturnRegistrationForReadyIfNeeded() { |
| 586 if (!get_ready_callback_ || get_ready_callback_->called) |
| 587 return; |
| 588 ServiceWorkerRegistration* registration = MatchRegistration(); |
| 589 if (!registration) |
| 590 return; |
| 591 if (registration->active_version()) { |
| 592 get_ready_callback_->callback.Run(registration); |
| 593 get_ready_callback_->callback.Reset(); |
| 594 get_ready_callback_->called = true; |
| 595 return; |
| 596 } |
| 597 } |
| 598 |
507 bool ServiceWorkerProviderHost::IsReadyToSendMessages() const { | 599 bool ServiceWorkerProviderHost::IsReadyToSendMessages() const { |
508 return render_thread_id_ != kInvalidEmbeddedWorkerThreadId; | 600 return render_thread_id_ != kInvalidEmbeddedWorkerThreadId; |
509 } | 601 } |
510 | 602 |
511 bool ServiceWorkerProviderHost::IsContextAlive() { | 603 bool ServiceWorkerProviderHost::IsContextAlive() { |
512 return context_ != NULL; | 604 return context_ != NULL; |
513 } | 605 } |
514 | 606 |
515 void ServiceWorkerProviderHost::Send(IPC::Message* message) const { | 607 void ServiceWorkerProviderHost::Send(IPC::Message* message) const { |
516 DCHECK(dispatcher_host_); | 608 DCHECK(dispatcher_host_); |
517 DCHECK(IsReadyToSendMessages()); | 609 DCHECK(IsReadyToSendMessages()); |
518 dispatcher_host_->Send(message); | 610 dispatcher_host_->Send(message); |
519 } | 611 } |
520 | 612 |
521 } // namespace content | 613 } // namespace content |
OLD | NEW |