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
3 // found in the LICENSE file.
5 #include "content/browser/service_worker/service_worker_provider_host.h"
8 #include "base/stl_util.h"
9 #include "content/browser/frame_host/frame_tree.h"
10 #include "content/browser/frame_host/frame_tree_node.h"
11 #include "content/browser/frame_host/render_frame_host_impl.h"
12 #include "content/browser/message_port_message_filter.h"
13 #include "content/browser/service_worker/service_worker_context_core.h"
14 #include "content/browser/service_worker/service_worker_context_request_handler.h"
15 #include "content/browser/service_worker/service_worker_controllee_request_handler.h"
16 #include "content/browser/service_worker/service_worker_dispatcher_host.h"
17 #include "content/browser/service_worker/service_worker_handle.h"
18 #include "content/browser/service_worker/service_worker_registration_handle.h"
19 #include "content/browser/service_worker/service_worker_version.h"
20 #include "content/browser/web_contents/web_contents_impl.h"
21 #include "content/common/resource_request_body.h"
22 #include "content/common/service_worker/service_worker_messages.h"
23 #include "content/common/service_worker/service_worker_types.h"
24 #include "content/common/service_worker/service_worker_utils.h"
25 #include "content/public/browser/render_frame_host.h"
26 #include "content/public/browser/render_widget_host_view.h"
27 #include "content/public/browser/web_contents.h"
28 #include "content/public/common/child_process_host.h"
34 ServiceWorkerClientInfo
FocusOnUIThread(int render_process_id
,
35 int render_frame_id
) {
36 RenderFrameHostImpl
* render_frame_host
=
37 RenderFrameHostImpl::FromID(render_process_id
, render_frame_id
);
38 WebContentsImpl
* web_contents
= static_cast<WebContentsImpl
*>(
39 WebContents::FromRenderFrameHost(render_frame_host
));
41 if (!render_frame_host
|| !web_contents
)
42 return ServiceWorkerClientInfo();
44 FrameTreeNode
* frame_tree_node
= render_frame_host
->frame_tree_node();
46 // Focus the frame in the frame tree node, in case it has changed.
47 frame_tree_node
->frame_tree()->SetFocusedFrame(frame_tree_node
);
49 // Focus the frame's view to make sure the frame is now considered as focused.
50 render_frame_host
->GetView()->Focus();
52 // Move the web contents to the foreground.
53 web_contents
->Activate();
55 return ServiceWorkerProviderHost::GetWindowClientInfoOnUI(render_process_id
,
59 } // anonymous namespace
61 ServiceWorkerProviderHost::OneShotGetReadyCallback::OneShotGetReadyCallback(
62 const GetRegistrationForReadyCallback
& callback
)
67 ServiceWorkerProviderHost::OneShotGetReadyCallback::~OneShotGetReadyCallback() {
70 ServiceWorkerProviderHost::ServiceWorkerProviderHost(
71 int render_process_id
,
74 ServiceWorkerProviderType provider_type
,
75 base::WeakPtr
<ServiceWorkerContextCore
> context
,
76 ServiceWorkerDispatcherHost
* dispatcher_host
)
77 : client_uuid_(base::GenerateGUID()),
78 render_process_id_(render_process_id
),
80 render_thread_id_(kDocumentMainThreadId
),
81 provider_id_(provider_id
),
82 provider_type_(provider_type
),
84 dispatcher_host_(dispatcher_host
),
85 allow_association_(true) {
86 DCHECK_NE(ChildProcessHost::kInvalidUniqueID
, render_process_id_
);
87 DCHECK_NE(SERVICE_WORKER_PROVIDER_UNKNOWN
, provider_type_
);
88 DCHECK_NE(SERVICE_WORKER_PROVIDER_FOR_SANDBOXED_FRAME
, provider_type_
);
89 if (provider_type_
== SERVICE_WORKER_PROVIDER_FOR_CONTROLLER
) {
90 // Actual thread id is set when the service worker context gets started.
91 render_thread_id_
= kInvalidEmbeddedWorkerThreadId
;
93 context_
->RegisterProviderHostByClientID(client_uuid_
, this);
96 ServiceWorkerProviderHost::~ServiceWorkerProviderHost() {
98 context_
->UnregisterProviderHostByClientID(client_uuid_
);
100 // Clear docurl so the deferred activation of a waiting worker
101 // won't associate the new version with a provider being destroyed.
102 document_url_
= GURL();
103 if (controlling_version_
.get())
104 controlling_version_
->RemoveControllee(this);
106 for (auto& key_registration
: matching_registrations_
) {
107 DecreaseProcessReference(key_registration
.second
->pattern());
108 key_registration
.second
->RemoveListener(this);
111 for (const GURL
& pattern
: associated_patterns_
)
112 DecreaseProcessReference(pattern
);
115 int ServiceWorkerProviderHost::frame_id() const {
116 if (provider_type_
== SERVICE_WORKER_PROVIDER_FOR_WINDOW
)
118 return MSG_ROUTING_NONE
;
121 void ServiceWorkerProviderHost::OnVersionAttributesChanged(
122 ServiceWorkerRegistration
* registration
,
123 ChangedVersionAttributesMask changed_mask
,
124 const ServiceWorkerRegistrationInfo
& info
) {
125 if (!get_ready_callback_
|| get_ready_callback_
->called
)
127 if (changed_mask
.active_changed() && registration
->active_version()) {
128 // Wait until the state change so we don't send the get for ready
129 // registration complete message before set version attributes message.
130 registration
->active_version()->RegisterStatusChangeCallback(base::Bind(
131 &ServiceWorkerProviderHost::ReturnRegistrationForReadyIfNeeded
,
136 void ServiceWorkerProviderHost::OnRegistrationFailed(
137 ServiceWorkerRegistration
* registration
) {
138 if (associated_registration_
== registration
)
139 DisassociateRegistration();
140 RemoveMatchingRegistration(registration
);
143 void ServiceWorkerProviderHost::OnRegistrationFinishedUninstalling(
144 ServiceWorkerRegistration
* registration
) {
145 RemoveMatchingRegistration(registration
);
148 void ServiceWorkerProviderHost::OnSkippedWaiting(
149 ServiceWorkerRegistration
* registration
) {
150 if (associated_registration_
!= registration
)
152 // A client is "using" a registration if it is controlled by the active
153 // worker of the registration. skipWaiting doesn't cause a client to start
154 // using the registration.
155 if (!controlling_version_
)
157 ServiceWorkerVersion
* active_version
= registration
->active_version();
158 DCHECK_EQ(active_version
->status(), ServiceWorkerVersion::ACTIVATING
);
159 SetControllerVersionAttribute(active_version
,
160 true /* notify_controllerchange */);
163 void ServiceWorkerProviderHost::SetDocumentUrl(const GURL
& url
) {
164 DCHECK(!url
.has_ref());
168 void ServiceWorkerProviderHost::SetTopmostFrameUrl(const GURL
& url
) {
169 topmost_frame_url_
= url
;
172 void ServiceWorkerProviderHost::SetControllerVersionAttribute(
173 ServiceWorkerVersion
* version
,
174 bool notify_controllerchange
) {
175 if (version
== controlling_version_
.get())
178 scoped_refptr
<ServiceWorkerVersion
> previous_version
= controlling_version_
;
179 controlling_version_
= version
;
181 version
->AddControllee(this);
182 if (previous_version
.get())
183 previous_version
->RemoveControllee(this);
185 if (!dispatcher_host_
)
186 return; // Could be NULL in some tests.
188 // SetController message should be sent only for controllees.
189 DCHECK(IsProviderForClient());
190 Send(new ServiceWorkerMsg_SetControllerServiceWorker(
191 render_thread_id_
, provider_id(), GetOrCreateServiceWorkerHandle(version
),
192 notify_controllerchange
));
195 bool ServiceWorkerProviderHost::SetHostedVersionId(int64 version_id
) {
197 return true; // System is shutting down.
198 if (active_version())
199 return false; // Unexpected bad message.
201 ServiceWorkerVersion
* live_version
= context_
->GetLiveVersion(version_id
);
203 return true; // Was deleted before it got started.
205 ServiceWorkerVersionInfo info
= live_version
->GetInfo();
206 if (info
.running_status
!= ServiceWorkerVersion::STARTING
||
207 info
.process_id
!= render_process_id_
) {
208 // If we aren't trying to start this version in our process
209 // something is amiss.
213 running_hosted_version_
= live_version
;
217 bool ServiceWorkerProviderHost::IsProviderForClient() const {
218 switch (provider_type_
) {
219 case SERVICE_WORKER_PROVIDER_FOR_WINDOW
:
220 case SERVICE_WORKER_PROVIDER_FOR_WORKER
:
221 case SERVICE_WORKER_PROVIDER_FOR_SHARED_WORKER
:
223 case SERVICE_WORKER_PROVIDER_FOR_CONTROLLER
:
225 case SERVICE_WORKER_PROVIDER_FOR_SANDBOXED_FRAME
:
226 case SERVICE_WORKER_PROVIDER_UNKNOWN
:
227 NOTREACHED() << provider_type_
;
229 NOTREACHED() << provider_type_
;
233 blink::WebServiceWorkerClientType
ServiceWorkerProviderHost::client_type()
235 switch (provider_type_
) {
236 case SERVICE_WORKER_PROVIDER_FOR_WINDOW
:
237 return blink::WebServiceWorkerClientTypeWindow
;
238 case SERVICE_WORKER_PROVIDER_FOR_WORKER
:
239 return blink::WebServiceWorkerClientTypeWorker
;
240 case SERVICE_WORKER_PROVIDER_FOR_SHARED_WORKER
:
241 return blink::WebServiceWorkerClientTypeSharedWorker
;
242 case SERVICE_WORKER_PROVIDER_FOR_CONTROLLER
:
243 case SERVICE_WORKER_PROVIDER_FOR_SANDBOXED_FRAME
:
244 case SERVICE_WORKER_PROVIDER_UNKNOWN
:
245 NOTREACHED() << provider_type_
;
247 NOTREACHED() << provider_type_
;
248 return blink::WebServiceWorkerClientTypeWindow
;
251 void ServiceWorkerProviderHost::AssociateRegistration(
252 ServiceWorkerRegistration
* registration
,
253 bool notify_controllerchange
) {
254 DCHECK(CanAssociateRegistration(registration
));
255 associated_registration_
= registration
;
256 AddMatchingRegistration(registration
);
257 SendAssociateRegistrationMessage();
258 SetControllerVersionAttribute(registration
->active_version(),
259 notify_controllerchange
);
262 void ServiceWorkerProviderHost::DisassociateRegistration() {
263 queued_events_
.clear();
264 if (!associated_registration_
.get())
266 associated_registration_
= NULL
;
267 SetControllerVersionAttribute(NULL
, false /* notify_controllerchange */);
269 if (!dispatcher_host_
)
272 // Disassociation message should be sent only for controllees.
273 DCHECK(IsProviderForClient());
274 Send(new ServiceWorkerMsg_DisassociateRegistration(
275 render_thread_id_
, provider_id()));
278 void ServiceWorkerProviderHost::AddMatchingRegistration(
279 ServiceWorkerRegistration
* registration
) {
280 DCHECK(ServiceWorkerUtils::ScopeMatches(
281 registration
->pattern(), document_url_
));
282 size_t key
= registration
->pattern().spec().size();
283 if (ContainsKey(matching_registrations_
, key
))
285 IncreaseProcessReference(registration
->pattern());
286 registration
->AddListener(this);
287 matching_registrations_
[key
] = registration
;
288 ReturnRegistrationForReadyIfNeeded();
291 void ServiceWorkerProviderHost::RemoveMatchingRegistration(
292 ServiceWorkerRegistration
* registration
) {
293 size_t key
= registration
->pattern().spec().size();
294 DCHECK(ContainsKey(matching_registrations_
, key
));
295 DecreaseProcessReference(registration
->pattern());
296 registration
->RemoveListener(this);
297 matching_registrations_
.erase(key
);
300 void ServiceWorkerProviderHost::AddAllMatchingRegistrations() {
302 const std::map
<int64
, ServiceWorkerRegistration
*>& registrations
=
303 context_
->GetLiveRegistrations();
304 for (const auto& key_registration
: registrations
) {
305 ServiceWorkerRegistration
* registration
= key_registration
.second
;
306 if (!registration
->is_uninstalled() &&
307 ServiceWorkerUtils::ScopeMatches(registration
->pattern(),
309 AddMatchingRegistration(registration
);
313 ServiceWorkerRegistration
*
314 ServiceWorkerProviderHost::MatchRegistration() const {
315 ServiceWorkerRegistrationMap::const_reverse_iterator it
=
316 matching_registrations_
.rbegin();
317 for (; it
!= matching_registrations_
.rend(); ++it
) {
318 if (it
->second
->is_uninstalled())
320 if (it
->second
->is_uninstalling())
322 return it
->second
.get();
327 void ServiceWorkerProviderHost::NotifyControllerLost() {
328 SetControllerVersionAttribute(nullptr, true /* notify_controllerchange */);
331 scoped_ptr
<ServiceWorkerRequestHandler
>
332 ServiceWorkerProviderHost::CreateRequestHandler(
333 FetchRequestMode request_mode
,
334 FetchCredentialsMode credentials_mode
,
335 ResourceType resource_type
,
336 RequestContextType request_context_type
,
337 RequestContextFrameType frame_type
,
338 base::WeakPtr
<storage::BlobStorageContext
> blob_storage_context
,
339 scoped_refptr
<ResourceRequestBody
> body
) {
340 if (IsHostToRunningServiceWorker()) {
341 return scoped_ptr
<ServiceWorkerRequestHandler
>(
342 new ServiceWorkerContextRequestHandler(
343 context_
, AsWeakPtr(), blob_storage_context
, resource_type
));
345 if (ServiceWorkerUtils::IsMainResourceType(resource_type
) ||
346 controlling_version()) {
347 return scoped_ptr
<ServiceWorkerRequestHandler
>(
348 new ServiceWorkerControlleeRequestHandler(context_
,
350 blob_storage_context
,
354 request_context_type
,
358 return scoped_ptr
<ServiceWorkerRequestHandler
>();
361 ServiceWorkerObjectInfo
362 ServiceWorkerProviderHost::GetOrCreateServiceWorkerHandle(
363 ServiceWorkerVersion
* version
) {
364 DCHECK(dispatcher_host_
);
365 if (!context_
|| !version
)
366 return ServiceWorkerObjectInfo();
367 ServiceWorkerHandle
* handle
= dispatcher_host_
->FindServiceWorkerHandle(
368 provider_id(), version
->version_id());
370 handle
->IncrementRefCount();
371 return handle
->GetObjectInfo();
374 scoped_ptr
<ServiceWorkerHandle
> new_handle(
375 ServiceWorkerHandle::Create(context_
, AsWeakPtr(), version
));
376 handle
= new_handle
.get();
377 dispatcher_host_
->RegisterServiceWorkerHandle(new_handle
.Pass());
378 return handle
->GetObjectInfo();
381 bool ServiceWorkerProviderHost::CanAssociateRegistration(
382 ServiceWorkerRegistration
* registration
) {
385 if (running_hosted_version_
.get())
387 if (!registration
|| associated_registration_
.get() || !allow_association_
)
392 void ServiceWorkerProviderHost::PostMessage(
393 ServiceWorkerVersion
* version
,
394 const base::string16
& message
,
395 const std::vector
<TransferredMessagePort
>& sent_message_ports
) {
396 if (!dispatcher_host_
)
397 return; // Could be NULL in some tests.
399 std::vector
<int> new_routing_ids
;
400 dispatcher_host_
->message_port_message_filter()->
401 UpdateMessagePortsWithNewRoutes(sent_message_ports
,
404 ServiceWorkerMsg_MessageToDocument_Params params
;
405 params
.thread_id
= kDocumentMainThreadId
;
406 params
.provider_id
= provider_id();
407 params
.service_worker_info
= GetOrCreateServiceWorkerHandle(version
);
408 params
.message
= message
;
409 params
.message_ports
= sent_message_ports
;
410 params
.new_routing_ids
= new_routing_ids
;
411 Send(new ServiceWorkerMsg_MessageToDocument(params
));
414 void ServiceWorkerProviderHost::Focus(const GetClientInfoCallback
& callback
) {
415 if (provider_type_
!= SERVICE_WORKER_PROVIDER_FOR_WINDOW
) {
416 callback
.Run(ServiceWorkerClientInfo());
419 BrowserThread::PostTaskAndReplyWithResult(
420 BrowserThread::UI
, FROM_HERE
,
421 base::Bind(&FocusOnUIThread
, render_process_id_
, route_id_
), callback
);
424 void ServiceWorkerProviderHost::GetWindowClientInfo(
425 const GetClientInfoCallback
& callback
) const {
426 if (provider_type_
!= SERVICE_WORKER_PROVIDER_FOR_WINDOW
) {
427 callback
.Run(ServiceWorkerClientInfo());
430 BrowserThread::PostTaskAndReplyWithResult(
431 BrowserThread::UI
, FROM_HERE
,
432 base::Bind(&ServiceWorkerProviderHost::GetWindowClientInfoOnUI
,
433 render_process_id_
, route_id_
),
438 ServiceWorkerClientInfo
ServiceWorkerProviderHost::GetWindowClientInfoOnUI(
439 int render_process_id
,
440 int render_frame_id
) {
441 RenderFrameHostImpl
* render_frame_host
=
442 RenderFrameHostImpl::FromID(render_process_id
, render_frame_id
);
443 if (!render_frame_host
)
444 return ServiceWorkerClientInfo();
446 // TODO(mlamouri,michaeln): it is possible to end up collecting information
447 // for a frame that is actually being navigated and isn't exactly what we are
449 return ServiceWorkerClientInfo(
450 render_frame_host
->GetVisibilityState(),
451 render_frame_host
->IsFocused(),
452 render_frame_host
->GetLastCommittedURL(),
453 render_frame_host
->GetParent() ? REQUEST_CONTEXT_FRAME_TYPE_NESTED
454 : REQUEST_CONTEXT_FRAME_TYPE_TOP_LEVEL
,
455 blink::WebServiceWorkerClientTypeWindow
);
458 void ServiceWorkerProviderHost::AddScopedProcessReferenceToPattern(
459 const GURL
& pattern
) {
460 associated_patterns_
.push_back(pattern
);
461 IncreaseProcessReference(pattern
);
464 void ServiceWorkerProviderHost::ClaimedByRegistration(
465 ServiceWorkerRegistration
* registration
) {
466 DCHECK(registration
->active_version());
467 if (registration
== associated_registration_
) {
468 SetControllerVersionAttribute(registration
->active_version(),
469 true /* notify_controllerchange */);
470 } else if (allow_association_
) {
471 DisassociateRegistration();
472 AssociateRegistration(registration
, true /* notify_controllerchange */);
476 bool ServiceWorkerProviderHost::GetRegistrationForReady(
477 const GetRegistrationForReadyCallback
& callback
) {
478 if (get_ready_callback_
)
480 get_ready_callback_
.reset(new OneShotGetReadyCallback(callback
));
481 ReturnRegistrationForReadyIfNeeded();
485 void ServiceWorkerProviderHost::PrepareForCrossSiteTransfer() {
486 DCHECK_NE(ChildProcessHost::kInvalidUniqueID
, render_process_id_
);
487 DCHECK_NE(MSG_ROUTING_NONE
, route_id_
);
488 DCHECK_EQ(kDocumentMainThreadId
, render_thread_id_
);
489 DCHECK_NE(SERVICE_WORKER_PROVIDER_UNKNOWN
, provider_type_
);
491 for (const GURL
& pattern
: associated_patterns_
)
492 DecreaseProcessReference(pattern
);
494 for (auto& key_registration
: matching_registrations_
)
495 DecreaseProcessReference(key_registration
.second
->pattern());
497 if (associated_registration_
.get()) {
498 if (dispatcher_host_
) {
499 Send(new ServiceWorkerMsg_DisassociateRegistration(
500 render_thread_id_
, provider_id()));
504 render_process_id_
= ChildProcessHost::kInvalidUniqueID
;
505 route_id_
= MSG_ROUTING_NONE
;
506 render_thread_id_
= kInvalidEmbeddedWorkerThreadId
;
507 provider_id_
= kInvalidServiceWorkerProviderId
;
508 provider_type_
= SERVICE_WORKER_PROVIDER_UNKNOWN
;
509 dispatcher_host_
= nullptr;
512 void ServiceWorkerProviderHost::CompleteCrossSiteTransfer(
516 ServiceWorkerProviderType new_provider_type
,
517 ServiceWorkerDispatcherHost
* new_dispatcher_host
) {
518 DCHECK_EQ(ChildProcessHost::kInvalidUniqueID
, render_process_id_
);
519 DCHECK_NE(ChildProcessHost::kInvalidUniqueID
, new_process_id
);
520 DCHECK_NE(MSG_ROUTING_NONE
, new_frame_id
);
522 render_process_id_
= new_process_id
;
523 route_id_
= new_frame_id
;
524 render_thread_id_
= kDocumentMainThreadId
;
525 provider_id_
= new_provider_id
;
526 provider_type_
= new_provider_type
;
527 dispatcher_host_
= new_dispatcher_host
;
529 for (const GURL
& pattern
: associated_patterns_
)
530 IncreaseProcessReference(pattern
);
532 for (auto& key_registration
: matching_registrations_
)
533 IncreaseProcessReference(key_registration
.second
->pattern());
535 if (associated_registration_
.get()) {
536 SendAssociateRegistrationMessage();
537 if (dispatcher_host_
&& associated_registration_
->active_version()) {
538 Send(new ServiceWorkerMsg_SetControllerServiceWorker(
539 render_thread_id_
, provider_id(),
540 GetOrCreateServiceWorkerHandle(
541 associated_registration_
->active_version()),
542 false /* shouldNotifyControllerChange */));
547 void ServiceWorkerProviderHost::SendUpdateFoundMessage(
548 int registration_handle_id
) {
549 if (!dispatcher_host_
)
550 return; // Could be nullptr in some tests.
552 if (!IsReadyToSendMessages()) {
553 queued_events_
.push_back(
554 base::Bind(&ServiceWorkerProviderHost::SendUpdateFoundMessage
,
555 AsWeakPtr(), registration_handle_id
));
559 Send(new ServiceWorkerMsg_UpdateFound(
560 render_thread_id_
, registration_handle_id
));
563 void ServiceWorkerProviderHost::SendSetVersionAttributesMessage(
564 int registration_handle_id
,
565 ChangedVersionAttributesMask changed_mask
,
566 ServiceWorkerVersion
* installing_version
,
567 ServiceWorkerVersion
* waiting_version
,
568 ServiceWorkerVersion
* active_version
) {
569 if (!dispatcher_host_
)
570 return; // Could be nullptr in some tests.
571 if (!changed_mask
.changed())
574 if (!IsReadyToSendMessages()) {
575 queued_events_
.push_back(
576 base::Bind(&ServiceWorkerProviderHost::SendSetVersionAttributesMessage
,
577 AsWeakPtr(), registration_handle_id
, changed_mask
,
578 make_scoped_refptr(installing_version
),
579 make_scoped_refptr(waiting_version
),
580 make_scoped_refptr(active_version
)));
584 ServiceWorkerVersionAttributes attrs
;
585 if (changed_mask
.installing_changed())
586 attrs
.installing
= GetOrCreateServiceWorkerHandle(installing_version
);
587 if (changed_mask
.waiting_changed())
588 attrs
.waiting
= GetOrCreateServiceWorkerHandle(waiting_version
);
589 if (changed_mask
.active_changed())
590 attrs
.active
= GetOrCreateServiceWorkerHandle(active_version
);
592 Send(new ServiceWorkerMsg_SetVersionAttributes(
593 render_thread_id_
, provider_id_
, registration_handle_id
,
594 changed_mask
.changed(), attrs
));
597 void ServiceWorkerProviderHost::SendServiceWorkerStateChangedMessage(
598 int worker_handle_id
,
599 blink::WebServiceWorkerState state
) {
600 if (!dispatcher_host_
)
603 if (!IsReadyToSendMessages()) {
604 queued_events_
.push_back(base::Bind(
605 &ServiceWorkerProviderHost::SendServiceWorkerStateChangedMessage
,
606 AsWeakPtr(), worker_handle_id
, state
));
610 Send(new ServiceWorkerMsg_ServiceWorkerStateChanged(
611 render_thread_id_
, worker_handle_id
, state
));
614 void ServiceWorkerProviderHost::SetReadyToSendMessagesToWorker(
615 int render_thread_id
) {
616 DCHECK(!IsReadyToSendMessages());
617 render_thread_id_
= render_thread_id
;
619 for (const auto& event
: queued_events_
)
621 queued_events_
.clear();
624 void ServiceWorkerProviderHost::SendAssociateRegistrationMessage() {
625 if (!dispatcher_host_
)
628 ServiceWorkerRegistrationHandle
* handle
=
629 dispatcher_host_
->GetOrCreateRegistrationHandle(
630 AsWeakPtr(), associated_registration_
.get());
632 ServiceWorkerVersionAttributes attrs
;
633 attrs
.installing
= GetOrCreateServiceWorkerHandle(
634 associated_registration_
->installing_version());
635 attrs
.waiting
= GetOrCreateServiceWorkerHandle(
636 associated_registration_
->waiting_version());
637 attrs
.active
= GetOrCreateServiceWorkerHandle(
638 associated_registration_
->active_version());
640 // Association message should be sent only for controllees.
641 DCHECK(IsProviderForClient());
642 dispatcher_host_
->Send(new ServiceWorkerMsg_AssociateRegistration(
643 render_thread_id_
, provider_id(), handle
->GetObjectInfo(), attrs
));
646 void ServiceWorkerProviderHost::IncreaseProcessReference(
647 const GURL
& pattern
) {
648 if (context_
&& context_
->process_manager()) {
649 context_
->process_manager()->AddProcessReferenceToPattern(
650 pattern
, render_process_id_
);
654 void ServiceWorkerProviderHost::DecreaseProcessReference(
655 const GURL
& pattern
) {
656 if (context_
&& context_
->process_manager()) {
657 context_
->process_manager()->RemoveProcessReferenceFromPattern(
658 pattern
, render_process_id_
);
662 void ServiceWorkerProviderHost::ReturnRegistrationForReadyIfNeeded() {
663 if (!get_ready_callback_
|| get_ready_callback_
->called
)
665 ServiceWorkerRegistration
* registration
= MatchRegistration();
668 if (registration
->active_version()) {
669 get_ready_callback_
->callback
.Run(registration
);
670 get_ready_callback_
->callback
.Reset();
671 get_ready_callback_
->called
= true;
676 bool ServiceWorkerProviderHost::IsReadyToSendMessages() const {
677 return render_thread_id_
!= kInvalidEmbeddedWorkerThreadId
;
680 bool ServiceWorkerProviderHost::IsContextAlive() {
681 return context_
!= NULL
;
684 void ServiceWorkerProviderHost::Send(IPC::Message
* message
) const {
685 DCHECK(dispatcher_host_
);
686 DCHECK(IsReadyToSendMessages());
687 dispatcher_host_
->Send(message
);
690 } // namespace content