[MacViews] Show comboboxes with a native NSMenu
[chromium-blink-merge.git] / content / browser / service_worker / service_worker_provider_host.cc
blobd27ceb40602b71fea60092d55c96cb3e9b71b7dc
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 "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"
31 namespace content {
33 namespace {
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,
57 render_frame_id);
60 } // anonymous namespace
62 ServiceWorkerProviderHost::OneShotGetReadyCallback::OneShotGetReadyCallback(
63 const GetRegistrationForReadyCallback& callback)
64 : callback(callback),
65 called(false) {
68 ServiceWorkerProviderHost::OneShotGetReadyCallback::~OneShotGetReadyCallback() {
71 ServiceWorkerProviderHost::ServiceWorkerProviderHost(
72 int render_process_id,
73 int route_id,
74 int provider_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),
80 route_id_(route_id),
81 render_thread_id_(kDocumentMainThreadId),
82 provider_id_(provider_id),
83 provider_type_(provider_type),
84 context_(context),
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() {
98 if (context_)
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)
118 return route_id_;
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)
127 return;
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,
133 AsWeakPtr()));
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)
152 return;
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_)
157 return;
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());
166 document_url_ = url;
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())
177 return;
179 scoped_refptr<ServiceWorkerVersion> previous_version = controlling_version_;
180 controlling_version_ = version;
181 if (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) {
197 if (!context_)
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);
203 if (!live_version)
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.
211 return false;
214 running_hosted_version_ = live_version;
215 return true;
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:
223 return true;
224 case SERVICE_WORKER_PROVIDER_FOR_CONTROLLER:
225 return false;
226 case SERVICE_WORKER_PROVIDER_FOR_SANDBOXED_FRAME:
227 case SERVICE_WORKER_PROVIDER_UNKNOWN:
228 NOTREACHED() << provider_type_;
230 NOTREACHED() << provider_type_;
231 return false;
234 blink::WebServiceWorkerClientType ServiceWorkerProviderHost::client_type()
235 const {
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())
266 return;
267 associated_registration_ = NULL;
268 SetControllerVersionAttribute(NULL, false /* notify_controllerchange */);
270 if (!dispatcher_host_)
271 return;
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))
285 return;
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() {
302 DCHECK(context_);
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(),
309 document_url_))
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())
320 continue;
321 if (it->second->is_uninstalling())
322 return nullptr;
323 return it->second.get();
325 return nullptr;
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());
366 if (handle) {
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) {
380 if (!context_)
381 return false;
382 if (running_hosted_version_.get())
383 return false;
384 if (!registration || associated_registration_.get() || !allow_association_)
385 return false;
386 return true;
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,
399 &new_routing_ids);
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());
414 return;
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());
425 return;
427 BrowserThread::PostTaskAndReplyWithResult(
428 BrowserThread::UI, FROM_HERE,
429 base::Bind(&ServiceWorkerProviderHost::GetWindowClientInfoOnUI,
430 render_process_id_, route_id_),
431 callback);
434 // static
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
445 // expecting.
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_)
476 return false;
477 get_ready_callback_.reset(new OneShotGetReadyCallback(callback));
478 ReturnRegistrationForReadyIfNeeded();
479 return true;
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(
510 int new_process_id,
511 int new_frame_id,
512 int new_provider_id,
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));
553 return;
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())
569 return;
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)));
578 return;
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_)
598 return;
600 if (!IsReadyToSendMessages()) {
601 queued_events_.push_back(base::Bind(
602 &ServiceWorkerProviderHost::SendServiceWorkerStateChangedMessage,
603 AsWeakPtr(), worker_handle_id, state));
604 return;
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_)
617 event.Run();
618 queued_events_.clear();
621 void ServiceWorkerProviderHost::SendAssociateRegistrationMessage() {
622 if (!dispatcher_host_)
623 return;
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)
661 return;
662 ServiceWorkerRegistration* registration = MatchRegistration();
663 if (!registration)
664 return;
665 if (registration->active_version()) {
666 get_ready_callback_->callback.Run(registration);
667 get_ready_callback_->callback.Reset();
668 get_ready_callback_->called = true;
669 return;
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