diff options
Diffstat (limited to 'device/bluetooth/bluetooth_advertisement_chromeos_unittest.cc')
-rw-r--r-- | device/bluetooth/bluetooth_advertisement_chromeos_unittest.cc | 242 |
1 files changed, 242 insertions, 0 deletions
diff --git a/device/bluetooth/bluetooth_advertisement_chromeos_unittest.cc b/device/bluetooth/bluetooth_advertisement_chromeos_unittest.cc new file mode 100644 index 0000000..165dc8d --- /dev/null +++ b/device/bluetooth/bluetooth_advertisement_chromeos_unittest.cc @@ -0,0 +1,242 @@ +// Copyright 2015 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 <vector> + +#include "base/bind.h" +#include "base/logging.h" +#include "base/memory/ref_counted.h" +#include "base/memory/scoped_ptr.h" +#include "base/message_loop/message_loop.h" +#include "device/bluetooth/bluetooth_adapter.h" +#include "device/bluetooth/bluetooth_adapter_factory.h" +#include "device/bluetooth/bluetooth_advertisement.h" +#include "device/bluetooth/bluetooth_advertisement_chromeos.h" +#include "device/bluetooth/dbus/bluez_dbus_manager.h" +#include "device/bluetooth/dbus/fake_bluetooth_le_advertisement_service_provider.h" +#include "testing/gtest/include/gtest/gtest.h" + +using device::BluetoothAdapter; +using device::BluetoothAdapterFactory; +using device::BluetoothAdvertisement; + +namespace chromeos { + +class TestAdvertisementObserver : public BluetoothAdvertisement::Observer { + public: + explicit TestAdvertisementObserver( + scoped_refptr<BluetoothAdvertisement> advertisement) + : released_(false), advertisement_(advertisement) { + advertisement_->AddObserver(this); + } + + ~TestAdvertisementObserver() override { + advertisement_->RemoveObserver(this); + } + + // BluetoothAdvertisement::Observer overrides: + void AdvertisementReleased(BluetoothAdvertisement* advertisement) override { + released_ = true; + } + + bool released() { return released_; } + + private: + bool released_; + scoped_refptr<BluetoothAdvertisement> advertisement_; + + DISALLOW_COPY_AND_ASSIGN(TestAdvertisementObserver); +}; + +class BluetoothAdvertisementChromeOSTest : public testing::Test { + public: + void SetUp() override { + bluez::BluezDBusManager::Initialize(NULL, true); + + callback_count_ = 0; + error_callback_count_ = 0; + + last_callback_count_ = 0; + last_error_callback_count_ = 0; + + last_error_code_ = BluetoothAdvertisement::INVALID_ADVERTISEMENT_ERROR_CODE; + + GetAdapter(); + } + + void TearDown() override { + observer_.reset(); + // The adapter should outlive the advertisement. + advertisement_ = nullptr; + adapter_ = nullptr; + bluez::BluezDBusManager::Shutdown(); + } + + // Gets the existing Bluetooth adapter. + void GetAdapter() { + BluetoothAdapterFactory::GetAdapter( + base::Bind(&BluetoothAdvertisementChromeOSTest::GetAdapterCallback, + base::Unretained(this))); + } + + // Called whenever BluetoothAdapter is retrieved successfully. + void GetAdapterCallback(scoped_refptr<BluetoothAdapter> adapter) { + adapter_ = adapter; + ASSERT_NE(adapter_.get(), nullptr); + ASSERT_TRUE(adapter_->IsInitialized()); + } + + scoped_ptr<BluetoothAdvertisement::Data> CreateAdvertisementData() { + scoped_ptr<BluetoothAdvertisement::Data> data = + make_scoped_ptr(new BluetoothAdvertisement::Data( + BluetoothAdvertisement::ADVERTISEMENT_TYPE_BROADCAST)); + data->set_service_uuids( + make_scoped_ptr(new BluetoothAdvertisement::UUIDList()).Pass()); + data->set_manufacturer_data( + make_scoped_ptr(new BluetoothAdvertisement::ManufacturerData()).Pass()); + data->set_solicit_uuids( + make_scoped_ptr(new BluetoothAdvertisement::UUIDList()).Pass()); + data->set_service_data( + make_scoped_ptr(new BluetoothAdvertisement::ServiceData()).Pass()); + return data.Pass(); + } + + // Creates and registers an advertisement with the adapter. + scoped_refptr<BluetoothAdvertisement> CreateAdvertisement() { + // Clear the last advertisement we created. + advertisement_ = nullptr; + + adapter_->RegisterAdvertisement( + CreateAdvertisementData().Pass(), + base::Bind(&BluetoothAdvertisementChromeOSTest::RegisterCallback, + base::Unretained(this)), + base::Bind( + &BluetoothAdvertisementChromeOSTest::AdvertisementErrorCallback, + base::Unretained(this))); + + message_loop_.RunUntilIdle(); + return advertisement_; + } + + void UnregisterAdvertisement( + scoped_refptr<BluetoothAdvertisement> advertisement) { + advertisement->Unregister( + base::Bind(&BluetoothAdvertisementChromeOSTest::Callback, + base::Unretained(this)), + base::Bind( + &BluetoothAdvertisementChromeOSTest::AdvertisementErrorCallback, + base::Unretained(this))); + + message_loop_.RunUntilIdle(); + } + + void TriggerReleased(scoped_refptr<BluetoothAdvertisement> advertisement) { + BluetoothAdvertisementChromeOS* adv = + static_cast<BluetoothAdvertisementChromeOS*>(advertisement.get()); + bluez::FakeBluetoothLEAdvertisementServiceProvider* provider = + static_cast<bluez::FakeBluetoothLEAdvertisementServiceProvider*>( + adv->provider()); + provider->Release(); + } + + // Called whenever RegisterAdvertisement is completed successfully. + void RegisterCallback(scoped_refptr<BluetoothAdvertisement> advertisement) { + ++callback_count_; + advertisement_ = advertisement; + + ASSERT_NE(advertisement_.get(), nullptr); + } + + void AdvertisementErrorCallback( + BluetoothAdvertisement::ErrorCode error_code) { + ++error_callback_count_; + last_error_code_ = error_code; + } + + // Generic callbacks. + void Callback() { ++callback_count_; } + + void ErrorCallback() { ++error_callback_count_; } + + void ExpectSuccess() { + EXPECT_EQ(last_error_callback_count_, error_callback_count_); + EXPECT_EQ(last_callback_count_ + 1, callback_count_); + last_callback_count_ = callback_count_; + last_error_callback_count_ = error_callback_count_; + } + + void ExpectError(BluetoothAdvertisement::ErrorCode error_code) { + EXPECT_EQ(last_callback_count_, callback_count_); + EXPECT_EQ(last_error_callback_count_ + 1, error_callback_count_); + last_callback_count_ = callback_count_; + last_error_callback_count_ = error_callback_count_; + EXPECT_EQ(error_code, last_error_code_); + } + + protected: + int callback_count_; + int error_callback_count_; + + int last_callback_count_; + int last_error_callback_count_; + + BluetoothAdvertisement::ErrorCode last_error_code_; + + base::MessageLoopForIO message_loop_; + + scoped_ptr<TestAdvertisementObserver> observer_; + scoped_refptr<BluetoothAdapter> adapter_; + scoped_refptr<BluetoothAdvertisement> advertisement_; +}; + +TEST_F(BluetoothAdvertisementChromeOSTest, RegisterSucceeded) { + scoped_refptr<BluetoothAdvertisement> advertisement = CreateAdvertisement(); + ExpectSuccess(); + EXPECT_NE(nullptr, advertisement); + + UnregisterAdvertisement(advertisement); + ExpectSuccess(); +} + +TEST_F(BluetoothAdvertisementChromeOSTest, DoubleRegisterFailed) { + scoped_refptr<BluetoothAdvertisement> advertisement = CreateAdvertisement(); + ExpectSuccess(); + EXPECT_NE(nullptr, advertisement); + + // Creating a second advertisement should give us an error. + scoped_refptr<BluetoothAdvertisement> advertisement2 = CreateAdvertisement(); + ExpectError(BluetoothAdvertisement::ERROR_ADVERTISEMENT_ALREADY_EXISTS); + EXPECT_EQ(nullptr, advertisement2); +} + +TEST_F(BluetoothAdvertisementChromeOSTest, DoubleUnregisterFailed) { + scoped_refptr<BluetoothAdvertisement> advertisement = CreateAdvertisement(); + ExpectSuccess(); + EXPECT_NE(nullptr, advertisement); + + UnregisterAdvertisement(advertisement); + ExpectSuccess(); + + // Unregistering an already unregistered advertisement should give us an + // error. + UnregisterAdvertisement(advertisement); + ExpectError(BluetoothAdvertisement::ERROR_ADVERTISEMENT_DOES_NOT_EXIST); +} + +TEST_F(BluetoothAdvertisementChromeOSTest, UnregisterAfterReleasedFailed) { + scoped_refptr<BluetoothAdvertisement> advertisement = CreateAdvertisement(); + ExpectSuccess(); + EXPECT_NE(nullptr, advertisement); + + observer_.reset(new TestAdvertisementObserver(advertisement)); + TriggerReleased(advertisement); + EXPECT_TRUE(observer_->released()); + + // Unregistering an advertisement that has been released should give us an + // error. + UnregisterAdvertisement(advertisement); + ExpectError(BluetoothAdvertisement::ERROR_ADVERTISEMENT_DOES_NOT_EXIST); +} + +} // namespace chromeos |