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_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, RawAddress, uint16_t, uint16_t,
71 StartSyncCb, SyncReportCb, SyncLostCb));
72 MOCK_METHOD1(StopSync, void(uint16_t));
73
ScanFilterAdd(int filter_index,std::vector<ApcfCommand> filters,FilterConfigCallback cb)74 void ScanFilterAdd(int filter_index, std::vector<ApcfCommand> filters,
75 FilterConfigCallback cb) override{};
76
ScanFilterParamSetup(uint8_t client_if,uint8_t action,uint8_t filt_index,std::unique_ptr<btgatt_filt_param_setup_t> filt_param,FilterParamSetupCallback cb)77 void ScanFilterParamSetup(
78 uint8_t client_if, uint8_t action, uint8_t filt_index,
79 std::unique_ptr<btgatt_filt_param_setup_t> filt_param,
80 FilterParamSetupCallback cb) override {
81 ScanFilterParamSetupImpl(client_if, action, filt_index, filt_param.get(),
82 std::move(cb));
83 }
84 };
85
86 class TestDelegate : public LowEnergyScanner::Delegate {
87 public:
TestDelegate()88 TestDelegate() : scan_result_count_(0) {}
89
90 ~TestDelegate() override = default;
91
scan_result_count() const92 int scan_result_count() const { return scan_result_count_; }
last_scan_result() const93 const ScanResult& last_scan_result() const { return last_scan_result_; }
94
OnScanResult(LowEnergyScanner * scanner,const ScanResult & scan_result)95 void OnScanResult(LowEnergyScanner* scanner,
96 const ScanResult& scan_result) override {
97 ASSERT_TRUE(scanner);
98 scan_result_count_++;
99 last_scan_result_ = scan_result;
100 }
101
102 private:
103 int scan_result_count_;
104 ScanResult last_scan_result_;
105
106 DISALLOW_COPY_AND_ASSIGN(TestDelegate);
107 };
108
109 class LowEnergyScannerTest : public ::testing::Test {
110 public:
111 LowEnergyScannerTest() = default;
112 ~LowEnergyScannerTest() override = default;
113
SetUp()114 void SetUp() override {
115 // Only set |mock_handler_| if a test hasn't set it.
116 if (!mock_handler_) mock_handler_.reset(new MockScannerHandler());
117 fake_hal_gatt_iface_ = new hal::FakeBluetoothGattInterface(
118 nullptr, std::static_pointer_cast<BleScannerInterface>(mock_handler_),
119 nullptr, nullptr);
120 hal::BluetoothGattInterface::InitializeForTesting(fake_hal_gatt_iface_);
121 ble_factory_.reset(new LowEnergyScannerFactory(mock_adapter_));
122 }
123
TearDown()124 void TearDown() override {
125 ble_factory_.reset();
126 hal::BluetoothGattInterface::CleanUp();
127 }
128
129 protected:
130 hal::FakeBluetoothGattInterface* fake_hal_gatt_iface_;
131 testing::MockAdapter mock_adapter_;
132 std::shared_ptr<MockScannerHandler> mock_handler_;
133 std::unique_ptr<LowEnergyScannerFactory> ble_factory_;
134
135 private:
136 DISALLOW_COPY_AND_ASSIGN(LowEnergyScannerTest);
137 };
138
139 // Used for tests that operate on a pre-registered scanner.
140 class LowEnergyScannerPostRegisterTest : public LowEnergyScannerTest {
141 public:
LowEnergyScannerPostRegisterTest()142 LowEnergyScannerPostRegisterTest() : next_scanner_id_(0) {}
143 ~LowEnergyScannerPostRegisterTest() override = default;
144
SetUp()145 void SetUp() override {
146 LowEnergyScannerTest::SetUp();
147 auto callback = [&](std::unique_ptr<LowEnergyScanner> scanner) {
148 le_scanner_ = std::move(scanner);
149 };
150 RegisterTestScanner(callback);
151 }
152
TearDown()153 void TearDown() override {
154 EXPECT_CALL(*mock_handler_, Unregister(_)).Times(1).WillOnce(Return());
155 le_scanner_.reset();
156 LowEnergyScannerTest::TearDown();
157 }
158
RegisterTestScanner(const std::function<void (std::unique_ptr<LowEnergyScanner> scanner)> callback)159 void RegisterTestScanner(
160 const std::function<void(std::unique_ptr<LowEnergyScanner> scanner)>
161 callback) {
162 Uuid uuid = Uuid::GetRandom();
163 auto api_callback = [&](BLEStatus status, const Uuid& in_uuid,
164 std::unique_ptr<BluetoothInstance> in_scanner) {
165 CHECK(in_uuid == uuid);
166 CHECK(in_scanner.get());
167 CHECK(status == BLE_STATUS_SUCCESS);
168
169 callback(std::unique_ptr<LowEnergyScanner>(
170 static_cast<LowEnergyScanner*>(in_scanner.release())));
171 };
172
173 BleScannerInterface::RegisterCallback reg_scanner_cb;
174 EXPECT_CALL(*mock_handler_, RegisterScanner(_))
175 .Times(1)
176 .WillOnce(SaveArg<0>(®_scanner_cb));
177
178 ble_factory_->RegisterInstance(uuid, api_callback);
179
180 reg_scanner_cb.Run(next_scanner_id_++, BT_STATUS_SUCCESS);
181 ::testing::Mock::VerifyAndClearExpectations(mock_handler_.get());
182 }
183
184 protected:
185 std::unique_ptr<LowEnergyScanner> le_scanner_;
186
187 private:
188 int next_scanner_id_;
189
190 DISALLOW_COPY_AND_ASSIGN(LowEnergyScannerPostRegisterTest);
191 };
192
TEST_F(LowEnergyScannerTest,RegisterInstance)193 TEST_F(LowEnergyScannerTest, RegisterInstance) {
194 BleScannerInterface::RegisterCallback reg_scanner_cb1;
195 EXPECT_CALL(*mock_handler_, RegisterScanner(_))
196 .Times(1)
197 .WillOnce(SaveArg<0>(®_scanner_cb1));
198
199 // These will be asynchronously populated with a result when the callback
200 // executes.
201 BLEStatus status = BLE_STATUS_SUCCESS;
202 Uuid cb_uuid;
203 std::unique_ptr<LowEnergyScanner> scanner;
204 int callback_count = 0;
205
206 auto callback = [&](BLEStatus in_status, const Uuid& uuid,
207 std::unique_ptr<BluetoothInstance> in_scanner) {
208 status = in_status;
209 cb_uuid = uuid;
210 scanner = std::unique_ptr<LowEnergyScanner>(
211 static_cast<LowEnergyScanner*>(in_scanner.release()));
212 callback_count++;
213 };
214
215 Uuid uuid0 = Uuid::GetRandom();
216
217 // HAL returns success.
218 EXPECT_TRUE(ble_factory_->RegisterInstance(uuid0, callback));
219 EXPECT_EQ(0, callback_count);
220
221 // Calling twice with the same Uuid should fail with no additional call into
222 // the stack.
223 EXPECT_FALSE(ble_factory_->RegisterInstance(uuid0, callback));
224
225 ::testing::Mock::VerifyAndClearExpectations(mock_handler_.get());
226
227 // Call with a different Uuid while one is pending.
228 Uuid uuid1 = Uuid::GetRandom();
229 BleScannerInterface::RegisterCallback reg_scanner_cb2;
230 EXPECT_CALL(*mock_handler_, RegisterScanner(_))
231 .Times(1)
232 .WillOnce(SaveArg<0>(®_scanner_cb2));
233 EXPECT_TRUE(ble_factory_->RegisterInstance(uuid1, callback));
234
235 // |uuid0| succeeds.
236 int scanner_if0 = 2; // Pick something that's not 0.
237 reg_scanner_cb1.Run(scanner_if0, BT_STATUS_SUCCESS);
238
239 EXPECT_EQ(1, callback_count);
240 ASSERT_TRUE(scanner.get() !=
241 nullptr); // Assert to terminate in case of error
242 EXPECT_EQ(BLE_STATUS_SUCCESS, status);
243 EXPECT_EQ(scanner_if0, scanner->GetInstanceId());
244 EXPECT_EQ(uuid0, scanner->GetAppIdentifier());
245 EXPECT_EQ(uuid0, cb_uuid);
246
247 // The scanner should unregister itself when deleted.
248 EXPECT_CALL(*mock_handler_, Unregister(scanner_if0))
249 .Times(1)
250 .WillOnce(Return());
251 scanner.reset();
252 ::testing::Mock::VerifyAndClearExpectations(mock_handler_.get());
253
254 // |uuid1| fails.
255 int scanner_if1 = 3;
256 reg_scanner_cb2.Run(scanner_if1, BT_STATUS_FAIL);
257
258 EXPECT_EQ(2, callback_count);
259 ASSERT_TRUE(scanner.get() ==
260 nullptr); // Assert to terminate in case of error
261 EXPECT_EQ(BLE_STATUS_FAILURE, status);
262 EXPECT_EQ(uuid1, cb_uuid);
263 }
264
TEST_F(LowEnergyScannerPostRegisterTest,ScanSettings)265 TEST_F(LowEnergyScannerPostRegisterTest, ScanSettings) {
266 EXPECT_CALL(mock_adapter_, IsEnabled())
267 .WillOnce(Return(false))
268 .WillRepeatedly(Return(true));
269
270 ScanSettings settings;
271 std::vector<ScanFilter> filters;
272
273 // Adapter is not enabled.
274 EXPECT_FALSE(le_scanner_->StartScan(settings, filters));
275
276 // TODO(jpawlowski): add tests checking settings and filter parsing when
277 // implemented
278
279 // These should succeed and result in a HAL call
280 EXPECT_CALL(*mock_handler_, Scan(true)).Times(1).WillOnce(Return());
281 EXPECT_TRUE(le_scanner_->StartScan(settings, filters));
282
283 // These should succeed and result in a HAL call
284 EXPECT_CALL(*mock_handler_, Scan(false)).Times(1).WillOnce(Return());
285 EXPECT_TRUE(le_scanner_->StopScan());
286
287 ::testing::Mock::VerifyAndClearExpectations(mock_handler_.get());
288 }
289
TEST_F(LowEnergyScannerPostRegisterTest,ScanRecord)290 TEST_F(LowEnergyScannerPostRegisterTest, ScanRecord) {
291 TestDelegate delegate;
292 le_scanner_->SetDelegate(&delegate);
293
294 EXPECT_EQ(0, delegate.scan_result_count());
295
296 std::vector<uint8_t> kTestRecord0({0x02, 0x01, 0x00, 0x00});
297 std::vector<uint8_t> kTestRecord1({0x00});
298 std::vector<uint8_t> kTestRecord2(
299 {0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01,
300 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
301 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01,
302 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
303 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01,
304 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00});
305 const RawAddress kTestAddress = {{0x01, 0x02, 0x03, 0x0A, 0x0B, 0x0C}};
306 const char kTestAddressStr[] = "01:02:03:0A:0B:0C";
307 const int kTestRssi = 64;
308
309 // Scan wasn't started. Result should be ignored.
310 fake_hal_gatt_iface_->NotifyScanResultCallback(kTestAddress, kTestRssi,
311 kTestRecord0);
312 EXPECT_EQ(0, delegate.scan_result_count());
313
314 // Start a scan session for |le_scanner_|.
315 EXPECT_CALL(mock_adapter_, IsEnabled()).Times(1).WillOnce(Return(true));
316 EXPECT_CALL(*mock_handler_, Scan(_))
317 .Times(2)
318 .WillOnce(Return())
319 .WillOnce(Return());
320 ScanSettings settings;
321 std::vector<ScanFilter> filters;
322 ASSERT_TRUE(le_scanner_->StartScan(settings, filters));
323
324 fake_hal_gatt_iface_->NotifyScanResultCallback(kTestAddress, kTestRssi,
325 kTestRecord0);
326 EXPECT_EQ(1, delegate.scan_result_count());
327 EXPECT_EQ(kTestAddressStr, delegate.last_scan_result().device_address());
328 EXPECT_EQ(kTestRssi, delegate.last_scan_result().rssi());
329 EXPECT_EQ(3U, delegate.last_scan_result().scan_record().size());
330
331 fake_hal_gatt_iface_->NotifyScanResultCallback(kTestAddress, kTestRssi,
332 kTestRecord1);
333 EXPECT_EQ(2, delegate.scan_result_count());
334 EXPECT_EQ(kTestAddressStr, delegate.last_scan_result().device_address());
335 EXPECT_EQ(kTestRssi, delegate.last_scan_result().rssi());
336 EXPECT_TRUE(delegate.last_scan_result().scan_record().empty());
337
338 fake_hal_gatt_iface_->NotifyScanResultCallback(kTestAddress, kTestRssi,
339 kTestRecord2);
340 EXPECT_EQ(3, delegate.scan_result_count());
341 EXPECT_EQ(kTestAddressStr, delegate.last_scan_result().device_address());
342 EXPECT_EQ(kTestRssi, delegate.last_scan_result().rssi());
343 EXPECT_EQ(62U, delegate.last_scan_result().scan_record().size());
344
345 le_scanner_->SetDelegate(nullptr);
346 }
347
348 } // namespace
349 } // namespace bluetooth
350