summaryrefslogtreecommitdiffstats
path: root/chrome/browser/extensions
diff options
context:
space:
mode:
authormpcomplete@chromium.org <mpcomplete@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-07-09 19:26:35 +0000
committermpcomplete@chromium.org <mpcomplete@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-07-09 19:26:35 +0000
commit0f605396ab522e1f2f48824c42bb784e9784d479 (patch)
tree062f717563b296a520791bd29c25fd21038b2920 /chrome/browser/extensions
parent609a1ec621cdcce03328b56e4b744ce9498b2177 (diff)
downloadchromium_src-0f605396ab522e1f2f48824c42bb784e9784d479.zip
chromium_src-0f605396ab522e1f2f48824c42bb784e9784d479.tar.gz
chromium_src-0f605396ab522e1f2f48824c42bb784e9784d479.tar.bz2
Make the API to open a message channel symmetric, so it works the same whether opening from a tab or extension.
Also, move the callback handling back to extension_process_bindings, since I didn't need it in event_bindings to implement this, and it didn't make sense there anyway. BUG=12461 TEST=no Review URL: http://codereview.chromium.org/149237 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@20296 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/extensions')
-rw-r--r--chrome/browser/extensions/extension_browsertests_misc.cc132
-rw-r--r--chrome/browser/extensions/extension_function_dispatcher.cc9
-rw-r--r--chrome/browser/extensions/extension_message_service.cc174
-rw-r--r--chrome/browser/extensions/extension_message_service.h66
-rw-r--r--chrome/browser/extensions/extension_messages_unittest.cc1
-rw-r--r--chrome/browser/extensions/extensions_service_unittest.cc2
6 files changed, 222 insertions, 162 deletions
diff --git a/chrome/browser/extensions/extension_browsertests_misc.cc b/chrome/browser/extensions/extension_browsertests_misc.cc
index b594477..0211b96 100644
--- a/chrome/browser/extensions/extension_browsertests_misc.cc
+++ b/chrome/browser/extensions/extension_browsertests_misc.cc
@@ -17,8 +17,29 @@
#include "chrome/browser/views/frame/browser_view.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/extensions/extension_error_reporter.h"
+#include "chrome/common/notification_service.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/ui_test_utils.h"
+#include "net/base/net_util.h"
+
+// Looks for an ExtensionHost whose URL has the given path component (including
+// leading slash). Also verifies that the expected number of hosts are loaded.
+static ExtensionHost* FindHostWithPath(ExtensionProcessManager* manager,
+ const std::string& path,
+ int expected_hosts) {
+ ExtensionHost* host = NULL;
+ int num_hosts = 0;
+ for (ExtensionProcessManager::const_iterator iter = manager->begin();
+ iter != manager->end(); ++iter) {
+ if ((*iter)->GetURL().path() == path) {
+ EXPECT_FALSE(host);
+ host = *iter;
+ }
+ num_hosts++;
+ }
+ EXPECT_EQ(expected_hosts, num_hosts);
+ return host;
+}
// Tests that toolstrips initializes properly and can run basic extension js.
IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, Toolstrip) {
@@ -31,17 +52,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, Toolstrip) {
// extension has two toolstrips. Find the one that is hosting toolstrip1.html.
ExtensionProcessManager* manager =
browser()->profile()->GetExtensionProcessManager();
- ExtensionHost* host = NULL;
- int num_hosts = 0;
- for (ExtensionProcessManager::const_iterator iter = manager->begin();
- iter != manager->end(); ++iter) {
- if ((*iter)->GetURL().path() == "/toolstrip1.html") {
- ASSERT_FALSE(host);
- host = *iter;
- }
- num_hosts++;
- }
- EXPECT_EQ(2, num_hosts);
+ ExtensionHost* host = FindHostWithPath(manager, "/toolstrip1.html", 2);
// Tell it to run some JavaScript that tests that basic extension code works.
bool result = false;
@@ -105,3 +116,102 @@ IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, TabContents) {
L"testTabsAPI()", &result);
EXPECT_TRUE(result);
}
+
+// Tests that message passing between extensions and tabs works.
+IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, MessagingExtensionTab) {
+ ASSERT_TRUE(LoadExtension(
+ test_data_dir_.AppendASCII("good").AppendASCII("Extensions")
+ .AppendASCII("bjafgdebaacbbbecmhlhpofkepfkgcpa")
+ .AppendASCII("1.0")));
+
+ // Get the ExtensionHost that is hosting our background page.
+ ExtensionProcessManager* manager =
+ browser()->profile()->GetExtensionProcessManager();
+ ExtensionHost* host = FindHostWithPath(manager, "/background.html", 1);
+
+ // Load the tab that will communicate with our background page.
+ ui_test_utils::NavigateToURL(
+ browser(),
+ GURL("chrome-extension://bjafgdebaacbbbecmhlhpofkepfkgcpa/page.html"));
+
+ // First test that tab->extension messaging works.
+ bool result = false;
+ ui_test_utils::ExecuteJavaScriptAndExtractBool(
+ browser()->GetSelectedTabContents()->render_view_host(), L"",
+ L"testPostMessageFromTab()", &result);
+ EXPECT_TRUE(result);
+
+ // Now test extension->tab messaging, with disconnect events.
+ result = false;
+ ui_test_utils::ExecuteJavaScriptAndExtractBool(
+ host->render_view_host(), L"", L"testDisconnect()", &result);
+ EXPECT_TRUE(result);
+
+ result = false;
+ ui_test_utils::ExecuteJavaScriptAndExtractBool(
+ host->render_view_host(), L"", L"testPostMessage()", &result);
+ EXPECT_TRUE(result);
+
+ result = false;
+ ui_test_utils::ExecuteJavaScriptAndExtractBool(
+ host->render_view_host(), L"", L"testDisconnectOnClose()", &result);
+ EXPECT_TRUE(result);
+}
+
+// TODO(mpcomplete): reenable this when content script messaging is fixed:
+// http://code.google.com/p/chromium/issues/detail?id=16228.
+#if 0
+// Tests that message passing between extensions and content scripts works.
+IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, MessagingContentScript) {
+ ASSERT_TRUE(LoadExtension(
+ test_data_dir_.AppendASCII("good").AppendASCII("Extensions")
+ .AppendASCII("bjafgdebaacbbbecmhlhpofkepfkgcpa")
+ .AppendASCII("1.0")));
+
+ UserScriptMaster* master = browser()->profile()->GetUserScriptMaster();
+ if (!master->ScriptsReady()) {
+ // Wait for UserScriptMaster to finish its scan.
+ NotificationRegistrar registrar;
+ registrar.Add(this, NotificationType::USER_SCRIPTS_UPDATED,
+ NotificationService::AllSources());
+ ui_test_utils::RunMessageLoop();
+ }
+ ASSERT_TRUE(master->ScriptsReady());
+
+ // Get the ExtensionHost that is hosting our background page.
+ ExtensionProcessManager* manager =
+ browser()->profile()->GetExtensionProcessManager();
+ ExtensionHost* host = FindHostWithPath(manager, "/background.html", 1);
+
+ // Load the tab whose content script will communicate with our background
+ // page.
+ FilePath test_file;
+ PathService::Get(chrome::DIR_TEST_DATA, &test_file);
+ test_file = test_file.AppendASCII("extensions")
+ .AppendASCII("test_file.html");
+ ui_test_utils::NavigateToURL(browser(), net::FilePathToFileURL(test_file));
+
+ // First test that tab->extension messaging works.
+ bool result = false;
+ ui_test_utils::ExecuteJavaScriptAndExtractBool(
+ browser()->GetSelectedTabContents()->render_view_host(), L"",
+ L"testPostMessageFromTab()", &result);
+ EXPECT_TRUE(result);
+
+ // Now test extension->tab messaging, with disconnect events.
+ result = false;
+ ui_test_utils::ExecuteJavaScriptAndExtractBool(
+ host->render_view_host(), L"", L"testDisconnect()", &result);
+ EXPECT_TRUE(result);
+
+ result = false;
+ ui_test_utils::ExecuteJavaScriptAndExtractBool(
+ host->render_view_host(), L"", L"testPostMessage()", &result);
+ EXPECT_TRUE(result);
+
+ result = false;
+ ui_test_utils::ExecuteJavaScriptAndExtractBool(
+ host->render_view_host(), L"", L"testDisconnectOnClose()", &result);
+ EXPECT_TRUE(result);
+}
+#endif \ No newline at end of file
diff --git a/chrome/browser/extensions/extension_function_dispatcher.cc b/chrome/browser/extensions/extension_function_dispatcher.cc
index 24eacf2..70cb59e 100644
--- a/chrome/browser/extensions/extension_function_dispatcher.cc
+++ b/chrome/browser/extensions/extension_function_dispatcher.cc
@@ -183,12 +183,9 @@ ExtensionFunctionDispatcher::ExtensionFunctionDispatcher(
url_(url),
ALLOW_THIS_IN_INITIALIZER_LIST(peer_(new Peer(this))) {
all_instances()->insert(this);
- RenderProcessHost* process = render_view_host_->process();
- ExtensionMessageService* message_service =
- ExtensionMessageService::GetInstance(profile()->GetRequestContext());
- DCHECK(process);
- DCHECK(message_service);
- message_service->RegisterExtension(extension_id(), process->pid());
+
+ // Ensure the message service is initialized.
+ ExtensionMessageService::GetInstance(profile()->GetRequestContext())->Init();
}
ExtensionFunctionDispatcher::~ExtensionFunctionDispatcher() {
diff --git a/chrome/browser/extensions/extension_message_service.cc b/chrome/browser/extensions/extension_message_service.cc
index 4929eea..78dd1f2 100644
--- a/chrome/browser/extensions/extension_message_service.cc
+++ b/chrome/browser/extensions/extension_message_service.cc
@@ -23,11 +23,11 @@
// 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)
+#define GET_CHANNEL_OPENER_ID(channel_id) ((channel_id) * 2)
+#define GET_CHANNEL_RECEIVERS_ID(channel_id) ((channel_id) * 2 + 1)
// Port1 is always even, port2 is always odd.
-#define IS_PORT1_ID(port_id) (((port_id) & 1) == 0)
+#define IS_OPENER_PORT_ID(port_id) (((port_id) & 1) == 0)
// Change even to odd and vice versa, to get the other side of a given channel.
#define GET_OPPOSITE_PORT_ID(source_port_id) ((source_port_id) ^ 1)
@@ -80,6 +80,10 @@ static void DispatchEvent(IPC::Message::Sender* channel,
ExtensionMessageService::kDispatchEvent, args));
}
+static std::string GetChannelConnectEvent(const std::string& extension_id) {
+ return StringPrintf("channel-connect:%s", extension_id.c_str());
+}
+
} // namespace
// Since ExtensionMessageService is a collection of Singletons, we don't need to
@@ -132,19 +136,6 @@ void ExtensionMessageService::Init() {
NotificationService::AllSources());
}
-void ExtensionMessageService::RegisterExtension(
- const std::string& extension_id, int render_process_id) {
- DCHECK_EQ(MessageLoop::current()->type(), MessageLoop::TYPE_UI);
-
- // Make sure we're initialized.
- Init();
-
- AutoLock lock(process_ids_lock_);
- DCHECK(process_ids_.find(extension_id) == process_ids_.end() ||
- process_ids_[extension_id] == render_process_id);
- process_ids_[extension_id] = render_process_id;
-}
-
void ExtensionMessageService::AddEventListener(std::string event_name,
int render_process_id) {
DCHECK_EQ(MessageLoop::current()->type(), MessageLoop::TYPE_UI);
@@ -166,54 +157,24 @@ void ExtensionMessageService::AllocatePortIdPair(int* port1, int* port2) {
int port1_id = next_port_id_++;
int port2_id = next_port_id_++;
- DCHECK(IS_PORT1_ID(port1_id));
+ DCHECK(IS_OPENER_PORT_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 channel_id = GET_CHANNEL_ID(port1_id);
- DCHECK(GET_CHANNEL_PORT1(channel_id) == port1_id);
- DCHECK(GET_CHANNEL_PORT2(channel_id) == port2_id);
+ DCHECK(GET_CHANNEL_OPENER_ID(channel_id) == port1_id);
+ DCHECK(GET_CHANNEL_RECEIVERS_ID(channel_id) == port2_id);
*port1 = port1_id;
*port2 = port2_id;
}
-int ExtensionMessageService::GetProcessIdForExtension(
- const std::string& extension_id) {
- AutoLock lock(process_ids_lock_);
- ProcessIDMap::iterator process_id_it = process_ids_.find(
- StringToLowerASCII(extension_id));
- if (process_id_it == process_ids_.end())
- return -1;
- return process_id_it->second;
-}
-
-RenderProcessHost* ExtensionMessageService::GetProcessForExtension(
- const std::string& extension_id) {
- DCHECK_EQ(MessageLoop::current()->type(), MessageLoop::TYPE_UI);
-
- int process_id = GetProcessIdForExtension(extension_id);
- if (process_id == -1)
- return NULL;
-
- RenderProcessHost* host = RenderProcessHost::FromID(process_id);
- DCHECK(host);
-
- return host;
-}
-
int ExtensionMessageService::OpenChannelToExtension(
int routing_id, const std::string& extension_id,
ResourceMessageFilter* source) {
DCHECK_EQ(MessageLoop::current(),
ChromeThread::GetMessageLoop(ChromeThread::IO));
-
- // Lookup the targeted extension process.
- int process_id = GetProcessIdForExtension(extension_id);
- if (process_id == -1)
- return -1;
-
DCHECK(initialized_);
// Create a channel ID for both sides of the channel.
@@ -223,37 +184,49 @@ int ExtensionMessageService::OpenChannelToExtension(
ui_loop_->PostTask(FROM_HERE,
NewRunnableMethod(this, &ExtensionMessageService::OpenChannelOnUIThread,
- routing_id, port1_id, source->GetProcessId(), port2_id, process_id,
- extension_id));
+ routing_id, port1_id, source->GetProcessId(), extension_id));
return port2_id;
}
void ExtensionMessageService::OpenChannelOnUIThread(
int source_routing_id, int source_port_id, int source_process_id,
- int dest_port_id, int dest_process_id, const std::string& extension_id) {
+ const std::string& extension_id) {
RenderProcessHost* source = RenderProcessHost::FromID(source_process_id);
OpenChannelOnUIThreadImpl(source_routing_id, source_port_id,
- source_process_id, source, dest_port_id,
- dest_process_id, extension_id);
+ source_process_id, source, extension_id);
}
void ExtensionMessageService::OpenChannelOnUIThreadImpl(
int source_routing_id, int source_port_id, int source_process_id,
- IPC::Message::Sender* source, int dest_port_id, int dest_process_id,
- const std::string& extension_id) {
+ IPC::Message::Sender* source, const std::string& extension_id) {
DCHECK_EQ(MessageLoop::current()->type(), MessageLoop::TYPE_UI);
- MessageChannel channel;
- 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.
+ if (!source)
+ return; // Source closed while task was in flight.
+
+ linked_ptr<MessageChannel> channel(new MessageChannel);
+ channel->opener.insert(source);
+
+ // Get the list of processes that are listening for this extension's channel
+ // connect event.
+ std::string event_name = GetChannelConnectEvent(extension_id);
+ std::set<int>& pids = listeners_[event_name];
+ for (std::set<int>::iterator pid = pids.begin(); pid != pids.end(); ++pid) {
+ RenderProcessHost* renderer = RenderProcessHost::FromID(*pid);
+ if (!renderer)
+ continue;
+ channel->receivers.insert(renderer);
+ }
+ if (channel->receivers.empty()) {
+ // Either no one is listening, or all listeners have since closed.
+ // TODO(mpcomplete): should we notify the source?
return;
}
channels_[GET_CHANNEL_ID(source_port_id)] = channel;
+ // Include info about the opener's tab (if it was a tab).
std::string tab_json = "null";
TabContents* contents = tab_util::GetTabContentsByID(source_process_id,
source_routing_id);
@@ -262,20 +235,18 @@ void ExtensionMessageService::OpenChannelOnUIThreadImpl(
JSONWriter::Write(tab_value, false, &tab_json);
}
- // Send the process the id for the opposite port.
- DispatchOnConnect(channel.port2, source_port_id, tab_json, extension_id);
+ // Broadcast the connect event to the receivers. Give them the opener's
+ // port ID (the opener has the opposite port ID).
+ for (MessageChannel::Ports::iterator it = channel->receivers.begin();
+ it != channel->receivers.end(); ++it) {
+ DispatchOnConnect(*it, source_port_id, tab_json, extension_id);
+ }
}
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;
@@ -289,7 +260,7 @@ int ExtensionMessageService::OpenAutomationChannelToExtension(
// information should be supplied by the caller for
// automation-initiated ports.
OpenChannelOnUIThreadImpl(routing_id, port1_id, source_process_id,
- source, port2_id, process_id, extension_id);
+ source, extension_id);
return port2_id;
}
@@ -304,38 +275,41 @@ void ExtensionMessageService::CloseChannel(int port_id) {
}
void ExtensionMessageService::CloseChannelImpl(
- MessageChannelMap::iterator channel_iter, int port_id) {
+ MessageChannelMap::iterator channel_iter, int closing_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,
- GET_OPPOSITE_PORT_ID(port_id));
- } else {
- DCHECK_EQ(port_id, GET_CHANNEL_PORT2(channel_iter->first));
- DispatchOnDisconnect(channel_iter->second.port1,
- GET_OPPOSITE_PORT_ID(port_id));
+ MessageChannel::Ports* ports =
+ IS_OPENER_PORT_ID(closing_port_id) ?
+ &channel_iter->second->receivers : &channel_iter->second->opener;
+
+ for (MessageChannel::Ports::iterator it = ports->begin();
+ it != ports->end(); ++it) {
+ DispatchOnDisconnect(*it, GET_OPPOSITE_PORT_ID(closing_port_id));
}
channels_.erase(channel_iter);
}
void ExtensionMessageService::PostMessageFromRenderer(
- int port_id, const std::string& message) {
+ int dest_port_id, const std::string& message) {
DCHECK_EQ(MessageLoop::current()->type(), MessageLoop::TYPE_UI);
MessageChannelMap::iterator iter =
- channels_.find(GET_CHANNEL_ID(port_id));
+ channels_.find(GET_CHANNEL_ID(dest_port_id));
if (iter == channels_.end())
return;
- MessageChannel& channel = iter->second;
// Figure out which port the ID corresponds to.
- IPC::Message::Sender* dest =
- IS_PORT1_ID(port_id) ? channel.port1 : channel.port2;
-
- int source_port_id = GET_OPPOSITE_PORT_ID(port_id);
- DispatchOnMessage(dest, message, source_port_id);
+ MessageChannel::Ports* ports =
+ IS_OPENER_PORT_ID(dest_port_id) ?
+ &iter->second->opener : &iter->second->receivers;
+ int source_port_id = GET_OPPOSITE_PORT_ID(dest_port_id);
+
+ for (MessageChannel::Ports::iterator it = ports->begin();
+ it != ports->end(); ++it) {
+ DispatchOnMessage(*it, message, source_port_id);
+ }
}
void ExtensionMessageService::DispatchEventToRenderers(
@@ -369,26 +343,24 @@ void ExtensionMessageService::Observe(NotificationType type,
RenderProcessHost* renderer = Source<RenderProcessHost>(source).ptr();
- {
- AutoLock lock(process_ids_lock_);
- for (ProcessIDMap::iterator it = process_ids_.begin();
- it != process_ids_.end(); ) {
- ProcessIDMap::iterator current = it++;
- if (current->second == renderer->pid()) {
- process_ids_.erase(current);
- }
- }
- }
-
// 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) {
- CloseChannelImpl(current, GET_CHANNEL_PORT1(current->first));
- } else if (current->second.port2 == renderer) {
- CloseChannelImpl(current, GET_CHANNEL_PORT2(current->first));
+ if (current->second->opener.count(renderer) > 0) {
+ CloseChannelImpl(current, GET_CHANNEL_OPENER_ID(current->first));
+ } else if (current->second->receivers.count(renderer) > 0) {
+ CloseChannelImpl(current, GET_CHANNEL_RECEIVERS_ID(current->first));
}
}
+
+ // Remove this renderer from our listener maps.
+ for (ListenerMap::iterator it = listeners_.begin();
+ it != listeners_.end(); ) {
+ ListenerMap::iterator current = it++;
+ current->second.erase(renderer->pid());
+ if (current->second.empty())
+ listeners_.erase(current);
+ }
}
diff --git a/chrome/browser/extensions/extension_message_service.h b/chrome/browser/extensions/extension_message_service.h
index e3b7ba8..7a87adf 100644
--- a/chrome/browser/extensions/extension_message_service.h
+++ b/chrome/browser/extensions/extension_message_service.h
@@ -9,6 +9,7 @@
#include <set>
#include <string>
+#include "base/linked_ptr.h"
#include "base/lock.h"
#include "chrome/common/ipc_message.h"
#include "chrome/common/notification_registrar.h"
@@ -43,12 +44,8 @@ class ExtensionMessageService : public NotificationObserver {
// --- UI thread only:
- // Gets the process for the specified extension.
- RenderProcessHost* GetProcessForExtension(const std::string& extension_id);
-
- // Register an extension and its corresponding renderer process.
- void RegisterExtension(const std::string& extension_id,
- int render_process_id);
+ // UI-thread specific initialization. Does nothing if called more than once.
+ void Init();
// Add or remove |render_process_pid| as a listener for |event_name|.
void AddEventListener(std::string event_name, int render_process_id);
@@ -87,71 +84,54 @@ class ExtensionMessageService : public NotificationObserver {
// message.
int OpenChannelToExtension(int routing_id, const std::string& extension_id,
ResourceMessageFilter* source);
-
+
private:
- // The connection between two ports. It is possible that both ports
- // refer to the same renderer.
+ // A messaging channel. Since messages are broadcast, the channel can have
+ // multiple processes listening for messages. Note that the opening port
+ // can also be among the receivers, if an extension toolstrip wants to talk
+ // to its tab (for example).
struct MessageChannel {
- IPC::Message::Sender* port1;
- IPC::Message::Sender* port2;
+ typedef std::set<IPC::Message::Sender*> Ports;
+ Ports opener; // only 1 opener, but we use a set to simplify logic
+ Ports receivers;
};
// A map of channel ID to its channel object.
- typedef std::map<int, MessageChannel> MessageChannelMap;
+ typedef std::map<int, linked_ptr<MessageChannel> > MessageChannelMap;
// Allocates a pair of port ids.
// NOTE: this can be called from any thread.
void AllocatePortIdPair(int* port1, int* port2);
- // Gets the process ID for the specified extension.
- // 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);
-
- NotificationRegistrar registrar_;
-
// The UI message loop, used for posting tasks.
MessageLoop* ui_loop_;
- // A map of extension ID to the render_process_id that the extension lives in.
- typedef std::map<std::string, int> ProcessIDMap;
- ProcessIDMap process_ids_;
-
- // Protects the process_ids map, since it can be accessed on the IO thread
- // or UI thread. Be careful not to hold this lock when calling external
- // code (especially sending messages) to avoid deadlock.
- Lock process_ids_lock_;
-
- // A map between an event name and a set of process id's that are listening
- // to that event.
- typedef std::map<std::string, std::set<int> > ListenerMap;
- ListenerMap listeners_;
-
// --- UI thread only:
- // UI-thread specific initialization. Does nothing if called more than once.
- void Init();
-
// Handles channel creation and notifies the destination that a channel was
// opened.
void OpenChannelOnUIThread(int source_routing_id,
int source_port_id, int source_process_id,
- int dest_port_id, int dest_process_id,
const std::string& extension_id);
- // Common between OpenChannelOnUIThread and
- // OpenAutomationChannelToExtension.
+ // Common between OpenChannelOnUIThread and OpenAutomationChannelToExtension.
void OpenChannelOnUIThreadImpl(
int source_routing_id, int source_port_id, int source_process_id,
- IPC::Message::Sender* source, int dest_port_id, int dest_process_id,
- const std::string& extension_id);
+ IPC::Message::Sender* source, const std::string& extension_id);
+
+ NotificationRegistrar registrar_;
MessageChannelMap channels_;
+ // A map between an event name and a set of process id's that are listening
+ // to that event.
+ typedef std::map<std::string, std::set<int> > ListenerMap;
+ ListenerMap listeners_;
+
+ // --- UI or IO thread:
+
// True if Init has been called.
bool initialized_;
diff --git a/chrome/browser/extensions/extension_messages_unittest.cc b/chrome/browser/extensions/extension_messages_unittest.cc
index 86a3180..27a5bd9 100644
--- a/chrome/browser/extensions/extension_messages_unittest.cc
+++ b/chrome/browser/extensions/extension_messages_unittest.cc
@@ -13,6 +13,7 @@ static void DispatchOnConnect(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));
+ args.Set(2, Value::CreateStringValue("")); // extension ID is empty for tests
RendererExtensionBindings::Invoke(
ExtensionMessageService::kDispatchOnConnect, args);
}
diff --git a/chrome/browser/extensions/extensions_service_unittest.cc b/chrome/browser/extensions/extensions_service_unittest.cc
index ac0bd97..555655c 100644
--- a/chrome/browser/extensions/extensions_service_unittest.cc
+++ b/chrome/browser/extensions/extensions_service_unittest.cc
@@ -572,7 +572,7 @@ TEST_F(ExtensionsServiceTest, LoadAllExtensionsFromDirectorySuccess) {
EXPECT_EQ(std::string(good2), loaded_[2]->id());
EXPECT_EQ(std::string("My extension 3"), loaded_[2]->name());
EXPECT_EQ(std::string(""), loaded_[2]->description());
- EXPECT_EQ(0u, loaded_[2]->content_scripts().size());
+ EXPECT_EQ(1u, loaded_[2]->content_scripts().size());
EXPECT_EQ(Extension::INTERNAL, loaded_[2]->location());
};