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