summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/extensions/extension_browsertests_misc.cc16
-rw-r--r--chrome/browser/extensions/extension_message_service.cc20
-rw-r--r--chrome/renderer/extensions/event_bindings.cc25
-rw-r--r--chrome/test/data/extensions/good/Extensions/bjafgdebaacbbbecmhlhpofkepfkgcpa/1.0/background.html38
-rw-r--r--chrome/test/data/extensions/good/Extensions/bjafgdebaacbbbecmhlhpofkepfkgcpa/1.0/manifest.json2
-rw-r--r--chrome/test/data/extensions/good/Extensions/bjafgdebaacbbbecmhlhpofkepfkgcpa/1.0/page.js37
-rw-r--r--chrome/test/data/extensions/good/Extensions/bjafgdebaacbbbecmhlhpofkepfkgcpa/1.0/toolstrip.html46
7 files changed, 107 insertions, 77 deletions
diff --git a/chrome/browser/extensions/extension_browsertests_misc.cc b/chrome/browser/extensions/extension_browsertests_misc.cc
index 48fb0ca..9c9a50d 100644
--- a/chrome/browser/extensions/extension_browsertests_misc.cc
+++ b/chrome/browser/extensions/extension_browsertests_misc.cc
@@ -286,12 +286,12 @@ IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, MessagingExtensionTab) {
.AppendASCII("bjafgdebaacbbbecmhlhpofkepfkgcpa")
.AppendASCII("1.0")));
- // Get the ExtensionHost that is hosting our background page.
+ // Get the ExtensionHost that is hosting our toolstrip page.
ExtensionProcessManager* manager =
browser()->profile()->GetExtensionProcessManager();
- ExtensionHost* host = FindHostWithPath(manager, "/background.html", 1);
+ ExtensionHost* host = FindHostWithPath(manager, "/toolstrip.html", 1);
- // Load the tab that will communicate with our background page.
+ // Load the tab that will communicate with our toolstrip.
ui_test_utils::NavigateToURL(
browser(),
GURL("chrome-extension://bjafgdebaacbbbecmhlhpofkepfkgcpa/page.html"));
@@ -321,8 +321,6 @@ IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, MessagingExtensionTab) {
}
// Tests that message passing between extensions and content scripts works.
-#if 0
-// TODO(mpcomplete): re-enable this
IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, MessagingContentScript) {
ASSERT_TRUE(LoadExtension(
test_data_dir_.AppendASCII("good").AppendASCII("Extensions")
@@ -339,13 +337,12 @@ IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, MessagingContentScript) {
}
ASSERT_TRUE(master->ScriptsReady());
- // Get the ExtensionHost that is hosting our background page.
+ // Get the ExtensionHost that is hosting our toolstrip page.
ExtensionProcessManager* manager =
browser()->profile()->GetExtensionProcessManager();
- ExtensionHost* host = FindHostWithPath(manager, "/background.html", 1);
+ ExtensionHost* host = FindHostWithPath(manager, "/toolstrip.html", 1);
- // Load the tab whose content script will communicate with our background
- // page.
+ // Load the tab whose content script will communicate with our toolstrip.
FilePath test_file;
PathService::Get(chrome::DIR_TEST_DATA, &test_file);
test_file = test_file.AppendASCII("extensions")
@@ -375,4 +372,3 @@ IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, MessagingContentScript) {
host->render_view_host(), L"", L"testDisconnectOnClose()", &result);
EXPECT_TRUE(result);
}
-#endif
diff --git a/chrome/browser/extensions/extension_message_service.cc b/chrome/browser/extensions/extension_message_service.cc
index 5424ad2..d4e6d0f 100644
--- a/chrome/browser/extensions/extension_message_service.cc
+++ b/chrome/browser/extensions/extension_message_service.cc
@@ -130,15 +130,23 @@ void ExtensionMessageService::ProfileDestroyed() {
void ExtensionMessageService::AddEventListener(std::string event_name,
int render_process_id) {
+ DCHECK(RenderProcessHost::FromID(render_process_id)) <<
+ "Adding event listener to a non-existant RenderProcessHost.";
DCHECK_EQ(MessageLoop::current()->type(), MessageLoop::TYPE_UI);
- DCHECK(listeners_[event_name].count(render_process_id) == 0);
+ DCHECK_EQ(listeners_[event_name].count(render_process_id), 0u) << event_name;
listeners_[event_name].insert(render_process_id);
}
void ExtensionMessageService::RemoveEventListener(std::string event_name,
int render_process_id) {
+ // It is possible that this RenderProcessHost is being destroyed. If that is
+ // the case, we'll have already removed his listeners, so do nothing here.
+ RenderProcessHost* rph = RenderProcessHost::FromID(render_process_id);
+ if (!rph)
+ return;
+
DCHECK_EQ(MessageLoop::current()->type(), MessageLoop::TYPE_UI);
- DCHECK(listeners_[event_name].count(render_process_id) == 1);
+ DCHECK_EQ(listeners_[event_name].count(render_process_id), 1u) << event_name;
listeners_[event_name].erase(render_process_id);
}
@@ -245,9 +253,15 @@ void ExtensionMessageService::OpenChannelOnUIThreadImpl(
DCHECK_EQ(MessageLoop::current()->type(), MessageLoop::TYPE_UI);
// TODO(mpcomplete): notify source if reciever doesn't exist
- if (!source || !receiver.sender)
+ if (!source)
return; // Closed while in flight.
+ if (!receiver.sender) {
+ // Treat it as a disconnect.
+ DispatchOnDisconnect(MessagePort(source, MSG_ROUTING_CONTROL),
+ GET_OPPOSITE_PORT_ID(receiver_port_id));
+ }
+
linked_ptr<MessageChannel> channel(new MessageChannel);
channel->opener = MessagePort(source, MSG_ROUTING_CONTROL);
channel->receiver = receiver;
diff --git a/chrome/renderer/extensions/event_bindings.cc b/chrome/renderer/extensions/event_bindings.cc
index 863ebbf..81924cb 100644
--- a/chrome/renderer/extensions/event_bindings.cc
+++ b/chrome/renderer/extensions/event_bindings.cc
@@ -129,8 +129,7 @@ static void DeferredUnload(v8::Persistent<v8::Context> context) {
context.Clear();
}
-static void HandleContextDestroyed(ContextList::iterator context_iter,
- bool in_gc) {
+static void UnregisterContext(ContextList::iterator context_iter, bool in_gc) {
// Notify the bindings that they're going away.
if (in_gc) {
// We shouldn't call back into javascript during a garbage collect. Do it
@@ -154,14 +153,6 @@ static void HandleContextDestroyed(ContextList::iterator context_iter,
}
}
- // Unload any content script contexts for this frame.
- for (ContextList::iterator it = GetContexts().begin();
- it != GetContexts().end(); ) {
- ContextList::iterator current = it++;
- if ((*current)->parent_context == (*context_iter)->context)
- HandleContextDestroyed(current, in_gc);
- }
-
if (!(*context_iter)->parent_context.IsEmpty()) {
(*context_iter)->parent_context.Dispose();
(*context_iter)->parent_context.Clear();
@@ -179,10 +170,11 @@ static void HandleContextDestroyed(ContextList::iterator context_iter,
static void ContextWeakReferenceCallback(v8::Persistent<v8::Value> context,
void*) {
+ // This should only get called for content script contexts.
for (ContextList::iterator it = GetContexts().begin();
it != GetContexts().end(); ++it) {
if ((*it)->context == context) {
- HandleContextDestroyed(it, true);
+ UnregisterContext(it, true);
return;
}
}
@@ -258,7 +250,16 @@ void EventBindings::HandleContextDestroyed(WebFrame* frame) {
ContextList::iterator context_iter = bindings_utils::FindContext(context);
if (context_iter != GetContexts().end())
- ::HandleContextDestroyed(context_iter, false);
+ UnregisterContext(context_iter, false);
+
+ // Unload any content script contexts for this frame. Note that the frame
+ // itself might not be registered, but can still be a parent context.
+ for (ContextList::iterator it = GetContexts().begin();
+ it != GetContexts().end(); ) {
+ ContextList::iterator current = it++;
+ if ((*current)->parent_context == context)
+ UnregisterContext(current, false);
+ }
}
// static
diff --git a/chrome/test/data/extensions/good/Extensions/bjafgdebaacbbbecmhlhpofkepfkgcpa/1.0/background.html b/chrome/test/data/extensions/good/Extensions/bjafgdebaacbbbecmhlhpofkepfkgcpa/1.0/background.html
deleted file mode 100644
index d68d4d6..0000000
--- a/chrome/test/data/extensions/good/Extensions/bjafgdebaacbbbecmhlhpofkepfkgcpa/1.0/background.html
+++ /dev/null
@@ -1,38 +0,0 @@
-<script>
-chrome.extension.onConnect.addListener(function(port) {
- port.onMessage.addListener(function(msg) {
- if (msg.testPostMessageFromTab) {
- port.postMessage({success: true});
- }
- // Ignore other messages since they are from us.
- });
-});
-
-// Tests that postMessage to the tab and its response works.
-function testPostMessage() {
- var port = chrome.extension.connect();
- port.postMessage({testPostMessage: true});
- port.onMessage.addListener(function(msg) {
- window.domAutomationController.send(msg.success);
- port.disconnect();
- });
-}
-
-// Tests that we get the disconnect event when the tab disconnect.
-function testDisconnect() {
- var port = chrome.extension.connect();
- port.postMessage({testDisconnect: true});
- port.onDisconnect.addListener(function() {
- window.domAutomationController.send(true);
- });
-}
-
-// Tests that we get the disconnect event when the tab context closes.
-function testDisconnectOnClose() {
- var port = chrome.extension.connect();
- port.postMessage({testDisconnectOnClose: true});
- port.onDisconnect.addListener(function() {
- window.domAutomationController.send(true);
- });
-}
-</script>
diff --git a/chrome/test/data/extensions/good/Extensions/bjafgdebaacbbbecmhlhpofkepfkgcpa/1.0/manifest.json b/chrome/test/data/extensions/good/Extensions/bjafgdebaacbbbecmhlhpofkepfkgcpa/1.0/manifest.json
index b1a24a9..6cb06ff 100644
--- a/chrome/test/data/extensions/good/Extensions/bjafgdebaacbbbecmhlhpofkepfkgcpa/1.0/manifest.json
+++ b/chrome/test/data/extensions/good/Extensions/bjafgdebaacbbbecmhlhpofkepfkgcpa/1.0/manifest.json
@@ -2,7 +2,7 @@
"key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDRS2GUBOUAO5VZ2CMRId/eRR8/e9V42nUvY5XG+0sZ+JDHEjIQdq8qQy7HqdqEpCXKPMSPuMiC2t2HE9/hpL89SblNn3mwYPtSJGQdZvAzuv6SB0oA6jZ66V7+h/k0noGD3Tcu+Ko/vfkt5wCx2uHVK29k5JR/vGr0klaoVezGlwIDAQAB",
"version": "1.0",
"name": "My extension 3",
- "background_page": "background.html",
+ "toolstrips": ["toolstrip.html"],
"content_scripts": [
{
"matches": ["file://*"],
diff --git a/chrome/test/data/extensions/good/Extensions/bjafgdebaacbbbecmhlhpofkepfkgcpa/1.0/page.js b/chrome/test/data/extensions/good/Extensions/bjafgdebaacbbbecmhlhpofkepfkgcpa/1.0/page.js
index 7adb0c5..cee9476 100644
--- a/chrome/test/data/extensions/good/Extensions/bjafgdebaacbbbecmhlhpofkepfkgcpa/1.0/page.js
+++ b/chrome/test/data/extensions/good/Extensions/bjafgdebaacbbbecmhlhpofkepfkgcpa/1.0/page.js
@@ -3,20 +3,24 @@ if (typeof(contentWindow) != 'undefined') {
win = contentWindow;
}
-chrome.extension.onConnect.addListener(function(port) {
- console.log('connected');
- port.onMessage.addListener(function(msg) {
- console.log('got ' + msg);
- if (msg.testPostMessage) {
- port.postMessage({success: true});
- } else if (msg.testDisconnect) {
- port.disconnect();
- } else if (msg.testDisconnectOnClose) {
- win.location = "about:blank";
- }
- // Ignore other messages since they are from us.
+win.onload = function() {
+ // Do this in an onload handler because I'm not sure if chrome.extension
+ // is available before then.
+ chrome.extension.onConnect.addListener(function(port) {
+ console.log('connected');
+ port.onMessage.addListener(function(msg) {
+ console.log('got ' + msg);
+ if (msg.testPostMessage) {
+ port.postMessage({success: true});
+ } else if (msg.testDisconnect) {
+ port.disconnect();
+ } else if (msg.testDisconnectOnClose) {
+ win.location = "about:blank";
+ }
+ // Ignore other messages since they are from us.
+ });
});
-});
+}
// Tests that postMessage to the extension and its response works.
win.testPostMessageFromTab = function() {
@@ -29,3 +33,10 @@ win.testPostMessageFromTab = function() {
});
console.log('posted message');
}
+
+// Workaround two bugs: shutdown crash if we hook 'unload', and content script
+// GC if we don't register any event handlers.
+// http://code.google.com/p/chromium/issues/detail?id=17410
+// http://code.google.com/p/chromium/issues/detail?id=17582
+function foo() {}
+win.addEventListener('error', foo);
diff --git a/chrome/test/data/extensions/good/Extensions/bjafgdebaacbbbecmhlhpofkepfkgcpa/1.0/toolstrip.html b/chrome/test/data/extensions/good/Extensions/bjafgdebaacbbbecmhlhpofkepfkgcpa/1.0/toolstrip.html
new file mode 100644
index 0000000..aae7daa
--- /dev/null
+++ b/chrome/test/data/extensions/good/Extensions/bjafgdebaacbbbecmhlhpofkepfkgcpa/1.0/toolstrip.html
@@ -0,0 +1,46 @@
+<script>
+window.onload = function() {
+ chrome.extension.onConnect.addListener(function(port) {
+ port.onMessage.addListener(function(msg) {
+ if (msg.testPostMessageFromTab) {
+ port.postMessage({success: true});
+ }
+ // Ignore other messages since they are from us.
+ });
+ });
+};
+
+// Tests that postMessage to the tab and its response works.
+function testPostMessage() {
+ chrome.tabs.getSelected(null, function(tab) {
+ var port = chrome.tabs.connect(tab.id);
+ port.postMessage({testPostMessage: true});
+ port.onMessage.addListener(function(msg) {
+ window.domAutomationController.send(msg.success);
+ port.disconnect();
+ });
+ });
+}
+
+// Tests that we get the disconnect event when the tab disconnect.
+function testDisconnect() {
+ chrome.tabs.getSelected(null, function(tab) {
+ var port = chrome.tabs.connect(tab.id);
+ port.postMessage({testDisconnect: true});
+ port.onDisconnect.addListener(function() {
+ window.domAutomationController.send(true);
+ });
+ });
+}
+
+// Tests that we get the disconnect event when the tab context closes.
+function testDisconnectOnClose() {
+ chrome.tabs.getSelected(null, function(tab) {
+ var port = chrome.tabs.connect(tab.id);
+ port.postMessage({testDisconnectOnClose: true});
+ port.onDisconnect.addListener(function() {
+ window.domAutomationController.send(true);
+ });
+ });
+}
+</script>