blob: d536eb08901aa96948b34a57b662435a4c1fdafd [file] [log] [blame]
// Copyright 2016 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 "device/bluetooth/bluez/bluetooth_socket_bluez.h"
#include <memory>
#include "base/bind.h"
#include "base/memory/ref_counted.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/test/scoped_async_task_scheduler.h"
#include "device/bluetooth/bluetooth_adapter.h"
#include "device/bluetooth/bluetooth_adapter_factory.h"
#include "device/bluetooth/bluetooth_device.h"
#include "device/bluetooth/bluetooth_socket.h"
#include "device/bluetooth/bluetooth_socket_thread.h"
#include "device/bluetooth/bluetooth_uuid.h"
#include "device/bluetooth/bluez/bluetooth_adapter_bluez.h"
#include "device/bluetooth/bluez/bluetooth_device_bluez.h"
#include "device/bluetooth/dbus/bluez_dbus_manager.h"
#include "device/bluetooth/dbus/fake_bluetooth_adapter_client.h"
#include "device/bluetooth/dbus/fake_bluetooth_agent_manager_client.h"
#include "device/bluetooth/dbus/fake_bluetooth_device_client.h"
#include "device/bluetooth/dbus/fake_bluetooth_gatt_service_client.h"
#include "device/bluetooth/dbus/fake_bluetooth_input_client.h"
#include "device/bluetooth/dbus/fake_bluetooth_profile_manager_client.h"
#include "device/bluetooth/dbus/fake_bluetooth_profile_service_provider.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
#include "testing/gtest/include/gtest/gtest.h"
using device::BluetoothAdapter;
using device::BluetoothDevice;
using device::BluetoothSocket;
using device::BluetoothSocketThread;
using device::BluetoothUUID;
namespace {
void DoNothingDBusErrorCallback(const std::string& error_name,
const std::string& error_message) {}
} // namespace
namespace bluez {
class BluetoothSocketBlueZTest : public testing::Test {
public:
BluetoothSocketBlueZTest()
: success_callback_count_(0),
error_callback_count_(0),
last_bytes_sent_(0),
last_bytes_received_(0),
last_reason_(BluetoothSocket::kSystemError) {}
void SetUp() override {
std::unique_ptr<bluez::BluezDBusManagerSetter> dbus_setter =
bluez::BluezDBusManager::GetSetterForTesting();
dbus_setter->SetBluetoothAdapterClient(
std::unique_ptr<bluez::BluetoothAdapterClient>(
new bluez::FakeBluetoothAdapterClient));
dbus_setter->SetBluetoothAgentManagerClient(
std::unique_ptr<bluez::BluetoothAgentManagerClient>(
new bluez::FakeBluetoothAgentManagerClient));
dbus_setter->SetBluetoothDeviceClient(
std::unique_ptr<bluez::BluetoothDeviceClient>(
new bluez::FakeBluetoothDeviceClient));
dbus_setter->SetBluetoothGattServiceClient(
std::unique_ptr<bluez::BluetoothGattServiceClient>(
new bluez::FakeBluetoothGattServiceClient));
dbus_setter->SetBluetoothInputClient(
std::unique_ptr<bluez::BluetoothInputClient>(
new bluez::FakeBluetoothInputClient));
dbus_setter->SetBluetoothProfileManagerClient(
std::unique_ptr<bluez::BluetoothProfileManagerClient>(
new bluez::FakeBluetoothProfileManagerClient));
BluetoothSocketThread::Get();
// Grab a pointer to the adapter.
{
base::RunLoop run_loop;
device::BluetoothAdapterFactory::GetAdapter(
base::Bind(&BluetoothSocketBlueZTest::AdapterCallback,
base::Unretained(this), run_loop.QuitWhenIdleClosure()));
run_loop.Run();
}
ASSERT_TRUE(adapter_.get() != nullptr);
ASSERT_TRUE(adapter_->IsInitialized());
ASSERT_TRUE(adapter_->IsPresent());
// Turn on the adapter.
adapter_->SetPowered(true, base::Bind(&base::DoNothing),
base::Bind(&base::DoNothing));
ASSERT_TRUE(adapter_->IsPowered());
}
void TearDown() override {
adapter_ = nullptr;
BluetoothSocketThread::CleanupForTesting();
bluez::BluezDBusManager::Shutdown();
}
void AdapterCallback(base::OnceClosure continuation,
scoped_refptr<BluetoothAdapter> adapter) {
adapter_ = adapter;
std::move(continuation).Run();
}
void SuccessCallback(base::OnceClosure continuation) {
++success_callback_count_;
std::move(continuation).Run();
}
void ErrorCallback(base::OnceClosure continuation,
const std::string& message) {
++error_callback_count_;
last_message_ = message;
std::move(continuation).Run();
}
void ConnectToServiceSuccessCallback(base::OnceClosure continuation,
scoped_refptr<BluetoothSocket> socket) {
++success_callback_count_;
last_socket_ = socket;
std::move(continuation).Run();
}
void SendSuccessCallback(base::OnceClosure continuation, int bytes_sent) {
++success_callback_count_;
last_bytes_sent_ = bytes_sent;
std::move(continuation).Run();
}
void ReceiveSuccessCallback(base::OnceClosure continuation,
int bytes_received,
scoped_refptr<net::IOBuffer> io_buffer) {
++success_callback_count_;
last_bytes_received_ = bytes_received;
last_io_buffer_ = io_buffer;
std::move(continuation).Run();
}
void ReceiveErrorCallback(base::OnceClosure continuation,
BluetoothSocket::ErrorReason reason,
const std::string& error_message) {
++error_callback_count_;
last_reason_ = reason;
last_message_ = error_message;
std::move(continuation).Run();
}
void CreateServiceSuccessCallback(base::OnceClosure continuation,
scoped_refptr<BluetoothSocket> socket) {
++success_callback_count_;
last_socket_ = socket;
std::move(continuation).Run();
}
void AcceptSuccessCallback(base::OnceClosure continuation,
const BluetoothDevice* device,
scoped_refptr<BluetoothSocket> socket) {
++success_callback_count_;
last_device_ = device;
last_socket_ = socket;
std::move(continuation).Run();
}
void ImmediateSuccessCallback() { ++success_callback_count_; }
protected:
base::MessageLoop message_loop_;
base::test::ScopedAsyncTaskScheduler scoped_async_task_scheduler_;
scoped_refptr<BluetoothAdapter> adapter_;
unsigned int success_callback_count_;
unsigned int error_callback_count_;
std::string last_message_;
scoped_refptr<BluetoothSocket> last_socket_;
int last_bytes_sent_;
int last_bytes_received_;
scoped_refptr<net::IOBuffer> last_io_buffer_;
BluetoothSocket::ErrorReason last_reason_;
const BluetoothDevice* last_device_;
};
TEST_F(BluetoothSocketBlueZTest, Connect) {
BluetoothDevice* device = adapter_->GetDevice(
bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress);
ASSERT_TRUE(device != nullptr);
{
base::RunLoop run_loop;
device->ConnectToService(
BluetoothUUID(bluez::FakeBluetoothProfileManagerClient::kRfcommUuid),
base::Bind(&BluetoothSocketBlueZTest::ConnectToServiceSuccessCallback,
base::Unretained(this), run_loop.QuitWhenIdleClosure()),
base::Bind(&BluetoothSocketBlueZTest::ErrorCallback,
base::Unretained(this), run_loop.QuitWhenIdleClosure()));
run_loop.Run();
}
EXPECT_EQ(1U, success_callback_count_);
EXPECT_EQ(0U, error_callback_count_);
EXPECT_TRUE(last_socket_.get() != nullptr);
// Take ownership of the socket for the remainder of the test.
scoped_refptr<BluetoothSocket> socket = last_socket_;
last_socket_ = nullptr;
success_callback_count_ = 0;
error_callback_count_ = 0;
// Send data to the socket, expect all of the data to be sent.
scoped_refptr<net::StringIOBuffer> write_buffer(
new net::StringIOBuffer("test"));
{
base::RunLoop run_loop;
socket->Send(
write_buffer.get(), write_buffer->size(),
base::Bind(&BluetoothSocketBlueZTest::SendSuccessCallback,
base::Unretained(this), run_loop.QuitWhenIdleClosure()),
base::Bind(&BluetoothSocketBlueZTest::ErrorCallback,
base::Unretained(this), run_loop.QuitWhenIdleClosure()));
run_loop.Run();
}
EXPECT_EQ(1U, success_callback_count_);
EXPECT_EQ(0U, error_callback_count_);
EXPECT_EQ(last_bytes_sent_, write_buffer->size());
success_callback_count_ = 0;
error_callback_count_ = 0;
// Receive data from the socket, and fetch the buffer from the callback; since
// the fake is an echo server, we expect to receive what we wrote.
{
base::RunLoop run_loop;
socket->Receive(
4096,
base::Bind(&BluetoothSocketBlueZTest::ReceiveSuccessCallback,
base::Unretained(this), run_loop.QuitWhenIdleClosure()),
base::Bind(&BluetoothSocketBlueZTest::ReceiveErrorCallback,
base::Unretained(this), run_loop.QuitWhenIdleClosure()));
run_loop.Run();
}
EXPECT_EQ(1U, success_callback_count_);
EXPECT_EQ(0U, error_callback_count_);
EXPECT_EQ(4, last_bytes_received_);
EXPECT_TRUE(last_io_buffer_.get() != nullptr);
// Take ownership of the received buffer.
scoped_refptr<net::IOBuffer> read_buffer = last_io_buffer_;
last_io_buffer_ = nullptr;
success_callback_count_ = 0;
error_callback_count_ = 0;
std::string data = std::string(read_buffer->data(), last_bytes_received_);
EXPECT_EQ("test", data);
read_buffer = nullptr;
// Receive data again; the socket will have been closed, this should cause a
// disconnected error to be returned via the error callback.
{
base::RunLoop run_loop;
socket->Receive(
4096,
base::Bind(&BluetoothSocketBlueZTest::ReceiveSuccessCallback,
base::Unretained(this), run_loop.QuitWhenIdleClosure()),
base::Bind(&BluetoothSocketBlueZTest::ReceiveErrorCallback,
base::Unretained(this), run_loop.QuitWhenIdleClosure()));
run_loop.Run();
}
EXPECT_EQ(0U, success_callback_count_);
EXPECT_EQ(1U, error_callback_count_);
EXPECT_EQ(BluetoothSocket::kDisconnected, last_reason_);
EXPECT_EQ(net::ErrorToString(net::OK), last_message_);
success_callback_count_ = 0;
error_callback_count_ = 0;
// Send data again; since the socket is closed we should get a system error
// equivalent to the connection reset error.
write_buffer = new net::StringIOBuffer("second test");
{
base::RunLoop run_loop;
socket->Send(
write_buffer.get(), write_buffer->size(),
base::Bind(&BluetoothSocketBlueZTest::SendSuccessCallback,
base::Unretained(this), run_loop.QuitWhenIdleClosure()),
base::Bind(&BluetoothSocketBlueZTest::ErrorCallback,
base::Unretained(this), run_loop.QuitWhenIdleClosure()));
run_loop.Run();
}
EXPECT_EQ(0U, success_callback_count_);
EXPECT_EQ(1U, error_callback_count_);
EXPECT_EQ(net::ErrorToString(net::ERR_CONNECTION_RESET), last_message_);
success_callback_count_ = 0;
error_callback_count_ = 0;
// Close our end of the socket.
{
base::RunLoop run_loop;
socket->Disconnect(base::Bind(&BluetoothSocketBlueZTest::SuccessCallback,
base::Unretained(this),
run_loop.QuitWhenIdleClosure()));
run_loop.Run();
}
EXPECT_EQ(1U, success_callback_count_);
}
TEST_F(BluetoothSocketBlueZTest, Listen) {
{
base::RunLoop run_loop;
adapter_->CreateRfcommService(
BluetoothUUID(bluez::FakeBluetoothProfileManagerClient::kRfcommUuid),
BluetoothAdapter::ServiceOptions(),
base::Bind(&BluetoothSocketBlueZTest::CreateServiceSuccessCallback,
base::Unretained(this), run_loop.QuitWhenIdleClosure()),
base::Bind(&BluetoothSocketBlueZTest::ErrorCallback,
base::Unretained(this), run_loop.QuitWhenIdleClosure()));
run_loop.Run();
}
EXPECT_EQ(1U, success_callback_count_);
EXPECT_EQ(0U, error_callback_count_);
EXPECT_TRUE(last_socket_.get() != nullptr);
// Take ownership of the socket for the remainder of the test.
scoped_refptr<BluetoothSocket> server_socket = last_socket_;
last_socket_ = nullptr;
success_callback_count_ = 0;
error_callback_count_ = 0;
// Simulate an incoming connection by just calling the ConnectProfile method
// of the underlying fake device client (from the BlueZ point of view,
// outgoing and incoming look the same).
//
// This is done before the Accept() call to simulate a pending call at the
// point that Accept() is called.
bluez::FakeBluetoothDeviceClient* fake_bluetooth_device_client =
static_cast<bluez::FakeBluetoothDeviceClient*>(
bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient());
BluetoothDevice* device = adapter_->GetDevice(
bluez::FakeBluetoothDeviceClient::kPairedDeviceAddress);
ASSERT_TRUE(device != nullptr);
{
base::RunLoop run_loop;
fake_bluetooth_device_client->ConnectProfile(
static_cast<BluetoothDeviceBlueZ*>(device)->object_path(),
bluez::FakeBluetoothProfileManagerClient::kRfcommUuid,
base::Bind(&base::DoNothing), base::Bind(&DoNothingDBusErrorCallback));
run_loop.RunUntilIdle();
}
{
base::RunLoop run_loop;
server_socket->Accept(
base::Bind(&BluetoothSocketBlueZTest::AcceptSuccessCallback,
base::Unretained(this), run_loop.QuitWhenIdleClosure()),
base::Bind(&BluetoothSocketBlueZTest::ErrorCallback,
base::Unretained(this), run_loop.QuitWhenIdleClosure()));
run_loop.Run();
}
EXPECT_EQ(1U, success_callback_count_);
EXPECT_EQ(0U, error_callback_count_);
EXPECT_TRUE(last_socket_.get() != nullptr);
// Take ownership of the client socket for the remainder of the test.
scoped_refptr<BluetoothSocket> client_socket = last_socket_;
last_socket_ = nullptr;
success_callback_count_ = 0;
error_callback_count_ = 0;
// Close our end of the client socket.
{
base::RunLoop run_loop;
client_socket->Disconnect(
base::Bind(&BluetoothSocketBlueZTest::SuccessCallback,
base::Unretained(this), run_loop.QuitWhenIdleClosure()));
run_loop.Run();
}
EXPECT_EQ(1U, success_callback_count_);
client_socket = nullptr;
success_callback_count_ = 0;
error_callback_count_ = 0;
// Run a second connection test, this time calling Accept() before the
// incoming connection comes in.
{
base::RunLoop run_loop1;
// |run_loop2| is expected to be quit in ConnectProfile() through the quit
// closures saved in the Accept() call.
base::RunLoop run_loop2;
server_socket->Accept(
base::Bind(&BluetoothSocketBlueZTest::AcceptSuccessCallback,
base::Unretained(this), run_loop2.QuitWhenIdleClosure()),
base::Bind(&BluetoothSocketBlueZTest::ErrorCallback,
base::Unretained(this), run_loop2.QuitWhenIdleClosure()));
run_loop1.RunUntilIdle();
fake_bluetooth_device_client->ConnectProfile(
static_cast<BluetoothDeviceBlueZ*>(device)->object_path(),
bluez::FakeBluetoothProfileManagerClient::kRfcommUuid,
base::Bind(&base::DoNothing), base::Bind(&DoNothingDBusErrorCallback));
run_loop2.Run();
}
EXPECT_EQ(1U, success_callback_count_);
EXPECT_EQ(0U, error_callback_count_);
EXPECT_TRUE(last_socket_.get() != nullptr);
// Take ownership of the client socket for the remainder of the test.
client_socket = last_socket_;
last_socket_ = nullptr;
success_callback_count_ = 0;
error_callback_count_ = 0;
// Close our end of the client socket.
{
base::RunLoop run_loop;
client_socket->Disconnect(
base::Bind(&BluetoothSocketBlueZTest::SuccessCallback,
base::Unretained(this), run_loop.QuitWhenIdleClosure()));
run_loop.Run();
}
EXPECT_EQ(1U, success_callback_count_);
client_socket = nullptr;
success_callback_count_ = 0;
error_callback_count_ = 0;
// Now close the server socket.
{
base::RunLoop run_loop;
server_socket->Disconnect(
base::Bind(&BluetoothSocketBlueZTest::ImmediateSuccessCallback,
base::Unretained(this)));
run_loop.RunUntilIdle();
}
EXPECT_EQ(1U, success_callback_count_);
}
TEST_F(BluetoothSocketBlueZTest, ListenBeforeAdapterStart) {
// Start off with an invisible adapter, register the profile, then make
// the adapter visible.
bluez::FakeBluetoothAdapterClient* fake_bluetooth_adapter_client =
static_cast<bluez::FakeBluetoothAdapterClient*>(
bluez::BluezDBusManager::Get()->GetBluetoothAdapterClient());
fake_bluetooth_adapter_client->SetVisible(false);
{
base::RunLoop run_loop;
adapter_->CreateRfcommService(
BluetoothUUID(bluez::FakeBluetoothProfileManagerClient::kRfcommUuid),
BluetoothAdapter::ServiceOptions(),
base::Bind(&BluetoothSocketBlueZTest::CreateServiceSuccessCallback,
base::Unretained(this), run_loop.QuitWhenIdleClosure()),
base::Bind(&BluetoothSocketBlueZTest::ErrorCallback,
base::Unretained(this), run_loop.QuitWhenIdleClosure()));
run_loop.Run();
}
EXPECT_EQ(1U, success_callback_count_);
EXPECT_EQ(0U, error_callback_count_);
EXPECT_TRUE(last_socket_.get() != nullptr);
// Take ownership of the socket for the remainder of the test.
scoped_refptr<BluetoothSocket> socket = last_socket_;
last_socket_ = nullptr;
success_callback_count_ = 0;
error_callback_count_ = 0;
// But there shouldn't be a profile registered yet.
bluez::FakeBluetoothProfileManagerClient*
fake_bluetooth_profile_manager_client =
static_cast<bluez::FakeBluetoothProfileManagerClient*>(
bluez::BluezDBusManager::Get()
->GetBluetoothProfileManagerClient());
bluez::FakeBluetoothProfileServiceProvider* profile_service_provider =
fake_bluetooth_profile_manager_client->GetProfileServiceProvider(
bluez::FakeBluetoothProfileManagerClient::kRfcommUuid);
EXPECT_TRUE(profile_service_provider == nullptr);
// Make the adapter visible. This should register a profile.
{
base::RunLoop run_loop;
fake_bluetooth_adapter_client->SetVisible(true);
run_loop.RunUntilIdle();
}
profile_service_provider =
fake_bluetooth_profile_manager_client->GetProfileServiceProvider(
bluez::FakeBluetoothProfileManagerClient::kRfcommUuid);
EXPECT_TRUE(profile_service_provider != nullptr);
// Cleanup the socket.
{
base::RunLoop run_loop;
socket->Disconnect(
base::Bind(&BluetoothSocketBlueZTest::ImmediateSuccessCallback,
base::Unretained(this)));
run_loop.RunUntilIdle();
}
EXPECT_EQ(1U, success_callback_count_);
}
TEST_F(BluetoothSocketBlueZTest, ListenAcrossAdapterRestart) {
// The fake adapter starts off visible by default.
bluez::FakeBluetoothAdapterClient* fake_bluetooth_adapter_client =
static_cast<bluez::FakeBluetoothAdapterClient*>(
bluez::BluezDBusManager::Get()->GetBluetoothAdapterClient());
{
base::RunLoop run_loop;
adapter_->CreateRfcommService(
BluetoothUUID(bluez::FakeBluetoothProfileManagerClient::kRfcommUuid),
BluetoothAdapter::ServiceOptions(),
base::Bind(&BluetoothSocketBlueZTest::CreateServiceSuccessCallback,
base::Unretained(this), run_loop.QuitWhenIdleClosure()),
base::Bind(&BluetoothSocketBlueZTest::ErrorCallback,
base::Unretained(this), run_loop.QuitWhenIdleClosure()));
run_loop.Run();
}
EXPECT_EQ(1U, success_callback_count_);
EXPECT_EQ(0U, error_callback_count_);
EXPECT_TRUE(last_socket_.get() != nullptr);
// Take ownership of the socket for the remainder of the test.
scoped_refptr<BluetoothSocket> socket = last_socket_;
last_socket_ = nullptr;
success_callback_count_ = 0;
error_callback_count_ = 0;
// Make sure the profile was registered with the daemon.
bluez::FakeBluetoothProfileManagerClient*
fake_bluetooth_profile_manager_client =
static_cast<bluez::FakeBluetoothProfileManagerClient*>(
bluez::BluezDBusManager::Get()
->GetBluetoothProfileManagerClient());
bluez::FakeBluetoothProfileServiceProvider* profile_service_provider =
fake_bluetooth_profile_manager_client->GetProfileServiceProvider(
bluez::FakeBluetoothProfileManagerClient::kRfcommUuid);
EXPECT_TRUE(profile_service_provider != nullptr);
// Make the adapter invisible, and fiddle with the profile fake to unregister
// the profile since this doesn't happen automatically.
{
base::RunLoop run_loop;
fake_bluetooth_adapter_client->SetVisible(false);
run_loop.RunUntilIdle();
}
// Then make the adapter visible again. This should re-register the profile.
{
base::RunLoop run_loop;
fake_bluetooth_adapter_client->SetVisible(true);
run_loop.RunUntilIdle();
}
profile_service_provider =
fake_bluetooth_profile_manager_client->GetProfileServiceProvider(
bluez::FakeBluetoothProfileManagerClient::kRfcommUuid);
EXPECT_TRUE(profile_service_provider != nullptr);
// Cleanup the socket.
{
base::RunLoop run_loop;
socket->Disconnect(
base::Bind(&BluetoothSocketBlueZTest::ImmediateSuccessCallback,
base::Unretained(this)));
run_loop.RunUntilIdle();
}
EXPECT_EQ(1U, success_callback_count_);
}
TEST_F(BluetoothSocketBlueZTest, PairedConnectFails) {
BluetoothDevice* device = adapter_->GetDevice(
bluez::FakeBluetoothDeviceClient::kPairedUnconnectableDeviceAddress);
ASSERT_TRUE(device != nullptr);
{
base::RunLoop run_loop;
device->ConnectToService(
BluetoothUUID(bluez::FakeBluetoothProfileManagerClient::kRfcommUuid),
base::Bind(&BluetoothSocketBlueZTest::ConnectToServiceSuccessCallback,
base::Unretained(this), run_loop.QuitWhenIdleClosure()),
base::Bind(&BluetoothSocketBlueZTest::ErrorCallback,
base::Unretained(this), run_loop.QuitWhenIdleClosure()));
run_loop.Run();
}
EXPECT_EQ(0U, success_callback_count_);
EXPECT_EQ(1U, error_callback_count_);
EXPECT_TRUE(last_socket_.get() == nullptr);
{
base::RunLoop run_loop;
device->ConnectToService(
BluetoothUUID(bluez::FakeBluetoothProfileManagerClient::kRfcommUuid),
base::Bind(&BluetoothSocketBlueZTest::ConnectToServiceSuccessCallback,
base::Unretained(this), run_loop.QuitWhenIdleClosure()),
base::Bind(&BluetoothSocketBlueZTest::ErrorCallback,
base::Unretained(this), run_loop.QuitWhenIdleClosure()));
run_loop.Run();
}
EXPECT_EQ(0U, success_callback_count_);
EXPECT_EQ(2U, error_callback_count_);
EXPECT_TRUE(last_socket_.get() == nullptr);
}
TEST_F(BluetoothSocketBlueZTest, SocketListenTwice) {
{
base::RunLoop run_loop;
adapter_->CreateRfcommService(
BluetoothUUID(bluez::FakeBluetoothProfileManagerClient::kRfcommUuid),
BluetoothAdapter::ServiceOptions(),
base::Bind(&BluetoothSocketBlueZTest::CreateServiceSuccessCallback,
base::Unretained(this), run_loop.QuitWhenIdleClosure()),
base::Bind(&BluetoothSocketBlueZTest::ErrorCallback,
base::Unretained(this), run_loop.QuitWhenIdleClosure()));
run_loop.Run();
}
EXPECT_EQ(1U, success_callback_count_);
EXPECT_EQ(0U, error_callback_count_);
EXPECT_TRUE(last_socket_.get() != nullptr);
// Take control of this socket.
scoped_refptr<BluetoothSocket> server_socket;
server_socket.swap(last_socket_);
{
base::RunLoop run_loop;
server_socket->Accept(
base::Bind(&BluetoothSocketBlueZTest::AcceptSuccessCallback,
base::Unretained(this), run_loop.QuitWhenIdleClosure()),
base::Bind(&BluetoothSocketBlueZTest::ErrorCallback,
base::Unretained(this), run_loop.QuitWhenIdleClosure()));
server_socket->Close();
server_socket = nullptr;
run_loop.RunUntilIdle();
}
EXPECT_EQ(1U, success_callback_count_);
EXPECT_EQ(1U, error_callback_count_);
{
base::RunLoop run_loop;
adapter_->CreateRfcommService(
BluetoothUUID(bluez::FakeBluetoothProfileManagerClient::kRfcommUuid),
BluetoothAdapter::ServiceOptions(),
base::Bind(&BluetoothSocketBlueZTest::CreateServiceSuccessCallback,
base::Unretained(this), run_loop.QuitWhenIdleClosure()),
base::Bind(&BluetoothSocketBlueZTest::ErrorCallback,
base::Unretained(this), run_loop.QuitWhenIdleClosure()));
run_loop.Run();
}
EXPECT_EQ(2U, success_callback_count_);
EXPECT_EQ(1U, error_callback_count_);
EXPECT_TRUE(last_socket_.get() != nullptr);
// Take control of this socket.
server_socket.swap(last_socket_);
{
base::RunLoop run_loop;
server_socket->Accept(
base::Bind(&BluetoothSocketBlueZTest::AcceptSuccessCallback,
base::Unretained(this), run_loop.QuitWhenIdleClosure()),
base::Bind(&BluetoothSocketBlueZTest::ErrorCallback,
base::Unretained(this), run_loop.QuitWhenIdleClosure()));
server_socket->Close();
server_socket = nullptr;
run_loop.RunUntilIdle();
}
EXPECT_EQ(2U, success_callback_count_);
EXPECT_EQ(2U, error_callback_count_);
}
} // namespace bluez