blob: f46eae43a67fe1011dfb7197dd126f39ccd17a66 [file] [log] [blame]
// 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/message_loop/message_loop.h"
#include "base/run_loop.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::RunLoop::QuitCurrentWhenIdleDeprecated();
}
}
}