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 |