| 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 |