summaryrefslogtreecommitdiffstats
path: root/chrome/browser
diff options
context:
space:
mode:
authormpcomplete@chromium.org <mpcomplete@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-10-08 21:32:34 +0000
committermpcomplete@chromium.org <mpcomplete@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-10-08 21:32:34 +0000
commit414785a5dce34bbe90b08c360992fd850612c2a1 (patch)
tree74a3f7b053dfc409afbc9187281dc0eac87160de /chrome/browser
parent0df4ace4713e5b74a5215638111d514971aaf40d (diff)
downloadchromium_src-414785a5dce34bbe90b08c360992fd850612c2a1.zip
chromium_src-414785a5dce34bbe90b08c360992fd850612c2a1.tar.gz
chromium_src-414785a5dce34bbe90b08c360992fd850612c2a1.tar.bz2
Ensure global extension events (like bookmarks) are sent to the incognito
extension process for split-mode extensions. Also cleaned up some naming. BUG=58189 TEST=no Review URL: http://codereview.chromium.org/3578017 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@62018 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
-rw-r--r--chrome/browser/extensions/all_urls_apitest.cc26
-rw-r--r--chrome/browser/extensions/extension_accessibility_api.cc2
-rw-r--r--chrome/browser/extensions/extension_bookmark_manager_api.cc2
-rw-r--r--chrome/browser/extensions/extension_bookmarks_module.cc2
-rw-r--r--chrome/browser/extensions/extension_context_menu_browsertest.cc14
-rw-r--r--chrome/browser/extensions/extension_incognito_apitest.cc9
-rw-r--r--chrome/browser/extensions/extension_management_api.cc2
-rw-r--r--chrome/browser/extensions/extension_management_api_browsertest.cc8
-rw-r--r--chrome/browser/extensions/extension_management_browsertest.cc4
-rw-r--r--chrome/browser/extensions/extension_message_service.cc18
-rw-r--r--chrome/browser/extensions/extension_message_service.h14
-rw-r--r--chrome/browser/extensions/extension_test_api.cc10
-rw-r--r--chrome/browser/extensions/extension_test_api.h8
-rw-r--r--chrome/browser/extensions/extension_test_message_listener.cc23
-rw-r--r--chrome/browser/extensions/extension_test_message_listener.h35
15 files changed, 118 insertions, 59 deletions
diff --git a/chrome/browser/extensions/all_urls_apitest.cc b/chrome/browser/extensions/all_urls_apitest.cc
index 24166fc..ff82075 100644
--- a/chrome/browser/extensions/all_urls_apitest.cc
+++ b/chrome/browser/extensions/all_urls_apitest.cc
@@ -46,32 +46,32 @@ IN_PROC_BROWSER_TEST_F(AllUrlsApiTest, WhitelistedExtension) {
// Now verify we run content scripts on chrome://newtab/.
url = "chrome://newtab/";
- ExtensionTestMessageListener listener1a("content script: " + url);
- ExtensionTestMessageListener listener1b("execute: " + url);
+ ExtensionTestMessageListener listener1a("content script: " + url, false);
+ ExtensionTestMessageListener listener1b("execute: " + url, false);
ui_test_utils::NavigateToURL(browser(), GURL(url));
ASSERT_TRUE(listener1a.WaitUntilSatisfied());
ASSERT_TRUE(listener1b.WaitUntilSatisfied());
// Now verify data: urls.
url = "data:text/html;charset=utf-8,<html>asdf</html>";
- ExtensionTestMessageListener listener2a("content script: " + url);
- ExtensionTestMessageListener listener2b("execute: " + url);
+ ExtensionTestMessageListener listener2a("content script: " + url, false);
+ ExtensionTestMessageListener listener2b("execute: " + url, false);
ui_test_utils::NavigateToURL(browser(), GURL(url));
ASSERT_TRUE(listener2a.WaitUntilSatisfied());
ASSERT_TRUE(listener2b.WaitUntilSatisfied());
// Now verify about:version.
url = "about:version";
- ExtensionTestMessageListener listener3a("content script: " + url);
- ExtensionTestMessageListener listener3b("execute: " + url);
+ ExtensionTestMessageListener listener3a("content script: " + url, false);
+ ExtensionTestMessageListener listener3b("execute: " + url, false);
ui_test_utils::NavigateToURL(browser(), GURL(url));
ASSERT_TRUE(listener3a.WaitUntilSatisfied());
ASSERT_TRUE(listener3b.WaitUntilSatisfied());
// Now verify about:blank.
url = "about:blank";
- ExtensionTestMessageListener listener4a("content script: " + url);
- ExtensionTestMessageListener listener4b("execute: " + url);
+ ExtensionTestMessageListener listener4a("content script: " + url, false);
+ ExtensionTestMessageListener listener4b("execute: " + url, false);
ui_test_utils::NavigateToURL(browser(), GURL(url));
ASSERT_TRUE(listener4a.WaitUntilSatisfied());
ASSERT_TRUE(listener4b.WaitUntilSatisfied());
@@ -79,8 +79,9 @@ IN_PROC_BROWSER_TEST_F(AllUrlsApiTest, WhitelistedExtension) {
// Now verify we can script a regular http page.
ASSERT_TRUE(test_server()->Start());
GURL page_url = test_server()->GetURL(kAllUrlsTarget);
- ExtensionTestMessageListener listener5a("content script: " + page_url.spec());
- ExtensionTestMessageListener listener5b("execute: " + page_url.spec());
+ ExtensionTestMessageListener listener5a("content script: " + page_url.spec(),
+ false);
+ ExtensionTestMessageListener listener5b("execute: " + page_url.spec(), false);
ui_test_utils::NavigateToURL(browser(), page_url);
ASSERT_TRUE(listener5a.WaitUntilSatisfied());
ASSERT_TRUE(listener5b.WaitUntilSatisfied());
@@ -104,8 +105,9 @@ IN_PROC_BROWSER_TEST_F(AllUrlsApiTest, RegularExtensions) {
// Now verify we can script a regular http page.
ASSERT_TRUE(test_server()->Start());
GURL page_url = test_server()->GetURL(kAllUrlsTarget);
- ExtensionTestMessageListener listener1a("content script: " + page_url.spec());
- ExtensionTestMessageListener listener1b("execute: " + page_url.spec());
+ ExtensionTestMessageListener listener1a("content script: " + page_url.spec(),
+ false);
+ ExtensionTestMessageListener listener1b("execute: " + page_url.spec(), false);
ui_test_utils::NavigateToURL(browser(), page_url);
ASSERT_TRUE(listener1a.WaitUntilSatisfied());
ASSERT_TRUE(listener1b.WaitUntilSatisfied());
diff --git a/chrome/browser/extensions/extension_accessibility_api.cc b/chrome/browser/extensions/extension_accessibility_api.cc
index 83a6194..235a521 100644
--- a/chrome/browser/extensions/extension_accessibility_api.cc
+++ b/chrome/browser/extensions/extension_accessibility_api.cc
@@ -183,7 +183,7 @@ void ExtensionAccessibilityEventRouter::DispatchEvent(
const std::string& json_args) {
if (enabled_ && profile && profile->GetExtensionMessageService()) {
profile->GetExtensionMessageService()->DispatchEventToRenderers(
- event_name, json_args, profile, GURL());
+ event_name, json_args, NULL, GURL());
}
}
diff --git a/chrome/browser/extensions/extension_bookmark_manager_api.cc b/chrome/browser/extensions/extension_bookmark_manager_api.cc
index 0b0dc0f..f5db93f 100644
--- a/chrome/browser/extensions/extension_bookmark_manager_api.cc
+++ b/chrome/browser/extensions/extension_bookmark_manager_api.cc
@@ -161,7 +161,7 @@ void ExtensionBookmarkManagerEventRouter::DispatchEvent(const char* event_name,
std::string json_args;
base::JSONWriter::Write(args, false, &json_args);
profile_->GetExtensionMessageService()->DispatchEventToRenderers(
- event_name, json_args, profile_, GURL());
+ event_name, json_args, NULL, GURL());
}
void ExtensionBookmarkManagerEventRouter::DispatchDragEvent(
diff --git a/chrome/browser/extensions/extension_bookmarks_module.cc b/chrome/browser/extensions/extension_bookmarks_module.cc
index 4044bfc..991ea2d 100644
--- a/chrome/browser/extensions/extension_bookmarks_module.cc
+++ b/chrome/browser/extensions/extension_bookmarks_module.cc
@@ -97,7 +97,7 @@ void ExtensionBookmarkEventRouter::DispatchEvent(Profile *profile,
const std::string json_args) {
if (profile->GetExtensionMessageService()) {
profile->GetExtensionMessageService()->DispatchEventToRenderers(
- event_name, json_args, profile, GURL());
+ event_name, json_args, NULL, GURL());
}
}
diff --git a/chrome/browser/extensions/extension_context_menu_browsertest.cc b/chrome/browser/extensions/extension_context_menu_browsertest.cc
index 427a7fc..62221e1 100644
--- a/chrome/browser/extensions/extension_context_menu_browsertest.cc
+++ b/chrome/browser/extensions/extension_context_menu_browsertest.cc
@@ -180,8 +180,8 @@ class ExtensionContextMenuBrowserTest : public ExtensionBrowserTest {
// Tests adding a simple context menu item.
IN_PROC_BROWSER_TEST_F(ExtensionContextMenuBrowserTest, Simple) {
- ExtensionTestMessageListener listener1("created item");
- ExtensionTestMessageListener listener2("onclick fired");
+ ExtensionTestMessageListener listener1("created item", false);
+ ExtensionTestMessageListener listener2("onclick fired", false);
ASSERT_TRUE(LoadContextMenuExtension("simple"));
// Wait for the extension to tell us it's created an item.
@@ -204,7 +204,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionContextMenuBrowserTest, Simple) {
// Tests that setting "documentUrlPatterns" for an item properly restricts
// those items to matching pages.
IN_PROC_BROWSER_TEST_F(ExtensionContextMenuBrowserTest, Patterns) {
- ExtensionTestMessageListener listener("created items");
+ ExtensionTestMessageListener listener("created items", false);
ASSERT_TRUE(LoadContextMenuExtension("patterns"));
@@ -233,7 +233,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionContextMenuBrowserTest, Patterns) {
// Tests registering an item with a very long title that should get truncated in
// the actual menu displayed.
IN_PROC_BROWSER_TEST_F(ExtensionContextMenuBrowserTest, LongTitle) {
- ExtensionTestMessageListener listener("created");
+ ExtensionTestMessageListener listener("created", false);
// Load the extension and wait until it's created a menu item.
ASSERT_TRUE(LoadContextMenuExtension("long_title"));
@@ -307,7 +307,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionContextMenuBrowserTest, Separators) {
// Navigate to test1.html inside the extension, which should create a bunch
// of items at the top-level (but they'll get pushed into an auto-generated
// parent).
- ExtensionTestMessageListener listener1("test1 create finished");
+ ExtensionTestMessageListener listener1("test1 create finished", false);
ui_test_utils::NavigateToURL(browser(),
GURL(extension->GetResourceURL("test1.html")));
listener1.WaitUntilSatisfied();
@@ -332,7 +332,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionContextMenuBrowserTest, Separators) {
// Now run our second test - navigate to test2.html which creates an explicit
// parent node and populates that with the same items as in test1.
- ExtensionTestMessageListener listener2("test2 create finished");
+ ExtensionTestMessageListener listener2("test2 create finished", false);
ui_test_utils::NavigateToURL(browser(),
GURL(extension->GetResourceURL("test2.html")));
listener2.WaitUntilSatisfied();
@@ -348,7 +348,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionContextMenuBrowserTest, Separators) {
// Tests that targetUrlPattern keeps items from appearing when there is no
// target url.
IN_PROC_BROWSER_TEST_F(ExtensionContextMenuBrowserTest, TargetURLs) {
- ExtensionTestMessageListener listener("created items");
+ ExtensionTestMessageListener listener("created items", false);
ASSERT_TRUE(LoadContextMenuExtension("target_urls"));
ASSERT_TRUE(listener.WaitUntilSatisfied());
diff --git a/chrome/browser/extensions/extension_incognito_apitest.cc b/chrome/browser/extensions/extension_incognito_apitest.cc
index 51742e8..675e2bb 100644
--- a/chrome/browser/extensions/extension_incognito_apitest.cc
+++ b/chrome/browser/extensions/extension_incognito_apitest.cc
@@ -7,6 +7,7 @@
#include "chrome/browser/browser_window.h"
#include "chrome/browser/extensions/browser_action_test_util.h"
#include "chrome/browser/extensions/extension_apitest.h"
+#include "chrome/browser/extensions/extension_test_message_listener.h"
#include "chrome/browser/extensions/extensions_service.h"
#include "chrome/browser/extensions/user_script_master.h"
#include "chrome/browser/profile.h"
@@ -132,6 +133,14 @@ IN_PROC_BROWSER_TEST_F(ExtensionApiTest, MAYBE_IncognitoSplitMode) {
ASSERT_TRUE(LoadExtensionIncognito(test_data_dir_
.AppendASCII("incognito").AppendASCII("split")));
+ // Wait for both extensions to be ready before telling them to proceed.
+ ExtensionTestMessageListener listener("waiting", true);
+ EXPECT_TRUE(listener.WaitUntilSatisfied());
+ ExtensionTestMessageListener listener_incognito("waiting", true);
+ EXPECT_TRUE(listener_incognito.WaitUntilSatisfied());
+ listener.Reply("go");
+ listener_incognito.Reply("go");
+
EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
EXPECT_TRUE(catcher_incognito.GetNextResult()) << catcher.message();
}
diff --git a/chrome/browser/extensions/extension_management_api.cc b/chrome/browser/extensions/extension_management_api.cc
index fe6888a..e42764d 100644
--- a/chrome/browser/extensions/extension_management_api.cc
+++ b/chrome/browser/extensions/extension_management_api.cc
@@ -233,6 +233,6 @@ void ExtensionManagementEventRouter::Observe(
profile->GetExtensionMessageService();
message_service->DispatchEventToRenderers(event_name,
args_json,
- profile,
+ NULL,
GURL());
}
diff --git a/chrome/browser/extensions/extension_management_api_browsertest.cc b/chrome/browser/extensions/extension_management_api_browsertest.cc
index 7061637..80955ba 100644
--- a/chrome/browser/extensions/extension_management_api_browsertest.cc
+++ b/chrome/browser/extensions/extension_management_api_browsertest.cc
@@ -10,20 +10,20 @@ class ExtensionManagementApiBrowserTest : public ExtensionBrowserTest {};
// We test this here instead of in an ExtensionApiTest because normal extensions
// are not allowed to call the install function.
IN_PROC_BROWSER_TEST_F(ExtensionManagementApiBrowserTest, InstallEvent) {
- ExtensionTestMessageListener listener1("ready");
+ ExtensionTestMessageListener listener1("ready", false);
ASSERT_TRUE(LoadExtension(
test_data_dir_.AppendASCII("management/install_event")));
ASSERT_TRUE(listener1.WaitUntilSatisfied());
- ExtensionTestMessageListener listener2("got_event");
+ ExtensionTestMessageListener listener2("got_event", false);
ASSERT_TRUE(LoadExtension(
test_data_dir_.AppendASCII("api_test/management/enabled_extension")));
ASSERT_TRUE(listener2.WaitUntilSatisfied());
}
IN_PROC_BROWSER_TEST_F(ExtensionManagementApiBrowserTest, LaunchApp) {
- ExtensionTestMessageListener listener1("app_launched");
- ExtensionTestMessageListener listener2("got_expected_error");
+ ExtensionTestMessageListener listener1("app_launched", false);
+ ExtensionTestMessageListener listener2("got_expected_error", false);
ASSERT_TRUE(LoadExtension(
test_data_dir_.AppendASCII("management/simple_extension")));
ASSERT_TRUE(LoadExtension(
diff --git a/chrome/browser/extensions/extension_management_browsertest.cc b/chrome/browser/extensions/extension_management_browsertest.cc
index 1c6fb68b..2e528b5 100644
--- a/chrome/browser/extensions/extension_management_browsertest.cc
+++ b/chrome/browser/extensions/extension_management_browsertest.cc
@@ -209,7 +209,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, AutoUpdate) {
basedir.AppendASCII("v2.crx"));
// Install version 1 of the extension.
- ExtensionTestMessageListener listener1("v1 installed");
+ ExtensionTestMessageListener listener1("v1 installed", false);
ExtensionsService* service = browser()->profile()->GetExtensionsService();
const size_t size_before = service->extensions()->size();
ASSERT_TRUE(service->disabled_extensions()->empty());
@@ -226,7 +226,7 @@ IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, AutoUpdate) {
service->updater()->set_blacklist_checks_enabled(false);
// Run autoupdate and make sure version 2 of the extension was installed.
- ExtensionTestMessageListener listener2("v2 installed");
+ ExtensionTestMessageListener listener2("v2 installed", false);
service->updater()->CheckNow();
ASSERT_TRUE(WaitForExtensionInstall());
listener2.WaitUntilSatisfied();
diff --git a/chrome/browser/extensions/extension_message_service.cc b/chrome/browser/extensions/extension_message_service.cc
index 40bfc32..6a615ff 100644
--- a/chrome/browser/extensions/extension_message_service.cc
+++ b/chrome/browser/extensions/extension_message_service.cc
@@ -96,13 +96,13 @@ static void DispatchOnMessage(const ExtensionMessageService::MessagePort& port,
static void DispatchEvent(const ExtensionMessageService::MessagePort& port,
const std::string& event_name,
const std::string& event_args,
- bool has_incognito_data,
+ bool cross_incognito,
const GURL& event_url) {
ListValue args;
args.Set(0, Value::CreateStringValue(event_name));
args.Set(1, Value::CreateStringValue(event_args));
port.sender->Send(new ViewMsg_ExtensionMessageInvoke(port.routing_id,
- ExtensionMessageService::kDispatchEvent, args, has_incognito_data,
+ ExtensionMessageService::kDispatchEvent, args, cross_incognito,
event_url));
}
@@ -392,12 +392,12 @@ void ExtensionMessageService::PostMessageFromRenderer(
void ExtensionMessageService::DispatchEventToRenderers(
const std::string& event_name, const std::string& event_args,
- Profile* source_profile, const GURL& event_url) {
+ Profile* restrict_to_profile, const GURL& event_url) {
if (!profile_)
return;
// We don't expect to get events from a completely different profile.
- DCHECK(!source_profile || profile_->IsSameProfile(source_profile));
+ DCHECK(!restrict_to_profile || profile_->IsSameProfile(restrict_to_profile));
ListenerMap::iterator it = listeners_.find(event_name);
if (it == listeners_.end())
@@ -418,18 +418,18 @@ void ExtensionMessageService::DispatchEventToRenderers(
// Is this event from a different profile than the renderer (ie, an
// incognito tab event sent to a normal process, or vice versa).
- bool cross_profile =
- source_profile && renderer->profile() != source_profile;
- DispatchEvent(renderer, event_name, event_args, cross_profile, event_url);
+ bool cross_incognito =
+ restrict_to_profile && renderer->profile() != restrict_to_profile;
+ DispatchEvent(renderer, event_name, event_args, cross_incognito, event_url);
}
}
void ExtensionMessageService::DispatchEventToExtension(
const std::string& extension_id,
const std::string& event_name, const std::string& event_args,
- Profile* source_profile, const GURL& event_url) {
+ Profile* restrict_to_profile, const GURL& event_url) {
DispatchEventToRenderers(GetPerExtensionEventName(event_name, extension_id),
- event_args, source_profile, event_url);
+ event_args, restrict_to_profile, event_url);
}
void ExtensionMessageService::Observe(NotificationType type,
diff --git a/chrome/browser/extensions/extension_message_service.h b/chrome/browser/extensions/extension_message_service.h
index 9d8c038..79ef344 100644
--- a/chrome/browser/extensions/extension_message_service.h
+++ b/chrome/browser/extensions/extension_message_service.h
@@ -81,20 +81,22 @@ class ExtensionMessageService
// Returns true if there is at least one listener for the given event.
bool HasEventListener(const std::string& event_name);
- // Send an event to every registered extension renderer. If
- // |has_incognito_data| is true, the event is only sent to extension with the
- // permission to access incognito data. If |event_url| is not empty, the
- // event is only sent to extension with host permissions for this url.
+ // Send an event to every registered extension renderer. If
+ // |restrict_to_profile| is non-NULL, then the event will not be sent to other
+ // profiles unless the extension has permission (e.g. incognito tab update ->
+ // normal profile only works if extension is allowed incognito access). If
+ // |event_url| is not empty, the event is only sent to extension with host
+ // permissions for this url.
virtual void DispatchEventToRenderers(
const std::string& event_name, const std::string& event_args,
- Profile* source_profile, const GURL& event_url);
+ Profile* restrict_to_profile, const GURL& event_url);
// Same as above, except use the extension-specific naming scheme for the
// event. This is used by events that are per-extension.
void DispatchEventToExtension(
const std::string& extension_id,
const std::string& event_name, const std::string& event_args,
- Profile* source_profile, const GURL& event_url);
+ Profile* restrict_to_profile, const GURL& event_url);
// Given an extension's ID, opens a channel between the given renderer "port"
// and every listening context owned by that extension. |channel_name| is
diff --git a/chrome/browser/extensions/extension_test_api.cc b/chrome/browser/extensions/extension_test_api.cc
index 858d25b..b5f64ba 100644
--- a/chrome/browser/extensions/extension_test_api.cc
+++ b/chrome/browser/extensions/extension_test_api.cc
@@ -54,10 +54,16 @@ bool ExtensionTestCreateIncognitoTabFunction::RunImpl() {
bool ExtensionTestSendMessageFunction::RunImpl() {
std::string message;
EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &message));
- std::string id = extension_id();
+ AddRef(); // balanced in Reply
NotificationService::current()->Notify(
NotificationType::EXTENSION_TEST_MESSAGE,
- Source<std::string>(&id),
+ Source<ExtensionTestSendMessageFunction>(this),
Details<std::string>(&message));
return true;
}
+
+void ExtensionTestSendMessageFunction::Reply(const std::string& message) {
+ result_.reset(Value::CreateStringValue(message));
+ SendResponse(true);
+ Release(); // balanced in RunImpl
+}
diff --git a/chrome/browser/extensions/extension_test_api.h b/chrome/browser/extensions/extension_test_api.h
index f59d0b5..e0b8dce 100644
--- a/chrome/browser/extensions/extension_test_api.h
+++ b/chrome/browser/extensions/extension_test_api.h
@@ -38,7 +38,13 @@ class ExtensionTestCreateIncognitoTabFunction : public SyncExtensionFunction {
DECLARE_EXTENSION_FUNCTION_NAME("test.createIncognitoTab")
};
-class ExtensionTestSendMessageFunction : public SyncExtensionFunction {
+class ExtensionTestSendMessageFunction : public AsyncExtensionFunction {
+ public:
+ // Sends a reply back to the calling extension. Many extensions don't need
+ // a reply and will just ignore it.
+ void Reply(const std::string& message);
+
+ private:
~ExtensionTestSendMessageFunction() {}
virtual bool RunImpl();
DECLARE_EXTENSION_FUNCTION_NAME("test.sendMessage")
diff --git a/chrome/browser/extensions/extension_test_message_listener.cc b/chrome/browser/extensions/extension_test_message_listener.cc
index bfa9db7..423bf3b 100644
--- a/chrome/browser/extensions/extension_test_message_listener.cc
+++ b/chrome/browser/extensions/extension_test_message_listener.cc
@@ -4,14 +4,18 @@
#include "chrome/browser/extensions/extension_test_message_listener.h"
+#include "chrome/browser/extensions/extension_test_api.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/notification_type.h"
#include "chrome/test/ui_test_utils.h"
ExtensionTestMessageListener::ExtensionTestMessageListener(
- const std::string& expected_message)
- : expected_message_(expected_message), satisfied_(false),
- waiting_(false) {
+ const std::string& expected_message,
+ bool will_reply)
+ : expected_message_(expected_message),
+ satisfied_(false),
+ waiting_(false),
+ will_reply_(will_reply) {
registrar_.Add(this, NotificationType::EXTENSION_TEST_MESSAGE,
NotificationService::AllSources());
}
@@ -26,14 +30,27 @@ bool ExtensionTestMessageListener::WaitUntilSatisfied() {
return satisfied_;
}
+void ExtensionTestMessageListener::Reply(const std::string& message) {
+ DCHECK(satisfied_);
+ DCHECK(will_reply_);
+ function_->Reply(message);
+ function_ = NULL;
+ will_reply_ = false;
+}
+
void ExtensionTestMessageListener::Observe(
NotificationType type,
const NotificationSource& source,
const NotificationDetails& details) {
const std::string& content = *Details<std::string>(details).ptr();
+ function_ = Source<ExtensionTestSendMessageFunction>(source).ptr();
if (!satisfied_ && content == expected_message_) {
satisfied_ = true;
registrar_.RemoveAll(); // Stop listening for more messages.
+ if (!will_reply_) {
+ function_->Reply("");
+ function_ = NULL;
+ }
if (waiting_) {
waiting_ = false;
MessageLoopForUI::current()->Quit();
diff --git a/chrome/browser/extensions/extension_test_message_listener.h b/chrome/browser/extensions/extension_test_message_listener.h
index 2aeedd8..bead446 100644
--- a/chrome/browser/extensions/extension_test_message_listener.h
+++ b/chrome/browser/extensions/extension_test_message_listener.h
@@ -11,14 +11,7 @@
#include "chrome/common/notification_observer.h"
#include "chrome/common/notification_registrar.h"
-// A message from javascript sent via chrome.test.sendMessage().
-struct ExtensionTestMessage {
- // The sender's extension id.
- std::string extension_id;
-
- // The message content.
- std::string content;
-};
+class ExtensionTestSendMessageFunction;
// This class helps us wait for incoming messages sent from javascript via
// chrome.test.sendMessage(). A sample usage would be:
@@ -27,6 +20,18 @@ struct ExtensionTestMessage {
// ... do some work
// ASSERT_TRUE(listener.WaitUntilSatisfied());
//
+// It is also possible to have the extension wait for our reply. This is
+// useful for coordinating multiple pages/processes and having them wait on
+// each other. Example:
+//
+// ExtensionTestMessageListener listener1("foo1");
+// ExtensionTestMessageListener listener2("foo2");
+// ASSERT_TRUE(listener1.WaitUntilSatisfied());
+// ASSERT_TRUE(listener2.WaitUntilSatisfied());
+// ... do some work
+// listener1.Reply("foo2 is ready");
+// listener2.Reply("foo1 is ready");
+//
// TODO(asargent) - In the future we may want to add the ability to listen for
// multiple messages, and/or to wait for "any" message and then retrieve the
// contents of that message. We may also want to specify an extension id as
@@ -40,7 +45,8 @@ struct ExtensionTestMessage {
class ExtensionTestMessageListener : public NotificationObserver {
public:
// We immediately start listening for |expected_message|.
- explicit ExtensionTestMessageListener(const std::string& expected_message);
+ ExtensionTestMessageListener(const std::string& expected_message,
+ bool will_reply);
~ExtensionTestMessageListener();
// This returns true immediately if we've already gotten the expected
@@ -48,6 +54,10 @@ class ExtensionTestMessageListener : public NotificationObserver {
// interrupted and we still haven't gotten the message.
bool WaitUntilSatisfied();
+ // Send the given message as a reply. It is only valid to call this after
+ // WaitUntilSatisfied has returned true, and if will_reply is true.
+ void Reply(const std::string& message);
+
// Implements the NotificationObserver interface.
virtual void Observe(NotificationType type,
const NotificationSource& source,
@@ -65,6 +75,13 @@ class ExtensionTestMessageListener : public NotificationObserver {
// If we're waiting, then we want to post a quit task when the expected
// message arrives.
bool waiting_;
+
+ // If true, we expect the calling code to manually send a reply. Otherwise,
+ // we send an automatic empty reply to the extension.
+ bool will_reply_;
+
+ // The function we need to reply to.
+ ExtensionTestSendMessageFunction* function_;
};
#endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_TEST_MESSAGE_LISTENER_H_