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/stl_util.h"
8 #include "content/browser/message_port_message_filter.h"
9 #include "content/browser/service_worker/service_worker_context_core.h"
10 #include "content/browser/service_worker/service_worker_context_request_handler.h"
11 #include "content/browser/service_worker/service_worker_controllee_request_handler.h"
12 #include "content/browser/service_worker/service_worker_dispatcher_host.h"
13 #include "content/browser/service_worker/service_worker_handle.h"
14 #include "content/browser/service_worker/service_worker_utils.h"
15 #include "content/browser/service_worker/service_worker_version.h"
16 #include "content/common/service_worker/service_worker_messages.h"
20 static const int kDocumentMainThreadId = 0;
22 ServiceWorkerProviderHost::ServiceWorkerProviderHost(
23 int process_id, int provider_id,
24 base::WeakPtr<ServiceWorkerContextCore> context,
25 ServiceWorkerDispatcherHost* dispatcher_host)
26 : process_id_(process_id),
27 provider_id_(provider_id),
29 dispatcher_host_(dispatcher_host) {
32 ServiceWorkerProviderHost::~ServiceWorkerProviderHost() {
34 active_version_->RemoveControllee(this);
36 pending_version_->RemovePendingControllee(this);
39 void ServiceWorkerProviderHost::SetActiveVersion(
40 ServiceWorkerVersion* version) {
41 if (version == active_version_)
43 scoped_refptr<ServiceWorkerVersion> previous_version = active_version_;
44 active_version_ = version;
46 version->AddControllee(this);
48 previous_version->RemoveControllee(this);
50 if (!dispatcher_host_)
51 return; // Could be NULL in some tests.
53 ServiceWorkerObjectInfo info;
54 if (context_ && version) {
55 scoped_ptr<ServiceWorkerHandle> handle =
56 ServiceWorkerHandle::Create(context_, dispatcher_host_,
57 kDocumentMainThreadId, version);
58 info = handle->GetObjectInfo();
59 dispatcher_host_->RegisterServiceWorkerHandle(handle.Pass());
61 dispatcher_host_->Send(
62 new ServiceWorkerMsg_SetCurrentServiceWorker(
63 kDocumentMainThreadId, provider_id(), info));
66 void ServiceWorkerProviderHost::SetPendingVersion(
67 ServiceWorkerVersion* version) {
68 if (version == pending_version_)
70 scoped_refptr<ServiceWorkerVersion> previous_version = pending_version_;
71 pending_version_ = version;
73 version->AddPendingControllee(this);
75 previous_version->RemovePendingControllee(this);
77 if (!dispatcher_host_)
78 return; // Could be NULL in some tests.
80 // TODO(kinuko): dispatch pendingchange event to the document.
83 bool ServiceWorkerProviderHost::SetHostedVersionId(int64 version_id) {
85 return true; // System is shutting down.
87 return false; // Unexpected bad message.
89 ServiceWorkerVersion* live_version = context_->GetLiveVersion(version_id);
91 return true; // Was deleted before it got started.
93 ServiceWorkerVersionInfo info = live_version->GetInfo();
94 if (info.running_status != ServiceWorkerVersion::STARTING ||
95 info.process_id != process_id_) {
96 // If we aren't trying to start this version in our process
97 // something is amiss.
101 running_hosted_version_ = live_version;
105 scoped_ptr<ServiceWorkerRequestHandler>
106 ServiceWorkerProviderHost::CreateRequestHandler(
107 ResourceType::Type resource_type) {
108 if (IsHostToRunningServiceWorker()) {
109 return scoped_ptr<ServiceWorkerRequestHandler>(
110 new ServiceWorkerContextRequestHandler(
111 context_, AsWeakPtr(), resource_type));
113 if (ServiceWorkerUtils::IsMainResourceType(resource_type) ||
115 return scoped_ptr<ServiceWorkerRequestHandler>(
116 new ServiceWorkerControlleeRequestHandler(
117 context_, AsWeakPtr(), resource_type));
119 return scoped_ptr<ServiceWorkerRequestHandler>();
122 void ServiceWorkerProviderHost::PostMessage(
123 const base::string16& message,
124 const std::vector<int>& sent_message_port_ids) {
125 if (!dispatcher_host_)
126 return; // Could be NULL in some tests.
128 std::vector<int> new_routing_ids;
129 dispatcher_host_->message_port_message_filter()->
130 UpdateMessagePortsWithNewRoutes(sent_message_port_ids,
133 dispatcher_host_->Send(
134 new ServiceWorkerMsg_MessageToDocument(
135 kDocumentMainThreadId, provider_id(),
137 sent_message_port_ids,
141 } // namespace content