Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / content / renderer / shared_worker / embedded_shared_worker_stub.cc
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.
4
5 #include "content/renderer/shared_worker/embedded_shared_worker_stub.h"
6
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/scoped_child_process_reference.h"
11 #include "content/child/shared_worker_devtools_agent.h"
12 #include "content/child/webmessageportchannel_impl.h"
13 #include "content/common/worker_messages.h"
14 #include "content/renderer/render_thread_impl.h"
15 #include "ipc/ipc_message_macros.h"
16 #include "third_party/WebKit/public/web/WebSharedWorker.h"
17 #include "third_party/WebKit/public/web/WebSharedWorkerClient.h"
18
19 namespace content {
20
21 namespace {
22
23 class SharedWorkerWebApplicationCacheHostImpl
24     : public WebApplicationCacheHostImpl {
25  public:
26   SharedWorkerWebApplicationCacheHostImpl(
27       blink::WebApplicationCacheHostClient* client)
28       : WebApplicationCacheHostImpl(client,
29                                     RenderThreadImpl::current()
30                                         ->appcache_dispatcher()
31                                         ->backend_proxy()) {}
32
33   // Main resource loading is different for workers. The main resource is
34   // loaded by the worker using WorkerScriptLoader.
35   // These overrides are stubbed out.
36   virtual void willStartMainResourceRequest(
37       blink::WebURLRequest&,
38       const blink::WebApplicationCacheHost*) {}
39   virtual void didReceiveResponseForMainResource(const blink::WebURLResponse&) {
40   }
41   virtual void didReceiveDataForMainResource(const char* data, int len) {}
42   virtual void didFinishLoadingMainResource(bool success) {}
43
44   // Cache selection is also different for workers. We know at construction
45   // time what cache to select and do so then.
46   // These overrides are stubbed out.
47   virtual void selectCacheWithoutManifest() {}
48   virtual bool selectCacheWithManifest(const blink::WebURL& manifestURL) {
49     return true;
50   }
51 };
52 }
53
54 EmbeddedSharedWorkerStub::EmbeddedSharedWorkerStub(
55     const GURL& url,
56     const base::string16& name,
57     const base::string16& content_security_policy,
58     blink::WebContentSecurityPolicyType security_policy_type,
59     bool pause_on_start,
60     int route_id)
61     : route_id_(route_id), name_(name), runing_(false), url_(url) {
62   RenderThreadImpl::current()->AddEmbeddedWorkerRoute(route_id_, this);
63   impl_ = blink::WebSharedWorker::create(this);
64   if (pause_on_start) {
65     // Pause worker context when it starts and wait until either DevTools client
66     // is attached or explicit resume notification is received.
67     impl_->pauseWorkerContextOnStart();
68   }
69   worker_devtools_agent_.reset(
70       new SharedWorkerDevToolsAgent(route_id, impl_));
71   impl_->startWorkerContext(url, name_,
72                             content_security_policy, security_policy_type);
73 }
74
75 EmbeddedSharedWorkerStub::~EmbeddedSharedWorkerStub() {
76   RenderThreadImpl::current()->RemoveEmbeddedWorkerRoute(route_id_);
77 }
78
79 bool EmbeddedSharedWorkerStub::OnMessageReceived(
80     const IPC::Message& message) {
81   if (worker_devtools_agent_->OnMessageReceived(message))
82     return true;
83   bool handled = true;
84   IPC_BEGIN_MESSAGE_MAP(EmbeddedSharedWorkerStub, message)
85     IPC_MESSAGE_HANDLER(WorkerMsg_TerminateWorkerContext,
86                         OnTerminateWorkerContext)
87     IPC_MESSAGE_HANDLER(WorkerMsg_Connect, OnConnect)
88     IPC_MESSAGE_UNHANDLED(handled = false)
89   IPC_END_MESSAGE_MAP()
90   return handled;
91 }
92
93 void EmbeddedSharedWorkerStub::OnChannelError() {
94   OnTerminateWorkerContext();
95 }
96
97 void EmbeddedSharedWorkerStub::workerScriptLoaded() {
98   Send(new WorkerHostMsg_WorkerScriptLoaded(route_id_));
99   runing_ = true;
100   // Process any pending connections.
101   for (PendingChannelList::const_iterator iter = pending_channels_.begin();
102        iter != pending_channels_.end();
103        ++iter) {
104     ConnectToChannel(*iter);
105   }
106   pending_channels_.clear();
107 }
108
109 void EmbeddedSharedWorkerStub::workerScriptLoadFailed() {
110   Send(new WorkerHostMsg_WorkerScriptLoadFailed(route_id_));
111   for (PendingChannelList::const_iterator iter = pending_channels_.begin();
112        iter != pending_channels_.end();
113        ++iter) {
114     blink::WebMessagePortChannel* channel = *iter;
115     channel->destroy();
116   }
117   pending_channels_.clear();
118   Shutdown();
119 }
120
121 void EmbeddedSharedWorkerStub::workerContextClosed() {
122   Send(new WorkerHostMsg_WorkerContextClosed(route_id_));
123 }
124
125 void EmbeddedSharedWorkerStub::workerContextDestroyed() {
126   Send(new WorkerHostMsg_WorkerContextDestroyed(route_id_));
127   Shutdown();
128 }
129
130 void EmbeddedSharedWorkerStub::selectAppCacheID(long long app_cache_id) {
131   if (app_cache_host_) {
132     // app_cache_host_ could become stale as it's owned by blink's
133     // DocumentLoader. This method is assumed to be called while it's valid.
134     app_cache_host_->backend()->SelectCacheForSharedWorker(
135         app_cache_host_->host_id(), app_cache_id);
136   }
137 }
138
139 blink::WebNotificationPresenter*
140 EmbeddedSharedWorkerStub::notificationPresenter() {
141   // TODO(horo): delete this method if we have no plan to implement this.
142   NOTREACHED();
143   return NULL;
144 }
145
146 blink::WebApplicationCacheHost*
147 EmbeddedSharedWorkerStub::createApplicationCacheHost(
148     blink::WebApplicationCacheHostClient* client) {
149   app_cache_host_ = new SharedWorkerWebApplicationCacheHostImpl(client);
150   return app_cache_host_;
151 }
152
153 blink::WebWorkerPermissionClientProxy*
154     EmbeddedSharedWorkerStub::createWorkerPermissionClientProxy(
155     const blink::WebSecurityOrigin& origin) {
156   // TODO(horo): implement this.
157   return NULL;
158 }
159
160 void EmbeddedSharedWorkerStub::dispatchDevToolsMessage(
161       const blink::WebString& message) {
162   worker_devtools_agent_->SendDevToolsMessage(message);
163 }
164
165 void EmbeddedSharedWorkerStub::saveDevToolsAgentState(
166       const blink::WebString& state) {
167   worker_devtools_agent_->SaveDevToolsAgentState(state);
168 }
169
170 void EmbeddedSharedWorkerStub::Shutdown() {
171   delete this;
172 }
173
174 bool EmbeddedSharedWorkerStub::Send(IPC::Message* message) {
175   return RenderThreadImpl::current()->Send(message);
176 }
177
178 void EmbeddedSharedWorkerStub::ConnectToChannel(
179     WebMessagePortChannelImpl* channel) {
180   impl_->connect(channel);
181   Send(
182       new WorkerHostMsg_WorkerConnected(channel->message_port_id(), route_id_));
183 }
184
185 void EmbeddedSharedWorkerStub::OnConnect(int sent_message_port_id,
186                                          int routing_id) {
187   WebMessagePortChannelImpl* channel =
188       new WebMessagePortChannelImpl(routing_id,
189                                     sent_message_port_id,
190                                     base::MessageLoopProxy::current().get());
191   if (runing_) {
192     ConnectToChannel(channel);
193   } else {
194     // If two documents try to load a SharedWorker at the same time, the
195     // WorkerMsg_Connect for one of the documents can come in before the
196     // worker is started. Just queue up the connect and deliver it once the
197     // worker starts.
198     pending_channels_.push_back(channel);
199   }
200 }
201
202 void EmbeddedSharedWorkerStub::OnTerminateWorkerContext() {
203   runing_ = false;
204   impl_->terminateWorkerContext();
205 }
206
207 }  // namespace content