1 // 2 // Copyright (C) 2016 The Android Open Source Project 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at: 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 // 16 17 #include <base/macros.h> 18 #include <gmock/gmock.h> 19 #include <gtest/gtest.h> 20 #include <memory> 21 22 #include "service/adapter.h" 23 #include "service/hal/fake_bluetooth_gatt_interface.h" 24 #include "service/low_energy_scanner.h" 25 #include "stack/include/bt_types.h" 26 #include "stack/include/hcidefs.h" 27 #include "test/mock_adapter.h" 28 29 using ::testing::_; 30 using ::testing::Return; 31 using ::testing::Pointee; 32 using ::testing::DoAll; 33 using ::testing::Invoke; 34 using ::testing::SaveArg; 35 36 namespace bluetooth { 37 namespace { 38 39 class MockScannerHandler : public BleScannerInterface { 40 public: 41 MockScannerHandler() {} 42 ~MockScannerHandler() override = default; 43 44 MOCK_METHOD1(RegisterScanner, void(BleScannerInterface::RegisterCallback)); 45 MOCK_METHOD1(Unregister, void(int)); 46 MOCK_METHOD1(Scan, void(bool)); 47 48 MOCK_METHOD5(ScanFilterParamSetupImpl, 49 void(uint8_t client_if, uint8_t action, uint8_t filt_index, 50 btgatt_filt_param_setup_t* filt_param, 51 FilterParamSetupCallback cb)); 52 MOCK_METHOD2(ScanFilterClear, void(int filt_index, FilterConfigCallback cb)); 53 MOCK_METHOD2(ScanFilterEnable, void(bool enable, EnableCallback cb)); 54 MOCK_METHOD3(SetScanParameters, 55 void(int scan_interval, int scan_window, Callback cb)); 56 57 MOCK_METHOD5(BatchscanConfigStorage, 58 void(int client_if, int batch_scan_full_max, 59 int batch_scan_trunc_max, int batch_scan_notify_threshold, 60 Callback cb)); 61 62 MOCK_METHOD6(BatchscanEnable, 63 void(int scan_mode, int scan_interval, int scan_window, 64 int addr_type, int discard_rule, Callback cb)); 65 66 MOCK_METHOD1(BatchscanDisable, void(Callback cb)); 67 68 MOCK_METHOD2(BatchscanReadReports, void(int client_if, int scan_mode)); 69 70 MOCK_METHOD7(StartSync, void(uint8_t, bt_bdaddr_t, uint16_t, uint16_t, 71 StartSyncCb, SyncReportCb, SyncLostCb)); 72 MOCK_METHOD1(StopSync, void(uint16_t)); 73 74 void ScanFilterAddRemove(int action, int filt_type, int filt_index, 75 int company_id, int company_id_mask, 76 const bt_uuid_t* p_uuid, 77 const bt_uuid_t* p_uuid_mask, 78 const bt_bdaddr_t* bd_addr, char addr_type, 79 std::vector<uint8_t> data, 80 std::vector<uint8_t> p_mask, 81 FilterConfigCallback cb){}; 82 83 void ScanFilterParamSetup( 84 uint8_t client_if, uint8_t action, uint8_t filt_index, 85 std::unique_ptr<btgatt_filt_param_setup_t> filt_param, 86 FilterParamSetupCallback cb) { 87 ScanFilterParamSetupImpl(client_if, action, filt_index, filt_param.get(), 88 std::move(cb)); 89 } 90 }; 91 92 class TestDelegate : public LowEnergyScanner::Delegate { 93 public: 94 TestDelegate() : scan_result_count_(0) {} 95 96 ~TestDelegate() override = default; 97 98 int scan_result_count() const { return scan_result_count_; } 99 const ScanResult& last_scan_result() const { return last_scan_result_; } 100 101 void OnScanResult(LowEnergyScanner* scanner, const ScanResult& scan_result) { 102 ASSERT_TRUE(scanner); 103 scan_result_count_++; 104 last_scan_result_ = scan_result; 105 } 106 107 private: 108 int scan_result_count_; 109 ScanResult last_scan_result_; 110 111 DISALLOW_COPY_AND_ASSIGN(TestDelegate); 112 }; 113 114 class LowEnergyScannerTest : public ::testing::Test { 115 public: 116 LowEnergyScannerTest() = default; 117 ~LowEnergyScannerTest() override = default; 118 119 void SetUp() override { 120 // Only set |mock_handler_| if a test hasn't set it. 121 if (!mock_handler_) mock_handler_.reset(new MockScannerHandler()); 122 fake_hal_gatt_iface_ = new hal::FakeBluetoothGattInterface( 123 nullptr, std::static_pointer_cast<BleScannerInterface>(mock_handler_), 124 nullptr, nullptr); 125 hal::BluetoothGattInterface::InitializeForTesting(fake_hal_gatt_iface_); 126 ble_factory_.reset(new LowEnergyScannerFactory(mock_adapter_)); 127 } 128 129 void TearDown() override { 130 ble_factory_.reset(); 131 hal::BluetoothGattInterface::CleanUp(); 132 } 133 134 protected: 135 hal::FakeBluetoothGattInterface* fake_hal_gatt_iface_; 136 testing::MockAdapter mock_adapter_; 137 std::shared_ptr<MockScannerHandler> mock_handler_; 138 std::unique_ptr<LowEnergyScannerFactory> ble_factory_; 139 140 private: 141 DISALLOW_COPY_AND_ASSIGN(LowEnergyScannerTest); 142 }; 143 144 // Used for tests that operate on a pre-registered scanner. 145 class LowEnergyScannerPostRegisterTest : public LowEnergyScannerTest { 146 public: 147 LowEnergyScannerPostRegisterTest() : next_scanner_id_(0) {} 148 ~LowEnergyScannerPostRegisterTest() override = default; 149 150 void SetUp() override { 151 LowEnergyScannerTest::SetUp(); 152 auto callback = [&](std::unique_ptr<LowEnergyScanner> scanner) { 153 le_scanner_ = std::move(scanner); 154 }; 155 RegisterTestScanner(callback); 156 } 157 158 void TearDown() override { 159 EXPECT_CALL(*mock_handler_, Unregister(_)).Times(1).WillOnce(Return()); 160 le_scanner_.reset(); 161 LowEnergyScannerTest::TearDown(); 162 } 163 164 void RegisterTestScanner( 165 const std::function<void(std::unique_ptr<LowEnergyScanner> scanner)> 166 callback) { 167 UUID uuid = UUID::GetRandom(); 168 auto api_callback = [&](BLEStatus status, const UUID& in_uuid, 169 std::unique_ptr<BluetoothInstance> in_scanner) { 170 CHECK(in_uuid == uuid); 171 CHECK(in_scanner.get()); 172 CHECK(status == BLE_STATUS_SUCCESS); 173 174 callback(std::unique_ptr<LowEnergyScanner>( 175 static_cast<LowEnergyScanner*>(in_scanner.release()))); 176 }; 177 178 BleScannerInterface::RegisterCallback reg_scanner_cb; 179 EXPECT_CALL(*mock_handler_, RegisterScanner(_)) 180 .Times(1) 181 .WillOnce(SaveArg<0>(®_scanner_cb)); 182 183 ble_factory_->RegisterInstance(uuid, api_callback); 184 185 reg_scanner_cb.Run(next_scanner_id_++, BT_STATUS_SUCCESS); 186 ::testing::Mock::VerifyAndClearExpectations(mock_handler_.get()); 187 } 188 189 protected: 190 std::unique_ptr<LowEnergyScanner> le_scanner_; 191 192 private: 193 int next_scanner_id_; 194 195 DISALLOW_COPY_AND_ASSIGN(LowEnergyScannerPostRegisterTest); 196 }; 197 198 TEST_F(LowEnergyScannerTest, RegisterInstance) { 199 BleScannerInterface::RegisterCallback reg_scanner_cb1; 200 EXPECT_CALL(*mock_handler_, RegisterScanner(_)) 201 .Times(1) 202 .WillOnce(SaveArg<0>(®_scanner_cb1)); 203 204 // These will be asynchronously populated with a result when the callback 205 // executes. 206 BLEStatus status = BLE_STATUS_SUCCESS; 207 UUID cb_uuid; 208 std::unique_ptr<LowEnergyScanner> scanner; 209 int callback_count = 0; 210 211 auto callback = [&](BLEStatus in_status, const UUID& uuid, 212 std::unique_ptr<BluetoothInstance> in_scanner) { 213 status = in_status; 214 cb_uuid = uuid; 215 scanner = std::unique_ptr<LowEnergyScanner>( 216 static_cast<LowEnergyScanner*>(in_scanner.release())); 217 callback_count++; 218 }; 219 220 UUID uuid0 = UUID::GetRandom(); 221 222 // HAL returns success. 223 EXPECT_TRUE(ble_factory_->RegisterInstance(uuid0, callback)); 224 EXPECT_EQ(0, callback_count); 225 226 // Calling twice with the same UUID should fail with no additional call into 227 // the stack. 228 EXPECT_FALSE(ble_factory_->RegisterInstance(uuid0, callback)); 229 230 ::testing::Mock::VerifyAndClearExpectations(mock_handler_.get()); 231 232 // Call with a different UUID while one is pending. 233 UUID uuid1 = UUID::GetRandom(); 234 BleScannerInterface::RegisterCallback reg_scanner_cb2; 235 EXPECT_CALL(*mock_handler_, RegisterScanner(_)) 236 .Times(1) 237 .WillOnce(SaveArg<0>(®_scanner_cb2)); 238 EXPECT_TRUE(ble_factory_->RegisterInstance(uuid1, callback)); 239 240 // |uuid0| succeeds. 241 int scanner_if0 = 2; // Pick something that's not 0. 242 reg_scanner_cb1.Run(scanner_if0, BT_STATUS_SUCCESS); 243 244 EXPECT_EQ(1, callback_count); 245 ASSERT_TRUE(scanner.get() != 246 nullptr); // Assert to terminate in case of error 247 EXPECT_EQ(BLE_STATUS_SUCCESS, status); 248 EXPECT_EQ(scanner_if0, scanner->GetInstanceId()); 249 EXPECT_EQ(uuid0, scanner->GetAppIdentifier()); 250 EXPECT_EQ(uuid0, cb_uuid); 251 252 // The scanner should unregister itself when deleted. 253 EXPECT_CALL(*mock_handler_, Unregister(scanner_if0)) 254 .Times(1) 255 .WillOnce(Return()); 256 scanner.reset(); 257 ::testing::Mock::VerifyAndClearExpectations(mock_handler_.get()); 258 259 // |uuid1| fails. 260 int scanner_if1 = 3; 261 reg_scanner_cb2.Run(scanner_if1, BT_STATUS_FAIL); 262 263 EXPECT_EQ(2, callback_count); 264 ASSERT_TRUE(scanner.get() == 265 nullptr); // Assert to terminate in case of error 266 EXPECT_EQ(BLE_STATUS_FAILURE, status); 267 EXPECT_EQ(uuid1, cb_uuid); 268 } 269 270 TEST_F(LowEnergyScannerPostRegisterTest, ScanSettings) { 271 EXPECT_CALL(mock_adapter_, IsEnabled()) 272 .WillOnce(Return(false)) 273 .WillRepeatedly(Return(true)); 274 275 ScanSettings settings; 276 std::vector<ScanFilter> filters; 277 278 // Adapter is not enabled. 279 EXPECT_FALSE(le_scanner_->StartScan(settings, filters)); 280 281 // TODO(jpawlowski): add tests checking settings and filter parsing when 282 // implemented 283 284 // These should succeed and result in a HAL call 285 EXPECT_CALL(*mock_handler_, Scan(true)).Times(1).WillOnce(Return()); 286 EXPECT_TRUE(le_scanner_->StartScan(settings, filters)); 287 288 // These should succeed and result in a HAL call 289 EXPECT_CALL(*mock_handler_, Scan(false)).Times(1).WillOnce(Return()); 290 EXPECT_TRUE(le_scanner_->StopScan()); 291 292 ::testing::Mock::VerifyAndClearExpectations(mock_handler_.get()); 293 } 294 295 TEST_F(LowEnergyScannerPostRegisterTest, ScanRecord) { 296 TestDelegate delegate; 297 le_scanner_->SetDelegate(&delegate); 298 299 EXPECT_EQ(0, delegate.scan_result_count()); 300 301 std::vector<uint8_t> kTestRecord0({0x02, 0x01, 0x00, 0x00}); 302 std::vector<uint8_t> kTestRecord1({0x00}); 303 std::vector<uint8_t> kTestRecord2( 304 {0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 305 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 306 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 307 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 308 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 309 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00}); 310 const bt_bdaddr_t kTestAddress = {{0x01, 0x02, 0x03, 0x0A, 0x0B, 0x0C}}; 311 const char kTestAddressStr[] = "01:02:03:0A:0B:0C"; 312 const int kTestRssi = 64; 313 314 // Scan wasn't started. Result should be ignored. 315 fake_hal_gatt_iface_->NotifyScanResultCallback(kTestAddress, kTestRssi, 316 kTestRecord0); 317 EXPECT_EQ(0, delegate.scan_result_count()); 318 319 // Start a scan session for |le_scanner_|. 320 EXPECT_CALL(mock_adapter_, IsEnabled()).Times(1).WillOnce(Return(true)); 321 EXPECT_CALL(*mock_handler_, Scan(_)) 322 .Times(2) 323 .WillOnce(Return()) 324 .WillOnce(Return()); 325 ScanSettings settings; 326 std::vector<ScanFilter> filters; 327 ASSERT_TRUE(le_scanner_->StartScan(settings, filters)); 328 329 fake_hal_gatt_iface_->NotifyScanResultCallback(kTestAddress, kTestRssi, 330 kTestRecord0); 331 EXPECT_EQ(1, delegate.scan_result_count()); 332 EXPECT_EQ(kTestAddressStr, delegate.last_scan_result().device_address()); 333 EXPECT_EQ(kTestRssi, delegate.last_scan_result().rssi()); 334 EXPECT_EQ(3U, delegate.last_scan_result().scan_record().size()); 335 336 fake_hal_gatt_iface_->NotifyScanResultCallback(kTestAddress, kTestRssi, 337 kTestRecord1); 338 EXPECT_EQ(2, delegate.scan_result_count()); 339 EXPECT_EQ(kTestAddressStr, delegate.last_scan_result().device_address()); 340 EXPECT_EQ(kTestRssi, delegate.last_scan_result().rssi()); 341 EXPECT_TRUE(delegate.last_scan_result().scan_record().empty()); 342 343 fake_hal_gatt_iface_->NotifyScanResultCallback(kTestAddress, kTestRssi, 344 kTestRecord2); 345 EXPECT_EQ(3, delegate.scan_result_count()); 346 EXPECT_EQ(kTestAddressStr, delegate.last_scan_result().device_address()); 347 EXPECT_EQ(kTestRssi, delegate.last_scan_result().rssi()); 348 EXPECT_EQ(62U, delegate.last_scan_result().scan_record().size()); 349 350 le_scanner_->SetDelegate(nullptr); 351 } 352 353 } // namespace 354 } // namespace bluetooth 355