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