Battery Status API: add UMA logging for Linux.
[chromium-blink-merge.git] / content / browser / service_worker / service_worker_provider_host.cc
blob8e1d43ccc8a8518986d60fa0caec93eb819b32c3
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_registration_handle.h"
15 #include "content/browser/service_worker/service_worker_utils.h"
16 #include "content/browser/service_worker/service_worker_version.h"
17 #include "content/common/resource_request_body.h"
18 #include "content/common/service_worker/service_worker_messages.h"
20 namespace content {
22 static const int kDocumentMainThreadId = 0;
24 ServiceWorkerProviderHost::ServiceWorkerProviderHost(
25 int process_id, int provider_id,
26 base::WeakPtr<ServiceWorkerContextCore> context,
27 ServiceWorkerDispatcherHost* dispatcher_host)
28 : process_id_(process_id),
29 provider_id_(provider_id),
30 context_(context),
31 dispatcher_host_(dispatcher_host) {
34 ServiceWorkerProviderHost::~ServiceWorkerProviderHost() {
35 // Clear docurl so the deferred activation of a waiting worker
36 // won't associate the new version with a provider being destroyed.
37 document_url_ = GURL();
38 if (controlling_version_.get())
39 controlling_version_->RemoveControllee(this);
40 if (active_version_.get())
41 active_version_->RemovePotentialControllee(this);
42 if (waiting_version_.get())
43 waiting_version_->RemovePotentialControllee(this);
44 if (installing_version_.get())
45 installing_version_->RemovePotentialControllee(this);
46 if (associated_registration_.get())
47 associated_registration_->RemoveListener(this);
50 void ServiceWorkerProviderHost::OnVersionAttributesChanged(
51 ServiceWorkerRegistration* registration,
52 ChangedVersionAttributesMask changed_mask,
53 const ServiceWorkerRegistrationInfo& info) {
54 DCHECK_EQ(associated_registration_.get(), registration);
55 UpdatePotentialControllees(registration->installing_version(),
56 registration->waiting_version(),
57 registration->active_version());
60 void ServiceWorkerProviderHost::OnRegistrationFailed(
61 ServiceWorkerRegistration* registration) {
62 DCHECK_EQ(associated_registration_.get(), registration);
63 UnassociateRegistration();
66 void ServiceWorkerProviderHost::SetDocumentUrl(const GURL& url) {
67 DCHECK(!url.has_ref());
68 document_url_ = url;
71 void ServiceWorkerProviderHost::UpdatePotentialControllees(
72 ServiceWorkerVersion* installing_version,
73 ServiceWorkerVersion* waiting_version,
74 ServiceWorkerVersion* active_version) {
75 if (installing_version != installing_version_.get()) {
76 scoped_refptr<ServiceWorkerVersion> previous_version = installing_version_;
77 if (previous_version)
78 previous_version->RemovePotentialControllee(this);
79 if (installing_version)
80 installing_version->AddPotentialControllee(this);
81 installing_version_ = installing_version;
84 if (waiting_version != waiting_version_.get()) {
85 scoped_refptr<ServiceWorkerVersion> previous_version = waiting_version_;
86 if (previous_version)
87 previous_version->RemovePotentialControllee(this);
88 if (waiting_version)
89 waiting_version->AddPotentialControllee(this);
90 waiting_version_ = waiting_version;
93 if (active_version != active_version_.get()) {
94 scoped_refptr<ServiceWorkerVersion> previous_version = active_version_;
95 if (previous_version)
96 previous_version->RemovePotentialControllee(this);
97 if (active_version)
98 active_version->AddPotentialControllee(this);
99 active_version_ = active_version;
103 void ServiceWorkerProviderHost::SetControllerVersionAttribute(
104 ServiceWorkerVersion* version) {
105 if (version == controlling_version_.get())
106 return;
108 scoped_refptr<ServiceWorkerVersion> previous_version = controlling_version_;
109 controlling_version_ = version;
110 if (version)
111 version->AddControllee(this);
112 if (previous_version.get())
113 previous_version->RemoveControllee(this);
115 if (!dispatcher_host_)
116 return; // Could be NULL in some tests.
118 dispatcher_host_->Send(new ServiceWorkerMsg_SetControllerServiceWorker(
119 kDocumentMainThreadId, provider_id(), CreateHandleAndPass(version)));
122 bool ServiceWorkerProviderHost::SetHostedVersionId(int64 version_id) {
123 if (!context_)
124 return true; // System is shutting down.
125 if (active_version_.get())
126 return false; // Unexpected bad message.
128 ServiceWorkerVersion* live_version = context_->GetLiveVersion(version_id);
129 if (!live_version)
130 return true; // Was deleted before it got started.
132 ServiceWorkerVersionInfo info = live_version->GetInfo();
133 if (info.running_status != ServiceWorkerVersion::STARTING ||
134 info.process_id != process_id_) {
135 // If we aren't trying to start this version in our process
136 // something is amiss.
137 return false;
140 running_hosted_version_ = live_version;
141 return true;
144 void ServiceWorkerProviderHost::AssociateRegistration(
145 ServiceWorkerRegistration* registration) {
146 DCHECK(CanAssociateRegistration(registration));
147 associated_registration_ = registration;
148 registration->AddListener(this);
149 UpdatePotentialControllees(registration->installing_version(),
150 registration->waiting_version(),
151 registration->active_version());
152 SetControllerVersionAttribute(registration->active_version());
155 void ServiceWorkerProviderHost::UnassociateRegistration() {
156 if (!associated_registration_.get())
157 return;
158 associated_registration_->RemoveListener(this);
159 associated_registration_ = NULL;
160 UpdatePotentialControllees(NULL, NULL, NULL);
161 SetControllerVersionAttribute(NULL);
164 scoped_ptr<ServiceWorkerRequestHandler>
165 ServiceWorkerProviderHost::CreateRequestHandler(
166 ResourceType resource_type,
167 base::WeakPtr<storage::BlobStorageContext> blob_storage_context,
168 scoped_refptr<ResourceRequestBody> body) {
169 if (IsHostToRunningServiceWorker()) {
170 return scoped_ptr<ServiceWorkerRequestHandler>(
171 new ServiceWorkerContextRequestHandler(
172 context_, AsWeakPtr(), blob_storage_context, resource_type));
174 if (ServiceWorkerUtils::IsMainResourceType(resource_type) ||
175 active_version()) {
176 return scoped_ptr<ServiceWorkerRequestHandler>(
177 new ServiceWorkerControlleeRequestHandler(
178 context_, AsWeakPtr(), blob_storage_context, resource_type, body));
180 return scoped_ptr<ServiceWorkerRequestHandler>();
183 bool ServiceWorkerProviderHost::CanAssociateRegistration(
184 ServiceWorkerRegistration* registration) {
185 if (!context_)
186 return false;
187 if (running_hosted_version_.get())
188 return false;
189 if (!registration || associated_registration_.get())
190 return false;
191 return true;
194 void ServiceWorkerProviderHost::PostMessage(
195 const base::string16& message,
196 const std::vector<int>& sent_message_port_ids) {
197 if (!dispatcher_host_)
198 return; // Could be NULL in some tests.
200 std::vector<int> new_routing_ids;
201 dispatcher_host_->message_port_message_filter()->
202 UpdateMessagePortsWithNewRoutes(sent_message_port_ids,
203 &new_routing_ids);
205 dispatcher_host_->Send(
206 new ServiceWorkerMsg_MessageToDocument(
207 kDocumentMainThreadId, provider_id(),
208 message,
209 sent_message_port_ids,
210 new_routing_ids));
213 ServiceWorkerObjectInfo ServiceWorkerProviderHost::CreateHandleAndPass(
214 ServiceWorkerVersion* version) {
215 ServiceWorkerObjectInfo info;
216 if (context_ && version) {
217 scoped_ptr<ServiceWorkerHandle> handle =
218 ServiceWorkerHandle::Create(context_,
219 dispatcher_host_,
220 kDocumentMainThreadId,
221 provider_id_,
222 version);
223 info = handle->GetObjectInfo();
224 dispatcher_host_->RegisterServiceWorkerHandle(handle.Pass());
226 return info;
229 bool ServiceWorkerProviderHost::IsContextAlive() {
230 return context_ != NULL;
233 } // namespace content