OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/child/webmessageportchannel_impl.h" | 5 #include "content/child/webmessageportchannel_impl.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/message_loop/message_loop_proxy.h" | 8 #include "base/message_loop/message_loop_proxy.h" |
9 #include "base/values.h" | 9 #include "base/values.h" |
10 #include "content/child/child_process.h" | 10 #include "content/child/child_process.h" |
(...skipping 18 matching lines...) Expand all Loading... |
29 route_id_(MSG_ROUTING_NONE), | 29 route_id_(MSG_ROUTING_NONE), |
30 message_port_id_(MSG_ROUTING_NONE), | 30 message_port_id_(MSG_ROUTING_NONE), |
31 send_messages_as_values_(false), | 31 send_messages_as_values_(false), |
32 main_thread_task_runner_(main_thread_task_runner) { | 32 main_thread_task_runner_(main_thread_task_runner) { |
33 AddRef(); | 33 AddRef(); |
34 Init(); | 34 Init(); |
35 } | 35 } |
36 | 36 |
37 WebMessagePortChannelImpl::WebMessagePortChannelImpl( | 37 WebMessagePortChannelImpl::WebMessagePortChannelImpl( |
38 int route_id, | 38 int route_id, |
39 int message_port_id, | 39 const TransferredMessagePort& port, |
40 const scoped_refptr<base::SingleThreadTaskRunner>& main_thread_task_runner) | 40 const scoped_refptr<base::SingleThreadTaskRunner>& main_thread_task_runner) |
41 : client_(NULL), | 41 : client_(NULL), |
42 route_id_(route_id), | 42 route_id_(route_id), |
43 message_port_id_(message_port_id), | 43 message_port_id_(port.id), |
44 send_messages_as_values_(false), | 44 send_messages_as_values_(port.send_messages_as_values), |
45 main_thread_task_runner_(main_thread_task_runner) { | 45 main_thread_task_runner_(main_thread_task_runner) { |
46 AddRef(); | 46 AddRef(); |
47 Init(); | 47 Init(); |
48 } | 48 } |
49 | 49 |
50 WebMessagePortChannelImpl::~WebMessagePortChannelImpl() { | 50 WebMessagePortChannelImpl::~WebMessagePortChannelImpl() { |
51 // If we have any queued messages with attached ports, manually destroy them. | 51 // If we have any queued messages with attached ports, manually destroy them. |
52 while (!message_queue_.empty()) { | 52 while (!message_queue_.empty()) { |
53 const std::vector<WebMessagePortChannelImpl*>& channel_array = | 53 const WebMessagePortChannelArray& channel_array = |
54 message_queue_.front().ports; | 54 message_queue_.front().ports; |
55 for (size_t i = 0; i < channel_array.size(); i++) { | 55 for (size_t i = 0; i < channel_array.size(); i++) { |
56 channel_array[i]->destroy(); | 56 channel_array[i]->destroy(); |
57 } | 57 } |
58 message_queue_.pop(); | 58 message_queue_.pop(); |
59 } | 59 } |
60 | 60 |
61 if (message_port_id_ != MSG_ROUTING_NONE) | 61 if (message_port_id_ != MSG_ROUTING_NONE) |
62 Send(new MessagePortHostMsg_DestroyMessagePort(message_port_id_)); | 62 Send(new MessagePortHostMsg_DestroyMessagePort(message_port_id_)); |
63 | 63 |
(...skipping 12 matching lines...) Expand all Loading... |
76 new WebMessagePortChannelImpl(main_thread_task_runner); | 76 new WebMessagePortChannelImpl(main_thread_task_runner); |
77 | 77 |
78 impl1->Entangle(impl2); | 78 impl1->Entangle(impl2); |
79 impl2->Entangle(impl1); | 79 impl2->Entangle(impl1); |
80 | 80 |
81 *channel1 = impl1; | 81 *channel1 = impl1; |
82 *channel2 = impl2; | 82 *channel2 = impl2; |
83 } | 83 } |
84 | 84 |
85 // static | 85 // static |
86 std::vector<int> WebMessagePortChannelImpl::ExtractMessagePortIDs( | 86 std::vector<TransferredMessagePort> |
| 87 WebMessagePortChannelImpl::ExtractMessagePortIDs( |
87 WebMessagePortChannelArray* channels) { | 88 WebMessagePortChannelArray* channels) { |
88 std::vector<int> message_port_ids; | 89 std::vector<TransferredMessagePort> message_ports; |
89 if (channels) { | 90 if (channels) { |
90 message_port_ids.resize(channels->size()); | |
91 // Extract the port IDs from the source array, then free it. | 91 // Extract the port IDs from the source array, then free it. |
92 for (size_t i = 0; i < channels->size(); ++i) { | 92 message_ports = ExtractMessagePortIDs(*channels); |
93 WebMessagePortChannelImpl* webchannel = | |
94 static_cast<WebMessagePortChannelImpl*>((*channels)[i]); | |
95 // The message port ids might not be set up yet if this channel | |
96 // wasn't created on the main thread. | |
97 DCHECK(webchannel->main_thread_task_runner_->BelongsToCurrentThread()); | |
98 message_port_ids[i] = webchannel->message_port_id(); | |
99 webchannel->QueueMessages(); | |
100 DCHECK(message_port_ids[i] != MSG_ROUTING_NONE); | |
101 } | |
102 delete channels; | 93 delete channels; |
103 } | 94 } |
104 return message_port_ids; | 95 return message_ports; |
| 96 } |
| 97 |
| 98 // static |
| 99 std::vector<TransferredMessagePort> |
| 100 WebMessagePortChannelImpl::ExtractMessagePortIDs( |
| 101 const WebMessagePortChannelArray& channels) { |
| 102 std::vector<TransferredMessagePort> message_ports(channels.size()); |
| 103 for (size_t i = 0; i < channels.size(); ++i) { |
| 104 WebMessagePortChannelImpl* webchannel = |
| 105 static_cast<WebMessagePortChannelImpl*>(channels[i]); |
| 106 // The message port ids might not be set up yet if this channel |
| 107 // wasn't created on the main thread. |
| 108 DCHECK(webchannel->main_thread_task_runner_->BelongsToCurrentThread()); |
| 109 message_ports[i].id = webchannel->message_port_id(); |
| 110 message_ports[i].send_messages_as_values = |
| 111 webchannel->send_messages_as_values_; |
| 112 webchannel->QueueMessages(); |
| 113 DCHECK(message_ports[i].id != MSG_ROUTING_NONE); |
| 114 } |
| 115 return message_ports; |
| 116 } |
| 117 |
| 118 // static |
| 119 WebMessagePortChannelArray WebMessagePortChannelImpl::CreatePorts( |
| 120 const std::vector<TransferredMessagePort>& message_ports, |
| 121 const std::vector<int>& new_routing_ids, |
| 122 const scoped_refptr<base::SingleThreadTaskRunner>& |
| 123 main_thread_task_runner) { |
| 124 DCHECK_EQ(message_ports.size(), new_routing_ids.size()); |
| 125 WebMessagePortChannelArray channels(message_ports.size()); |
| 126 for (size_t i = 0; i < message_ports.size() && i < new_routing_ids.size(); |
| 127 ++i) { |
| 128 channels[i] = new WebMessagePortChannelImpl( |
| 129 new_routing_ids[i], message_ports[i], |
| 130 main_thread_task_runner); |
| 131 } |
| 132 return channels; |
105 } | 133 } |
106 | 134 |
107 void WebMessagePortChannelImpl::setClient(WebMessagePortChannelClient* client) { | 135 void WebMessagePortChannelImpl::setClient(WebMessagePortChannelClient* client) { |
108 // Must lock here since client_ is called on the main thread. | 136 // Must lock here since client_ is called on the main thread. |
109 base::AutoLock auto_lock(lock_); | 137 base::AutoLock auto_lock(lock_); |
110 client_ = client; | 138 client_ = client; |
111 } | 139 } |
112 | 140 |
113 void WebMessagePortChannelImpl::destroy() { | 141 void WebMessagePortChannelImpl::destroy() { |
114 setClient(NULL); | 142 setClient(NULL); |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
167 converter->SetDateAllowed(true); | 195 converter->SetDateAllowed(true); |
168 converter->SetRegExpAllowed(true); | 196 converter->SetRegExpAllowed(true); |
169 v8::Handle<v8::Value> v8_value = converter->ToV8Value( | 197 v8::Handle<v8::Value> v8_value = converter->ToV8Value( |
170 data.as_value(), client_->scriptContextForMessageConversion()); | 198 data.as_value(), client_->scriptContextForMessageConversion()); |
171 blink::WebSerializedScriptValue serialized_value = | 199 blink::WebSerializedScriptValue serialized_value = |
172 blink::WebSerializedScriptValue::serialize(v8_value); | 200 blink::WebSerializedScriptValue::serialize(v8_value); |
173 *message = serialized_value.toString(); | 201 *message = serialized_value.toString(); |
174 } else { | 202 } else { |
175 *message = message_queue_.front().message.message_as_string; | 203 *message = message_queue_.front().message.message_as_string; |
176 } | 204 } |
177 const std::vector<WebMessagePortChannelImpl*>& channel_array = | 205 channels = message_queue_.front().ports; |
178 message_queue_.front().ports; | |
179 WebMessagePortChannelArray result_ports(channel_array.size()); | |
180 for (size_t i = 0; i < channel_array.size(); i++) { | |
181 result_ports[i] = channel_array[i]; | |
182 } | |
183 | |
184 channels.swap(result_ports); | |
185 message_queue_.pop(); | 206 message_queue_.pop(); |
186 return true; | 207 return true; |
187 } | 208 } |
188 | 209 |
189 void WebMessagePortChannelImpl::Init() { | 210 void WebMessagePortChannelImpl::Init() { |
190 if (!main_thread_task_runner_->BelongsToCurrentThread()) { | 211 if (!main_thread_task_runner_->BelongsToCurrentThread()) { |
191 main_thread_task_runner_->PostTask( | 212 main_thread_task_runner_->PostTask( |
192 FROM_HERE, base::Bind(&WebMessagePortChannelImpl::Init, this)); | 213 FROM_HERE, base::Bind(&WebMessagePortChannelImpl::Init, this)); |
193 return; | 214 return; |
194 } | 215 } |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
256 IPC_BEGIN_MESSAGE_MAP(WebMessagePortChannelImpl, message) | 277 IPC_BEGIN_MESSAGE_MAP(WebMessagePortChannelImpl, message) |
257 IPC_MESSAGE_HANDLER(MessagePortMsg_Message, OnMessage) | 278 IPC_MESSAGE_HANDLER(MessagePortMsg_Message, OnMessage) |
258 IPC_MESSAGE_HANDLER(MessagePortMsg_MessagesQueued, OnMessagesQueued) | 279 IPC_MESSAGE_HANDLER(MessagePortMsg_MessagesQueued, OnMessagesQueued) |
259 IPC_MESSAGE_UNHANDLED(handled = false) | 280 IPC_MESSAGE_UNHANDLED(handled = false) |
260 IPC_END_MESSAGE_MAP() | 281 IPC_END_MESSAGE_MAP() |
261 return handled; | 282 return handled; |
262 } | 283 } |
263 | 284 |
264 void WebMessagePortChannelImpl::OnMessage( | 285 void WebMessagePortChannelImpl::OnMessage( |
265 const MessagePortMessage& message, | 286 const MessagePortMessage& message, |
266 const std::vector<int>& sent_message_port_ids, | 287 const std::vector<TransferredMessagePort>& sent_message_ports, |
267 const std::vector<int>& new_routing_ids) { | 288 const std::vector<int>& new_routing_ids) { |
268 base::AutoLock auto_lock(lock_); | 289 base::AutoLock auto_lock(lock_); |
269 Message msg; | 290 Message msg; |
270 msg.message = message; | 291 msg.message = message; |
271 if (!sent_message_port_ids.empty()) { | 292 msg.ports = CreatePorts(sent_message_ports, new_routing_ids, |
272 msg.ports.resize(sent_message_port_ids.size()); | 293 main_thread_task_runner_.get()); |
273 for (size_t i = 0; i < sent_message_port_ids.size(); ++i) { | |
274 msg.ports[i] = new WebMessagePortChannelImpl( | |
275 new_routing_ids[i], sent_message_port_ids[i], | |
276 main_thread_task_runner_.get()); | |
277 } | |
278 } | |
279 | 294 |
280 bool was_empty = message_queue_.empty(); | 295 bool was_empty = message_queue_.empty(); |
281 message_queue_.push(msg); | 296 message_queue_.push(msg); |
282 if (client_ && was_empty) | 297 if (client_ && was_empty) |
283 client_->messageAvailable(); | 298 client_->messageAvailable(); |
284 } | 299 } |
285 | 300 |
286 void WebMessagePortChannelImpl::OnMessagesQueued() { | 301 void WebMessagePortChannelImpl::OnMessagesQueued() { |
287 std::vector<QueuedMessage> queued_messages; | 302 std::vector<QueuedMessage> queued_messages; |
288 | 303 |
289 { | 304 { |
290 base::AutoLock auto_lock(lock_); | 305 base::AutoLock auto_lock(lock_); |
291 queued_messages.reserve(message_queue_.size()); | 306 queued_messages.reserve(message_queue_.size()); |
292 while (!message_queue_.empty()) { | 307 while (!message_queue_.empty()) { |
293 MessagePortMessage message = message_queue_.front().message; | 308 MessagePortMessage message = message_queue_.front().message; |
294 const std::vector<WebMessagePortChannelImpl*>& channel_array = | 309 std::vector<TransferredMessagePort> ports = |
295 message_queue_.front().ports; | 310 ExtractMessagePortIDs(message_queue_.front().ports); |
296 std::vector<int> port_ids(channel_array.size()); | 311 queued_messages.push_back(std::make_pair(message, ports)); |
297 for (size_t i = 0; i < channel_array.size(); ++i) { | |
298 port_ids[i] = channel_array[i]->message_port_id(); | |
299 channel_array[i]->QueueMessages(); | |
300 } | |
301 queued_messages.push_back(std::make_pair(message, port_ids)); | |
302 message_queue_.pop(); | 312 message_queue_.pop(); |
303 } | 313 } |
304 } | 314 } |
305 | 315 |
306 Send(new MessagePortHostMsg_SendQueuedMessages( | 316 Send(new MessagePortHostMsg_SendQueuedMessages( |
307 message_port_id_, queued_messages)); | 317 message_port_id_, queued_messages)); |
308 | 318 |
309 message_port_id_ = MSG_ROUTING_NONE; | 319 message_port_id_ = MSG_ROUTING_NONE; |
310 | 320 |
311 Release(); | 321 Release(); |
312 ChildProcess::current()->ReleaseProcess(); | 322 ChildProcess::current()->ReleaseProcess(); |
313 } | 323 } |
314 | 324 |
315 WebMessagePortChannelImpl::Message::Message() {} | 325 WebMessagePortChannelImpl::Message::Message() {} |
316 | 326 |
317 WebMessagePortChannelImpl::Message::~Message() {} | 327 WebMessagePortChannelImpl::Message::~Message() {} |
318 | 328 |
319 } // namespace content | 329 } // namespace content |
OLD | NEW |