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:
MockScannerHandler()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
ScanFilterAddRemove(int action,int filt_type,int filt_index,int company_id,int company_id_mask,const bt_uuid_t * p_uuid,const bt_uuid_t * p_uuid_mask,const bt_bdaddr_t * bd_addr,char addr_type,std::vector<uint8_t> data,std::vector<uint8_t> p_mask,FilterConfigCallback cb)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
ScanFilterParamSetup(uint8_t client_if,uint8_t action,uint8_t filt_index,std::unique_ptr<btgatt_filt_param_setup_t> filt_param,FilterParamSetupCallback cb)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:
TestDelegate()94 TestDelegate() : scan_result_count_(0) {}
95
96 ~TestDelegate() override = default;
97
scan_result_count() const98 int scan_result_count() const { return scan_result_count_; }
last_scan_result() const99 const ScanResult& last_scan_result() const { return last_scan_result_; }
100
OnScanResult(LowEnergyScanner * scanner,const ScanResult & scan_result)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
SetUp()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
TearDown()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:
LowEnergyScannerPostRegisterTest()147 LowEnergyScannerPostRegisterTest() : next_scanner_id_(0) {}
148 ~LowEnergyScannerPostRegisterTest() override = default;
149
SetUp()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
TearDown()158 void TearDown() override {
159 EXPECT_CALL(*mock_handler_, Unregister(_)).Times(1).WillOnce(Return());
160 le_scanner_.reset();
161 LowEnergyScannerTest::TearDown();
162 }
163
RegisterTestScanner(const std::function<void (std::unique_ptr<LowEnergyScanner> scanner)> callback)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
TEST_F(LowEnergyScannerTest,RegisterInstance)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
TEST_F(LowEnergyScannerPostRegisterTest,ScanSettings)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
TEST_F(LowEnergyScannerPostRegisterTest,ScanRecord)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