summaryrefslogtreecommitdiffstats
path: root/chrome/browser/extensions
diff options
context:
space:
mode:
authormpcomplete@google.com <mpcomplete@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-18 22:56:58 +0000
committermpcomplete@google.com <mpcomplete@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-18 22:56:58 +0000
commit1f70f0ca51d1c61d3a775507b2b69dcdf60e77df (patch)
tree41659daa24b3e9af8996b2782dffead89fdcc63c /chrome/browser/extensions
parent11de3e98153ad8dcb9e6628e527f7bfb2ca0a8ed (diff)
downloadchromium_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.cc33
-rw-r--r--chrome/browser/extensions/extension_message_service.h37
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.