low_energy_client_unittest.cpp revision a6551079fe71b1c76505ada0e4f758f6faf651e0
1//
2//  Copyright (C) 2015 Google, Inc.
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
21#include "service/adapter.h"
22#include "service/hal/fake_bluetooth_gatt_interface.h"
23#include "service/low_energy_client.h"
24#include "stack/include/bt_types.h"
25#include "stack/include/hcidefs.h"
26#include "test/mock_adapter.h"
27
28using ::testing::_;
29using ::testing::Return;
30using ::testing::Pointee;
31using ::testing::DoAll;
32using ::testing::Invoke;
33
34namespace bluetooth {
35namespace {
36
37class MockGattHandler
38    : public hal::FakeBluetoothGattInterface::TestClientHandler {
39 public:
40  MockGattHandler() {
41    ON_CALL(*this, Scan(false))
42        .WillByDefault(Return(BT_STATUS_SUCCESS));
43  }
44  ~MockGattHandler() override = default;
45
46  MOCK_METHOD1(RegisterClient, bt_status_t(bt_uuid_t*));
47  MOCK_METHOD1(UnregisterClient, bt_status_t(int));
48  MOCK_METHOD1(Scan, bt_status_t(bool));
49  MOCK_METHOD4(Connect, bt_status_t(int , const bt_bdaddr_t *, bool, int));
50  MOCK_METHOD3(Disconnect, bt_status_t(int , const bt_bdaddr_t *, int));
51  MOCK_METHOD7(MultiAdvEnable, bt_status_t(int, int, int, int, int, int, int));
52  MOCK_METHOD10(
53      MultiAdvSetInstDataMock,
54      bt_status_t(bool, bool, bool, int, int, char*, int, char*, int, char*));
55  MOCK_METHOD1(MultiAdvDisable, bt_status_t(int));
56
57  // GMock has macros for up to 10 arguments (11 is really just too many...).
58  // For now we forward this call to a 10 argument mock, omitting the
59  // |client_if| argument.
60  bt_status_t MultiAdvSetInstData(
61      int /* client_if */,
62      bool set_scan_rsp, bool include_name,
63      bool incl_txpower, int appearance,
64      int manufacturer_len, char* manufacturer_data,
65      int service_data_len, char* service_data,
66      int service_uuid_len, char* service_uuid) override {
67    return MultiAdvSetInstDataMock(
68        set_scan_rsp, include_name, incl_txpower, appearance,
69        manufacturer_len, manufacturer_data,
70        service_data_len, service_data,
71        service_uuid_len, service_uuid);
72  }
73
74 private:
75  DISALLOW_COPY_AND_ASSIGN(MockGattHandler);
76};
77
78class TestDelegate : public LowEnergyClient::Delegate {
79 public:
80  TestDelegate() : scan_result_count_(0), connection_state_count_(0),
81                   last_mtu_(0) {
82  }
83
84  ~TestDelegate() override = default;
85
86  int scan_result_count() const { return scan_result_count_; }
87  const ScanResult& last_scan_result() const { return last_scan_result_; }
88
89  int connection_state_count() const { return connection_state_count_; }
90
91  void OnConnectionState(LowEnergyClient* client, int status,
92                         const char* address, bool connected)  {
93    ASSERT_TRUE(client);
94    connection_state_count_++;
95  }
96
97  void OnMtuChanged(LowEnergyClient* client, int status, const char* address,
98                    int mtu) {
99    ASSERT_TRUE(client);
100    last_mtu_ = mtu;
101  }
102
103  void OnScanResult(LowEnergyClient* client, const ScanResult& scan_result) {
104    ASSERT_TRUE(client);
105    scan_result_count_++;
106    last_scan_result_ = scan_result;
107  }
108
109 private:
110  int scan_result_count_;
111  ScanResult last_scan_result_;
112
113  int connection_state_count_;
114
115  int last_mtu_;
116
117  DISALLOW_COPY_AND_ASSIGN(TestDelegate);
118};
119
120// Created this class for testing Advertising Data Setting
121// It provides a work around in order to verify the arguments
122// in the arrays passed to MultiAdvSetInstData due to mocks
123// not having an easy way to verify entire arrays
124class AdvertiseDataHandler : public MockGattHandler {
125 public:
126  AdvertiseDataHandler() : call_count_(0) {}
127  ~AdvertiseDataHandler() override = default;
128
129  bt_status_t MultiAdvSetInstData(
130      int /* client_if */,
131      bool set_scan_rsp, bool include_name,
132      bool incl_txpower, int appearance,
133      int manufacturer_len, char* manufacturer_data,
134      int service_data_len, char* service_data,
135      int service_uuid_len, char* service_uuid) override {
136    call_count_++;
137    service_data_.assign(
138        service_data, service_data+service_data_len);
139    manufacturer_data_.assign(
140        manufacturer_data, manufacturer_data+manufacturer_len);
141    uuid_data_.assign(
142        service_uuid, service_uuid+service_uuid_len);
143    return BT_STATUS_SUCCESS;
144  }
145
146  const std::vector<uint8_t>& manufacturer_data() const {
147    return manufacturer_data_;
148  }
149  const std::vector<uint8_t>& service_data() const { return service_data_; }
150  const std::vector<uint8_t>& uuid_data() const { return uuid_data_; }
151  int call_count() const { return call_count_; }
152
153 private:
154  int call_count_;
155  std::vector<uint8_t> manufacturer_data_;
156  std::vector<uint8_t> service_data_;
157  std::vector<uint8_t> uuid_data_;
158};
159
160class LowEnergyClientTest : public ::testing::Test {
161 public:
162  LowEnergyClientTest() = default;
163  ~LowEnergyClientTest() override = default;
164
165  void SetUp() override {
166    // Only set |mock_handler_| if a test hasn't set it.
167    if (!mock_handler_)
168        mock_handler_.reset(new MockGattHandler());
169    fake_hal_gatt_iface_ = new hal::FakeBluetoothGattInterface(
170        std::static_pointer_cast<
171            hal::FakeBluetoothGattInterface::TestClientHandler>(mock_handler_),
172        nullptr);
173    hal::BluetoothGattInterface::InitializeForTesting(fake_hal_gatt_iface_);
174    ble_factory_.reset(new LowEnergyClientFactory(mock_adapter_));
175  }
176
177  void TearDown() override {
178    ble_factory_.reset();
179    hal::BluetoothGattInterface::CleanUp();
180  }
181
182 protected:
183  hal::FakeBluetoothGattInterface* fake_hal_gatt_iface_;
184  testing::MockAdapter mock_adapter_;
185  std::shared_ptr<MockGattHandler> mock_handler_;
186  std::unique_ptr<LowEnergyClientFactory> ble_factory_;
187
188 private:
189  DISALLOW_COPY_AND_ASSIGN(LowEnergyClientTest);
190};
191
192// Used for tests that operate on a pre-registered client.
193class LowEnergyClientPostRegisterTest : public LowEnergyClientTest {
194 public:
195  LowEnergyClientPostRegisterTest() : next_client_id_(0) {
196  }
197  ~LowEnergyClientPostRegisterTest() override = default;
198
199  void SetUp() override {
200    LowEnergyClientTest::SetUp();
201    auto callback = [&](std::unique_ptr<LowEnergyClient> client) {
202      le_client_ = std::move(client);
203    };
204    RegisterTestClient(callback);
205  }
206
207  void TearDown() override {
208    EXPECT_CALL(*mock_handler_, MultiAdvDisable(_))
209        .Times(1)
210        .WillOnce(Return(BT_STATUS_SUCCESS));
211    EXPECT_CALL(*mock_handler_, UnregisterClient(_))
212        .Times(1)
213        .WillOnce(Return(BT_STATUS_SUCCESS));
214    le_client_.reset();
215    LowEnergyClientTest::TearDown();
216  }
217
218  void RegisterTestClient(
219      const std::function<void(std::unique_ptr<LowEnergyClient> client)>
220          callback) {
221    UUID uuid = UUID::GetRandom();
222    auto api_callback = [&](BLEStatus status, const UUID& in_uuid,
223                        std::unique_ptr<BluetoothInstance> in_client) {
224      CHECK(in_uuid == uuid);
225      CHECK(in_client.get());
226      CHECK(status == BLE_STATUS_SUCCESS);
227
228      callback(std::unique_ptr<LowEnergyClient>(
229          static_cast<LowEnergyClient*>(in_client.release())));
230    };
231
232    EXPECT_CALL(*mock_handler_, RegisterClient(_))
233        .Times(1)
234        .WillOnce(Return(BT_STATUS_SUCCESS));
235
236    ble_factory_->RegisterInstance(uuid, api_callback);
237
238    bt_uuid_t hal_uuid = uuid.GetBlueDroid();
239    fake_hal_gatt_iface_->NotifyRegisterClientCallback(
240        0, next_client_id_++, hal_uuid);
241    ::testing::Mock::VerifyAndClearExpectations(mock_handler_.get());
242  }
243
244  void StartAdvertising() {
245    ASSERT_FALSE(le_client_->IsAdvertisingStarted());
246    ASSERT_FALSE(le_client_->IsStartingAdvertising());
247    ASSERT_FALSE(le_client_->IsStoppingAdvertising());
248
249    EXPECT_CALL(*mock_handler_, MultiAdvEnable(_, _, _, _, _, _, _))
250        .Times(1)
251        .WillOnce(Return(BT_STATUS_SUCCESS));
252    EXPECT_CALL(*mock_handler_,
253                MultiAdvSetInstDataMock(_, _, _, _, _, _, _, _, _, _))
254        .Times(1)
255        .WillOnce(Return(BT_STATUS_SUCCESS));
256
257    AdvertiseSettings settings;
258    AdvertiseData adv, scan_rsp;
259    ASSERT_TRUE(le_client_->StartAdvertising(
260        settings, adv, scan_rsp, LowEnergyClient::StatusCallback()));
261    ASSERT_TRUE(le_client_->IsStartingAdvertising());
262
263    fake_hal_gatt_iface_->NotifyMultiAdvEnableCallback(
264        le_client_->GetInstanceId(), BT_STATUS_SUCCESS);
265    fake_hal_gatt_iface_->NotifyMultiAdvDataCallback(
266        le_client_->GetInstanceId(), BT_STATUS_SUCCESS);
267
268    ASSERT_TRUE(le_client_->IsAdvertisingStarted());
269    ASSERT_FALSE(le_client_->IsStartingAdvertising());
270    ASSERT_FALSE(le_client_->IsStoppingAdvertising());
271  }
272
273  void AdvertiseDataTestHelper(AdvertiseData data, std::function<void(BLEStatus)> callback) {
274    AdvertiseSettings settings;
275    EXPECT_TRUE(le_client_->StartAdvertising(
276        settings, data, AdvertiseData(), callback));
277    fake_hal_gatt_iface_->NotifyMultiAdvEnableCallback(
278        le_client_->GetInstanceId(), BT_STATUS_SUCCESS);
279    fake_hal_gatt_iface_->NotifyMultiAdvDataCallback(
280        le_client_->GetInstanceId(), BT_STATUS_SUCCESS);
281    EXPECT_TRUE(le_client_->StopAdvertising(LowEnergyClient::StatusCallback()));
282    fake_hal_gatt_iface_->NotifyMultiAdvDisableCallback(
283        le_client_->GetInstanceId(), BT_STATUS_SUCCESS);
284  }
285
286 protected:
287  std::unique_ptr<LowEnergyClient> le_client_;
288
289 private:
290  int next_client_id_;
291
292  DISALLOW_COPY_AND_ASSIGN(LowEnergyClientPostRegisterTest);
293};
294
295TEST_F(LowEnergyClientTest, RegisterInstance) {
296  EXPECT_CALL(*mock_handler_, RegisterClient(_))
297      .Times(2)
298      .WillOnce(Return(BT_STATUS_FAIL))
299      .WillOnce(Return(BT_STATUS_SUCCESS));
300
301  // These will be asynchronously populated with a result when the callback
302  // executes.
303  BLEStatus status = BLE_STATUS_SUCCESS;
304  UUID cb_uuid;
305  std::unique_ptr<LowEnergyClient> client;
306  int callback_count = 0;
307
308  auto callback = [&](BLEStatus in_status, const UUID& uuid,
309                      std::unique_ptr<BluetoothInstance> in_client) {
310        status = in_status;
311        cb_uuid = uuid;
312        client = std::unique_ptr<LowEnergyClient>(
313            static_cast<LowEnergyClient*>(in_client.release()));
314        callback_count++;
315      };
316
317  UUID uuid0 = UUID::GetRandom();
318
319  // HAL returns failure.
320  EXPECT_FALSE(ble_factory_->RegisterInstance(uuid0, callback));
321  EXPECT_EQ(0, callback_count);
322
323  // HAL returns success.
324  EXPECT_TRUE(ble_factory_->RegisterInstance(uuid0, callback));
325  EXPECT_EQ(0, callback_count);
326
327  // Calling twice with the same UUID should fail with no additional call into
328  // the stack.
329  EXPECT_FALSE(ble_factory_->RegisterInstance(uuid0, callback));
330
331  ::testing::Mock::VerifyAndClearExpectations(mock_handler_.get());
332
333  // Call with a different UUID while one is pending.
334  UUID uuid1 = UUID::GetRandom();
335  EXPECT_CALL(*mock_handler_, RegisterClient(_))
336      .Times(1)
337      .WillOnce(Return(BT_STATUS_SUCCESS));
338  EXPECT_TRUE(ble_factory_->RegisterInstance(uuid1, callback));
339
340  // Trigger callback with an unknown UUID. This should get ignored.
341  UUID uuid2 = UUID::GetRandom();
342  bt_uuid_t hal_uuid = uuid2.GetBlueDroid();
343  fake_hal_gatt_iface_->NotifyRegisterClientCallback(0, 0, hal_uuid);
344  EXPECT_EQ(0, callback_count);
345
346  // |uuid0| succeeds.
347  int client_if0 = 2;  // Pick something that's not 0.
348  hal_uuid = uuid0.GetBlueDroid();
349  fake_hal_gatt_iface_->NotifyRegisterClientCallback(
350      BT_STATUS_SUCCESS, client_if0, hal_uuid);
351
352  EXPECT_EQ(1, callback_count);
353  ASSERT_TRUE(client.get() != nullptr);  // Assert to terminate in case of error
354  EXPECT_EQ(BLE_STATUS_SUCCESS, status);
355  EXPECT_EQ(client_if0, client->GetInstanceId());
356  EXPECT_EQ(uuid0, client->GetAppIdentifier());
357  EXPECT_EQ(uuid0, cb_uuid);
358
359  // The client should unregister itself when deleted.
360  EXPECT_CALL(*mock_handler_, MultiAdvDisable(client_if0))
361      .Times(1)
362      .WillOnce(Return(BT_STATUS_SUCCESS));
363  EXPECT_CALL(*mock_handler_, UnregisterClient(client_if0))
364      .Times(1)
365      .WillOnce(Return(BT_STATUS_SUCCESS));
366  client.reset();
367  ::testing::Mock::VerifyAndClearExpectations(mock_handler_.get());
368
369  // |uuid1| fails.
370  int client_if1 = 3;
371  hal_uuid = uuid1.GetBlueDroid();
372  fake_hal_gatt_iface_->NotifyRegisterClientCallback(
373      BT_STATUS_FAIL, client_if1, hal_uuid);
374
375  EXPECT_EQ(2, callback_count);
376  ASSERT_TRUE(client.get() == nullptr);  // Assert to terminate in case of error
377  EXPECT_EQ(BLE_STATUS_FAILURE, status);
378  EXPECT_EQ(uuid1, cb_uuid);
379}
380
381TEST_F(LowEnergyClientPostRegisterTest, StartAdvertisingBasic) {
382  EXPECT_FALSE(le_client_->IsAdvertisingStarted());
383  EXPECT_FALSE(le_client_->IsStartingAdvertising());
384  EXPECT_FALSE(le_client_->IsStoppingAdvertising());
385
386  // Use default advertising settings and data.
387  AdvertiseSettings settings;
388  AdvertiseData adv_data, scan_rsp;
389  int callback_count = 0;
390  BLEStatus last_status = BLE_STATUS_FAILURE;
391  auto callback = [&](BLEStatus status) {
392    last_status = status;
393    callback_count++;
394  };
395
396  EXPECT_CALL(*mock_handler_, MultiAdvEnable(_, _, _, _, _, _, _))
397      .Times(5)
398      .WillOnce(Return(BT_STATUS_FAIL))
399      .WillRepeatedly(Return(BT_STATUS_SUCCESS));
400
401  // Stack call returns failure.
402  EXPECT_FALSE(le_client_->StartAdvertising(
403      settings, adv_data, scan_rsp, callback));
404  EXPECT_FALSE(le_client_->IsAdvertisingStarted());
405  EXPECT_FALSE(le_client_->IsStartingAdvertising());
406  EXPECT_FALSE(le_client_->IsStoppingAdvertising());
407  EXPECT_EQ(0, callback_count);
408
409  // Stack call returns success.
410  EXPECT_TRUE(le_client_->StartAdvertising(
411      settings, adv_data, scan_rsp, callback));
412  EXPECT_FALSE(le_client_->IsAdvertisingStarted());
413  EXPECT_TRUE(le_client_->IsStartingAdvertising());
414  EXPECT_FALSE(le_client_->IsStoppingAdvertising());
415  EXPECT_EQ(0, callback_count);
416
417  // Already starting.
418  EXPECT_FALSE(le_client_->StartAdvertising(
419      settings, adv_data, scan_rsp, callback));
420
421  // Notify failure.
422  fake_hal_gatt_iface_->NotifyMultiAdvEnableCallback(
423      le_client_->GetInstanceId(), BT_STATUS_FAIL);
424  EXPECT_FALSE(le_client_->IsAdvertisingStarted());
425  EXPECT_FALSE(le_client_->IsStartingAdvertising());
426  EXPECT_FALSE(le_client_->IsStoppingAdvertising());
427  EXPECT_EQ(1, callback_count);
428  EXPECT_EQ(BLE_STATUS_FAILURE, last_status);
429
430  // Try again.
431  EXPECT_TRUE(le_client_->StartAdvertising(
432      settings, adv_data, scan_rsp, callback));
433  EXPECT_FALSE(le_client_->IsAdvertisingStarted());
434  EXPECT_TRUE(le_client_->IsStartingAdvertising());
435  EXPECT_FALSE(le_client_->IsStoppingAdvertising());
436  EXPECT_EQ(1, callback_count);
437
438  // Success notification should trigger advertise data update.
439  EXPECT_CALL(*mock_handler_,
440              MultiAdvSetInstDataMock(
441                  false,  // set_scan_rsp
442                  false,  // include_name
443                  false,  // incl_txpower
444                  _, _, _, _, _, _, _))
445      .Times(3)
446      .WillOnce(Return(BT_STATUS_FAIL))
447      .WillRepeatedly(Return(BT_STATUS_SUCCESS));
448
449  // Notify success for enable. The procedure will fail since setting data will
450  // fail.
451  fake_hal_gatt_iface_->NotifyMultiAdvEnableCallback(
452      le_client_->GetInstanceId(), BT_STATUS_SUCCESS);
453  EXPECT_FALSE(le_client_->IsAdvertisingStarted());
454  EXPECT_FALSE(le_client_->IsStartingAdvertising());
455  EXPECT_FALSE(le_client_->IsStoppingAdvertising());
456  EXPECT_EQ(2, callback_count);
457  EXPECT_EQ(BLE_STATUS_FAILURE, last_status);
458
459  // Try again.
460  EXPECT_TRUE(le_client_->StartAdvertising(
461      settings, adv_data, scan_rsp, callback));
462  EXPECT_FALSE(le_client_->IsAdvertisingStarted());
463  EXPECT_TRUE(le_client_->IsStartingAdvertising());
464  EXPECT_FALSE(le_client_->IsStoppingAdvertising());
465  EXPECT_EQ(2, callback_count);
466
467  // Notify success for enable. the advertise data call should succeed but
468  // operation will remain pending.
469  fake_hal_gatt_iface_->NotifyMultiAdvEnableCallback(
470      le_client_->GetInstanceId(), BT_STATUS_SUCCESS);
471  EXPECT_FALSE(le_client_->IsAdvertisingStarted());
472  EXPECT_TRUE(le_client_->IsStartingAdvertising());
473  EXPECT_FALSE(le_client_->IsStoppingAdvertising());
474  EXPECT_EQ(2, callback_count);
475
476  // Notify failure from advertising call.
477  fake_hal_gatt_iface_->NotifyMultiAdvDataCallback(
478      le_client_->GetInstanceId(), BT_STATUS_FAIL);
479  EXPECT_FALSE(le_client_->IsAdvertisingStarted());
480  EXPECT_FALSE(le_client_->IsStartingAdvertising());
481  EXPECT_FALSE(le_client_->IsStoppingAdvertising());
482  EXPECT_EQ(3, callback_count);
483  EXPECT_EQ(BLE_STATUS_FAILURE, last_status);
484
485  // Try again. Make everything succeed.
486  EXPECT_TRUE(le_client_->StartAdvertising(
487      settings, adv_data, scan_rsp, callback));
488  EXPECT_FALSE(le_client_->IsAdvertisingStarted());
489  EXPECT_TRUE(le_client_->IsStartingAdvertising());
490  EXPECT_FALSE(le_client_->IsStoppingAdvertising());
491  EXPECT_EQ(3, callback_count);
492
493  fake_hal_gatt_iface_->NotifyMultiAdvEnableCallback(
494      le_client_->GetInstanceId(), BT_STATUS_SUCCESS);
495  fake_hal_gatt_iface_->NotifyMultiAdvDataCallback(
496      le_client_->GetInstanceId(), BT_STATUS_SUCCESS);
497  EXPECT_TRUE(le_client_->IsAdvertisingStarted());
498  EXPECT_FALSE(le_client_->IsStartingAdvertising());
499  EXPECT_FALSE(le_client_->IsStoppingAdvertising());
500  EXPECT_EQ(4, callback_count);
501  EXPECT_EQ(BLE_STATUS_SUCCESS, last_status);
502
503  // Already started.
504  EXPECT_FALSE(le_client_->StartAdvertising(
505      settings, adv_data, scan_rsp, callback));
506}
507
508TEST_F(LowEnergyClientPostRegisterTest, StopAdvertisingBasic) {
509  AdvertiseSettings settings;
510
511  // Not enabled.
512  EXPECT_FALSE(le_client_->IsAdvertisingStarted());
513  EXPECT_FALSE(le_client_->StopAdvertising(LowEnergyClient::StatusCallback()));
514
515  // Start advertising for testing.
516  StartAdvertising();
517
518  int callback_count = 0;
519  BLEStatus last_status = BLE_STATUS_FAILURE;
520  auto callback = [&](BLEStatus status) {
521    last_status = status;
522    callback_count++;
523  };
524
525  EXPECT_CALL(*mock_handler_, MultiAdvDisable(_))
526      .Times(3)
527      .WillOnce(Return(BT_STATUS_FAIL))
528      .WillRepeatedly(Return(BT_STATUS_SUCCESS));
529
530  // Stack call returns failure.
531  EXPECT_FALSE(le_client_->StopAdvertising(callback));
532  EXPECT_TRUE(le_client_->IsAdvertisingStarted());
533  EXPECT_FALSE(le_client_->IsStartingAdvertising());
534  EXPECT_FALSE(le_client_->IsStoppingAdvertising());
535  EXPECT_EQ(0, callback_count);
536
537  // Stack returns success.
538  EXPECT_TRUE(le_client_->StopAdvertising(callback));
539  EXPECT_TRUE(le_client_->IsAdvertisingStarted());
540  EXPECT_FALSE(le_client_->IsStartingAdvertising());
541  EXPECT_TRUE(le_client_->IsStoppingAdvertising());
542  EXPECT_EQ(0, callback_count);
543
544  // Already disabling.
545  EXPECT_FALSE(le_client_->StopAdvertising(callback));
546  EXPECT_TRUE(le_client_->IsAdvertisingStarted());
547  EXPECT_FALSE(le_client_->IsStartingAdvertising());
548  EXPECT_TRUE(le_client_->IsStoppingAdvertising());
549  EXPECT_EQ(0, callback_count);
550
551  // Notify failure.
552  fake_hal_gatt_iface_->NotifyMultiAdvDisableCallback(
553      le_client_->GetInstanceId(), BT_STATUS_FAIL);
554  EXPECT_TRUE(le_client_->IsAdvertisingStarted());
555  EXPECT_FALSE(le_client_->IsStartingAdvertising());
556  EXPECT_FALSE(le_client_->IsStoppingAdvertising());
557  EXPECT_EQ(1, callback_count);
558  EXPECT_EQ(BLE_STATUS_FAILURE, last_status);
559
560  // Try again.
561  EXPECT_TRUE(le_client_->StopAdvertising(callback));
562  EXPECT_TRUE(le_client_->IsAdvertisingStarted());
563  EXPECT_FALSE(le_client_->IsStartingAdvertising());
564  EXPECT_TRUE(le_client_->IsStoppingAdvertising());
565  EXPECT_EQ(1, callback_count);
566
567  // Notify success.
568  fake_hal_gatt_iface_->NotifyMultiAdvDisableCallback(
569      le_client_->GetInstanceId(), BT_STATUS_SUCCESS);
570  EXPECT_FALSE(le_client_->IsAdvertisingStarted());
571  EXPECT_FALSE(le_client_->IsStartingAdvertising());
572  EXPECT_FALSE(le_client_->IsStoppingAdvertising());
573  EXPECT_EQ(2, callback_count);
574  EXPECT_EQ(BLE_STATUS_SUCCESS, last_status);
575
576  // Already stopped.
577  EXPECT_FALSE(le_client_->StopAdvertising(callback));
578}
579
580TEST_F(LowEnergyClientPostRegisterTest, InvalidAdvertiseData) {
581  const std::vector<uint8_t> data0{ 0x02, HCI_EIR_FLAGS_TYPE, 0x00 };
582  const std::vector<uint8_t> data1{
583      0x04, HCI_EIR_MANUFACTURER_SPECIFIC_TYPE, 0x01, 0x02, 0x00
584  };
585  AdvertiseData invalid_adv(data0);
586  AdvertiseData valid_adv(data1);
587
588  AdvertiseSettings settings;
589
590  EXPECT_FALSE(le_client_->StartAdvertising(
591      settings, valid_adv, invalid_adv, LowEnergyClient::StatusCallback()));
592  EXPECT_FALSE(le_client_->StartAdvertising(
593      settings, invalid_adv, valid_adv, LowEnergyClient::StatusCallback()));
594
595  // Manufacturer data not correctly formatted according to spec. We let the
596  // stack handle this case.
597  const std::vector<uint8_t> data2{ 0x01, HCI_EIR_MANUFACTURER_SPECIFIC_TYPE };
598  AdvertiseData invalid_mfc(data2);
599
600  EXPECT_CALL(*mock_handler_, MultiAdvEnable(_, _, _, _, _, _, _))
601      .Times(1)
602      .WillOnce(Return(BT_STATUS_SUCCESS));
603  EXPECT_TRUE(le_client_->StartAdvertising(
604      settings, invalid_mfc, valid_adv, LowEnergyClient::StatusCallback()));
605}
606
607TEST_F(LowEnergyClientPostRegisterTest, ScanResponse) {
608  EXPECT_FALSE(le_client_->IsAdvertisingStarted());
609  EXPECT_FALSE(le_client_->IsStartingAdvertising());
610  EXPECT_FALSE(le_client_->IsStoppingAdvertising());
611
612  AdvertiseSettings settings(
613      AdvertiseSettings::MODE_LOW_POWER,
614      base::TimeDelta::FromMilliseconds(300),
615      AdvertiseSettings::TX_POWER_LEVEL_MEDIUM,
616      false /* connectable */);
617
618  const std::vector<uint8_t> data0;
619  const std::vector<uint8_t> data1{
620      0x04, HCI_EIR_MANUFACTURER_SPECIFIC_TYPE, 0x01, 0x02, 0x00
621  };
622
623  int callback_count = 0;
624  BLEStatus last_status = BLE_STATUS_FAILURE;
625  auto callback = [&](BLEStatus status) {
626    last_status = status;
627    callback_count++;
628  };
629
630  AdvertiseData adv0(data0);
631  adv0.set_include_tx_power_level(true);
632
633  AdvertiseData adv1(data1);
634  adv1.set_include_device_name(true);
635
636  EXPECT_CALL(*mock_handler_,
637              MultiAdvEnable(le_client_->GetInstanceId(), _, _,
638                             kAdvertisingEventTypeScannable,
639                             _, _, _))
640      .Times(2)
641      .WillRepeatedly(Return(BT_STATUS_SUCCESS));
642  EXPECT_CALL(
643      *mock_handler_,
644      MultiAdvSetInstDataMock(
645          false,  // set_scan_rsp
646          false,  // include_name
647          true,  // incl_txpower,
648          _,
649          0,  // 0 bytes
650          _, _, _, _, _))
651      .Times(2)
652      .WillRepeatedly(Return(BT_STATUS_SUCCESS));
653  EXPECT_CALL(
654      *mock_handler_,
655      MultiAdvSetInstDataMock(
656          true,  // set_scan_rsp
657          true,  // include_name
658          false,  // incl_txpower,
659          _,
660          data1.size() - 2,  // Mfc. Specific data field bytes.
661          _, _, _, _, _))
662      .Times(2)
663      .WillRepeatedly(Return(BT_STATUS_SUCCESS));
664
665  // Enable success; Adv. data success; Scan rsp. fail.
666  EXPECT_TRUE(le_client_->StartAdvertising(settings, adv0, adv1, callback));
667  fake_hal_gatt_iface_->NotifyMultiAdvEnableCallback(
668      le_client_->GetInstanceId(), BT_STATUS_SUCCESS);
669  fake_hal_gatt_iface_->NotifyMultiAdvDataCallback(
670      le_client_->GetInstanceId(), BT_STATUS_SUCCESS);
671  fake_hal_gatt_iface_->NotifyMultiAdvDataCallback(
672      le_client_->GetInstanceId(), BT_STATUS_FAIL);
673
674  EXPECT_EQ(1, callback_count);
675  EXPECT_EQ(BLE_STATUS_FAILURE, last_status);
676  EXPECT_FALSE(le_client_->IsAdvertisingStarted());
677
678  // Second time everything succeeds.
679  EXPECT_TRUE(le_client_->StartAdvertising(settings, adv0, adv1, callback));
680  fake_hal_gatt_iface_->NotifyMultiAdvEnableCallback(
681      le_client_->GetInstanceId(), BT_STATUS_SUCCESS);
682  fake_hal_gatt_iface_->NotifyMultiAdvDataCallback(
683      le_client_->GetInstanceId(), BT_STATUS_SUCCESS);
684  fake_hal_gatt_iface_->NotifyMultiAdvDataCallback(
685      le_client_->GetInstanceId(), BT_STATUS_SUCCESS);
686
687  EXPECT_EQ(2, callback_count);
688  EXPECT_EQ(BLE_STATUS_SUCCESS, last_status);
689  EXPECT_TRUE(le_client_->IsAdvertisingStarted());
690}
691
692TEST_F(LowEnergyClientPostRegisterTest, AdvertiseDataParsing) {
693  // Re-initialize the test with our own custom handler.
694  TearDown();
695  std::shared_ptr<AdvertiseDataHandler> adv_handler(new AdvertiseDataHandler());
696  mock_handler_ = std::static_pointer_cast<MockGattHandler>(adv_handler);
697  SetUp();
698
699  const std::vector<uint8_t> kUUID16BitData{
700    0x03, HCI_EIR_COMPLETE_16BITS_UUID_TYPE, 0xDE, 0xAD,
701  };
702
703  const std::vector<uint8_t> kUUID32BitData{
704    0x05, HCI_EIR_COMPLETE_32BITS_UUID_TYPE, 0xDE, 0xAD, 0x01, 0x02
705  };
706
707  const std::vector<uint8_t> kUUID128BitData{
708    0x11, HCI_EIR_COMPLETE_128BITS_UUID_TYPE,
709    0xDE, 0xAD, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
710    0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E
711  };
712
713  const std::vector<uint8_t> kMultiUUIDData{
714    0x11, HCI_EIR_COMPLETE_128BITS_UUID_TYPE,
715    0xDE, 0xAD, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
716    0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
717    0x05, HCI_EIR_COMPLETE_32BITS_UUID_TYPE, 0xDE, 0xAD, 0xBE, 0xEF
718  };
719
720  const std::vector<uint8_t> kServiceData16Bit{
721    0x05, HCI_EIR_SERVICE_DATA_16BITS_UUID_TYPE, 0xDE, 0xAD, 0xBE, 0xEF
722  };
723
724  const std::vector<uint8_t> kServiceData32Bit{
725    0x07, HCI_EIR_SERVICE_DATA_32BITS_UUID_TYPE, 0xDE, 0xAD, 0x01, 0x02, 0xBE, 0xEF
726  };
727
728  const std::vector<uint8_t> kServiceData128Bit{
729    0x13, HCI_EIR_SERVICE_DATA_128BITS_UUID_TYPE,
730    0xDE, 0xAD, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
731    0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0xBE, 0xEF
732  };
733
734  const std::vector<uint8_t> kMultiServiceData{
735    0x13, HCI_EIR_SERVICE_DATA_128BITS_UUID_TYPE,
736    0xDE, 0xAD, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0xBE, 0xEF,
737    0xDE, 0xAD, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
738    0x05, HCI_EIR_SERVICE_DATA_16BITS_UUID_TYPE, 0xDE, 0xAD, 0xBE, 0xEF
739  };
740
741  const std::vector<uint8_t> kServiceUUIDMatch{
742    0x05, HCI_EIR_COMPLETE_32BITS_UUID_TYPE, 0xDE, 0xAD, 0x01, 0x02,
743    0x07, HCI_EIR_SERVICE_DATA_32BITS_UUID_TYPE, 0xDE, 0xAD, 0x01, 0x02, 0xBE, 0xEF
744  };
745
746  const std::vector<uint8_t> kServiceUUIDMismatch{
747    0x05, HCI_EIR_COMPLETE_32BITS_UUID_TYPE, 0xDE, 0xAD, 0x01, 0x01,
748    0x07, HCI_EIR_SERVICE_DATA_32BITS_UUID_TYPE, 0xDE, 0xAD, 0x01, 0x02, 0xBE, 0xEF
749  };
750
751  AdvertiseData uuid_16bit_adv(kUUID16BitData);
752  AdvertiseData uuid_32bit_adv(kUUID32BitData);
753  AdvertiseData uuid_128bit_adv(kUUID128BitData);
754  AdvertiseData multi_uuid_adv(kMultiUUIDData);
755
756  AdvertiseData service_16bit_adv(kServiceData16Bit);
757  AdvertiseData service_32bit_adv(kServiceData32Bit);
758  AdvertiseData service_128bit_adv(kServiceData128Bit);
759  AdvertiseData multi_service_adv(kMultiServiceData);
760
761  AdvertiseData service_uuid_match(kServiceUUIDMatch);
762  AdvertiseData service_uuid_mismatch(kServiceUUIDMismatch);
763
764  AdvertiseSettings settings;
765
766  int callback_count = 0;
767  BLEStatus last_status = BLE_STATUS_FAILURE;
768  auto callback = [&](BLEStatus status) {
769    last_status = status;
770    callback_count++;
771  };
772
773  EXPECT_CALL(*mock_handler_, MultiAdvEnable(_, _, _, _, _, _, _))
774      .WillRepeatedly(Return(BT_STATUS_SUCCESS));
775  EXPECT_CALL(*mock_handler_, MultiAdvDisable(_))
776      .WillRepeatedly(Return(BT_STATUS_SUCCESS));
777
778  // Multiple UUID test, should fail due to only one UUID allowed
779  EXPECT_TRUE(le_client_->StartAdvertising(
780              settings, multi_uuid_adv, AdvertiseData(), callback));
781  fake_hal_gatt_iface_->NotifyMultiAdvEnableCallback(
782          le_client_->GetInstanceId(), BT_STATUS_SUCCESS);
783  EXPECT_EQ(1, callback_count);
784  EXPECT_EQ(0, adv_handler->call_count());
785  EXPECT_EQ(BLE_STATUS_FAILURE, last_status);
786
787  // Multiple Service Data test, should fail due to only one service data allowed
788  EXPECT_TRUE(le_client_->StartAdvertising(
789              settings, multi_uuid_adv, AdvertiseData(), callback));
790  fake_hal_gatt_iface_->NotifyMultiAdvEnableCallback(
791          le_client_->GetInstanceId(), BT_STATUS_SUCCESS);
792  EXPECT_EQ(2, callback_count);
793  EXPECT_EQ(0, adv_handler->call_count());
794  EXPECT_EQ(BLE_STATUS_FAILURE, last_status);
795
796  // 16bit uuid test, should succeed with correctly parsed uuid in little-endian
797  // 128-bit format.
798  AdvertiseDataTestHelper(uuid_16bit_adv, callback);
799  EXPECT_EQ(3, callback_count);
800  EXPECT_EQ(1, adv_handler->call_count());
801  const std::vector<uint8_t> uuid_16bit_canonical{
802    0xFB, 0x34, 0x9b, 0x5F, 0x80, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00,
803    0xDE, 0xAD, 0x00, 0x00
804  };
805  EXPECT_EQ(uuid_16bit_canonical, adv_handler->uuid_data());
806
807  // 32bit uuid test, should succeed with correctly parsed uuid
808  AdvertiseDataTestHelper(uuid_32bit_adv, callback);
809  EXPECT_EQ(4, callback_count);
810  EXPECT_EQ(2, adv_handler->call_count());
811  const std::vector<uint8_t> uuid_32bit_canonical{
812    0xFB, 0x34, 0x9b, 0x5F, 0x80, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00,
813    0xDE, 0xAD, 0x01, 0x02
814  };
815  EXPECT_EQ(uuid_32bit_canonical, adv_handler->uuid_data());
816
817  // 128bit uuid test, should succeed with correctly parsed uuid
818  AdvertiseDataTestHelper(uuid_128bit_adv, callback);
819  EXPECT_EQ(5, callback_count);
820  EXPECT_EQ(3, adv_handler->call_count());
821  const std::vector<uint8_t> uuid_128bit{
822    0xDE, 0xAD, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
823    0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E
824  };
825  EXPECT_EQ(uuid_128bit, adv_handler->uuid_data());
826
827  const std::vector<uint8_t> service_data{ 0xBE, 0xEF };
828
829  // Service data with 16bit uuid included, should succeed with
830  // uuid and service data parsed out
831  AdvertiseDataTestHelper(service_16bit_adv, callback);
832  EXPECT_EQ(6, callback_count);
833  EXPECT_EQ(4, adv_handler->call_count());
834  EXPECT_EQ(service_data, adv_handler->service_data());
835  EXPECT_EQ(uuid_16bit_canonical, adv_handler->uuid_data());
836
837  // Service data with 32bit uuid included, should succeed with
838  // uuid and service data parsed out
839  AdvertiseDataTestHelper(service_32bit_adv, callback);
840  EXPECT_EQ(7, callback_count);
841  EXPECT_EQ(5, adv_handler->call_count());
842  EXPECT_EQ(service_data, adv_handler->service_data());
843  EXPECT_EQ(uuid_32bit_canonical, adv_handler->uuid_data());
844
845  // Service data with 128bit uuid included, should succeed with
846  // uuid and service data parsed out
847  AdvertiseDataTestHelper(service_128bit_adv, callback);
848  EXPECT_EQ(8, callback_count);
849  EXPECT_EQ(6, adv_handler->call_count());
850  EXPECT_EQ(service_data, adv_handler->service_data());
851  EXPECT_EQ(uuid_128bit, adv_handler->uuid_data());
852
853  // Service data and UUID where the UUID for both match, should succeed.
854  AdvertiseDataTestHelper(service_uuid_match, callback);
855  EXPECT_EQ(9, callback_count);
856  EXPECT_EQ(7, adv_handler->call_count());
857  EXPECT_EQ(service_data, adv_handler->service_data());
858  EXPECT_EQ(uuid_32bit_canonical, adv_handler->uuid_data());
859
860  // Service data and UUID where the UUID for dont match, should fail
861  EXPECT_TRUE(le_client_->StartAdvertising(
862              settings, service_uuid_mismatch, AdvertiseData(), callback));
863  fake_hal_gatt_iface_->NotifyMultiAdvEnableCallback(
864      le_client_->GetInstanceId(), BT_STATUS_SUCCESS);
865  EXPECT_EQ(10, callback_count);
866  EXPECT_EQ(7, adv_handler->call_count());
867  EXPECT_EQ(BLE_STATUS_FAILURE, last_status);
868}
869
870TEST_F(LowEnergyClientPostRegisterTest, ScanSettings) {
871  EXPECT_CALL(mock_adapter_, IsEnabled())
872      .WillOnce(Return(false))
873      .WillRepeatedly(Return(true));
874
875  ScanSettings settings;
876  std::vector<ScanFilter> filters;
877
878  // Adapter is not enabled.
879  EXPECT_FALSE(le_client_->StartScan(settings, filters));
880
881  // TODO(jpawlowski): add tests checking settings and filter parsing when
882  // implemented
883
884  // These should succeed and result in a HAL call
885  EXPECT_CALL(*mock_handler_, Scan(true))
886      .Times(1)
887      .WillOnce(Return(BT_STATUS_SUCCESS));
888  EXPECT_TRUE(le_client_->StartScan(settings, filters));
889
890  // These should succeed and result in a HAL call
891  EXPECT_CALL(*mock_handler_, Scan(false))
892      .Times(1)
893      .WillOnce(Return(BT_STATUS_SUCCESS));
894  EXPECT_TRUE(le_client_->StopScan());
895
896  ::testing::Mock::VerifyAndClearExpectations(mock_handler_.get());
897}
898
899TEST_F(LowEnergyClientPostRegisterTest, ScanRecord) {
900  TestDelegate delegate;
901  le_client_->SetDelegate(&delegate);
902
903  EXPECT_EQ(0, delegate.scan_result_count());
904
905  const uint8_t kTestRecord0[] = { 0x02, 0x01, 0x00, 0x00 };
906  const uint8_t kTestRecord1[] = { 0x00 };
907  const uint8_t kTestRecord2[] = {
908    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
909    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
910    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
911    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
912    0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
913    0x01, 0x00
914  };
915  const bt_bdaddr_t kTestAddress = {
916    { 0x01, 0x02, 0x03, 0x0A, 0x0B, 0x0C }
917  };
918  const char kTestAddressStr[] = "01:02:03:0A:0B:0C";
919  const int kTestRssi = 64;
920
921  // Scan wasn't started. Result should be ignored.
922  fake_hal_gatt_iface_->NotifyScanResultCallback(
923      kTestAddress, kTestRssi, (uint8_t*) kTestRecord0);
924  EXPECT_EQ(0, delegate.scan_result_count());
925
926  // Start a scan session for |le_client_|.
927  EXPECT_CALL(mock_adapter_, IsEnabled())
928      .Times(1)
929      .WillOnce(Return(true));
930  EXPECT_CALL(*mock_handler_, Scan(_))
931      .Times(2)
932      .WillOnce(Return(BT_STATUS_SUCCESS))
933      .WillOnce(Return(BT_STATUS_SUCCESS));
934  ScanSettings settings;
935  std::vector<ScanFilter> filters;
936  ASSERT_TRUE(le_client_->StartScan(settings, filters));
937
938  fake_hal_gatt_iface_->NotifyScanResultCallback(
939      kTestAddress, kTestRssi, (uint8_t*) kTestRecord0);
940  EXPECT_EQ(1, delegate.scan_result_count());
941  EXPECT_EQ(kTestAddressStr, delegate.last_scan_result().device_address());
942  EXPECT_EQ(kTestRssi, delegate.last_scan_result().rssi());
943  EXPECT_EQ(3U, delegate.last_scan_result().scan_record().size());
944
945  fake_hal_gatt_iface_->NotifyScanResultCallback(
946      kTestAddress, kTestRssi, (uint8_t*) kTestRecord1);
947  EXPECT_EQ(2, delegate.scan_result_count());
948  EXPECT_EQ(kTestAddressStr, delegate.last_scan_result().device_address());
949  EXPECT_EQ(kTestRssi, delegate.last_scan_result().rssi());
950  EXPECT_TRUE(delegate.last_scan_result().scan_record().empty());
951
952  fake_hal_gatt_iface_->NotifyScanResultCallback(
953      kTestAddress, kTestRssi, (uint8_t*) kTestRecord2);
954  EXPECT_EQ(3, delegate.scan_result_count());
955  EXPECT_EQ(kTestAddressStr, delegate.last_scan_result().device_address());
956  EXPECT_EQ(kTestRssi, delegate.last_scan_result().rssi());
957  EXPECT_EQ(62U, delegate.last_scan_result().scan_record().size());
958
959  le_client_->SetDelegate(nullptr);
960}
961
962MATCHER_P(BitEq, x, std::string(negation ? "isn't" : "is") +
963                        " bitwise equal to " + ::testing::PrintToString(x)) {
964  static_assert(sizeof(x) == sizeof(arg), "Size mismatch");
965  return std::memcmp(&arg, &x, sizeof(x)) == 0;
966}
967
968TEST_F(LowEnergyClientPostRegisterTest, Connect) {
969  const bt_bdaddr_t kTestAddress = {
970    { 0x01, 0x02, 0x03, 0x0A, 0x0B, 0x0C }
971  };
972  const char kTestAddressStr[] = "01:02:03:0A:0B:0C";
973  const bool kTestDirect = false;
974  const int connId = 12;
975
976  TestDelegate delegate;
977  le_client_->SetDelegate(&delegate);
978
979  // TODO(jpawlowski): NotifyConnectCallback should be called after returning
980  // success, fix it when it becomes important.
981  // These should succeed and result in a HAL call
982  EXPECT_CALL(*mock_handler_, Connect(le_client_->GetInstanceId(),
983          Pointee(BitEq(kTestAddress)), kTestDirect, BT_TRANSPORT_LE))
984      .Times(1)
985      .WillOnce(DoAll(
986        Invoke([&](int client_id, const bt_bdaddr_t *bd_addr, bool is_direct,
987                   int transport){
988          fake_hal_gatt_iface_->NotifyConnectCallback(connId, BT_STATUS_SUCCESS,
989                                                      client_id, *bd_addr);
990        }),
991        Return(BT_STATUS_SUCCESS)));
992
993  EXPECT_TRUE(le_client_->Connect(kTestAddressStr, kTestDirect));
994  EXPECT_EQ(1, delegate.connection_state_count());
995
996  // TODO(jpawlowski): same as above
997  // These should succeed and result in a HAL call
998  EXPECT_CALL(*mock_handler_, Disconnect(le_client_->GetInstanceId(),
999        Pointee(BitEq(kTestAddress)), connId))
1000      .Times(1)
1001      .WillOnce(DoAll(
1002        Invoke([&](int client_id, const bt_bdaddr_t *bd_addr, int connId){
1003          fake_hal_gatt_iface_->NotifyDisconnectCallback(connId,
1004                                                         BT_STATUS_SUCCESS,
1005                                                         client_id, *bd_addr);
1006        }),
1007        Return(BT_STATUS_SUCCESS)));
1008
1009  EXPECT_TRUE(le_client_->Disconnect(kTestAddressStr));
1010  EXPECT_EQ(2, delegate.connection_state_count());
1011
1012  le_client_->SetDelegate(nullptr);
1013  ::testing::Mock::VerifyAndClearExpectations(mock_handler_.get());
1014}
1015
1016
1017}  // namespace
1018}  // namespace bluetooth
1019