| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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 "chrome/browser/extensions/extension_message_service.h" | 5 #include "chrome/browser/extensions/extension_message_service.h" |
| 6 | 6 |
| 7 #include "base/json_writer.h" | 7 #include "base/json_writer.h" |
| 8 #include "base/singleton.h" | 8 #include "base/singleton.h" |
| 9 #include "base/stl_util-inl.h" | 9 #include "base/stl_util-inl.h" |
| 10 #include "base/values.h" | 10 #include "base/values.h" |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 53 ExtensionMessageService::MessagePort receiver; | 53 ExtensionMessageService::MessagePort receiver; |
| 54 }; | 54 }; |
| 55 | 55 |
| 56 | 56 |
| 57 namespace { | 57 namespace { |
| 58 | 58 |
| 59 static void DispatchOnConnect(const ExtensionMessageService::MessagePort& port, | 59 static void DispatchOnConnect(const ExtensionMessageService::MessagePort& port, |
| 60 int dest_port_id, | 60 int dest_port_id, |
| 61 const std::string& channel_name, | 61 const std::string& channel_name, |
| 62 const std::string& tab_json, | 62 const std::string& tab_json, |
| 63 const std::string& extension_id) { | 63 const std::string& source_extension_id, |
| 64 const std::string& target_extension_id) { |
| 64 ListValue args; | 65 ListValue args; |
| 65 args.Set(0, Value::CreateIntegerValue(dest_port_id)); | 66 args.Set(0, Value::CreateIntegerValue(dest_port_id)); |
| 66 args.Set(1, Value::CreateStringValue(channel_name)); | 67 args.Set(1, Value::CreateStringValue(channel_name)); |
| 67 args.Set(2, Value::CreateStringValue(tab_json)); | 68 args.Set(2, Value::CreateStringValue(tab_json)); |
| 68 args.Set(3, Value::CreateStringValue(extension_id)); | 69 args.Set(3, Value::CreateStringValue(source_extension_id)); |
| 70 args.Set(4, Value::CreateStringValue(target_extension_id)); |
| 69 CHECK(port.sender); | 71 CHECK(port.sender); |
| 70 port.sender->Send(new ViewMsg_ExtensionMessageInvoke( | 72 port.sender->Send(new ViewMsg_ExtensionMessageInvoke( |
| 71 port.routing_id, ExtensionMessageService::kDispatchOnConnect, args)); | 73 port.routing_id, ExtensionMessageService::kDispatchOnConnect, args)); |
| 72 } | 74 } |
| 73 | 75 |
| 74 static void DispatchOnDisconnect( | 76 static void DispatchOnDisconnect( |
| 75 const ExtensionMessageService::MessagePort& port, int source_port_id) { | 77 const ExtensionMessageService::MessagePort& port, int source_port_id) { |
| 76 ListValue args; | 78 ListValue args; |
| 77 args.Set(0, Value::CreateIntegerValue(source_port_id)); | 79 args.Set(0, Value::CreateIntegerValue(source_port_id)); |
| 78 port.sender->Send(new ViewMsg_ExtensionMessageInvoke( | 80 port.sender->Send(new ViewMsg_ExtensionMessageInvoke( |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 186 | 188 |
| 187 int channel_id = GET_CHANNEL_ID(port1_id); | 189 int channel_id = GET_CHANNEL_ID(port1_id); |
| 188 DCHECK(GET_CHANNEL_OPENER_ID(channel_id) == port1_id); | 190 DCHECK(GET_CHANNEL_OPENER_ID(channel_id) == port1_id); |
| 189 DCHECK(GET_CHANNEL_RECEIVERS_ID(channel_id) == port2_id); | 191 DCHECK(GET_CHANNEL_RECEIVERS_ID(channel_id) == port2_id); |
| 190 | 192 |
| 191 *port1 = port1_id; | 193 *port1 = port1_id; |
| 192 *port2 = port2_id; | 194 *port2 = port2_id; |
| 193 } | 195 } |
| 194 | 196 |
| 195 int ExtensionMessageService::OpenChannelToExtension( | 197 int ExtensionMessageService::OpenChannelToExtension( |
| 196 int routing_id, const std::string& extension_id, | 198 int routing_id, const std::string& source_extension_id, |
| 199 const std::string& target_extension_id, |
| 197 const std::string& channel_name, ResourceMessageFilter* source) { | 200 const std::string& channel_name, ResourceMessageFilter* source) { |
| 198 DCHECK_EQ(MessageLoop::current(), | 201 DCHECK_EQ(MessageLoop::current(), |
| 199 ChromeThread::GetMessageLoop(ChromeThread::IO)); | 202 ChromeThread::GetMessageLoop(ChromeThread::IO)); |
| 200 | 203 |
| 201 // Create a channel ID for both sides of the channel. | 204 // Create a channel ID for both sides of the channel. |
| 202 int port1_id = -1; | 205 int port1_id = -1; |
| 203 int port2_id = -1; | 206 int port2_id = -1; |
| 204 AllocatePortIdPair(&port1_id, &port2_id); | 207 AllocatePortIdPair(&port1_id, &port2_id); |
| 205 | 208 |
| 206 // Each side of the port is given his own port ID. When they send messages, | 209 // Each side of the port is given his own port ID. When they send messages, |
| 207 // we convert to the opposite port ID. See PostMessageFromRenderer. | 210 // we convert to the opposite port ID. See PostMessageFromRenderer. |
| 208 ui_loop_->PostTask(FROM_HERE, | 211 ui_loop_->PostTask(FROM_HERE, |
| 209 NewRunnableMethod(this, | 212 NewRunnableMethod(this, |
| 210 &ExtensionMessageService::OpenChannelToExtensionOnUIThread, | 213 &ExtensionMessageService::OpenChannelToExtensionOnUIThread, |
| 211 source->id(), routing_id, port2_id, extension_id, channel_name)); | 214 source->id(), routing_id, port2_id, source_extension_id, |
| 215 target_extension_id, channel_name)); |
| 212 | 216 |
| 213 return port1_id; | 217 return port1_id; |
| 214 } | 218 } |
| 215 | 219 |
| 216 int ExtensionMessageService::OpenChannelToTab(int routing_id, | 220 int ExtensionMessageService::OpenChannelToTab(int routing_id, |
| 217 int tab_id, | 221 int tab_id, |
| 218 const std::string& extension_id, | 222 const std::string& extension_id, |
| 219 const std::string& channel_name, | 223 const std::string& channel_name, |
| 220 ResourceMessageFilter* source) { | 224 ResourceMessageFilter* source) { |
| 221 DCHECK_EQ(MessageLoop::current(), | 225 DCHECK_EQ(MessageLoop::current(), |
| (...skipping 10 matching lines...) Expand all Loading... |
| 232 NewRunnableMethod(this, | 236 NewRunnableMethod(this, |
| 233 &ExtensionMessageService::OpenChannelToTabOnUIThread, | 237 &ExtensionMessageService::OpenChannelToTabOnUIThread, |
| 234 source->id(), routing_id, port2_id, tab_id, extension_id, | 238 source->id(), routing_id, port2_id, tab_id, extension_id, |
| 235 channel_name)); | 239 channel_name)); |
| 236 | 240 |
| 237 return port1_id; | 241 return port1_id; |
| 238 } | 242 } |
| 239 | 243 |
| 240 void ExtensionMessageService::OpenChannelToExtensionOnUIThread( | 244 void ExtensionMessageService::OpenChannelToExtensionOnUIThread( |
| 241 int source_process_id, int source_routing_id, int receiver_port_id, | 245 int source_process_id, int source_routing_id, int receiver_port_id, |
| 242 const std::string& extension_id, const std::string& channel_name) { | 246 const std::string& source_extension_id, |
| 247 const std::string& target_extension_id, |
| 248 const std::string& channel_name) { |
| 243 if (!profile_) | 249 if (!profile_) |
| 244 return; | 250 return; |
| 245 | 251 |
| 246 RenderProcessHost* source = RenderProcessHost::FromID(source_process_id); | 252 RenderProcessHost* source = RenderProcessHost::FromID(source_process_id); |
| 247 MessagePort receiver( | 253 MessagePort receiver( |
| 248 profile_->GetExtensionProcessManager()->GetExtensionProcess(extension_id), | 254 profile_->GetExtensionProcessManager()->GetExtensionProcess( |
| 255 target_extension_id), |
| 249 MSG_ROUTING_CONTROL); | 256 MSG_ROUTING_CONTROL); |
| 250 receiver.debug_info = 1; | 257 receiver.debug_info = 1; |
| 251 TabContents* source_contents = tab_util::GetTabContentsByID( | 258 TabContents* source_contents = tab_util::GetTabContentsByID( |
| 252 source_process_id, source_routing_id); | 259 source_process_id, source_routing_id); |
| 253 OpenChannelOnUIThreadImpl(source, source_contents, | 260 OpenChannelOnUIThreadImpl(source, source_contents, |
| 254 receiver, receiver_port_id, | 261 receiver, receiver_port_id, |
| 255 extension_id, channel_name); | 262 source_extension_id, target_extension_id, |
| 263 channel_name); |
| 256 } | 264 } |
| 257 | 265 |
| 258 void ExtensionMessageService::OpenChannelToTabOnUIThread( | 266 void ExtensionMessageService::OpenChannelToTabOnUIThread( |
| 259 int source_process_id, int source_routing_id, int receiver_port_id, | 267 int source_process_id, int source_routing_id, int receiver_port_id, |
| 260 int tab_id, const std::string& extension_id, | 268 int tab_id, const std::string& extension_id, |
| 261 const std::string& channel_name) { | 269 const std::string& channel_name) { |
| 262 RenderProcessHost* source = RenderProcessHost::FromID(source_process_id); | 270 RenderProcessHost* source = RenderProcessHost::FromID(source_process_id); |
| 263 TabContents* contents; | 271 TabContents* contents; |
| 264 MessagePort receiver; | 272 MessagePort receiver; |
| 265 receiver.debug_info = 2; | 273 receiver.debug_info = 2; |
| 266 if (ExtensionTabUtil::GetTabById(tab_id, source->profile(), | 274 if (ExtensionTabUtil::GetTabById(tab_id, source->profile(), |
| 267 NULL, NULL, &contents, NULL)) { | 275 NULL, NULL, &contents, NULL)) { |
| 268 receiver.sender = contents->render_view_host(); | 276 receiver.sender = contents->render_view_host(); |
| 269 receiver.routing_id = contents->render_view_host()->routing_id(); | 277 receiver.routing_id = contents->render_view_host()->routing_id(); |
| 270 receiver.debug_info = 3; | 278 receiver.debug_info = 3; |
| 271 } | 279 } |
| 272 TabContents* source_contents = tab_util::GetTabContentsByID( | 280 TabContents* source_contents = tab_util::GetTabContentsByID( |
| 273 source_process_id, source_routing_id); | 281 source_process_id, source_routing_id); |
| 274 OpenChannelOnUIThreadImpl(source, source_contents, | 282 OpenChannelOnUIThreadImpl(source, source_contents, |
| 275 receiver, receiver_port_id, | 283 receiver, receiver_port_id, |
| 276 extension_id, channel_name); | 284 extension_id, extension_id, channel_name); |
| 277 } | 285 } |
| 278 | 286 |
| 279 bool ExtensionMessageService::OpenChannelOnUIThreadImpl( | 287 bool ExtensionMessageService::OpenChannelOnUIThreadImpl( |
| 280 IPC::Message::Sender* source, TabContents* source_contents, | 288 IPC::Message::Sender* source, TabContents* source_contents, |
| 281 const MessagePort& receiver, int receiver_port_id, | 289 const MessagePort& receiver, int receiver_port_id, |
| 282 const std::string& extension_id, const std::string& channel_name) { | 290 const std::string& source_extension_id, |
| 291 const std::string& target_extension_id, |
| 292 const std::string& channel_name) { |
| 283 DCHECK_EQ(MessageLoop::current()->type(), MessageLoop::TYPE_UI); | 293 DCHECK_EQ(MessageLoop::current()->type(), MessageLoop::TYPE_UI); |
| 284 | 294 |
| 285 // TODO(mpcomplete): notify source if reciever doesn't exist | 295 // TODO(mpcomplete): notify source if reciever doesn't exist |
| 286 if (!source) | 296 if (!source) |
| 287 return false; // Closed while in flight. | 297 return false; // Closed while in flight. |
| 288 | 298 |
| 289 if (!receiver.sender) { | 299 if (!receiver.sender) { |
| 290 // Treat it as a disconnect. | 300 // Treat it as a disconnect. |
| 291 DispatchOnDisconnect(MessagePort(source, MSG_ROUTING_CONTROL), | 301 DispatchOnDisconnect(MessagePort(source, MSG_ROUTING_CONTROL), |
| 292 GET_OPPOSITE_PORT_ID(receiver_port_id)); | 302 GET_OPPOSITE_PORT_ID(receiver_port_id)); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 313 DictionaryValue* tab_value = | 323 DictionaryValue* tab_value = |
| 314 ExtensionTabUtil::CreateTabValue(source_contents); | 324 ExtensionTabUtil::CreateTabValue(source_contents); |
| 315 JSONWriter::Write(tab_value, false, &tab_json); | 325 JSONWriter::Write(tab_value, false, &tab_json); |
| 316 } | 326 } |
| 317 | 327 |
| 318 CHECK(receiver.sender); | 328 CHECK(receiver.sender); |
| 319 | 329 |
| 320 // Send the connect event to the receiver. Give it the opener's port ID (the | 330 // Send the connect event to the receiver. Give it the opener's port ID (the |
| 321 // opener has the opposite port ID). | 331 // opener has the opposite port ID). |
| 322 DispatchOnConnect(receiver, receiver_port_id, channel_name, tab_json, | 332 DispatchOnConnect(receiver, receiver_port_id, channel_name, tab_json, |
| 323 extension_id); | 333 source_extension_id, target_extension_id); |
| 324 | 334 |
| 325 return true; | 335 return true; |
| 326 } | 336 } |
| 327 | 337 |
| 328 int ExtensionMessageService::OpenSpecialChannelToExtension( | 338 int ExtensionMessageService::OpenSpecialChannelToExtension( |
| 329 const std::string& extension_id, const std::string& channel_name, | 339 const std::string& extension_id, const std::string& channel_name, |
| 330 IPC::Message::Sender* source) { | 340 IPC::Message::Sender* source) { |
| 331 DCHECK_EQ(MessageLoop::current()->type(), MessageLoop::TYPE_UI); | 341 DCHECK_EQ(MessageLoop::current()->type(), MessageLoop::TYPE_UI); |
| 332 DCHECK(profile_); | 342 DCHECK(profile_); |
| 333 | 343 |
| 334 int port1_id = -1; | 344 int port1_id = -1; |
| 335 int port2_id = -1; | 345 int port2_id = -1; |
| 336 // Create a channel ID for both sides of the channel. | 346 // Create a channel ID for both sides of the channel. |
| 337 AllocatePortIdPair(&port1_id, &port2_id); | 347 AllocatePortIdPair(&port1_id, &port2_id); |
| 338 | 348 |
| 339 MessagePort receiver( | 349 MessagePort receiver( |
| 340 profile_->GetExtensionProcessManager()-> | 350 profile_->GetExtensionProcessManager()-> |
| 341 GetExtensionProcess(extension_id), | 351 GetExtensionProcess(extension_id), |
| 342 MSG_ROUTING_CONTROL); | 352 MSG_ROUTING_CONTROL); |
| 343 receiver.debug_info = 4; | 353 receiver.debug_info = 4; |
| 344 if (!OpenChannelOnUIThreadImpl( | 354 if (!OpenChannelOnUIThreadImpl( |
| 345 source, NULL, receiver, port2_id, extension_id, channel_name)) | 355 source, NULL, receiver, port2_id, extension_id, extension_id, |
| 356 channel_name)) |
| 346 return -1; | 357 return -1; |
| 347 | 358 |
| 348 return port1_id; | 359 return port1_id; |
| 349 } | 360 } |
| 350 | 361 |
| 351 int ExtensionMessageService::OpenSpecialChannelToTab( | 362 int ExtensionMessageService::OpenSpecialChannelToTab( |
| 352 const std::string& extension_id, const std::string& channel_name, | 363 const std::string& extension_id, const std::string& channel_name, |
| 353 TabContents* target_tab_contents, IPC::Message::Sender* source) { | 364 TabContents* target_tab_contents, IPC::Message::Sender* source) { |
| 354 DCHECK_EQ(MessageLoop::current()->type(), MessageLoop::TYPE_UI); | 365 DCHECK_EQ(MessageLoop::current()->type(), MessageLoop::TYPE_UI); |
| 355 DCHECK(target_tab_contents); | 366 DCHECK(target_tab_contents); |
| 356 | 367 |
| 357 int port1_id = -1; | 368 int port1_id = -1; |
| 358 int port2_id = -1; | 369 int port2_id = -1; |
| 359 // Create a channel ID for both sides of the channel. | 370 // Create a channel ID for both sides of the channel. |
| 360 AllocatePortIdPair(&port1_id, &port2_id); | 371 AllocatePortIdPair(&port1_id, &port2_id); |
| 361 | 372 |
| 362 MessagePort receiver( | 373 MessagePort receiver( |
| 363 target_tab_contents->render_view_host(), | 374 target_tab_contents->render_view_host(), |
| 364 target_tab_contents->render_view_host()->routing_id()); | 375 target_tab_contents->render_view_host()->routing_id()); |
| 365 receiver.debug_info = 5; | 376 receiver.debug_info = 5; |
| 366 if (!OpenChannelOnUIThreadImpl(source, NULL, | 377 if (!OpenChannelOnUIThreadImpl(source, NULL, |
| 367 receiver, port2_id, | 378 receiver, port2_id, |
| 368 extension_id, channel_name)) | 379 extension_id, extension_id, channel_name)) |
| 369 return -1; | 380 return -1; |
| 370 | 381 |
| 371 return port1_id; | 382 return port1_id; |
| 372 } | 383 } |
| 373 | 384 |
| 374 void ExtensionMessageService::CloseChannel(int port_id) { | 385 void ExtensionMessageService::CloseChannel(int port_id) { |
| 375 DCHECK_EQ(MessageLoop::current()->type(), MessageLoop::TYPE_UI); | 386 DCHECK_EQ(MessageLoop::current()->type(), MessageLoop::TYPE_UI); |
| 376 | 387 |
| 377 // Note: The channel might be gone already, if the other side closed first. | 388 // Note: The channel might be gone already, if the other side closed first. |
| 378 MessageChannelMap::iterator it = channels_.find(GET_CHANNEL_ID(port_id)); | 389 MessageChannelMap::iterator it = channels_.find(GET_CHANNEL_ID(port_id)); |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 497 | 508 |
| 498 if (current->second->opener.sender == sender) { | 509 if (current->second->opener.sender == sender) { |
| 499 CloseChannelImpl(current, GET_CHANNEL_OPENER_ID(current->first), | 510 CloseChannelImpl(current, GET_CHANNEL_OPENER_ID(current->first), |
| 500 notify_other_port); | 511 notify_other_port); |
| 501 } else if (current->second->receiver.sender == sender) { | 512 } else if (current->second->receiver.sender == sender) { |
| 502 CloseChannelImpl(current, GET_CHANNEL_RECEIVERS_ID(current->first), | 513 CloseChannelImpl(current, GET_CHANNEL_RECEIVERS_ID(current->first), |
| 503 notify_other_port); | 514 notify_other_port); |
| 504 } | 515 } |
| 505 } | 516 } |
| 506 } | 517 } |
| OLD | NEW |