diff options
author | mpcomplete@google.com <mpcomplete@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-18 22:56:58 +0000 |
---|---|---|
committer | mpcomplete@google.com <mpcomplete@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-18 22:56:58 +0000 |
commit | 1f70f0ca51d1c61d3a775507b2b69dcdf60e77df (patch) | |
tree | 41659daa24b3e9af8996b2782dffead89fdcc63c /chrome/browser/extensions | |
parent | 11de3e98153ad8dcb9e6628e527f7bfb2ca0a8ed (diff) | |
download | chromium_src-1f70f0ca51d1c61d3a775507b2b69dcdf60e77df.zip chromium_src-1f70f0ca51d1c61d3a775507b2b69dcdf60e77df.tar.gz chromium_src-1f70f0ca51d1c61d3a775507b2b69dcdf60e77df.tar.bz2 |
Send port-closed notification when a frame with ports unloads.
Also add onLoad and onUnload chrome Event to our bindings, so we can add
listeners to these events without needing a DOM. These don't hook into the
window "unload" event, so we no longer prevent Chrome's sudden termination of
tabs on shutdown.
BUG=12686
TEST=no
Review URL: http://codereview.chromium.org/125280
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@18765 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/extensions')
-rw-r--r-- | chrome/browser/extensions/extension_message_service.cc | 33 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_message_service.h | 37 |
2 files changed, 42 insertions, 28 deletions
diff --git a/chrome/browser/extensions/extension_message_service.cc b/chrome/browser/extensions/extension_message_service.cc index 33fbcf2..85f8146 100644 --- a/chrome/browser/extensions/extension_message_service.cc +++ b/chrome/browser/extensions/extension_message_service.cc @@ -291,13 +291,28 @@ int ExtensionMessageService::OpenAutomationChannelToExtension( return port2_id; } -void ExtensionMessageService::CloseAutomationChannel(int port_id) { +void ExtensionMessageService::CloseChannel(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)); + // Note: The channel might be gone already, if the other side closed first. + MessageChannelMap::iterator it = channels_.find(GET_CHANNEL_ID(port_id)); + if (it != channels_.end()) + CloseChannelImpl(it, port_id); +} + +void ExtensionMessageService::CloseChannelImpl( + MessageChannelMap::iterator channel_iter, int port_id) { + DCHECK_EQ(MessageLoop::current()->type(), MessageLoop::TYPE_UI); + + // Notify the other side. + if (port_id == GET_CHANNEL_PORT1(channel_iter->first)) { + DispatchOnDisconnect(channel_iter->second.port2, port_id); + } else { + DCHECK_EQ(port_id, GET_CHANNEL_PORT2(channel_iter->first)); + DispatchOnDisconnect(channel_iter->second.port1, port_id); + } + + channels_.erase(channel_iter); } void ExtensionMessageService::PostMessageFromRenderer( @@ -366,13 +381,9 @@ void ExtensionMessageService::Observe(NotificationType type, it != channels_.end(); ) { MessageChannelMap::iterator current = it++; if (current->second.port1 == renderer) { - DispatchOnDisconnect(current->second.port2, - GET_CHANNEL_PORT1(current->first)); - channels_.erase(current); + CloseChannelImpl(current, GET_CHANNEL_PORT1(current->first)); } else if (current->second.port2 == renderer) { - DispatchOnDisconnect(current->second.port1, - GET_CHANNEL_PORT2(current->first)); - channels_.erase(current); + CloseChannelImpl(current, GET_CHANNEL_PORT2(current->first)); } } } diff --git a/chrome/browser/extensions/extension_message_service.h b/chrome/browser/extensions/extension_message_service.h index dde7280..f128103 100644 --- a/chrome/browser/extensions/extension_message_service.h +++ b/chrome/browser/extensions/extension_message_service.h @@ -54,22 +54,17 @@ class ExtensionMessageService : public NotificationObserver { void AddEventListener(std::string event_name, int render_process_id); void RemoveEventListener(std::string event_name, int render_process_id); - // Closes an extension channel for test automation. - void CloseAutomationChannel(int port_id); + // Closes the message channel associated with the given port, and notifies + // the other side. + void CloseChannel(int port_id); // Sends a message from a renderer to the given port. - // TODO(mpcomplete): include the source tab. void PostMessageFromRenderer(int port_id, const std::string& message); // Send an event to every registered extension renderer. void DispatchEventToRenderers( const std::string& event_name, const std::string& event_args); - // NotificationObserver interface. - void Observe(NotificationType type, - const NotificationSource& source, - const NotificationDetails& details); - // Given an extension's ID, opens a channel between the given automation // "port" and that extension. Returns a channel ID to be used for posting // messages between the processes, or -1 if the extension doesn't exist. @@ -78,6 +73,11 @@ class ExtensionMessageService : public NotificationObserver { const std::string& extension_id, IPC::Message::Sender* source); + // NotificationObserver interface. + void Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details); + // --- IO thread only: // Given an extension's ID, opens a channel between the given renderer "port" @@ -89,6 +89,16 @@ class ExtensionMessageService : public NotificationObserver { ResourceMessageFilter* source); private: + // The connection between two ports. It is possible that both ports + // refer to the same renderer. + struct MessageChannel { + IPC::Message::Sender* port1; + IPC::Message::Sender* port2; + }; + + // A map of channel ID to its channel object. + typedef std::map<int, MessageChannel> MessageChannelMap; + // Allocates a pair of port ids. // NOTE: this can be called from any thread. void AllocatePortIdPair(int* port1, int* port2); @@ -97,6 +107,8 @@ class ExtensionMessageService : public NotificationObserver { // NOTE: this can be called from any thread. int GetProcessIdForExtension(const std::string& extension_id); + void CloseChannelImpl(MessageChannelMap::iterator channel_iter, int port_id); + int OpenChannelToExtensionImpl(const std::string& extension_id, IPC::Message::Sender* source); @@ -136,15 +148,6 @@ class ExtensionMessageService : public NotificationObserver { int source_routing_id, int source_port_id, IPC::Message::Sender* source, int dest_port_id, int dest_process_id, int source_process_id); - // The connection between two ports. It is possible that both ports - // refer to the same renderer. - struct MessageChannel { - IPC::Message::Sender* port1; - IPC::Message::Sender* port2; - }; - - // A map of channel ID to its channel object. - typedef std::map<int, MessageChannel> MessageChannelMap; MessageChannelMap channels_; // True if Init has been called. |