summaryrefslogtreecommitdiffstats
path: root/chrome/browser/extensions/extension_message_service.cc
diff options
context:
space:
mode:
authormpcomplete@google.com <mpcomplete@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-05-19 18:52:50 +0000
committermpcomplete@google.com <mpcomplete@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-05-19 18:52:50 +0000
commitf44265b0b203289b76b7d28b46bbfed1708829ea (patch)
treef4cd4bb88f20825863c90ec281bf48cb02cf8bd5 /chrome/browser/extensions/extension_message_service.cc
parent0b7b45d3b8642aa9d3acb422ae7ed7efd3c18f73 (diff)
downloadchromium_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.cc76
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);