diff options
author | mpcomplete@google.com <mpcomplete@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-17 19:32:43 +0000 |
---|---|---|
committer | mpcomplete@google.com <mpcomplete@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-17 19:32:43 +0000 |
commit | dfcb62a173898e182e2f10ca635deb753977b9f8 (patch) | |
tree | 39d4ca8b82cfc9f39f1726d4b0ad061cb141c516 /chrome/browser/extensions/extension_message_service.cc | |
parent | 851c567a756e96913098ac03d84fb9ea5761558d (diff) | |
download | chromium_src-dfcb62a173898e182e2f10ca635deb753977b9f8.zip chromium_src-dfcb62a173898e182e2f10ca635deb753977b9f8.tar.gz chromium_src-dfcb62a173898e182e2f10ca635deb753977b9f8.tar.bz2 |
Add a port disconnect event for when one side of an extension message port
goes away.
Combine the various ExtensionMessageService IPC message into a single "Invoke"
message.
BUG=12686
TEST=no
Review URL: http://codereview.chromium.org/126234
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@18645 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 | 75 |
1 files changed, 67 insertions, 8 deletions
diff --git a/chrome/browser/extensions/extension_message_service.cc b/chrome/browser/extensions/extension_message_service.cc index 39570a1..33fbcf2 100644 --- a/chrome/browser/extensions/extension_message_service.cc +++ b/chrome/browser/extensions/extension_message_service.cc @@ -24,6 +24,8 @@ // Since we have 2 ports for every channel, we just index channels by half the // port ID. #define GET_CHANNEL_ID(port_id) ((port_id) / 2) +#define GET_CHANNEL_PORT1(channel_id) ((channel_id) * 2) +#define GET_CHANNEL_PORT2(channel_id) ((channel_id) * 2 + 1) // Port1 is always even, port2 is always odd. #define IS_PORT1_ID(port_id) (((port_id) & 1) == 0) @@ -40,6 +42,43 @@ struct SingletonData { Lock lock; InstanceMap map; }; + +static void DispatchOnConnect(IPC::Message::Sender* channel, int source_port_id, + const std::string& tab_json) { + ListValue args; + args.Set(0, Value::CreateIntegerValue(source_port_id)); + args.Set(1, Value::CreateStringValue(tab_json)); + channel->Send(new ViewMsg_ExtensionMessageInvoke( + ExtensionMessageService::kDispatchOnConnect, args)); +} + +static void DispatchOnDisconnect(IPC::Message::Sender* channel, + int source_port_id) { + ListValue args; + args.Set(0, Value::CreateIntegerValue(source_port_id)); + channel->Send(new ViewMsg_ExtensionMessageInvoke( + ExtensionMessageService::kDispatchOnDisconnect, args)); +} + +static void DispatchOnMessage(IPC::Message::Sender* channel, + const std::string& message, int source_port_id) { + ListValue args; + args.Set(0, Value::CreateStringValue(message)); + args.Set(1, Value::CreateIntegerValue(source_port_id)); + channel->Send(new ViewMsg_ExtensionMessageInvoke( + ExtensionMessageService::kDispatchOnMessage, args)); +} + +static void DispatchEvent(IPC::Message::Sender* channel, + const std::string& event_name, + const std::string& event_args) { + ListValue args; + args.Set(0, Value::CreateStringValue(event_name)); + args.Set(1, Value::CreateStringValue(event_args)); + channel->Send(new ViewMsg_ExtensionMessageInvoke( + ExtensionMessageService::kDispatchEvent, args)); +} + } // namespace // Since ExtensionMessageService is a collection of Singletons, we don't need to @@ -49,6 +88,16 @@ template <> struct RunnableMethodTraits<ExtensionMessageService> { static void ReleaseCallee(ExtensionMessageService*) {} }; + +const char ExtensionMessageService::kDispatchOnConnect[] = + "chrome.Port.dispatchOnConnect_"; +const char ExtensionMessageService::kDispatchOnDisconnect[] = + "chrome.Port.dispatchOnDisconnect_"; +const char ExtensionMessageService::kDispatchOnMessage[] = + "chrome.Port.dispatchOnMessage_"; +const char ExtensionMessageService::kDispatchEvent[] = + "chrome.Event.dispatchJSON_"; + // static ExtensionMessageService* ExtensionMessageService::GetInstance( URLRequestContext* context) { @@ -121,6 +170,10 @@ void ExtensionMessageService::AllocatePortIdPair(int* port1, int* port2) { DCHECK(GET_OPPOSITE_PORT_ID(port2_id) == port1_id); DCHECK(GET_CHANNEL_ID(port1_id) == GET_CHANNEL_ID(port2_id)); + int channel_id = GET_CHANNEL_ID(port1_id); + DCHECK(GET_CHANNEL_PORT1(channel_id) == port1_id); + DCHECK(GET_CHANNEL_PORT2(channel_id) == port2_id); + *port1 = port1_id; *port2 = port2_id; } @@ -206,9 +259,8 @@ void ExtensionMessageService::OpenChannelOnUIThreadImpl( JSONWriter::Write(tab_value, false, &tab_json); } - // Send each process the id for the opposite port. - channel.port2->Send(new ViewMsg_ExtensionHandleConnect(source_port_id, - tab_json)); + // Send the process the id for the opposite port. + DispatchOnConnect(channel.port2, source_port_id, tab_json); } int ExtensionMessageService::OpenAutomationChannelToExtension( @@ -263,7 +315,7 @@ void ExtensionMessageService::PostMessageFromRenderer( IS_PORT1_ID(port_id) ? channel.port1 : channel.port2; int source_port_id = GET_OPPOSITE_PORT_ID(port_id); - dest->Send(new ViewMsg_ExtensionHandleMessage(message, source_port_id)); + DispatchOnMessage(dest, message, source_port_id); } void ExtensionMessageService::DispatchEventToRenderers( @@ -283,7 +335,7 @@ void ExtensionMessageService::DispatchEventToRenderers( continue; } - renderer->Send(new ViewMsg_ExtensionHandleEvent(event_name, event_args)); + DispatchEvent(renderer, event_name, event_args); } } @@ -308,12 +360,19 @@ void ExtensionMessageService::Observe(NotificationType type, } } - // Close any channels that share this renderer. - // TODO(mpcomplete): should we notify the other side of the port? + // Close any channels that share this renderer. We notify the opposite + // port that his pair has closed. for (MessageChannelMap::iterator it = channels_.begin(); it != channels_.end(); ) { MessageChannelMap::iterator current = it++; - if (current->second.port1 == renderer || current->second.port2 == renderer) + if (current->second.port1 == renderer) { + DispatchOnDisconnect(current->second.port2, + GET_CHANNEL_PORT1(current->first)); + channels_.erase(current); + } else if (current->second.port2 == renderer) { + DispatchOnDisconnect(current->second.port1, + GET_CHANNEL_PORT2(current->first)); channels_.erase(current); + } } } |