diff options
author | mpcomplete@google.com <mpcomplete@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-05-19 18:52:50 +0000 |
---|---|---|
committer | mpcomplete@google.com <mpcomplete@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-05-19 18:52:50 +0000 |
commit | f44265b0b203289b76b7d28b46bbfed1708829ea (patch) | |
tree | f4cd4bb88f20825863c90ec281bf48cb02cf8bd5 /chrome/browser/extensions/extension_message_service.cc | |
parent | 0b7b45d3b8642aa9d3acb422ae7ed7efd3c18f73 (diff) | |
download | chromium_src-f44265b0b203289b76b7d28b46bbfed1708829ea.zip chromium_src-f44265b0b203289b76b7d28b46bbfed1708829ea.tar.gz chromium_src-f44265b0b203289b76b7d28b46bbfed1708829ea.tar.bz2 |
Allow connecting and messaging with extension ports by funneling external
ports through the automation postMessage interface.
See original review at: http://codereview.chromium.org/113461
Patch by Siggi Asgeirsson <sigurdur.asgeirsson@gmail.com>
Review URL: http://codereview.chromium.org/113538
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@16396 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/extensions/extension_message_service.cc')
-rw-r--r-- | chrome/browser/extensions/extension_message_service.cc | 76 |
1 files changed, 67 insertions, 9 deletions
diff --git a/chrome/browser/extensions/extension_message_service.cc b/chrome/browser/extensions/extension_message_service.cc index 9c4f2b5..08dd703 100644 --- a/chrome/browser/extensions/extension_message_service.cc +++ b/chrome/browser/extensions/extension_message_service.cc @@ -111,6 +111,22 @@ void ExtensionMessageService::RemoveEventListener(std::string event_name, listeners_[event_name].erase(render_process_id); } +void ExtensionMessageService::AllocatePortIdPair(int* port1, int* port2) { + AutoLock lock(next_port_id_lock_); + + // TODO(mpcomplete): what happens when this wraps? + int port1_id = next_port_id_++; + int port2_id = next_port_id_++; + + DCHECK(IS_PORT1_ID(port1_id)); + DCHECK(GET_OPPOSITE_PORT_ID(port1_id) == port2_id); + DCHECK(GET_OPPOSITE_PORT_ID(port2_id) == port1_id); + DCHECK(GET_CHANNEL_ID(port1_id) == GET_CHANNEL_ID(port2_id)); + + *port1 = port1_id; + *port2 = port2_id; +} + int ExtensionMessageService::GetProcessIdForExtension( const std::string& extension_id) { AutoLock lock(process_ids_lock_); @@ -149,13 +165,9 @@ int ExtensionMessageService::OpenChannelToExtension( DCHECK(initialized_); // Create a channel ID for both sides of the channel. - // TODO(mpcomplete): what happens when this wraps? - int port1_id = next_port_id_++; - int port2_id = next_port_id_++; - DCHECK(IS_PORT1_ID(port1_id)); - DCHECK(GET_OPPOSITE_PORT_ID(port1_id) == port2_id); - DCHECK(GET_OPPOSITE_PORT_ID(port2_id) == port1_id); - DCHECK(GET_CHANNEL_ID(port1_id) == GET_CHANNEL_ID(port2_id)); + int port1_id = -1; + int port2_id = -1; + AllocatePortIdPair(&port1_id, &port2_id); ui_loop_->PostTask(FROM_HERE, NewRunnableMethod(this, &ExtensionMessageService::OpenChannelOnUIThread, @@ -167,10 +179,19 @@ int ExtensionMessageService::OpenChannelToExtension( void ExtensionMessageService::OpenChannelOnUIThread( int source_routing_id, int source_port_id, int source_process_id, int dest_port_id, int dest_process_id) { + RenderProcessHost* source = RenderProcessHost::FromID(source_process_id); + OpenChannelOnUIThreadImpl(source_routing_id, source_port_id, + source, dest_port_id, dest_process_id, + source_process_id); +} + +void ExtensionMessageService::OpenChannelOnUIThreadImpl( + int source_routing_id, int source_port_id, IPC::Message::Sender* source, + int dest_port_id, int dest_process_id, int source_process_id) { DCHECK_EQ(MessageLoop::current()->type(), MessageLoop::TYPE_UI); MessageChannel channel; - channel.port1 = RenderProcessHost::FromID(source_process_id); + channel.port1 = source; channel.port2 = RenderProcessHost::FromID(dest_process_id); if (!channel.port1 || !channel.port2) { // One of the processes could have been closed while posting this task. @@ -192,6 +213,43 @@ void ExtensionMessageService::OpenChannelOnUIThread( tab_json)); } +int ExtensionMessageService::OpenAutomationChannelToExtension( + int source_process_id, int routing_id, const std::string& extension_id, + IPC::Message::Sender* source) { + DCHECK_EQ(MessageLoop::current()->type(), MessageLoop::TYPE_UI); + + // Lookup the targeted extension process. + int process_id = GetProcessIdForExtension(extension_id); + if (process_id == -1) + return -1; + + DCHECK(initialized_); + + int port1_id = -1; + int port2_id = -1; + // Create a channel ID for both sides of the channel. + AllocatePortIdPair(&port1_id, &port2_id); + + // TODO(siggi): The source process- and routing ids are used to + // describe the originating tab to the target extension. + // This isn't really appropriate here, the originating tab + // information should be supplied by the caller for + // automation-initiated ports. + OpenChannelOnUIThreadImpl(routing_id, port1_id, source, port2_id, + process_id, source_process_id); + + return port2_id; +} + +void ExtensionMessageService::CloseAutomationChannel(int port_id) { + DCHECK_EQ(MessageLoop::current()->type(), MessageLoop::TYPE_UI); + + // TODO(siggi): Cleanup from the tab seems to beat this to the punch. + // DCHECK(channels_[GET_CHANNEL_ID(port_id)].port1 != NULL); + // TODO(siggi): should we notify the other side of the port? + channels_.erase(GET_CHANNEL_ID(port_id)); +} + void ExtensionMessageService::PostMessageFromRenderer( int port_id, const std::string& message) { DCHECK_EQ(MessageLoop::current()->type(), MessageLoop::TYPE_UI); @@ -203,7 +261,7 @@ void ExtensionMessageService::PostMessageFromRenderer( MessageChannel& channel = iter->second; // Figure out which port the ID corresponds to. - RenderProcessHost* dest = + IPC::Message::Sender* dest = IS_PORT1_ID(port_id) ? channel.port1 : channel.port2; int source_port_id = GET_OPPOSITE_PORT_ID(port_id); |