diff options
author | mpcomplete@chromium.org <mpcomplete@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-10-08 21:32:34 +0000 |
---|---|---|
committer | mpcomplete@chromium.org <mpcomplete@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-10-08 21:32:34 +0000 |
commit | 414785a5dce34bbe90b08c360992fd850612c2a1 (patch) | |
tree | 74a3f7b053dfc409afbc9187281dc0eac87160de /chrome/browser | |
parent | 0df4ace4713e5b74a5215638111d514971aaf40d (diff) | |
download | chromium_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')
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_ |