Add ICU message format support
[chromium-blink-merge.git] / content / browser / service_worker / service_worker_provider_host.cc
blob5be3d96c8aeb8168a24be2c5fcd9ba018d644104
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"
7 #include "base/guid.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"
30 namespace content {
32 namespace {
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,
56 render_frame_id);
59 } // anonymous namespace
61 ServiceWorkerProviderHost::OneShotGetReadyCallback::OneShotGetReadyCallback(
62 const GetRegistrationForReadyCallback& callback)
63 : callback(callback),
64 called(false) {
67 ServiceWorkerProviderHost::OneShotGetReadyCallback::~OneShotGetReadyCallback() {
70 ServiceWorkerProviderHost::ServiceWorkerProviderHost(
71 int render_process_id,
72 int route_id,
73 int provider_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),
79 route_id_(route_id),
80 render_thread_id_(kDocumentMainThreadId),
81 provider_id_(provider_id),
82 provider_type_(provider_type),
83 context_(context),
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() {
97 if (context_)
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)
117 return route_id_;
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)
126 return;
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,
132 AsWeakPtr()));
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)
151 return;
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_)
156 return;
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());
165 document_url_ = url;
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())
176 return;
178 scoped_refptr<ServiceWorkerVersion> previous_version = controlling_version_;
179 controlling_version_ = version;
180 if (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) {
196 if (!context_)
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);
202 if (!live_version)
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.
210 return false;
213 running_hosted_version_ = live_version;
214 return true;
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:
222 return true;
223 case SERVICE_WORKER_PROVIDER_FOR_CONTROLLER:
224 return false;
225 case SERVICE_WORKER_PROVIDER_FOR_SANDBOXED_FRAME:
226 case SERVICE_WORKER_PROVIDER_UNKNOWN:
227 NOTREACHED() << provider_type_;
229 NOTREACHED() << provider_type_;
230 return false;
233 blink::WebServiceWorkerClientType ServiceWorkerProviderHost::client_type()
234 const {
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())
265 return;
266 associated_registration_ = NULL;
267 SetControllerVersionAttribute(NULL, false /* notify_controllerchange */);
269 if (!dispatcher_host_)
270 return;
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))
284 return;
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() {
301 DCHECK(context_);
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(),
308 document_url_))
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())
319 continue;
320 if (it->second->is_uninstalling())
321 return nullptr;
322 return it->second.get();
324 return nullptr;
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_,
349 AsWeakPtr(),
350 blob_storage_context,
351 request_mode,
352 credentials_mode,
353 resource_type,
354 request_context_type,
355 frame_type,
356 body));
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());
369 if (handle) {
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) {
383 if (!context_)
384 return false;
385 if (running_hosted_version_.get())
386 return false;
387 if (!registration || associated_registration_.get() || !allow_association_)
388 return false;
389 return true;
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,
402 &new_routing_ids);
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());
417 return;
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());
428 return;
430 BrowserThread::PostTaskAndReplyWithResult(
431 BrowserThread::UI, FROM_HERE,
432 base::Bind(&ServiceWorkerProviderHost::GetWindowClientInfoOnUI,
433 render_process_id_, route_id_),
434 callback);
437 // static
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
448 // expecting.
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_)
479 return false;
480 get_ready_callback_.reset(new OneShotGetReadyCallback(callback));
481 ReturnRegistrationForReadyIfNeeded();
482 return true;
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(
513 int new_process_id,
514 int new_frame_id,
515 int new_provider_id,
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));
556 return;
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())
572 return;
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)));
581 return;
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_)
601 return;
603 if (!IsReadyToSendMessages()) {
604 queued_events_.push_back(base::Bind(
605 &ServiceWorkerProviderHost::SendServiceWorkerStateChangedMessage,
606 AsWeakPtr(), worker_handle_id, state));
607 return;
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_)
620 event.Run();
621 queued_events_.clear();
624 void ServiceWorkerProviderHost::SendAssociateRegistrationMessage() {
625 if (!dispatcher_host_)
626 return;
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)
664 return;
665 ServiceWorkerRegistration* registration = MatchRegistration();
666 if (!registration)
667 return;
668 if (registration->active_version()) {
669 get_ready_callback_->callback.Run(registration);
670 get_ready_callback_->callback.Reset();
671 get_ready_callback_->called = true;
672 return;
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