1 //
2 // Copyright 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_METHOD2(RegisterScanner, void(const bluetooth::Uuid& app_uuid,
45 BleScannerInterface::RegisterCallback));
46 MOCK_METHOD1(Unregister, void(int));
47 MOCK_METHOD1(Scan, void(bool));
48
49 MOCK_METHOD5(ScanFilterParamSetupImpl,
50 void(uint8_t client_if, uint8_t action, uint8_t filt_index,
51 btgatt_filt_param_setup_t* filt_param,
52 FilterParamSetupCallback cb));
53 MOCK_METHOD2(ScanFilterClear, void(int filt_index, FilterConfigCallback cb));
54 MOCK_METHOD2(ScanFilterEnable, void(bool enable, EnableCallback cb));
55 MOCK_METHOD3(SetScanParameters,
56 void(int scan_interval, int scan_window, Callback cb));
57
58 MOCK_METHOD5(BatchscanConfigStorage,
59 void(int client_if, int batch_scan_full_max,
60 int batch_scan_trunc_max, int batch_scan_notify_threshold,
61 Callback cb));
62
63 MOCK_METHOD6(BatchscanEnable,
64 void(int scan_mode, int scan_interval, int scan_window,
65 int addr_type, int discard_rule, Callback cb));
66
67 MOCK_METHOD1(BatchscanDisable, void(Callback cb));
68
69 MOCK_METHOD2(BatchscanReadReports, void(int client_if, int scan_mode));
70
71 MOCK_METHOD7(StartSync, void(uint8_t, RawAddress, uint16_t, uint16_t,
72 StartSyncCb, SyncReportCb, SyncLostCb));
73 MOCK_METHOD1(StopSync, void(uint16_t));
74
75 MOCK_METHOD1(RegisterCallbacks, void(ScanningCallbacks* callbacks));
76
ScanFilterAdd(int filter_index,std::vector<ApcfCommand> filters,FilterConfigCallback cb)77 void ScanFilterAdd(int filter_index, std::vector<ApcfCommand> filters,
78 FilterConfigCallback cb) override{};
79
ScanFilterParamSetup(uint8_t client_if,uint8_t action,uint8_t filt_index,std::unique_ptr<btgatt_filt_param_setup_t> filt_param,FilterParamSetupCallback cb)80 void ScanFilterParamSetup(
81 uint8_t client_if, uint8_t action, uint8_t filt_index,
82 std::unique_ptr<btgatt_filt_param_setup_t> filt_param,
83 FilterParamSetupCallback cb) override {
84 ScanFilterParamSetupImpl(client_if, action, filt_index, filt_param.get(),
85 std::move(cb));
86 }
87 };
88
89 class TestDelegate : public LowEnergyScanner::Delegate {
90 public:
TestDelegate()91 TestDelegate() : scan_result_count_(0) {}
92
93 ~TestDelegate() override = default;
94
scan_result_count() const95 int scan_result_count() const { return scan_result_count_; }
last_scan_result() const96 const ScanResult& last_scan_result() const { return last_scan_result_; }
97
OnScanResult(LowEnergyScanner * scanner,const ScanResult & scan_result)98 void OnScanResult(LowEnergyScanner* scanner,
99 const ScanResult& scan_result) override {
100 ASSERT_TRUE(scanner);
101 scan_result_count_++;
102 last_scan_result_ = scan_result;
103 }
104
105 private:
106 int scan_result_count_;
107 ScanResult last_scan_result_;
108
109 DISALLOW_COPY_AND_ASSIGN(TestDelegate);
110 };
111
112 class LowEnergyScannerTest : public ::testing::Test {
113 public:
114 LowEnergyScannerTest() = default;
115 ~LowEnergyScannerTest() override = default;
116
SetUp()117 void SetUp() override {
118 // Only set |mock_handler_| if a test hasn't set it.
119 if (!mock_handler_) mock_handler_.reset(new MockScannerHandler());
120 fake_hal_gatt_iface_ = new hal::FakeBluetoothGattInterface(
121 nullptr, std::static_pointer_cast<BleScannerInterface>(mock_handler_),
122 nullptr, nullptr);
123 hal::BluetoothGattInterface::InitializeForTesting(fake_hal_gatt_iface_);
124 ble_factory_.reset(new LowEnergyScannerFactory(mock_adapter_));
125 }
126
TearDown()127 void TearDown() override {
128 ble_factory_.reset();
129 hal::BluetoothGattInterface::CleanUp();
130 }
131
132 protected:
133 hal::FakeBluetoothGattInterface* fake_hal_gatt_iface_;
134 testing::MockAdapter mock_adapter_;
135 std::shared_ptr<MockScannerHandler> mock_handler_;
136 std::unique_ptr<LowEnergyScannerFactory> ble_factory_;
137
138 private:
139 DISALLOW_COPY_AND_ASSIGN(LowEnergyScannerTest);
140 };
141
142 // Used for tests that operate on a pre-registered scanner.
143 class LowEnergyScannerPostRegisterTest : public LowEnergyScannerTest {
144 public:
LowEnergyScannerPostRegisterTest()145 LowEnergyScannerPostRegisterTest() : next_scanner_id_(0) {}
146 ~LowEnergyScannerPostRegisterTest() override = default;
147
SetUp()148 void SetUp() override {
149 LowEnergyScannerTest::SetUp();
150 auto callback = [&](std::unique_ptr<LowEnergyScanner> scanner) {
151 le_scanner_ = std::move(scanner);
152 };
153 RegisterTestScanner(callback);
154 }
155
TearDown()156 void TearDown() override {
157 EXPECT_CALL(*mock_handler_, Unregister(_)).Times(1).WillOnce(Return());
158 le_scanner_.reset();
159 LowEnergyScannerTest::TearDown();
160 }
161
RegisterTestScanner(const std::function<void (std::unique_ptr<LowEnergyScanner> scanner)> callback)162 void RegisterTestScanner(
163 const std::function<void(std::unique_ptr<LowEnergyScanner> scanner)>
164 callback) {
165 Uuid uuid = Uuid::GetRandom();
166 auto api_callback = [&](BLEStatus status, const Uuid& in_uuid,
167 std::unique_ptr<BluetoothInstance> in_scanner) {
168 CHECK(in_uuid == uuid);
169 CHECK(in_scanner.get());
170 CHECK(status == BLE_STATUS_SUCCESS);
171
172 callback(std::unique_ptr<LowEnergyScanner>(
173 static_cast<LowEnergyScanner*>(in_scanner.release())));
174 };
175
176 BleScannerInterface::RegisterCallback reg_scanner_cb;
177 Uuid uuid_empty;
178 EXPECT_CALL(*mock_handler_, RegisterScanner(_, _))
179 .Times(1)
180 .WillOnce(DoAll(SaveArg<0>(&uuid_empty), SaveArg<1>(®_scanner_cb)));
181
182 ble_factory_->RegisterInstance(uuid, api_callback);
183
184 reg_scanner_cb.Run(next_scanner_id_++, BT_STATUS_SUCCESS);
185 ::testing::Mock::VerifyAndClearExpectations(mock_handler_.get());
186 }
187
188 protected:
189 std::unique_ptr<LowEnergyScanner> le_scanner_;
190
191 private:
192 int next_scanner_id_;
193
194 DISALLOW_COPY_AND_ASSIGN(LowEnergyScannerPostRegisterTest);
195 };
196
TEST_F(LowEnergyScannerTest,RegisterInstance)197 TEST_F(LowEnergyScannerTest, RegisterInstance) {
198 BleScannerInterface::RegisterCallback reg_scanner_cb1;
199 Uuid uuid_empty1;
200 EXPECT_CALL(*mock_handler_, RegisterScanner(_, _))
201 .Times(1)
202 .WillOnce(DoAll(SaveArg<0>(&uuid_empty1), SaveArg<1>(®_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 Uuid uuid_empty2;
236 EXPECT_CALL(*mock_handler_, RegisterScanner(_, _))
237 .Times(1)
238 .WillOnce(DoAll(SaveArg<0>(&uuid_empty2), SaveArg<1>(®_scanner_cb2)));
239 EXPECT_TRUE(ble_factory_->RegisterInstance(uuid1, callback));
240
241 // |uuid0| succeeds.
242 int scanner_if0 = 2; // Pick something that's not 0.
243 reg_scanner_cb1.Run(scanner_if0, BT_STATUS_SUCCESS);
244
245 EXPECT_EQ(1, callback_count);
246 ASSERT_TRUE(scanner.get() !=
247 nullptr); // Assert to terminate in case of error
248 EXPECT_EQ(BLE_STATUS_SUCCESS, status);
249 EXPECT_EQ(scanner_if0, scanner->GetInstanceId());
250 EXPECT_EQ(uuid0, scanner->GetAppIdentifier());
251 EXPECT_EQ(uuid0, cb_uuid);
252
253 // The scanner should unregister itself when deleted.
254 EXPECT_CALL(*mock_handler_, Unregister(scanner_if0))
255 .Times(1)
256 .WillOnce(Return());
257 scanner.reset();
258 ::testing::Mock::VerifyAndClearExpectations(mock_handler_.get());
259
260 // |uuid1| fails.
261 int scanner_if1 = 3;
262 reg_scanner_cb2.Run(scanner_if1, BT_STATUS_FAIL);
263
264 EXPECT_EQ(2, callback_count);
265 ASSERT_TRUE(scanner.get() ==
266 nullptr); // Assert to terminate in case of error
267 EXPECT_EQ(BLE_STATUS_FAILURE, status);
268 EXPECT_EQ(uuid1, cb_uuid);
269 }
270
TEST_F(LowEnergyScannerPostRegisterTest,ScanSettings)271 TEST_F(LowEnergyScannerPostRegisterTest, ScanSettings) {
272 EXPECT_CALL(mock_adapter_, IsEnabled())
273 .WillOnce(Return(false))
274 .WillRepeatedly(Return(true));
275
276 ScanSettings settings;
277 std::vector<ScanFilter> filters;
278
279 // Adapter is not enabled.
280 EXPECT_FALSE(le_scanner_->StartScan(settings, filters));
281
282 // TODO(jpawlowski): add tests checking settings and filter parsing when
283 // implemented
284
285 // These should succeed and result in a HAL call
286 EXPECT_CALL(*mock_handler_, Scan(true)).Times(1).WillOnce(Return());
287 EXPECT_TRUE(le_scanner_->StartScan(settings, filters));
288
289 // These should succeed and result in a HAL call
290 EXPECT_CALL(*mock_handler_, Scan(false)).Times(1).WillOnce(Return());
291 EXPECT_TRUE(le_scanner_->StopScan());
292
293 ::testing::Mock::VerifyAndClearExpectations(mock_handler_.get());
294 }
295
TEST_F(LowEnergyScannerPostRegisterTest,ScanRecord)296 TEST_F(LowEnergyScannerPostRegisterTest, ScanRecord) {
297 TestDelegate delegate;
298 le_scanner_->SetDelegate(&delegate);
299
300 EXPECT_EQ(0, delegate.scan_result_count());
301
302 std::vector<uint8_t> kTestRecord0({0x02, 0x01, 0x00, 0x00});
303 std::vector<uint8_t> kTestRecord1({0x00});
304 std::vector<uint8_t> kTestRecord2(
305 {0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01,
306 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
307 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01,
308 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
309 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01,
310 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00});
311 const RawAddress kTestAddress = {{0x01, 0x02, 0x03, 0x0A, 0x0B, 0x0C}};
312 const char kTestAddressStr[] = "01:02:03:0A:0B:0C";
313 const int kTestRssi = 64;
314
315 // Scan wasn't started. Result should be ignored.
316 fake_hal_gatt_iface_->NotifyScanResultCallback(kTestAddress, kTestRssi,
317 kTestRecord0);
318 EXPECT_EQ(0, delegate.scan_result_count());
319
320 // Start a scan session for |le_scanner_|.
321 EXPECT_CALL(mock_adapter_, IsEnabled()).Times(1).WillOnce(Return(true));
322 EXPECT_CALL(*mock_handler_, Scan(_))
323 .Times(2)
324 .WillOnce(Return())
325 .WillOnce(Return());
326 ScanSettings settings;
327 std::vector<ScanFilter> filters;
328 ASSERT_TRUE(le_scanner_->StartScan(settings, filters));
329
330 fake_hal_gatt_iface_->NotifyScanResultCallback(kTestAddress, kTestRssi,
331 kTestRecord0);
332 EXPECT_EQ(1, delegate.scan_result_count());
333 EXPECT_EQ(kTestAddressStr, delegate.last_scan_result().device_address());
334 EXPECT_EQ(kTestRssi, delegate.last_scan_result().rssi());
335 EXPECT_EQ(3U, delegate.last_scan_result().scan_record().size());
336
337 fake_hal_gatt_iface_->NotifyScanResultCallback(kTestAddress, kTestRssi,
338 kTestRecord1);
339 EXPECT_EQ(2, delegate.scan_result_count());
340 EXPECT_EQ(kTestAddressStr, delegate.last_scan_result().device_address());
341 EXPECT_EQ(kTestRssi, delegate.last_scan_result().rssi());
342 EXPECT_TRUE(delegate.last_scan_result().scan_record().empty());
343
344 fake_hal_gatt_iface_->NotifyScanResultCallback(kTestAddress, kTestRssi,
345 kTestRecord2);
346 EXPECT_EQ(3, delegate.scan_result_count());
347 EXPECT_EQ(kTestAddressStr, delegate.last_scan_result().device_address());
348 EXPECT_EQ(kTestRssi, delegate.last_scan_result().rssi());
349 EXPECT_EQ(62U, delegate.last_scan_result().scan_record().size());
350
351 le_scanner_->SetDelegate(nullptr);
352 }
353
354 } // namespace
355 } // namespace bluetooth
356