Upstream version 5.34.92.0
[platform/framework/web/crosswalk.git] / src / content / worker / websharedworker_stub.cc
1 // Copyright (c) 2012 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/worker/websharedworker_stub.h"
6
7 #include "base/compiler_specific.h"
8 #include "content/child/child_process.h"
9 #include "content/child/child_thread.h"
10 #include "content/child/fileapi/file_system_dispatcher.h"
11 #include "content/child/webmessageportchannel_impl.h"
12 #include "content/common/worker_messages.h"
13 #include "content/worker/shared_worker_devtools_agent.h"
14 #include "content/worker/worker_thread.h"
15 #include "third_party/WebKit/public/web/WebSharedWorker.h"
16 #include "third_party/WebKit/public/platform/WebString.h"
17 #include "third_party/WebKit/public/platform/WebURL.h"
18
19 namespace content {
20
21 WebSharedWorkerStub::WebSharedWorkerStub(
22     const GURL& url,
23     const base::string16& name,
24     const base::string16& content_security_policy,
25     blink::WebContentSecurityPolicyType security_policy_type,
26     int route_id,
27     const WorkerAppCacheInitInfo& appcache_init_info)
28     : route_id_(route_id),
29       appcache_init_info_(appcache_init_info),
30       client_(route_id, this),
31       name_(name),
32       started_(false),
33       worker_script_loaded_(false) {
34
35   WorkerThread* worker_thread = WorkerThread::current();
36   DCHECK(worker_thread);
37   worker_thread->AddWorkerStub(this);
38   // Start processing incoming IPCs for this worker.
39   worker_thread->AddRoute(route_id_, this);
40
41   // TODO(atwilson): Add support for NaCl when they support MessagePorts.
42   impl_ = blink::WebSharedWorker::create(client());
43   worker_devtools_agent_.reset(new SharedWorkerDevToolsAgent(route_id, impl_));
44   client()->set_devtools_agent(worker_devtools_agent_.get());
45 }
46
47 WebSharedWorkerStub::~WebSharedWorkerStub() {
48   impl_->clientDestroyed();
49   WorkerThread* worker_thread = WorkerThread::current();
50   DCHECK(worker_thread);
51   worker_thread->RemoveWorkerStub(this);
52   worker_thread->RemoveRoute(route_id_);
53 }
54
55 void WebSharedWorkerStub::Shutdown() {
56   // The worker has exited - free ourselves and the client.
57   delete this;
58 }
59
60 void WebSharedWorkerStub::EnsureWorkerContextTerminates() {
61   client_.EnsureWorkerContextTerminates();
62 }
63
64 bool WebSharedWorkerStub::OnMessageReceived(const IPC::Message& message) {
65   if (worker_devtools_agent_->OnMessageReceived(message))
66     return true;
67
68   bool handled = true;
69   IPC_BEGIN_MESSAGE_MAP(WebSharedWorkerStub, message)
70     IPC_MESSAGE_HANDLER(WorkerMsg_StartWorkerContext, OnStartWorkerContext)
71     IPC_MESSAGE_HANDLER(WorkerMsg_TerminateWorkerContext,
72                         OnTerminateWorkerContext)
73     IPC_MESSAGE_HANDLER(WorkerMsg_Connect, OnConnect)
74     IPC_MESSAGE_UNHANDLED(handled = false)
75   IPC_END_MESSAGE_MAP()
76   return handled;
77 }
78
79 void WebSharedWorkerStub::OnChannelError() {
80     OnTerminateWorkerContext();
81 }
82
83 const GURL& WebSharedWorkerStub::url() {
84   return url_;
85 }
86
87 void WebSharedWorkerStub::OnStartWorkerContext(
88     const GURL& url, const base::string16& user_agent,
89     const base::string16& source_code,
90     const base::string16& content_security_policy,
91     blink::WebContentSecurityPolicyType policy_type) {
92   // Ignore multiple attempts to start this worker (can happen if two pages
93   // try to start it simultaneously).
94   if (started_)
95     return;
96
97   impl_->startWorkerContext(url, name_, user_agent, source_code,
98                             content_security_policy, policy_type, 0);
99   started_ = true;
100   url_ = url;
101 }
102
103 void WebSharedWorkerStub::OnConnect(int sent_message_port_id, int routing_id) {
104   blink::WebMessagePortChannel* channel =
105       new WebMessagePortChannelImpl(routing_id,
106                                     sent_message_port_id,
107                                     base::MessageLoopProxy::current().get());
108   if (started_ && worker_script_loaded_) {
109     impl_->connect(channel);
110   } else {
111     // If two documents try to load a SharedWorker at the same time, the
112     // WorkerMsg_Connect for one of the documents can come in before the
113     // worker is started. Just queue up the connect and deliver it once the
114     // worker starts.
115     pending_channels_.push_back(channel);
116   }
117 }
118
119 void WebSharedWorkerStub::OnTerminateWorkerContext() {
120   impl_->terminateWorkerContext();
121
122   // Call the client to make sure context exits.
123   EnsureWorkerContextTerminates();
124   started_ = false;
125 }
126
127 void WebSharedWorkerStub::WorkerScriptLoaded() {
128   worker_script_loaded_ = true;
129   // Process any pending connections.
130   for (PendingChannelList::const_iterator iter = pending_channels_.begin();
131        iter != pending_channels_.end();
132        ++iter) {
133     impl_->connect(*iter);
134   }
135   pending_channels_.clear();
136 }
137
138 void WebSharedWorkerStub::WorkerScriptLoadFailed() {
139   // FIXME(horo): Implement this.
140 }
141
142 }  // namespace content