Upstream version 5.34.104.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/shared_worker_devtools_agent.h"
12 #include "content/child/webmessageportchannel_impl.h"
13 #include "content/common/worker_messages.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     : route_id_(route_id),
28       client_(route_id, this),
29       running_(false),
30       url_(url) {
31
32   WorkerThread* worker_thread = WorkerThread::current();
33   DCHECK(worker_thread);
34   worker_thread->AddWorkerStub(this);
35   // Start processing incoming IPCs for this worker.
36   worker_thread->AddRoute(route_id_, this);
37
38   // TODO(atwilson): Add support for NaCl when they support MessagePorts.
39   impl_ = blink::WebSharedWorker::create(client());
40   worker_devtools_agent_.reset(new SharedWorkerDevToolsAgent(route_id, impl_));
41   client()->set_devtools_agent(worker_devtools_agent_.get());
42   impl_->startWorkerContext(url_, name,
43                             content_security_policy, security_policy_type);
44 }
45
46 WebSharedWorkerStub::~WebSharedWorkerStub() {
47   impl_->clientDestroyed();
48   WorkerThread* worker_thread = WorkerThread::current();
49   DCHECK(worker_thread);
50   worker_thread->RemoveWorkerStub(this);
51   worker_thread->RemoveRoute(route_id_);
52 }
53
54 void WebSharedWorkerStub::Shutdown() {
55   // The worker has exited - free ourselves and the client.
56   delete this;
57 }
58
59 void WebSharedWorkerStub::EnsureWorkerContextTerminates() {
60   client_.EnsureWorkerContextTerminates();
61 }
62
63 bool WebSharedWorkerStub::OnMessageReceived(const IPC::Message& message) {
64   if (worker_devtools_agent_->OnMessageReceived(message))
65     return true;
66
67   bool handled = true;
68   IPC_BEGIN_MESSAGE_MAP(WebSharedWorkerStub, message)
69     IPC_MESSAGE_HANDLER(WorkerMsg_TerminateWorkerContext,
70                         OnTerminateWorkerContext)
71     IPC_MESSAGE_HANDLER(WorkerMsg_Connect, OnConnect)
72     IPC_MESSAGE_UNHANDLED(handled = false)
73   IPC_END_MESSAGE_MAP()
74   return handled;
75 }
76
77 void WebSharedWorkerStub::OnChannelError() {
78     OnTerminateWorkerContext();
79 }
80
81 const GURL& WebSharedWorkerStub::url() {
82   return url_;
83 }
84
85 void WebSharedWorkerStub::OnConnect(int sent_message_port_id, int routing_id) {
86   WebMessagePortChannelImpl* channel =
87       new WebMessagePortChannelImpl(routing_id,
88                                     sent_message_port_id,
89                                     base::MessageLoopProxy::current().get());
90   if (running_) {
91     impl_->connect(channel);
92     WorkerThread::current()->Send(
93         new WorkerHostMsg_WorkerConnected(channel->message_port_id(),
94                                           route_id_));
95   } else {
96     // If two documents try to load a SharedWorker at the same time, the
97     // WorkerMsg_Connect for one of the documents can come in before the
98     // worker is started. Just queue up the connect and deliver it once the
99     // worker starts.
100     pending_channels_.push_back(channel);
101   }
102 }
103
104 void WebSharedWorkerStub::OnTerminateWorkerContext() {
105   running_ = false;
106   // Call the client to make sure context exits.
107   EnsureWorkerContextTerminates();
108   // This may call "delete this" via WorkerScriptLoadFailed and Shutdown.
109   impl_->terminateWorkerContext();
110 }
111
112 void WebSharedWorkerStub::WorkerScriptLoaded() {
113   running_ = true;
114   // Process any pending connections.
115   for (PendingChannelList::const_iterator iter = pending_channels_.begin();
116        iter != pending_channels_.end();
117        ++iter) {
118     impl_->connect(*iter);
119     WorkerThread::current()->Send(
120         new WorkerHostMsg_WorkerConnected((*iter)->message_port_id(),
121                                           route_id_));
122   }
123   pending_channels_.clear();
124 }
125
126 void WebSharedWorkerStub::WorkerScriptLoadFailed() {
127   for (PendingChannelList::const_iterator iter = pending_channels_.begin();
128        iter != pending_channels_.end();
129        ++iter) {
130     blink::WebMessagePortChannel* channel = *iter;
131     channel->destroy();
132   }
133   pending_channels_.clear();
134   Shutdown();
135 }
136
137 }  // namespace content