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
29using ::testing::_;
30using ::testing::Return;
31using ::testing::Pointee;
32using ::testing::DoAll;
33using ::testing::Invoke;
34using ::testing::SaveArg;
35
36namespace bluetooth {
37namespace {
38
39class 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, RawAddress, 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 RawAddress* 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
92class 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
114class 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.
145class 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>(&reg_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
198TEST_F(LowEnergyScannerTest, RegisterInstance) {
199  BleScannerInterface::RegisterCallback reg_scanner_cb1;
200  EXPECT_CALL(*mock_handler_, RegisterScanner(_))
201      .Times(1)
202      .WillOnce(SaveArg<0>(&reg_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>(&reg_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
270TEST_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
295TEST_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 RawAddress 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