Enable right clicking on the applist doodle web contents and log the data.
[chromium-blink-merge.git] / content / renderer / shared_worker / embedded_shared_worker_stub.cc
blob4bcc63985ec65e298c9351f64ecc128fd72999a6
1 // Copyright 2014 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/renderer/shared_worker/embedded_shared_worker_stub.h"
7 #include "base/message_loop/message_loop_proxy.h"
8 #include "content/child/appcache/appcache_dispatcher.h"
9 #include "content/child/appcache/web_application_cache_host_impl.h"
10 #include "content/child/request_extra_data.h"
11 #include "content/child/scoped_child_process_reference.h"
12 #include "content/child/service_worker/service_worker_handle_reference.h"
13 #include "content/child/service_worker/service_worker_network_provider.h"
14 #include "content/child/service_worker/service_worker_provider_context.h"
15 #include "content/child/shared_worker_devtools_agent.h"
16 #include "content/child/webmessageportchannel_impl.h"
17 #include "content/common/worker_messages.h"
18 #include "content/renderer/render_thread_impl.h"
19 #include "content/renderer/shared_worker/embedded_shared_worker_permission_client_proxy.h"
20 #include "ipc/ipc_message_macros.h"
21 #include "third_party/WebKit/public/platform/WebURLRequest.h"
22 #include "third_party/WebKit/public/web/WebDataSource.h"
23 #include "third_party/WebKit/public/web/WebSecurityOrigin.h"
24 #include "third_party/WebKit/public/web/WebServiceWorkerNetworkProvider.h"
25 #include "third_party/WebKit/public/web/WebSharedWorker.h"
26 #include "third_party/WebKit/public/web/WebSharedWorkerClient.h"
28 namespace content {
30 namespace {
32 class SharedWorkerWebApplicationCacheHostImpl
33 : public WebApplicationCacheHostImpl {
34 public:
35 SharedWorkerWebApplicationCacheHostImpl(
36 blink::WebApplicationCacheHostClient* client)
37 : WebApplicationCacheHostImpl(client,
38 RenderThreadImpl::current()
39 ->appcache_dispatcher()
40 ->backend_proxy()) {}
42 // Main resource loading is different for workers. The main resource is
43 // loaded by the worker using WorkerScriptLoader.
44 // These overrides are stubbed out.
45 virtual void willStartMainResourceRequest(
46 blink::WebURLRequest&,
47 const blink::WebApplicationCacheHost*) {}
48 virtual void didReceiveResponseForMainResource(const blink::WebURLResponse&) {
50 virtual void didReceiveDataForMainResource(const char* data, unsigned len) {}
51 virtual void didFinishLoadingMainResource(bool success) {}
53 // Cache selection is also different for workers. We know at construction
54 // time what cache to select and do so then.
55 // These overrides are stubbed out.
56 virtual void selectCacheWithoutManifest() {}
57 virtual bool selectCacheWithManifest(const blink::WebURL& manifestURL) {
58 return true;
62 // We store an instance of this class in the "extra data" of the WebDataSource
63 // and attach a ServiceWorkerNetworkProvider to it as base::UserData.
64 // (see createServiceWorkerNetworkProvider).
65 class DataSourceExtraData
66 : public blink::WebDataSource::ExtraData,
67 public base::SupportsUserData {
68 public:
69 DataSourceExtraData() {}
70 virtual ~DataSourceExtraData() {}
73 // Called on the main thread only and blink owns it.
74 class WebServiceWorkerNetworkProviderImpl
75 : public blink::WebServiceWorkerNetworkProvider {
76 public:
77 // Blink calls this method for each request starting with the main script,
78 // we tag them with the provider id.
79 virtual void willSendRequest(
80 blink::WebDataSource* data_source,
81 blink::WebURLRequest& request) {
82 ServiceWorkerNetworkProvider* provider =
83 GetNetworkProviderFromDataSource(data_source);
84 scoped_ptr<RequestExtraData> extra_data(new RequestExtraData);
85 extra_data->set_service_worker_provider_id(provider->provider_id());
86 request.setExtraData(extra_data.release());
89 virtual bool isControlledByServiceWorker(
90 blink::WebDataSource& data_source) {
91 ServiceWorkerNetworkProvider* provider =
92 GetNetworkProviderFromDataSource(&data_source);
93 return provider->context()->controller_handle_id() !=
94 kInvalidServiceWorkerHandleId;
97 virtual int64_t serviceWorkerID(
98 blink::WebDataSource& data_source) {
99 ServiceWorkerNetworkProvider* provider =
100 GetNetworkProviderFromDataSource(&data_source);
101 if (provider->context()->controller())
102 return provider->context()->controller()->version_id();
103 return kInvalidServiceWorkerVersionId;
106 private:
107 ServiceWorkerNetworkProvider* GetNetworkProviderFromDataSource(
108 const blink::WebDataSource* data_source) {
109 return ServiceWorkerNetworkProvider::FromDocumentState(
110 static_cast<DataSourceExtraData*>(data_source->extraData()));
114 } // namespace
116 EmbeddedSharedWorkerStub::EmbeddedSharedWorkerStub(
117 const GURL& url,
118 const base::string16& name,
119 const base::string16& content_security_policy,
120 blink::WebContentSecurityPolicyType security_policy_type,
121 bool pause_on_start,
122 int route_id)
123 : route_id_(route_id),
124 name_(name),
125 runing_(false),
126 url_(url),
127 app_cache_host_(nullptr) {
128 RenderThreadImpl::current()->AddEmbeddedWorkerRoute(route_id_, this);
129 impl_ = blink::WebSharedWorker::create(this);
130 if (pause_on_start) {
131 // Pause worker context when it starts and wait until either DevTools client
132 // is attached or explicit resume notification is received.
133 impl_->pauseWorkerContextOnStart();
135 worker_devtools_agent_.reset(
136 new SharedWorkerDevToolsAgent(route_id, impl_));
137 impl_->startWorkerContext(url, name_,
138 content_security_policy, security_policy_type);
141 EmbeddedSharedWorkerStub::~EmbeddedSharedWorkerStub() {
142 RenderThreadImpl::current()->RemoveEmbeddedWorkerRoute(route_id_);
145 bool EmbeddedSharedWorkerStub::OnMessageReceived(
146 const IPC::Message& message) {
147 if (worker_devtools_agent_->OnMessageReceived(message))
148 return true;
149 bool handled = true;
150 IPC_BEGIN_MESSAGE_MAP(EmbeddedSharedWorkerStub, message)
151 IPC_MESSAGE_HANDLER(WorkerMsg_TerminateWorkerContext,
152 OnTerminateWorkerContext)
153 IPC_MESSAGE_HANDLER(WorkerMsg_Connect, OnConnect)
154 IPC_MESSAGE_UNHANDLED(handled = false)
155 IPC_END_MESSAGE_MAP()
156 return handled;
159 void EmbeddedSharedWorkerStub::OnChannelError() {
160 OnTerminateWorkerContext();
163 void EmbeddedSharedWorkerStub::workerReadyForInspection() {
164 Send(new WorkerHostMsg_WorkerReadyForInspection(route_id_));
167 void EmbeddedSharedWorkerStub::workerScriptLoaded() {
168 Send(new WorkerHostMsg_WorkerScriptLoaded(route_id_));
169 runing_ = true;
170 // Process any pending connections.
171 for (PendingChannelList::const_iterator iter = pending_channels_.begin();
172 iter != pending_channels_.end();
173 ++iter) {
174 ConnectToChannel(*iter);
176 pending_channels_.clear();
179 void EmbeddedSharedWorkerStub::workerScriptLoadFailed() {
180 Send(new WorkerHostMsg_WorkerScriptLoadFailed(route_id_));
181 for (PendingChannelList::const_iterator iter = pending_channels_.begin();
182 iter != pending_channels_.end();
183 ++iter) {
184 blink::WebMessagePortChannel* channel = *iter;
185 channel->destroy();
187 pending_channels_.clear();
188 Shutdown();
191 void EmbeddedSharedWorkerStub::workerContextClosed() {
192 Send(new WorkerHostMsg_WorkerContextClosed(route_id_));
195 void EmbeddedSharedWorkerStub::workerContextDestroyed() {
196 Send(new WorkerHostMsg_WorkerContextDestroyed(route_id_));
197 Shutdown();
200 void EmbeddedSharedWorkerStub::selectAppCacheID(long long app_cache_id) {
201 if (app_cache_host_) {
202 // app_cache_host_ could become stale as it's owned by blink's
203 // DocumentLoader. This method is assumed to be called while it's valid.
204 app_cache_host_->backend()->SelectCacheForSharedWorker(
205 app_cache_host_->host_id(), app_cache_id);
209 blink::WebNotificationPresenter*
210 EmbeddedSharedWorkerStub::notificationPresenter() {
211 // TODO(horo): delete this method if we have no plan to implement this.
212 NOTREACHED();
213 return NULL;
216 blink::WebApplicationCacheHost*
217 EmbeddedSharedWorkerStub::createApplicationCacheHost(
218 blink::WebApplicationCacheHostClient* client) {
219 app_cache_host_ = new SharedWorkerWebApplicationCacheHostImpl(client);
220 return app_cache_host_;
223 blink::WebWorkerPermissionClientProxy*
224 EmbeddedSharedWorkerStub::createWorkerPermissionClientProxy(
225 const blink::WebSecurityOrigin& origin) {
226 return new EmbeddedSharedWorkerPermissionClientProxy(
227 GURL(origin.toString()),
228 origin.isUnique(),
229 route_id_,
230 ChildThreadImpl::current()->thread_safe_sender());
233 blink::WebServiceWorkerNetworkProvider*
234 EmbeddedSharedWorkerStub::createServiceWorkerNetworkProvider(
235 blink::WebDataSource* data_source) {
236 // Create a content::ServiceWorkerNetworkProvider for this data source so
237 // we can observe its requests.
238 scoped_ptr<ServiceWorkerNetworkProvider> provider(
239 new ServiceWorkerNetworkProvider(
240 MSG_ROUTING_NONE, SERVICE_WORKER_PROVIDER_FOR_CONTROLLEE));
242 // The provider is kept around for the lifetime of the DataSource
243 // and ownership is transferred to the DataSource.
244 DataSourceExtraData* extra_data = new DataSourceExtraData();
245 data_source->setExtraData(extra_data);
246 ServiceWorkerNetworkProvider::AttachToDocumentState(
247 extra_data, provider.Pass());
249 // Blink is responsible for deleting the returned object.
250 return new WebServiceWorkerNetworkProviderImpl();
253 void EmbeddedSharedWorkerStub::sendDevToolsMessage(
254 int call_id,
255 const blink::WebString& message,
256 const blink::WebString& state) {
257 worker_devtools_agent_->SendDevToolsMessage(call_id, message, state);
260 void EmbeddedSharedWorkerStub::Shutdown() {
261 delete this;
264 bool EmbeddedSharedWorkerStub::Send(IPC::Message* message) {
265 return RenderThreadImpl::current()->Send(message);
268 void EmbeddedSharedWorkerStub::ConnectToChannel(
269 WebMessagePortChannelImpl* channel) {
270 impl_->connect(channel);
271 Send(
272 new WorkerHostMsg_WorkerConnected(channel->message_port_id(), route_id_));
275 void EmbeddedSharedWorkerStub::OnConnect(int sent_message_port_id,
276 int routing_id) {
277 WebMessagePortChannelImpl* channel =
278 new WebMessagePortChannelImpl(routing_id,
279 sent_message_port_id,
280 base::MessageLoopProxy::current().get());
281 if (runing_) {
282 ConnectToChannel(channel);
283 } else {
284 // If two documents try to load a SharedWorker at the same time, the
285 // WorkerMsg_Connect for one of the documents can come in before the
286 // worker is started. Just queue up the connect and deliver it once the
287 // worker starts.
288 pending_channels_.push_back(channel);
292 void EmbeddedSharedWorkerStub::OnTerminateWorkerContext() {
293 runing_ = false;
294 impl_->terminateWorkerContext();
297 } // namespace content