| // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "extensions/test/extension_test_message_listener.h" |
| |
| #include "base/strings/string_number_conversions.h" |
| #include "base/strings/string_util.h" |
| #include "content/public/browser/notification_service.h" |
| #include "content/public/browser/notification_source.h" |
| #include "content/public/test/test_utils.h" |
| #include "extensions/browser/api/test/test_api.h" |
| #include "extensions/browser/notification_types.h" |
| |
| ExtensionTestMessageListener::ExtensionTestMessageListener( |
| const std::string& expected_message, |
| bool will_reply) |
| : expected_message_(expected_message), |
| satisfied_(false), |
| waiting_(false), |
| wait_for_any_message_(false), |
| will_reply_(will_reply), |
| replied_(false), |
| failed_(false) { |
| registrar_.Add(this, |
| extensions::NOTIFICATION_EXTENSION_TEST_MESSAGE, |
| content::NotificationService::AllSources()); |
| } |
| |
| ExtensionTestMessageListener::ExtensionTestMessageListener(bool will_reply) |
| : satisfied_(false), |
| waiting_(false), |
| wait_for_any_message_(true), |
| will_reply_(will_reply), |
| replied_(false), |
| failed_(false) { |
| registrar_.Add(this, |
| extensions::NOTIFICATION_EXTENSION_TEST_MESSAGE, |
| content::NotificationService::AllSources()); |
| } |
| |
| ExtensionTestMessageListener::~ExtensionTestMessageListener() {} |
| |
| bool ExtensionTestMessageListener::WaitUntilSatisfied() { |
| if (satisfied_) |
| return !failed_; |
| waiting_ = true; |
| content::RunMessageLoop(); |
| return !failed_; |
| } |
| |
| void ExtensionTestMessageListener::Reply(const std::string& message) { |
| CHECK(satisfied_); |
| CHECK(!replied_); |
| |
| replied_ = true; |
| function_->Reply(message); |
| function_ = NULL; |
| } |
| |
| void ExtensionTestMessageListener::Reply(int message) { |
| Reply(base::IntToString(message)); |
| } |
| |
| void ExtensionTestMessageListener::ReplyWithError(const std::string& error) { |
| CHECK(satisfied_); |
| CHECK(!replied_); |
| |
| replied_ = true; |
| function_->ReplyWithError(error); |
| function_ = NULL; |
| } |
| |
| void ExtensionTestMessageListener::Reset() { |
| satisfied_ = false; |
| failed_ = false; |
| message_.clear(); |
| replied_ = false; |
| } |
| |
| void ExtensionTestMessageListener::Observe( |
| int type, |
| const content::NotificationSource& source, |
| const content::NotificationDetails& details) { |
| DCHECK_EQ(extensions::NOTIFICATION_EXTENSION_TEST_MESSAGE, type); |
| |
| // Return immediately if we're already satisfied or it's not the right |
| // extension. |
| extensions::TestSendMessageFunction* function = |
| content::Source<extensions::TestSendMessageFunction>(source).ptr(); |
| if (satisfied_ || |
| (!extension_id_.empty() && function->extension_id() != extension_id_)) { |
| return; |
| } |
| |
| // We should have an empty message if we're not already satisfied. |
| CHECK(message_.empty()); |
| |
| std::pair<std::string, bool*>* message_details = |
| content::Details<std::pair<std::string, bool*>>(details).ptr(); |
| const std::string& message = message_details->first; |
| if (message == expected_message_ || wait_for_any_message_ || |
| (!failure_message_.empty() && message == failure_message_)) { |
| // We always reply to the message we were waiting for, even if it's just an |
| // empty string. |
| *message_details->second = true; |
| message_ = message; |
| satisfied_ = true; |
| failed_ = (message_ == failure_message_); |
| |
| // Reply immediately, or save the function for future use. |
| function_ = function; |
| if (!will_reply_) |
| Reply(std::string()); |
| |
| if (waiting_) { |
| waiting_ = false; |
| base::MessageLoopForUI::current()->QuitWhenIdle(); |
| } |
| } |
| } |