| OLD | NEW |
| (Empty) |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "device/bluetooth/bluetooth_advertisement_bluez.h" | |
| 6 | |
| 7 #include <memory> | |
| 8 #include <vector> | |
| 9 | |
| 10 #include "base/bind.h" | |
| 11 #include "base/logging.h" | |
| 12 #include "base/macros.h" | |
| 13 #include "base/memory/ptr_util.h" | |
| 14 #include "base/memory/ref_counted.h" | |
| 15 #include "base/message_loop/message_loop.h" | |
| 16 #include "device/bluetooth/bluetooth_adapter.h" | |
| 17 #include "device/bluetooth/bluetooth_adapter_factory.h" | |
| 18 #include "device/bluetooth/bluetooth_advertisement.h" | |
| 19 #include "device/bluetooth/dbus/bluez_dbus_manager.h" | |
| 20 #include "device/bluetooth/dbus/fake_bluetooth_le_advertisement_service_provider
.h" | |
| 21 #include "testing/gtest/include/gtest/gtest.h" | |
| 22 | |
| 23 using device::BluetoothAdapter; | |
| 24 using device::BluetoothAdapterFactory; | |
| 25 using device::BluetoothAdvertisement; | |
| 26 | |
| 27 namespace bluez { | |
| 28 | |
| 29 class TestAdvertisementObserver : public BluetoothAdvertisement::Observer { | |
| 30 public: | |
| 31 explicit TestAdvertisementObserver( | |
| 32 scoped_refptr<BluetoothAdvertisement> advertisement) | |
| 33 : released_(false), advertisement_(advertisement) { | |
| 34 advertisement_->AddObserver(this); | |
| 35 } | |
| 36 | |
| 37 ~TestAdvertisementObserver() override { | |
| 38 advertisement_->RemoveObserver(this); | |
| 39 } | |
| 40 | |
| 41 // BluetoothAdvertisement::Observer overrides: | |
| 42 void AdvertisementReleased(BluetoothAdvertisement* advertisement) override { | |
| 43 released_ = true; | |
| 44 } | |
| 45 | |
| 46 bool released() { return released_; } | |
| 47 | |
| 48 private: | |
| 49 bool released_; | |
| 50 scoped_refptr<BluetoothAdvertisement> advertisement_; | |
| 51 | |
| 52 DISALLOW_COPY_AND_ASSIGN(TestAdvertisementObserver); | |
| 53 }; | |
| 54 | |
| 55 class BluetoothAdvertisementBlueZTest : public testing::Test { | |
| 56 public: | |
| 57 void SetUp() override { | |
| 58 bluez::BluezDBusManager::Initialize(nullptr /* bus */, | |
| 59 true /* use_dbus_stub */); | |
| 60 | |
| 61 callback_count_ = 0; | |
| 62 error_callback_count_ = 0; | |
| 63 | |
| 64 last_callback_count_ = 0; | |
| 65 last_error_callback_count_ = 0; | |
| 66 | |
| 67 last_error_code_ = BluetoothAdvertisement::INVALID_ADVERTISEMENT_ERROR_CODE; | |
| 68 | |
| 69 GetAdapter(); | |
| 70 } | |
| 71 | |
| 72 void TearDown() override { | |
| 73 observer_.reset(); | |
| 74 // The adapter should outlive the advertisement. | |
| 75 advertisement_ = nullptr; | |
| 76 adapter_ = nullptr; | |
| 77 bluez::BluezDBusManager::Shutdown(); | |
| 78 } | |
| 79 | |
| 80 // Gets the existing Bluetooth adapter. | |
| 81 void GetAdapter() { | |
| 82 BluetoothAdapterFactory::GetAdapter( | |
| 83 base::Bind(&BluetoothAdvertisementBlueZTest::GetAdapterCallback, | |
| 84 base::Unretained(this))); | |
| 85 base::MessageLoop::current()->Run(); | |
| 86 } | |
| 87 | |
| 88 // Called whenever BluetoothAdapter is retrieved successfully. | |
| 89 void GetAdapterCallback(scoped_refptr<BluetoothAdapter> adapter) { | |
| 90 adapter_ = adapter; | |
| 91 ASSERT_NE(adapter_.get(), nullptr); | |
| 92 ASSERT_TRUE(adapter_->IsInitialized()); | |
| 93 if (base::MessageLoop::current() && | |
| 94 base::MessageLoop::current()->is_running()) { | |
| 95 base::MessageLoop::current()->QuitWhenIdle(); | |
| 96 } | |
| 97 } | |
| 98 | |
| 99 std::unique_ptr<BluetoothAdvertisement::Data> CreateAdvertisementData() { | |
| 100 std::unique_ptr<BluetoothAdvertisement::Data> data = | |
| 101 base::WrapUnique(new BluetoothAdvertisement::Data( | |
| 102 BluetoothAdvertisement::ADVERTISEMENT_TYPE_BROADCAST)); | |
| 103 data->set_service_uuids( | |
| 104 base::WrapUnique(new BluetoothAdvertisement::UUIDList())); | |
| 105 data->set_manufacturer_data( | |
| 106 base::WrapUnique(new BluetoothAdvertisement::ManufacturerData())); | |
| 107 data->set_solicit_uuids( | |
| 108 base::WrapUnique(new BluetoothAdvertisement::UUIDList())); | |
| 109 data->set_service_data( | |
| 110 base::WrapUnique(new BluetoothAdvertisement::ServiceData())); | |
| 111 return data; | |
| 112 } | |
| 113 | |
| 114 // Creates and registers an advertisement with the adapter. | |
| 115 scoped_refptr<BluetoothAdvertisement> CreateAdvertisement() { | |
| 116 // Clear the last advertisement we created. | |
| 117 advertisement_ = nullptr; | |
| 118 | |
| 119 adapter_->RegisterAdvertisement( | |
| 120 CreateAdvertisementData(), | |
| 121 base::Bind(&BluetoothAdvertisementBlueZTest::RegisterCallback, | |
| 122 base::Unretained(this)), | |
| 123 base::Bind(&BluetoothAdvertisementBlueZTest::AdvertisementErrorCallback, | |
| 124 base::Unretained(this))); | |
| 125 | |
| 126 message_loop_.RunUntilIdle(); | |
| 127 return advertisement_; | |
| 128 } | |
| 129 | |
| 130 void UnregisterAdvertisement( | |
| 131 scoped_refptr<BluetoothAdvertisement> advertisement) { | |
| 132 advertisement->Unregister( | |
| 133 base::Bind(&BluetoothAdvertisementBlueZTest::Callback, | |
| 134 base::Unretained(this)), | |
| 135 base::Bind(&BluetoothAdvertisementBlueZTest::AdvertisementErrorCallback, | |
| 136 base::Unretained(this))); | |
| 137 | |
| 138 message_loop_.RunUntilIdle(); | |
| 139 } | |
| 140 | |
| 141 void TriggerReleased(scoped_refptr<BluetoothAdvertisement> advertisement) { | |
| 142 BluetoothAdvertisementBlueZ* adv = | |
| 143 static_cast<BluetoothAdvertisementBlueZ*>(advertisement.get()); | |
| 144 bluez::FakeBluetoothLEAdvertisementServiceProvider* provider = | |
| 145 static_cast<bluez::FakeBluetoothLEAdvertisementServiceProvider*>( | |
| 146 adv->provider()); | |
| 147 provider->Release(); | |
| 148 } | |
| 149 | |
| 150 // Called whenever RegisterAdvertisement is completed successfully. | |
| 151 void RegisterCallback(scoped_refptr<BluetoothAdvertisement> advertisement) { | |
| 152 ++callback_count_; | |
| 153 advertisement_ = advertisement; | |
| 154 | |
| 155 ASSERT_NE(advertisement_.get(), nullptr); | |
| 156 } | |
| 157 | |
| 158 void AdvertisementErrorCallback( | |
| 159 BluetoothAdvertisement::ErrorCode error_code) { | |
| 160 ++error_callback_count_; | |
| 161 last_error_code_ = error_code; | |
| 162 } | |
| 163 | |
| 164 // Generic callbacks. | |
| 165 void Callback() { ++callback_count_; } | |
| 166 | |
| 167 void ErrorCallback() { ++error_callback_count_; } | |
| 168 | |
| 169 void ExpectSuccess() { | |
| 170 EXPECT_EQ(last_error_callback_count_, error_callback_count_); | |
| 171 EXPECT_EQ(last_callback_count_ + 1, callback_count_); | |
| 172 last_callback_count_ = callback_count_; | |
| 173 last_error_callback_count_ = error_callback_count_; | |
| 174 } | |
| 175 | |
| 176 void ExpectError(BluetoothAdvertisement::ErrorCode error_code) { | |
| 177 EXPECT_EQ(last_callback_count_, callback_count_); | |
| 178 EXPECT_EQ(last_error_callback_count_ + 1, error_callback_count_); | |
| 179 last_callback_count_ = callback_count_; | |
| 180 last_error_callback_count_ = error_callback_count_; | |
| 181 EXPECT_EQ(error_code, last_error_code_); | |
| 182 } | |
| 183 | |
| 184 protected: | |
| 185 int callback_count_; | |
| 186 int error_callback_count_; | |
| 187 | |
| 188 int last_callback_count_; | |
| 189 int last_error_callback_count_; | |
| 190 | |
| 191 BluetoothAdvertisement::ErrorCode last_error_code_; | |
| 192 | |
| 193 base::MessageLoopForIO message_loop_; | |
| 194 | |
| 195 std::unique_ptr<TestAdvertisementObserver> observer_; | |
| 196 scoped_refptr<BluetoothAdapter> adapter_; | |
| 197 scoped_refptr<BluetoothAdvertisement> advertisement_; | |
| 198 }; | |
| 199 | |
| 200 TEST_F(BluetoothAdvertisementBlueZTest, RegisterSucceeded) { | |
| 201 scoped_refptr<BluetoothAdvertisement> advertisement = CreateAdvertisement(); | |
| 202 ExpectSuccess(); | |
| 203 EXPECT_NE(nullptr, advertisement); | |
| 204 | |
| 205 UnregisterAdvertisement(advertisement); | |
| 206 ExpectSuccess(); | |
| 207 } | |
| 208 | |
| 209 TEST_F(BluetoothAdvertisementBlueZTest, DoubleRegisterFailed) { | |
| 210 scoped_refptr<BluetoothAdvertisement> advertisement = CreateAdvertisement(); | |
| 211 ExpectSuccess(); | |
| 212 EXPECT_NE(nullptr, advertisement); | |
| 213 | |
| 214 // Creating a second advertisement should give us an error. | |
| 215 scoped_refptr<BluetoothAdvertisement> advertisement2 = CreateAdvertisement(); | |
| 216 ExpectError(BluetoothAdvertisement::ERROR_ADVERTISEMENT_ALREADY_EXISTS); | |
| 217 EXPECT_EQ(nullptr, advertisement2); | |
| 218 } | |
| 219 | |
| 220 TEST_F(BluetoothAdvertisementBlueZTest, DoubleUnregisterFailed) { | |
| 221 scoped_refptr<BluetoothAdvertisement> advertisement = CreateAdvertisement(); | |
| 222 ExpectSuccess(); | |
| 223 EXPECT_NE(nullptr, advertisement); | |
| 224 | |
| 225 UnregisterAdvertisement(advertisement); | |
| 226 ExpectSuccess(); | |
| 227 | |
| 228 // Unregistering an already unregistered advertisement should give us an | |
| 229 // error. | |
| 230 UnregisterAdvertisement(advertisement); | |
| 231 ExpectError(BluetoothAdvertisement::ERROR_ADVERTISEMENT_DOES_NOT_EXIST); | |
| 232 } | |
| 233 | |
| 234 TEST_F(BluetoothAdvertisementBlueZTest, UnregisterAfterReleasedFailed) { | |
| 235 scoped_refptr<BluetoothAdvertisement> advertisement = CreateAdvertisement(); | |
| 236 ExpectSuccess(); | |
| 237 EXPECT_NE(nullptr, advertisement); | |
| 238 | |
| 239 observer_.reset(new TestAdvertisementObserver(advertisement)); | |
| 240 TriggerReleased(advertisement); | |
| 241 EXPECT_TRUE(observer_->released()); | |
| 242 | |
| 243 // Unregistering an advertisement that has been released should give us an | |
| 244 // error. | |
| 245 UnregisterAdvertisement(advertisement); | |
| 246 ExpectError(BluetoothAdvertisement::ERROR_ADVERTISEMENT_DOES_NOT_EXIST); | |
| 247 } | |
| 248 | |
| 249 } // namespace bluez | |
| OLD | NEW |