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 "base/time/time.h"
10 #include "content/browser/frame_host/frame_tree.h"
11 #include "content/browser/frame_host/frame_tree_node.h"
12 #include "content/browser/frame_host/render_frame_host_impl.h"
13 #include "content/browser/message_port_message_filter.h"
14 #include "content/browser/service_worker/service_worker_context_core.h"
15 #include "content/browser/service_worker/service_worker_context_request_handler.h"
16 #include "content/browser/service_worker/service_worker_controllee_request_handler.h"
17 #include "content/browser/service_worker/service_worker_dispatcher_host.h"
18 #include "content/browser/service_worker/service_worker_handle.h"
19 #include "content/browser/service_worker/service_worker_registration_handle.h"
20 #include "content/browser/service_worker/service_worker_version.h"
21 #include "content/browser/web_contents/web_contents_impl.h"
22 #include "content/common/resource_request_body.h"
23 #include "content/common/service_worker/service_worker_messages.h"
24 #include "content/common/service_worker/service_worker_types.h"
25 #include "content/common/service_worker/service_worker_utils.h"
26 #include "content/public/browser/render_frame_host.h"
27 #include "content/public/browser/render_widget_host_view.h"
28 #include "content/public/browser/web_contents.h"
29 #include "content/public/common/child_process_host.h"
35 ServiceWorkerClientInfo
FocusOnUIThread(int render_process_id
,
36 int render_frame_id
) {
37 RenderFrameHostImpl
* render_frame_host
=
38 RenderFrameHostImpl::FromID(render_process_id
, render_frame_id
);
39 WebContentsImpl
* web_contents
= static_cast<WebContentsImpl
*>(
40 WebContents::FromRenderFrameHost(render_frame_host
));
42 if (!render_frame_host
|| !web_contents
)
43 return ServiceWorkerClientInfo();
45 FrameTreeNode
* frame_tree_node
= render_frame_host
->frame_tree_node();
47 // Focus the frame in the frame tree node, in case it has changed.
48 frame_tree_node
->frame_tree()->SetFocusedFrame(frame_tree_node
);
50 // Focus the frame's view to make sure the frame is now considered as focused.
51 render_frame_host
->GetView()->Focus();
53 // Move the web contents to the foreground.
54 web_contents
->Activate();
56 return ServiceWorkerProviderHost::GetWindowClientInfoOnUI(render_process_id
,
60 } // anonymous namespace
62 ServiceWorkerProviderHost::OneShotGetReadyCallback::OneShotGetReadyCallback(
63 const GetRegistrationForReadyCallback
& callback
)
68 ServiceWorkerProviderHost::OneShotGetReadyCallback::~OneShotGetReadyCallback() {
71 ServiceWorkerProviderHost::ServiceWorkerProviderHost(
72 int render_process_id
,
75 ServiceWorkerProviderType provider_type
,
76 base::WeakPtr
<ServiceWorkerContextCore
> context
,
77 ServiceWorkerDispatcherHost
* dispatcher_host
)
78 : client_uuid_(base::GenerateGUID()),
79 render_process_id_(render_process_id
),
81 render_thread_id_(kDocumentMainThreadId
),
82 provider_id_(provider_id
),
83 provider_type_(provider_type
),
85 dispatcher_host_(dispatcher_host
),
86 allow_association_(true) {
87 DCHECK_NE(ChildProcessHost::kInvalidUniqueID
, render_process_id_
);
88 DCHECK_NE(SERVICE_WORKER_PROVIDER_UNKNOWN
, provider_type_
);
89 DCHECK_NE(SERVICE_WORKER_PROVIDER_FOR_SANDBOXED_FRAME
, provider_type_
);
90 if (provider_type_
== SERVICE_WORKER_PROVIDER_FOR_CONTROLLER
) {
91 // Actual thread id is set when the service worker context gets started.
92 render_thread_id_
= kInvalidEmbeddedWorkerThreadId
;
94 context_
->RegisterProviderHostByClientID(client_uuid_
, this);
97 ServiceWorkerProviderHost::~ServiceWorkerProviderHost() {
99 context_
->UnregisterProviderHostByClientID(client_uuid_
);
101 // Clear docurl so the deferred activation of a waiting worker
102 // won't associate the new version with a provider being destroyed.
103 document_url_
= GURL();
104 if (controlling_version_
.get())
105 controlling_version_
->RemoveControllee(this);
107 for (auto& key_registration
: matching_registrations_
) {
108 DecreaseProcessReference(key_registration
.second
->pattern());
109 key_registration
.second
->RemoveListener(this);
112 for (const GURL
& pattern
: associated_patterns_
)
113 DecreaseProcessReference(pattern
);
116 int ServiceWorkerProviderHost::frame_id() const {
117 if (provider_type_
== SERVICE_WORKER_PROVIDER_FOR_WINDOW
)
119 return MSG_ROUTING_NONE
;
122 void ServiceWorkerProviderHost::OnVersionAttributesChanged(
123 ServiceWorkerRegistration
* registration
,
124 ChangedVersionAttributesMask changed_mask
,
125 const ServiceWorkerRegistrationInfo
& info
) {
126 if (!get_ready_callback_
|| get_ready_callback_
->called
)
128 if (changed_mask
.active_changed() && registration
->active_version()) {
129 // Wait until the state change so we don't send the get for ready
130 // registration complete message before set version attributes message.
131 registration
->active_version()->RegisterStatusChangeCallback(base::Bind(
132 &ServiceWorkerProviderHost::ReturnRegistrationForReadyIfNeeded
,
137 void ServiceWorkerProviderHost::OnRegistrationFailed(
138 ServiceWorkerRegistration
* registration
) {
139 if (associated_registration_
== registration
)
140 DisassociateRegistration();
141 RemoveMatchingRegistration(registration
);
144 void ServiceWorkerProviderHost::OnRegistrationFinishedUninstalling(
145 ServiceWorkerRegistration
* registration
) {
146 RemoveMatchingRegistration(registration
);
149 void ServiceWorkerProviderHost::OnSkippedWaiting(
150 ServiceWorkerRegistration
* registration
) {
151 if (associated_registration_
!= registration
)
153 // A client is "using" a registration if it is controlled by the active
154 // worker of the registration. skipWaiting doesn't cause a client to start
155 // using the registration.
156 if (!controlling_version_
)
158 ServiceWorkerVersion
* active_version
= registration
->active_version();
159 DCHECK_EQ(active_version
->status(), ServiceWorkerVersion::ACTIVATING
);
160 SetControllerVersionAttribute(active_version
,
161 true /* notify_controllerchange */);
164 void ServiceWorkerProviderHost::SetDocumentUrl(const GURL
& url
) {
165 DCHECK(!url
.has_ref());
169 void ServiceWorkerProviderHost::SetTopmostFrameUrl(const GURL
& url
) {
170 topmost_frame_url_
= url
;
173 void ServiceWorkerProviderHost::SetControllerVersionAttribute(
174 ServiceWorkerVersion
* version
,
175 bool notify_controllerchange
) {
176 if (version
== controlling_version_
.get())
179 scoped_refptr
<ServiceWorkerVersion
> previous_version
= controlling_version_
;
180 controlling_version_
= version
;
182 version
->AddControllee(this);
183 if (previous_version
.get())
184 previous_version
->RemoveControllee(this);
186 if (!dispatcher_host_
)
187 return; // Could be NULL in some tests.
189 // SetController message should be sent only for controllees.
190 DCHECK(IsProviderForClient());
191 Send(new ServiceWorkerMsg_SetControllerServiceWorker(
192 render_thread_id_
, provider_id(), GetOrCreateServiceWorkerHandle(version
),
193 notify_controllerchange
));
196 bool ServiceWorkerProviderHost::SetHostedVersionId(int64 version_id
) {
198 return true; // System is shutting down.
199 if (active_version())
200 return false; // Unexpected bad message.
202 ServiceWorkerVersion
* live_version
= context_
->GetLiveVersion(version_id
);
204 return true; // Was deleted before it got started.
206 ServiceWorkerVersionInfo info
= live_version
->GetInfo();
207 if (info
.running_status
!= ServiceWorkerVersion::STARTING
||
208 info
.process_id
!= render_process_id_
) {
209 // If we aren't trying to start this version in our process
210 // something is amiss.
214 running_hosted_version_
= live_version
;
218 bool ServiceWorkerProviderHost::IsProviderForClient() const {
219 switch (provider_type_
) {
220 case SERVICE_WORKER_PROVIDER_FOR_WINDOW
:
221 case SERVICE_WORKER_PROVIDER_FOR_WORKER
:
222 case SERVICE_WORKER_PROVIDER_FOR_SHARED_WORKER
:
224 case SERVICE_WORKER_PROVIDER_FOR_CONTROLLER
:
226 case SERVICE_WORKER_PROVIDER_FOR_SANDBOXED_FRAME
:
227 case SERVICE_WORKER_PROVIDER_UNKNOWN
:
228 NOTREACHED() << provider_type_
;
230 NOTREACHED() << provider_type_
;
234 blink::WebServiceWorkerClientType
ServiceWorkerProviderHost::client_type()
236 switch (provider_type_
) {
237 case SERVICE_WORKER_PROVIDER_FOR_WINDOW
:
238 return blink::WebServiceWorkerClientTypeWindow
;
239 case SERVICE_WORKER_PROVIDER_FOR_WORKER
:
240 return blink::WebServiceWorkerClientTypeWorker
;
241 case SERVICE_WORKER_PROVIDER_FOR_SHARED_WORKER
:
242 return blink::WebServiceWorkerClientTypeSharedWorker
;
243 case SERVICE_WORKER_PROVIDER_FOR_CONTROLLER
:
244 case SERVICE_WORKER_PROVIDER_FOR_SANDBOXED_FRAME
:
245 case SERVICE_WORKER_PROVIDER_UNKNOWN
:
246 NOTREACHED() << provider_type_
;
248 NOTREACHED() << provider_type_
;
249 return blink::WebServiceWorkerClientTypeWindow
;
252 void ServiceWorkerProviderHost::AssociateRegistration(
253 ServiceWorkerRegistration
* registration
,
254 bool notify_controllerchange
) {
255 DCHECK(CanAssociateRegistration(registration
));
256 associated_registration_
= registration
;
257 AddMatchingRegistration(registration
);
258 SendAssociateRegistrationMessage();
259 SetControllerVersionAttribute(registration
->active_version(),
260 notify_controllerchange
);
263 void ServiceWorkerProviderHost::DisassociateRegistration() {
264 queued_events_
.clear();
265 if (!associated_registration_
.get())
267 associated_registration_
= NULL
;
268 SetControllerVersionAttribute(NULL
, false /* notify_controllerchange */);
270 if (!dispatcher_host_
)
273 // Disassociation message should be sent only for controllees.
274 DCHECK(IsProviderForClient());
275 Send(new ServiceWorkerMsg_DisassociateRegistration(
276 render_thread_id_
, provider_id()));
279 void ServiceWorkerProviderHost::AddMatchingRegistration(
280 ServiceWorkerRegistration
* registration
) {
281 DCHECK(ServiceWorkerUtils::ScopeMatches(
282 registration
->pattern(), document_url_
));
283 size_t key
= registration
->pattern().spec().size();
284 if (ContainsKey(matching_registrations_
, key
))
286 IncreaseProcessReference(registration
->pattern());
287 registration
->AddListener(this);
288 matching_registrations_
[key
] = registration
;
289 ReturnRegistrationForReadyIfNeeded();
292 void ServiceWorkerProviderHost::RemoveMatchingRegistration(
293 ServiceWorkerRegistration
* registration
) {
294 size_t key
= registration
->pattern().spec().size();
295 DCHECK(ContainsKey(matching_registrations_
, key
));
296 DecreaseProcessReference(registration
->pattern());
297 registration
->RemoveListener(this);
298 matching_registrations_
.erase(key
);
301 void ServiceWorkerProviderHost::AddAllMatchingRegistrations() {
303 const std::map
<int64
, ServiceWorkerRegistration
*>& registrations
=
304 context_
->GetLiveRegistrations();
305 for (const auto& key_registration
: registrations
) {
306 ServiceWorkerRegistration
* registration
= key_registration
.second
;
307 if (!registration
->is_uninstalled() &&
308 ServiceWorkerUtils::ScopeMatches(registration
->pattern(),
310 AddMatchingRegistration(registration
);
314 ServiceWorkerRegistration
*
315 ServiceWorkerProviderHost::MatchRegistration() const {
316 ServiceWorkerRegistrationMap::const_reverse_iterator it
=
317 matching_registrations_
.rbegin();
318 for (; it
!= matching_registrations_
.rend(); ++it
) {
319 if (it
->second
->is_uninstalled())
321 if (it
->second
->is_uninstalling())
323 return it
->second
.get();
328 void ServiceWorkerProviderHost::NotifyControllerLost() {
329 SetControllerVersionAttribute(nullptr, true /* notify_controllerchange */);
332 scoped_ptr
<ServiceWorkerRequestHandler
>
333 ServiceWorkerProviderHost::CreateRequestHandler(
334 FetchRequestMode request_mode
,
335 FetchCredentialsMode credentials_mode
,
336 FetchRedirectMode redirect_mode
,
337 ResourceType resource_type
,
338 RequestContextType request_context_type
,
339 RequestContextFrameType frame_type
,
340 base::WeakPtr
<storage::BlobStorageContext
> blob_storage_context
,
341 scoped_refptr
<ResourceRequestBody
> body
) {
342 if (IsHostToRunningServiceWorker()) {
343 return scoped_ptr
<ServiceWorkerRequestHandler
>(
344 new ServiceWorkerContextRequestHandler(
345 context_
, AsWeakPtr(), blob_storage_context
, resource_type
));
347 if (ServiceWorkerUtils::IsMainResourceType(resource_type
) ||
348 controlling_version()) {
349 return scoped_ptr
<ServiceWorkerRequestHandler
>(
350 new ServiceWorkerControlleeRequestHandler(
351 context_
, AsWeakPtr(), blob_storage_context
, request_mode
,
352 credentials_mode
, redirect_mode
, resource_type
,
353 request_context_type
, frame_type
, body
));
355 return scoped_ptr
<ServiceWorkerRequestHandler
>();
358 ServiceWorkerObjectInfo
359 ServiceWorkerProviderHost::GetOrCreateServiceWorkerHandle(
360 ServiceWorkerVersion
* version
) {
361 DCHECK(dispatcher_host_
);
362 if (!context_
|| !version
)
363 return ServiceWorkerObjectInfo();
364 ServiceWorkerHandle
* handle
= dispatcher_host_
->FindServiceWorkerHandle(
365 provider_id(), version
->version_id());
367 handle
->IncrementRefCount();
368 return handle
->GetObjectInfo();
371 scoped_ptr
<ServiceWorkerHandle
> new_handle(
372 ServiceWorkerHandle::Create(context_
, AsWeakPtr(), version
));
373 handle
= new_handle
.get();
374 dispatcher_host_
->RegisterServiceWorkerHandle(new_handle
.Pass());
375 return handle
->GetObjectInfo();
378 bool ServiceWorkerProviderHost::CanAssociateRegistration(
379 ServiceWorkerRegistration
* registration
) {
382 if (running_hosted_version_
.get())
384 if (!registration
|| associated_registration_
.get() || !allow_association_
)
389 void ServiceWorkerProviderHost::PostMessage(
390 ServiceWorkerVersion
* version
,
391 const base::string16
& message
,
392 const std::vector
<TransferredMessagePort
>& sent_message_ports
) {
393 if (!dispatcher_host_
)
394 return; // Could be NULL in some tests.
396 std::vector
<int> new_routing_ids
;
397 dispatcher_host_
->message_port_message_filter()->
398 UpdateMessagePortsWithNewRoutes(sent_message_ports
,
401 ServiceWorkerMsg_MessageToDocument_Params params
;
402 params
.thread_id
= kDocumentMainThreadId
;
403 params
.provider_id
= provider_id();
404 params
.service_worker_info
= GetOrCreateServiceWorkerHandle(version
);
405 params
.message
= message
;
406 params
.message_ports
= sent_message_ports
;
407 params
.new_routing_ids
= new_routing_ids
;
408 Send(new ServiceWorkerMsg_MessageToDocument(params
));
411 void ServiceWorkerProviderHost::Focus(const GetClientInfoCallback
& callback
) {
412 if (provider_type_
!= SERVICE_WORKER_PROVIDER_FOR_WINDOW
) {
413 callback
.Run(ServiceWorkerClientInfo());
416 BrowserThread::PostTaskAndReplyWithResult(
417 BrowserThread::UI
, FROM_HERE
,
418 base::Bind(&FocusOnUIThread
, render_process_id_
, route_id_
), callback
);
421 void ServiceWorkerProviderHost::GetWindowClientInfo(
422 const GetClientInfoCallback
& callback
) const {
423 if (provider_type_
!= SERVICE_WORKER_PROVIDER_FOR_WINDOW
) {
424 callback
.Run(ServiceWorkerClientInfo());
427 BrowserThread::PostTaskAndReplyWithResult(
428 BrowserThread::UI
, FROM_HERE
,
429 base::Bind(&ServiceWorkerProviderHost::GetWindowClientInfoOnUI
,
430 render_process_id_
, route_id_
),
435 ServiceWorkerClientInfo
ServiceWorkerProviderHost::GetWindowClientInfoOnUI(
436 int render_process_id
,
437 int render_frame_id
) {
438 RenderFrameHostImpl
* render_frame_host
=
439 RenderFrameHostImpl::FromID(render_process_id
, render_frame_id
);
440 if (!render_frame_host
)
441 return ServiceWorkerClientInfo();
443 // TODO(mlamouri,michaeln): it is possible to end up collecting information
444 // for a frame that is actually being navigated and isn't exactly what we are
446 return ServiceWorkerClientInfo(
447 render_frame_host
->GetVisibilityState(), render_frame_host
->IsFocused(),
448 render_frame_host
->GetLastCommittedURL(),
449 render_frame_host
->GetParent() ? REQUEST_CONTEXT_FRAME_TYPE_NESTED
450 : REQUEST_CONTEXT_FRAME_TYPE_TOP_LEVEL
,
451 render_frame_host
->frame_tree_node()->last_focus_time(),
452 blink::WebServiceWorkerClientTypeWindow
);
455 void ServiceWorkerProviderHost::AddScopedProcessReferenceToPattern(
456 const GURL
& pattern
) {
457 associated_patterns_
.push_back(pattern
);
458 IncreaseProcessReference(pattern
);
461 void ServiceWorkerProviderHost::ClaimedByRegistration(
462 ServiceWorkerRegistration
* registration
) {
463 DCHECK(registration
->active_version());
464 if (registration
== associated_registration_
) {
465 SetControllerVersionAttribute(registration
->active_version(),
466 true /* notify_controllerchange */);
467 } else if (allow_association_
) {
468 DisassociateRegistration();
469 AssociateRegistration(registration
, true /* notify_controllerchange */);
473 bool ServiceWorkerProviderHost::GetRegistrationForReady(
474 const GetRegistrationForReadyCallback
& callback
) {
475 if (get_ready_callback_
)
477 get_ready_callback_
.reset(new OneShotGetReadyCallback(callback
));
478 ReturnRegistrationForReadyIfNeeded();
482 void ServiceWorkerProviderHost::PrepareForCrossSiteTransfer() {
483 DCHECK_NE(ChildProcessHost::kInvalidUniqueID
, render_process_id_
);
484 DCHECK_NE(MSG_ROUTING_NONE
, route_id_
);
485 DCHECK_EQ(kDocumentMainThreadId
, render_thread_id_
);
486 DCHECK_NE(SERVICE_WORKER_PROVIDER_UNKNOWN
, provider_type_
);
488 for (const GURL
& pattern
: associated_patterns_
)
489 DecreaseProcessReference(pattern
);
491 for (auto& key_registration
: matching_registrations_
)
492 DecreaseProcessReference(key_registration
.second
->pattern());
494 if (associated_registration_
.get()) {
495 if (dispatcher_host_
) {
496 Send(new ServiceWorkerMsg_DisassociateRegistration(
497 render_thread_id_
, provider_id()));
501 render_process_id_
= ChildProcessHost::kInvalidUniqueID
;
502 route_id_
= MSG_ROUTING_NONE
;
503 render_thread_id_
= kInvalidEmbeddedWorkerThreadId
;
504 provider_id_
= kInvalidServiceWorkerProviderId
;
505 provider_type_
= SERVICE_WORKER_PROVIDER_UNKNOWN
;
506 dispatcher_host_
= nullptr;
509 void ServiceWorkerProviderHost::CompleteCrossSiteTransfer(
513 ServiceWorkerProviderType new_provider_type
,
514 ServiceWorkerDispatcherHost
* new_dispatcher_host
) {
515 DCHECK_EQ(ChildProcessHost::kInvalidUniqueID
, render_process_id_
);
516 DCHECK_NE(ChildProcessHost::kInvalidUniqueID
, new_process_id
);
517 DCHECK_NE(MSG_ROUTING_NONE
, new_frame_id
);
519 render_process_id_
= new_process_id
;
520 route_id_
= new_frame_id
;
521 render_thread_id_
= kDocumentMainThreadId
;
522 provider_id_
= new_provider_id
;
523 provider_type_
= new_provider_type
;
524 dispatcher_host_
= new_dispatcher_host
;
526 for (const GURL
& pattern
: associated_patterns_
)
527 IncreaseProcessReference(pattern
);
529 for (auto& key_registration
: matching_registrations_
)
530 IncreaseProcessReference(key_registration
.second
->pattern());
532 if (associated_registration_
.get()) {
533 SendAssociateRegistrationMessage();
534 if (dispatcher_host_
&& associated_registration_
->active_version()) {
535 Send(new ServiceWorkerMsg_SetControllerServiceWorker(
536 render_thread_id_
, provider_id(),
537 GetOrCreateServiceWorkerHandle(
538 associated_registration_
->active_version()),
539 false /* shouldNotifyControllerChange */));
544 void ServiceWorkerProviderHost::SendUpdateFoundMessage(
545 int registration_handle_id
) {
546 if (!dispatcher_host_
)
547 return; // Could be nullptr in some tests.
549 if (!IsReadyToSendMessages()) {
550 queued_events_
.push_back(
551 base::Bind(&ServiceWorkerProviderHost::SendUpdateFoundMessage
,
552 AsWeakPtr(), registration_handle_id
));
556 Send(new ServiceWorkerMsg_UpdateFound(
557 render_thread_id_
, registration_handle_id
));
560 void ServiceWorkerProviderHost::SendSetVersionAttributesMessage(
561 int registration_handle_id
,
562 ChangedVersionAttributesMask changed_mask
,
563 ServiceWorkerVersion
* installing_version
,
564 ServiceWorkerVersion
* waiting_version
,
565 ServiceWorkerVersion
* active_version
) {
566 if (!dispatcher_host_
)
567 return; // Could be nullptr in some tests.
568 if (!changed_mask
.changed())
571 if (!IsReadyToSendMessages()) {
572 queued_events_
.push_back(
573 base::Bind(&ServiceWorkerProviderHost::SendSetVersionAttributesMessage
,
574 AsWeakPtr(), registration_handle_id
, changed_mask
,
575 make_scoped_refptr(installing_version
),
576 make_scoped_refptr(waiting_version
),
577 make_scoped_refptr(active_version
)));
581 ServiceWorkerVersionAttributes attrs
;
582 if (changed_mask
.installing_changed())
583 attrs
.installing
= GetOrCreateServiceWorkerHandle(installing_version
);
584 if (changed_mask
.waiting_changed())
585 attrs
.waiting
= GetOrCreateServiceWorkerHandle(waiting_version
);
586 if (changed_mask
.active_changed())
587 attrs
.active
= GetOrCreateServiceWorkerHandle(active_version
);
589 Send(new ServiceWorkerMsg_SetVersionAttributes(
590 render_thread_id_
, provider_id_
, registration_handle_id
,
591 changed_mask
.changed(), attrs
));
594 void ServiceWorkerProviderHost::SendServiceWorkerStateChangedMessage(
595 int worker_handle_id
,
596 blink::WebServiceWorkerState state
) {
597 if (!dispatcher_host_
)
600 if (!IsReadyToSendMessages()) {
601 queued_events_
.push_back(base::Bind(
602 &ServiceWorkerProviderHost::SendServiceWorkerStateChangedMessage
,
603 AsWeakPtr(), worker_handle_id
, state
));
607 Send(new ServiceWorkerMsg_ServiceWorkerStateChanged(
608 render_thread_id_
, worker_handle_id
, state
));
611 void ServiceWorkerProviderHost::SetReadyToSendMessagesToWorker(
612 int render_thread_id
) {
613 DCHECK(!IsReadyToSendMessages());
614 render_thread_id_
= render_thread_id
;
616 for (const auto& event
: queued_events_
)
618 queued_events_
.clear();
621 void ServiceWorkerProviderHost::SendAssociateRegistrationMessage() {
622 if (!dispatcher_host_
)
625 ServiceWorkerRegistrationHandle
* handle
=
626 dispatcher_host_
->CreateRegistrationHandle(
627 AsWeakPtr(), associated_registration_
.get());
629 ServiceWorkerVersionAttributes attrs
;
630 attrs
.installing
= GetOrCreateServiceWorkerHandle(
631 associated_registration_
->installing_version());
632 attrs
.waiting
= GetOrCreateServiceWorkerHandle(
633 associated_registration_
->waiting_version());
634 attrs
.active
= GetOrCreateServiceWorkerHandle(
635 associated_registration_
->active_version());
637 // Association message should be sent only for controllees.
638 DCHECK(IsProviderForClient());
639 dispatcher_host_
->Send(new ServiceWorkerMsg_AssociateRegistration(
640 render_thread_id_
, provider_id(), handle
->GetObjectInfo(), attrs
));
643 void ServiceWorkerProviderHost::IncreaseProcessReference(
644 const GURL
& pattern
) {
645 if (context_
&& context_
->process_manager()) {
646 context_
->process_manager()->AddProcessReferenceToPattern(
647 pattern
, render_process_id_
);
651 void ServiceWorkerProviderHost::DecreaseProcessReference(
652 const GURL
& pattern
) {
653 if (context_
&& context_
->process_manager()) {
654 context_
->process_manager()->RemoveProcessReferenceFromPattern(
655 pattern
, render_process_id_
);
659 void ServiceWorkerProviderHost::ReturnRegistrationForReadyIfNeeded() {
660 if (!get_ready_callback_
|| get_ready_callback_
->called
)
662 ServiceWorkerRegistration
* registration
= MatchRegistration();
665 if (registration
->active_version()) {
666 get_ready_callback_
->callback
.Run(registration
);
667 get_ready_callback_
->callback
.Reset();
668 get_ready_callback_
->called
= true;
673 bool ServiceWorkerProviderHost::IsReadyToSendMessages() const {
674 return render_thread_id_
!= kInvalidEmbeddedWorkerThreadId
;
677 bool ServiceWorkerProviderHost::IsContextAlive() {
678 return context_
!= NULL
;
681 void ServiceWorkerProviderHost::Send(IPC::Message
* message
) const {
682 DCHECK(dispatcher_host_
);
683 DCHECK(IsReadyToSendMessages());
684 dispatcher_host_
->Send(message
);
687 } // namespace content