// 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 <string>
#include "base/bind.h"
#include "base/memory/ref_counted.h"
#include "base/test/test_simple_task_runner.h"
#include "device/bluetooth/bluetooth_adapter.h"
#include "device/bluetooth/bluetooth_adapter_win.h"
#include "device/bluetooth/bluetooth_device.h"
#include "device/bluetooth/bluetooth_task_manager_win.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace {
const char kAdapterAddress[] = "A1:B2:C3:D4:E5:F6";
const char kAdapterName[] = "Bluetooth Adapter Name";
void MakeDeviceState(const std::string& name,
const std::string& address,
device::BluetoothTaskManagerWin::DeviceState* state) {
state->name = name;
state->address = address;
state->bluetooth_class = 0;
state->authenticated = false;
state->connected = false;
}
class AdapterObserver : public device::BluetoothAdapter::Observer {
public:
AdapterObserver()
: num_present_changed_(0),
num_powered_changed_(0),
num_discovering_changed_(0),
num_device_added_(0) {
}
virtual void AdapterPresentChanged(
device::BluetoothAdapter* adapter, bool present) OVERRIDE {
num_present_changed_++;
}
virtual void AdapterPoweredChanged(
device::BluetoothAdapter* adapter, bool powered) OVERRIDE {
num_powered_changed_++;
}
virtual void AdapterDiscoveringChanged(
device::BluetoothAdapter* adapter, bool discovering) OVERRIDE {
num_discovering_changed_++;
}
virtual void DeviceAdded(
device::BluetoothAdapter* adapter,
device::BluetoothDevice* device) OVERRIDE {
num_device_added_++;
}
int num_present_changed() const {
return num_present_changed_;
}
int num_powered_changed() const {
return num_powered_changed_;
}
int num_discovering_changed() const {
return num_discovering_changed_;
}
int num_device_added() const {
return num_device_added_;
}
private:
int num_present_changed_;
int num_powered_changed_;
int num_discovering_changed_;
int num_device_added_;
};
} // namespace
namespace device {
class BluetoothAdapterWinTest : public testing::Test {
public:
BluetoothAdapterWinTest()
: ui_task_runner_(new base::TestSimpleTaskRunner()),
bluetooth_task_runner_(new base::TestSimpleTaskRunner()),
adapter_(new BluetoothAdapterWin(
base::Bind(&BluetoothAdapterWinTest::RunInitCallback,
base::Unretained(this)))),
adapter_win_(static_cast<BluetoothAdapterWin*>(adapter_.get())),
init_callback_called_(false) {
adapter_win_->InitForTest(ui_task_runner_, bluetooth_task_runner_);
}
virtual void SetUp() OVERRIDE {
adapter_win_->AddObserver(&adapter_observer_);
num_start_discovery_callbacks_ = 0;
num_start_discovery_error_callbacks_ = 0;
num_stop_discovery_callbacks_ = 0;
num_stop_discovery_error_callbacks_ = 0;
}
virtual void TearDown() OVERRIDE {
adapter_win_->RemoveObserver(&adapter_observer_);
}
void RunInitCallback() {
init_callback_called_ = true;
}
void IncrementNumStartDiscoveryCallbacks() {
num_start_discovery_callbacks_++;
}
void IncrementNumStartDiscoveryErrorCallbacks() {
num_start_discovery_error_callbacks_++;
}
void IncrementNumStopDiscoveryCallbacks() {
num_stop_discovery_callbacks_++;
}
void IncrementNumStopDiscoveryErrorCallbacks() {
num_stop_discovery_error_callbacks_++;
}
void CallAddDiscoverySession(
const base::Closure& callback,
const BluetoothAdapter::ErrorCallback& error_callback) {
adapter_win_->AddDiscoverySession(callback, error_callback);
}
void CallRemoveDiscoverySession(
const base::Closure& callback,
const BluetoothAdapter::ErrorCallback& error_callback) {
adapter_win_->RemoveDiscoverySession(callback, error_callback);
}
protected:
scoped_refptr<base::TestSimpleTaskRunner> ui_task_runner_;
scoped_refptr<base::TestSimpleTaskRunner> bluetooth_task_runner_;
scoped_refptr<BluetoothAdapter> adapter_;
BluetoothAdapterWin* adapter_win_;
AdapterObserver adapter_observer_;
bool init_callback_called_;
int num_start_discovery_callbacks_;
int num_start_discovery_error_callbacks_;
int num_stop_discovery_callbacks_;
int num_stop_discovery_error_callbacks_;
};
TEST_F(BluetoothAdapterWinTest, AdapterNotPresent) {
BluetoothTaskManagerWin::AdapterState state;
adapter_win_->AdapterStateChanged(state);
EXPECT_FALSE(adapter_win_->IsPresent());
}
TEST_F(BluetoothAdapterWinTest, AdapterPresent) {
BluetoothTaskManagerWin::AdapterState state;
state.address = kAdapterAddress;
state.name = kAdapterName;
adapter_win_->AdapterStateChanged(state);
EXPECT_TRUE(adapter_win_->IsPresent());
}
TEST_F(BluetoothAdapterWinTest, AdapterPresentChanged) {
BluetoothTaskManagerWin::AdapterState state;
state.address = kAdapterAddress;
state.name = kAdapterName;
adapter_win_->AdapterStateChanged(state);
EXPECT_EQ(1, adapter_observer_.num_present_changed());
adapter_win_->AdapterStateChanged(state);
EXPECT_EQ(1, adapter_observer_.num_present_changed());
BluetoothTaskManagerWin::AdapterState empty_state;
adapter_win_->AdapterStateChanged(empty_state);
EXPECT_EQ(2, adapter_observer_.num_present_changed());
}
TEST_F(BluetoothAdapterWinTest, AdapterPoweredChanged) {
BluetoothTaskManagerWin::AdapterState state;
state.powered = true;
adapter_win_->AdapterStateChanged(state);
EXPECT_EQ(1, adapter_observer_.num_powered_changed());
adapter_win_->AdapterStateChanged(state);
EXPECT_EQ(1, adapter_observer_.num_powered_changed());
state.powered = false;
adapter_win_->AdapterStateChanged(state);
EXPECT_EQ(2, adapter_observer_.num_powered_changed());
}
TEST_F(BluetoothAdapterWinTest, AdapterInitialized) {
EXPECT_FALSE(adapter_win_->IsInitialized());
EXPECT_FALSE(init_callback_called_);
BluetoothTaskManagerWin::AdapterState state;
adapter_win_->AdapterStateChanged(state);
EXPECT_TRUE(adapter_win_->IsInitialized());
EXPECT_TRUE(init_callback_called_);
}
TEST_F(BluetoothAdapterWinTest, SingleStartDiscovery) {
bluetooth_task_runner_->ClearPendingTasks();
CallAddDiscoverySession(
base::Bind(&BluetoothAdapterWinTest::IncrementNumStartDiscoveryCallbacks,
base::Unretained(this)),
BluetoothAdapter::ErrorCallback());
EXPECT_TRUE(ui_task_runner_->GetPendingTasks().empty());
EXPECT_EQ(1, bluetooth_task_runner_->GetPendingTasks().size());
EXPECT_FALSE(adapter_->IsDiscovering());
EXPECT_EQ(0, num_start_discovery_callbacks_);
adapter_win_->DiscoveryStarted(true);
ui_task_runner_->RunPendingTasks();
EXPECT_TRUE(adapter_->IsDiscovering());
EXPECT_EQ(1, num_start_discovery_callbacks_);
EXPECT_EQ(1, adapter_observer_.num_discovering_changed());
}
TEST_F(BluetoothAdapterWinTest, SingleStartDiscoveryFailure) {
CallAddDiscoverySession(
base::Closure(),
base::Bind(
&BluetoothAdapterWinTest::IncrementNumStartDiscoveryErrorCallbacks,
base::Unretained(this)));
adapter_win_->DiscoveryStarted(false);
ui_task_runner_->RunPendingTasks();
EXPECT_FALSE(adapter_->IsDiscovering());
EXPECT_EQ(1, num_start_discovery_error_callbacks_);
EXPECT_EQ(0, adapter_observer_.num_discovering_changed());
}
TEST_F(BluetoothAdapterWinTest, MultipleStartDiscoveries) {
bluetooth_task_runner_->ClearPendingTasks();
int num_discoveries = 5;
for (int i = 0; i < num_discoveries; i++) {
CallAddDiscoverySession(
base::Bind(
&BluetoothAdapterWinTest::IncrementNumStartDiscoveryCallbacks,
base::Unretained(this)),
BluetoothAdapter::ErrorCallback());
EXPECT_EQ(1, bluetooth_task_runner_->GetPendingTasks().size());
}
EXPECT_TRUE(ui_task_runner_->GetPendingTasks().empty());
EXPECT_FALSE(adapter_->IsDiscovering());
EXPECT_EQ(0, num_start_discovery_callbacks_);
adapter_win_->DiscoveryStarted(true);
ui_task_runner_->RunPendingTasks();
EXPECT_TRUE(adapter_->IsDiscovering());
EXPECT_EQ(num_discoveries, num_start_discovery_callbacks_);
EXPECT_EQ(1, adapter_observer_.num_discovering_changed());
}
TEST_F(BluetoothAdapterWinTest, MultipleStartDiscoveriesFailure) {
int num_discoveries = 5;
for (int i = 0; i < num_discoveries; i++) {
CallAddDiscoverySession(
base::Closure(),
base::Bind(
&BluetoothAdapterWinTest::IncrementNumStartDiscoveryErrorCallbacks,
base::Unretained(this)));
}
adapter_win_->DiscoveryStarted(false);
ui_task_runner_->RunPendingTasks();
EXPECT_FALSE(adapter_->IsDiscovering());
EXPECT_EQ(num_discoveries, num_start_discovery_error_callbacks_);
EXPECT_EQ(0, adapter_observer_.num_discovering_changed());
}
TEST_F(BluetoothAdapterWinTest, MultipleStartDiscoveriesAfterDiscovering) {
CallAddDiscoverySession(
base::Bind(&BluetoothAdapterWinTest::IncrementNumStartDiscoveryCallbacks,
base::Unretained(this)),
BluetoothAdapter::ErrorCallback());
adapter_win_->DiscoveryStarted(true);
ui_task_runner_->RunPendingTasks();
EXPECT_TRUE(adapter_->IsDiscovering());
EXPECT_EQ(1, num_start_discovery_callbacks_);
bluetooth_task_runner_->ClearPendingTasks();
for (int i = 0; i < 5; i++) {
int num_start_discovery_callbacks = num_start_discovery_callbacks_;
CallAddDiscoverySession(
base::Bind(
&BluetoothAdapterWinTest::IncrementNumStartDiscoveryCallbacks,
base::Unretained(this)),
BluetoothAdapter::ErrorCallback());
EXPECT_TRUE(adapter_->IsDiscovering());
EXPECT_TRUE(bluetooth_task_runner_->GetPendingTasks().empty());
EXPECT_TRUE(ui_task_runner_->GetPendingTasks().empty());
EXPECT_EQ(num_start_discovery_callbacks + 1,
num_start_discovery_callbacks_);
}
EXPECT_EQ(1, adapter_observer_.num_discovering_changed());
}
TEST_F(BluetoothAdapterWinTest, StartDiscoveryAfterDiscoveringFailure) {
CallAddDiscoverySession(
base::Closure(),
base::Bind(
&BluetoothAdapterWinTest::IncrementNumStartDiscoveryErrorCallbacks,
base::Unretained(this)));
adapter_win_->DiscoveryStarted(false);
ui_task_runner_->RunPendingTasks();
EXPECT_FALSE(adapter_->IsDiscovering());
EXPECT_EQ(1, num_start_discovery_error_callbacks_);
CallAddDiscoverySession(
base::Bind(&BluetoothAdapterWinTest::IncrementNumStartDiscoveryCallbacks,
base::Unretained(this)),
BluetoothAdapter::ErrorCallback());
adapter_win_->DiscoveryStarted(true);
ui_task_runner_->RunPendingTasks();
EXPECT_TRUE(adapter_->IsDiscovering());
EXPECT_EQ(1, num_start_discovery_callbacks_);
}
TEST_F(BluetoothAdapterWinTest, SingleStopDiscovery) {
CallAddDiscoverySession(
base::Closure(), BluetoothAdapter::ErrorCallback());
adapter_win_->DiscoveryStarted(true);
ui_task_runner_->ClearPendingTasks();
CallRemoveDiscoverySession(
base::Bind(&BluetoothAdapterWinTest::IncrementNumStopDiscoveryCallbacks,
base::Unretained(this)),
BluetoothAdapter::ErrorCallback());
EXPECT_TRUE(adapter_->IsDiscovering());
EXPECT_EQ(0, num_stop_discovery_callbacks_);
bluetooth_task_runner_->ClearPendingTasks();
adapter_win_->DiscoveryStopped();
ui_task_runner_->RunPendingTasks();
EXPECT_FALSE(adapter_->IsDiscovering());
EXPECT_EQ(1, num_stop_discovery_callbacks_);
EXPECT_TRUE(bluetooth_task_runner_->GetPendingTasks().empty());
EXPECT_EQ(2, adapter_observer_.num_discovering_changed());
}
TEST_F(BluetoothAdapterWinTest, MultipleStopDiscoveries) {
int num_discoveries = 5;
for (int i = 0; i < num_discoveries; i++) {
CallAddDiscoverySession(
base::Closure(), BluetoothAdapter::ErrorCallback());
}
adapter_win_->DiscoveryStarted(true);
ui_task_runner_->ClearPendingTasks();
bluetooth_task_runner_->ClearPendingTasks();
for (int i = 0; i < num_discoveries - 1; i++) {
CallRemoveDiscoverySession(
base::Bind(&BluetoothAdapterWinTest::IncrementNumStopDiscoveryCallbacks,
base::Unretained(this)),
BluetoothAdapter::ErrorCallback());
EXPECT_TRUE(bluetooth_task_runner_->GetPendingTasks().empty());
ui_task_runner_->RunPendingTasks();
EXPECT_EQ(i + 1, num_stop_discovery_callbacks_);
}
CallRemoveDiscoverySession(
base::Bind(&BluetoothAdapterWinTest::IncrementNumStopDiscoveryCallbacks,
base::Unretained(this)),
BluetoothAdapter::ErrorCallback());
EXPECT_EQ(1, bluetooth_task_runner_->GetPendingTasks().size());
EXPECT_TRUE(adapter_->IsDiscovering());
adapter_win_->DiscoveryStopped();
ui_task_runner_->RunPendingTasks();
EXPECT_FALSE(adapter_->IsDiscovering());
EXPECT_EQ(num_discoveries, num_stop_discovery_callbacks_);
EXPECT_EQ(2, adapter_observer_.num_discovering_changed());
}
TEST_F(BluetoothAdapterWinTest,
StartDiscoveryAndStartDiscoveryAndStopDiscoveries) {
CallAddDiscoverySession(
base::Bind(&BluetoothAdapterWinTest::IncrementNumStartDiscoveryCallbacks,
base::Unretained(this)),
BluetoothAdapter::ErrorCallback());
adapter_win_->DiscoveryStarted(true);
CallAddDiscoverySession(
base::Bind(&BluetoothAdapterWinTest::IncrementNumStartDiscoveryCallbacks,
base::Unretained(this)),
BluetoothAdapter::ErrorCallback());
ui_task_runner_->ClearPendingTasks();
bluetooth_task_runner_->ClearPendingTasks();
CallRemoveDiscoverySession(
base::Bind(&BluetoothAdapterWinTest::IncrementNumStopDiscoveryCallbacks,
base::Unretained(this)),
BluetoothAdapter::ErrorCallback());
EXPECT_TRUE(bluetooth_task_runner_->GetPendingTasks().empty());
CallRemoveDiscoverySession(
base::Bind(&BluetoothAdapterWinTest::IncrementNumStopDiscoveryCallbacks,
base::Unretained(this)),
BluetoothAdapter::ErrorCallback());
EXPECT_EQ(1, bluetooth_task_runner_->GetPendingTasks().size());
}
TEST_F(BluetoothAdapterWinTest,
StartDiscoveryAndStopDiscoveryAndStartDiscovery) {
CallAddDiscoverySession(
base::Closure(), BluetoothAdapter::ErrorCallback());
adapter_win_->DiscoveryStarted(true);
EXPECT_TRUE(adapter_->IsDiscovering());
CallRemoveDiscoverySession(
base::Closure(), BluetoothAdapter::ErrorCallback());
adapter_win_->DiscoveryStopped();
EXPECT_FALSE(adapter_->IsDiscovering());
CallAddDiscoverySession(
base::Closure(), BluetoothAdapter::ErrorCallback());
adapter_win_->DiscoveryStarted(true);
EXPECT_TRUE(adapter_->IsDiscovering());
}
TEST_F(BluetoothAdapterWinTest, StartDiscoveryBeforeDiscoveryStopped) {
CallAddDiscoverySession(
base::Closure(), BluetoothAdapter::ErrorCallback());
adapter_win_->DiscoveryStarted(true);
CallRemoveDiscoverySession(
base::Closure(), BluetoothAdapter::ErrorCallback());
CallAddDiscoverySession(
base::Closure(), BluetoothAdapter::ErrorCallback());
bluetooth_task_runner_->ClearPendingTasks();
adapter_win_->DiscoveryStopped();
EXPECT_EQ(1, bluetooth_task_runner_->GetPendingTasks().size());
}
TEST_F(BluetoothAdapterWinTest, StopDiscoveryWithoutStartDiscovery) {
CallRemoveDiscoverySession(
base::Closure(),
base::Bind(
&BluetoothAdapterWinTest::IncrementNumStopDiscoveryErrorCallbacks,
base::Unretained(this)));
EXPECT_EQ(1, num_stop_discovery_error_callbacks_);
}
TEST_F(BluetoothAdapterWinTest, StopDiscoveryBeforeDiscoveryStarted) {
CallAddDiscoverySession(
base::Closure(), BluetoothAdapter::ErrorCallback());
CallRemoveDiscoverySession(
base::Closure(), BluetoothAdapter::ErrorCallback());
bluetooth_task_runner_->ClearPendingTasks();
adapter_win_->DiscoveryStarted(true);
EXPECT_EQ(1, bluetooth_task_runner_->GetPendingTasks().size());
}
TEST_F(BluetoothAdapterWinTest, StartAndStopBeforeDiscoveryStarted) {
int num_expected_start_discoveries = 3;
int num_expected_stop_discoveries = 2;
for (int i = 0; i < num_expected_start_discoveries; i++) {
CallAddDiscoverySession(
base::Bind(
&BluetoothAdapterWinTest::IncrementNumStartDiscoveryCallbacks,
base::Unretained(this)),
BluetoothAdapter::ErrorCallback());
}
for (int i = 0; i < num_expected_stop_discoveries; i++) {
CallRemoveDiscoverySession(
base::Bind(
&BluetoothAdapterWinTest::IncrementNumStopDiscoveryCallbacks,
base::Unretained(this)),
BluetoothAdapter::ErrorCallback());
}
bluetooth_task_runner_->ClearPendingTasks();
adapter_win_->DiscoveryStarted(true);
EXPECT_TRUE(bluetooth_task_runner_->GetPendingTasks().empty());
ui_task_runner_->RunPendingTasks();
EXPECT_EQ(num_expected_start_discoveries, num_start_discovery_callbacks_);
EXPECT_EQ(num_expected_stop_discoveries, num_stop_discovery_callbacks_);
}
TEST_F(BluetoothAdapterWinTest, StopDiscoveryBeforeDiscoveryStartedAndFailed) {
CallAddDiscoverySession(
base::Closure(),
base::Bind(
&BluetoothAdapterWinTest::IncrementNumStartDiscoveryErrorCallbacks,
base::Unretained(this)));
CallRemoveDiscoverySession(
base::Bind(
&BluetoothAdapterWinTest::IncrementNumStopDiscoveryCallbacks,
base::Unretained(this)),
BluetoothAdapter::ErrorCallback());
ui_task_runner_->ClearPendingTasks();
adapter_win_->DiscoveryStarted(false);
ui_task_runner_->RunPendingTasks();
EXPECT_EQ(1, num_start_discovery_error_callbacks_);
EXPECT_EQ(1, num_stop_discovery_callbacks_);
EXPECT_EQ(0, adapter_observer_.num_discovering_changed());
}
TEST_F(BluetoothAdapterWinTest, DevicesDiscovered) {
BluetoothTaskManagerWin::DeviceState* android_phone_state =
new BluetoothTaskManagerWin::DeviceState();
MakeDeviceState("phone", "android phone address", android_phone_state);
BluetoothTaskManagerWin::DeviceState* laptop_state =
new BluetoothTaskManagerWin::DeviceState();
MakeDeviceState("laptop", "laptop address", laptop_state);
BluetoothTaskManagerWin::DeviceState* iphone_state =
new BluetoothTaskManagerWin::DeviceState();
MakeDeviceState("phone", "iphone address", iphone_state);
ScopedVector<BluetoothTaskManagerWin::DeviceState> devices;
devices.push_back(android_phone_state);
devices.push_back(laptop_state);
devices.push_back(iphone_state);
adapter_win_->DevicesDiscovered(devices);
EXPECT_EQ(3, adapter_observer_.num_device_added());
}
} // namespace device