• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2021 HIMSA II K/S - www.himsa.com.
3  * Represented by EHIMA - www.ehima.com
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #include <base/functional/bind.h>
19 #include <bluetooth/log.h>
20 #include <gmock/gmock.h>
21 #include <gtest/gtest.h>
22 
23 #include <vector>
24 
25 #include "bind_helpers.h"
26 #include "bta_csis_api.h"
27 #include "bta_dm_api_mock.h"
28 #include "bta_gatt_api_mock.h"
29 #include "bta_gatt_queue_mock.h"
30 #include "bta_le_audio_uuids.h"
31 #include "btif/include/btif_profile_storage.h"
32 #include "btm_api_mock.h"
33 #include "csis_types.h"
34 #include "gatt/database_builder.h"
35 #include "hardware/bt_gatt_types.h"
36 #include "stack/include/bt_uuid16.h"
37 #include "test/common/mock_functions.h"
38 
gatt_cl_read_sirk_req(const RawAddress & peer_bda,base::OnceCallback<void (tGATT_STATUS status,const RawAddress &,uint8_t sirk_type,Octet16 & sirk)> cb)39 bool gatt_cl_read_sirk_req(
40     const RawAddress& peer_bda,
41     base::OnceCallback<void(tGATT_STATUS status, const RawAddress&,
42                             uint8_t sirk_type, Octet16& sirk)>
43         cb) {
44   return true;
45 }
46 
47 namespace bluetooth {
48 namespace csis {
49 namespace internal {
50 namespace {
51 
52 using base::Bind;
53 using base::Closure;
54 using base::Unretained;
55 
56 using bluetooth::csis::ConnectionState;
57 using bluetooth::csis::CsisClient;
58 using bluetooth::csis::CsisClientCallbacks;
59 using bluetooth::csis::CsisClientInterface;
60 using bluetooth::csis::CsisGroupLockStatus;
61 using bluetooth::groups::DeviceGroups;
62 
63 using testing::_;
64 using testing::AtLeast;
65 using testing::DoAll;
66 using testing::DoDefault;
67 using testing::Invoke;
68 using testing::Mock;
69 using testing::NotNull;
70 using testing::Return;
71 using testing::SaveArg;
72 using testing::SetArgPointee;
73 using testing::WithArg;
74 
75 // Disables most likely false-positives from base::SplitString()
__asan_default_options()76 extern "C" const char* __asan_default_options() {
77   return "detect_container_overflow=0";
78 }
79 
GetTestAddress(int index)80 RawAddress GetTestAddress(int index) {
81   EXPECT_LT(index, UINT8_MAX);
82   RawAddress result = {
83       {0xC0, 0xDE, 0xC0, 0xDE, 0x00, static_cast<uint8_t>(index)}};
84   return result;
85 }
86 
87 /* Csis lock callback */
88 class MockCsisLockCallback {
89  public:
90   MockCsisLockCallback() = default;
91   MockCsisLockCallback(const MockCsisLockCallback&) = delete;
92   MockCsisLockCallback& operator=(const MockCsisLockCallback&) = delete;
93 
94   ~MockCsisLockCallback() = default;
95   MOCK_METHOD((void), CsisGroupLockCb,
96               (int group_id, bool locked, CsisGroupLockStatus status));
97 };
98 
99 static MockCsisLockCallback* csis_lock_callback_mock;
100 
SetMockCsisLockCallback(MockCsisLockCallback * mock)101 void SetMockCsisLockCallback(MockCsisLockCallback* mock) {
102   csis_lock_callback_mock = mock;
103 }
104 
105 /* Csis callbacks to JNI */
106 class MockCsisCallbacks : public CsisClientCallbacks {
107  public:
108   MockCsisCallbacks() = default;
109   MockCsisCallbacks(const MockCsisCallbacks&) = delete;
110   MockCsisCallbacks& operator=(const MockCsisCallbacks&) = delete;
111 
112   ~MockCsisCallbacks() override = default;
113 
114   MOCK_METHOD((void), OnConnectionState,
115               (const RawAddress& address, ConnectionState state), (override));
116   MOCK_METHOD((void), OnDeviceAvailable,
117               (const RawAddress& address, int group_id, int group_size,
118                int rank, const bluetooth::Uuid& uuid),
119               (override));
120   MOCK_METHOD((void), OnSetMemberAvailable,
121               (const RawAddress& address, int group_id), (override));
122   MOCK_METHOD((void), OnGroupLockChanged,
123               (int group_id, bool locked,
124                bluetooth::csis::CsisGroupLockStatus status),
125               (override));
126   MOCK_METHOD((void), OnGattCsisWriteLockRsp,
127               (uint16_t conn_id, tGATT_STATUS status, uint16_t handle,
128                void* data));
129 };
130 
131 class CsisClientTest : public ::testing::Test {
132  private:
set_sample_cap_included_database(uint16_t conn_id,bool csis,bool csis_broken,uint8_t rank,uint8_t sirk_msb=1)133   void set_sample_cap_included_database(uint16_t conn_id, bool csis,
134                                         bool csis_broken, uint8_t rank,
135                                         uint8_t sirk_msb = 1) {
136     gatt::DatabaseBuilder builder;
137     builder.AddService(0x0001, 0x0003, Uuid::From16Bit(0x1800), true);
138     builder.AddCharacteristic(0x0002, 0x0003, Uuid::From16Bit(0x2a00),
139                               GATT_CHAR_PROP_BIT_READ);
140     if (csis) {
141       builder.AddService(0x0005, 0x0009,
142                          bluetooth::Uuid::From16Bit(UUID_COMMON_AUDIO_SERVICE),
143                          true);
144       builder.AddIncludedService(0x0006, kCsisServiceUuid, 0x0010, 0x0030);
145 
146       builder.AddService(0x0010, 0x0030, kCsisServiceUuid, true);
147       builder.AddCharacteristic(
148           0x0020, 0x0021, kCsisSirkUuid,
149           GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_NOTIFY);
150 
151       builder.AddDescriptor(0x0022,
152                             Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
153       builder.AddCharacteristic(
154           0x0023, 0x0024, kCsisSizeUuid,
155           GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_NOTIFY);
156       builder.AddDescriptor(0x0025,
157                             Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
158       builder.AddCharacteristic(0x0026, 0x0027, kCsisLockUuid,
159                                 GATT_CHAR_PROP_BIT_READ |
160                                     GATT_CHAR_PROP_BIT_NOTIFY |
161                                     GATT_CHAR_PROP_BIT_WRITE);
162       builder.AddDescriptor(0x0028,
163                             Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
164       builder.AddCharacteristic(0x0029, 0x0030, kCsisRankUuid,
165                                 GATT_CHAR_PROP_BIT_READ);
166     }
167     if (csis_broken) {
168       builder.AddCharacteristic(
169           0x0020, 0x0021, kCsisSirkUuid,
170           GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_NOTIFY);
171 
172       builder.AddDescriptor(0x0022,
173                             Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
174     }
175     builder.AddService(0x0090, 0x0093,
176                        Uuid::From16Bit(UUID_SERVCLASS_GATT_SERVER), true);
177     builder.AddCharacteristic(0x0091, 0x0092,
178                               Uuid::From16Bit(GATT_UUID_GATT_SRV_CHGD),
179                               GATT_CHAR_PROP_BIT_NOTIFY);
180     builder.AddDescriptor(0x0093,
181                           Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
182     services_map[conn_id] = builder.Build().Services();
183 
184     ON_CALL(gatt_queue, ReadCharacteristic(conn_id, _, _, _))
185         .WillByDefault(
186             Invoke([rank, sirk_msb](uint16_t conn_id, uint16_t handle,
187                                     GATT_READ_OP_CB cb, void* cb_data) -> void {
188               std::vector<uint8_t> value;
189 
190               switch (handle) {
191                 case 0x0003:
192                   /* device name */
193                   value.resize(20);
194                   break;
195                 case 0x0021:
196                   value.assign(17, 1);
197                   value[16] = sirk_msb;
198                   break;
199                 case 0x0024:
200                   value.resize(1);
201                   break;
202                 case 0x0027:
203                   value.resize(1);
204                   break;
205                 case 0x0030:
206                   value.resize(1);
207                   value.assign(1, rank);
208                   break;
209                 default:
210                   FAIL();
211                   return;
212               }
213 
214               cb(conn_id, GATT_SUCCESS, handle, value.size(), value.data(),
215                  cb_data);
216             }));
217   }
218 
set_sample_database(uint16_t conn_id,bool csis,bool csis_broken,uint8_t rank,uint8_t sirk_msb=1)219   void set_sample_database(uint16_t conn_id, bool csis, bool csis_broken,
220                            uint8_t rank, uint8_t sirk_msb = 1) {
221     gatt::DatabaseBuilder builder;
222     builder.AddService(0x0001, 0x0003, Uuid::From16Bit(0x1800), true);
223     builder.AddCharacteristic(0x0002, 0x0003, Uuid::From16Bit(0x2a00),
224                               GATT_CHAR_PROP_BIT_READ);
225     if (csis) {
226       builder.AddService(0x0010, 0x0030, kCsisServiceUuid, true);
227       builder.AddCharacteristic(
228           0x0020, 0x0021, kCsisSirkUuid,
229           GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_NOTIFY);
230 
231       builder.AddDescriptor(0x0022,
232                             Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
233       builder.AddCharacteristic(
234           0x0023, 0x0024, kCsisSizeUuid,
235           GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_NOTIFY);
236       builder.AddDescriptor(0x0025,
237                             Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
238       builder.AddCharacteristic(0x0026, 0x0027, kCsisLockUuid,
239                                 GATT_CHAR_PROP_BIT_READ |
240                                     GATT_CHAR_PROP_BIT_NOTIFY |
241                                     GATT_CHAR_PROP_BIT_WRITE);
242       builder.AddDescriptor(0x0028,
243                             Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
244       builder.AddCharacteristic(0x0029, 0x0030, kCsisRankUuid,
245                                 GATT_CHAR_PROP_BIT_READ);
246     }
247     if (csis_broken) {
248       builder.AddCharacteristic(
249           0x0020, 0x0021, kCsisSirkUuid,
250           GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_NOTIFY);
251 
252       builder.AddDescriptor(0x0022,
253                             Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
254     }
255     builder.AddService(0x0090, 0x0093,
256                        Uuid::From16Bit(UUID_SERVCLASS_GATT_SERVER), true);
257     builder.AddCharacteristic(0x0091, 0x0092,
258                               Uuid::From16Bit(GATT_UUID_GATT_SRV_CHGD),
259                               GATT_CHAR_PROP_BIT_NOTIFY);
260     builder.AddDescriptor(0x0093,
261                           Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
262     services_map[conn_id] = builder.Build().Services();
263 
264     ON_CALL(gatt_queue, ReadCharacteristic(conn_id, _, _, _))
265         .WillByDefault(
266             Invoke([rank, sirk_msb](uint16_t conn_id, uint16_t handle,
267                                     GATT_READ_OP_CB cb, void* cb_data) -> void {
268               std::vector<uint8_t> value;
269 
270               switch (handle) {
271                 case 0x0003:
272                   /* device name */
273                   value.resize(20);
274                   break;
275                 case 0x0021:
276                   value.assign(17, 1);
277                   value[16] = sirk_msb;
278                   break;
279                 case 0x0024:
280                   value.resize(1);
281                   break;
282                 case 0x0027:
283                   value.resize(1);
284                   break;
285                 case 0x0030:
286                   value.resize(1);
287                   value.assign(1, rank);
288                   break;
289                 default:
290                   ASSERT_TRUE(false);
291                   return;
292               }
293 
294               cb(conn_id, GATT_SUCCESS, handle, value.size(), value.data(),
295                  cb_data);
296             }));
297   }
298 
set_sample_database_double_csis(uint16_t conn_id,uint8_t rank_1,uint8_t rank_2,bool broken,uint8_t sirk1_infill=1,uint8_t sirk2_infill=2)299   void set_sample_database_double_csis(uint16_t conn_id, uint8_t rank_1,
300                                        uint8_t rank_2, bool broken,
301                                        uint8_t sirk1_infill = 1,
302                                        uint8_t sirk2_infill = 2) {
303     gatt::DatabaseBuilder builder;
304 
305     builder.AddService(0x0001, 0x0003, Uuid::From16Bit(0x1800), true);
306     builder.AddCharacteristic(0x0002, 0x0003, Uuid::From16Bit(0x2a00),
307                               GATT_CHAR_PROP_BIT_READ);
308     builder.AddService(0x0010, 0x0026, bluetooth::Uuid::From16Bit(0x1850),
309                        true);
310     builder.AddIncludedService(0x0011, kCsisServiceUuid, 0x0031, 0x0041);
311     builder.AddCharacteristic(
312         0x0031, 0x0032, kCsisSirkUuid,
313         GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_NOTIFY);
314 
315     builder.AddDescriptor(0x0033,
316                           Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
317     builder.AddCharacteristic(
318         0x0034, 0x0035, kCsisSizeUuid,
319         GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_NOTIFY);
320     builder.AddDescriptor(0x0036,
321                           Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
322     builder.AddCharacteristic(0x0037, 0x0038, kCsisLockUuid,
323                               GATT_CHAR_PROP_BIT_READ |
324                                   GATT_CHAR_PROP_BIT_NOTIFY |
325                                   GATT_CHAR_PROP_BIT_WRITE);
326     builder.AddDescriptor(0x0039,
327                           Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
328     builder.AddCharacteristic(0x0040, 0x0041, kCsisRankUuid,
329                               GATT_CHAR_PROP_BIT_READ);
330 
331     if (broken) {
332       builder.AddCharacteristic(
333           0x0020, 0x0021, kCsisSirkUuid,
334           GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_NOTIFY);
335 
336       builder.AddDescriptor(0x0022,
337                             Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
338     }
339 
340     builder.AddService(0x0042, 0x0044, bluetooth::Uuid::From16Bit(0x1860),
341                        true);
342     builder.AddIncludedService(0x0043, kCsisServiceUuid, 0x0045, 0x0055);
343 
344     builder.AddCharacteristic(
345         0x0045, 0x0046, kCsisSirkUuid,
346         GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_NOTIFY);
347 
348     builder.AddDescriptor(0x0047,
349                           Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
350     builder.AddCharacteristic(
351         0x0048, 0x0049, kCsisSizeUuid,
352         GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_NOTIFY);
353     builder.AddDescriptor(0x0050,
354                           Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
355     builder.AddCharacteristic(0x0051, 0x0052, kCsisLockUuid,
356                               GATT_CHAR_PROP_BIT_READ |
357                                   GATT_CHAR_PROP_BIT_NOTIFY |
358                                   GATT_CHAR_PROP_BIT_WRITE);
359     builder.AddDescriptor(0x0053,
360                           Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
361     builder.AddCharacteristic(0x0054, 0x0055, kCsisRankUuid,
362                               GATT_CHAR_PROP_BIT_READ);
363 
364     builder.AddService(0x0090, 0x0093,
365                        Uuid::From16Bit(UUID_SERVCLASS_GATT_SERVER), true);
366     builder.AddCharacteristic(0x0091, 0x0092,
367                               Uuid::From16Bit(GATT_UUID_GATT_SRV_CHGD),
368                               GATT_CHAR_PROP_BIT_NOTIFY);
369     builder.AddDescriptor(0x0093,
370                           Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
371     services_map[conn_id] = builder.Build().Services();
372 
373     ON_CALL(gatt_queue, ReadCharacteristic(conn_id, _, _, _))
374         .WillByDefault(Invoke([sirk1_infill, sirk2_infill, rank_1, rank_2](
375                                   uint16_t conn_id, uint16_t handle,
376                                   GATT_READ_OP_CB cb, void* cb_data) -> void {
377           std::vector<uint8_t> value;
378 
379           switch (handle) {
380             case 0x0003:
381               /* device name */
382               value.resize(20);
383               break;
384             case 0x0032:
385               value.resize(17);
386               value.assign(17, sirk1_infill);
387               value[0] = 1;  // Plain text SIRK
388               break;
389             case 0x0035:
390               value.resize(1);
391               value.assign(1, 2);
392               break;
393             case 0x0038:
394               value.resize(1);
395               break;
396             case 0x0041:
397               value.resize(1);
398               value.assign(1, rank_1);
399               break;
400             case 0x0046:
401               value.resize(17);
402               value.assign(17, sirk2_infill);
403               value[0] = 1;  // Plain text SIRK
404               break;
405             case 0x0049:
406               value.resize(1);
407               value.assign(1, 2);
408               break;
409             case 0x0052:
410               value.resize(1);
411               break;
412             case 0x0055:
413               value.resize(1);
414               value.assign(1, rank_2);
415               break;
416             default:
417               log::error("Unknown handle? {}", handle);
418               ASSERT_TRUE(false);
419               return;
420           }
421 
422           cb(conn_id, GATT_SUCCESS, handle, value.size(), value.data(),
423              cb_data);
424         }));
425   }
426 
427  protected:
SetUp(void)428   void SetUp(void) override {
429     reset_mock_function_count_map();
430     bluetooth::manager::SetMockBtmInterface(&btm_interface);
431     dm::SetMockBtaDmInterface(&dm_interface);
432     gatt::SetMockBtaGattInterface(&gatt_interface);
433     gatt::SetMockBtaGattQueue(&gatt_queue);
434     SetMockCsisLockCallback(&csis_lock_cb);
435     callbacks.reset(new MockCsisCallbacks());
436 
437     ON_CALL(btm_interface, IsLinkKeyKnown(_, _))
438         .WillByDefault(DoAll(Return(true)));
439 
440     ON_CALL(btm_interface, BTM_IsEncrypted(_, _))
441         .WillByDefault(DoAll(Return(true)));
442 
443     ON_CALL(gatt_interface, GetCharacteristic(_, _))
444         .WillByDefault(
445             Invoke([&](uint16_t conn_id,
446                        uint16_t handle) -> const gatt::Characteristic* {
447               std::list<gatt::Service>& services = services_map[conn_id];
448               for (auto const& service : services) {
449                 for (auto const& characteristic : service.characteristics) {
450                   if (characteristic.value_handle == handle) {
451                     return &characteristic;
452                   }
453                 }
454               }
455 
456               return nullptr;
457             }));
458 
459     // default action for GetOwningService function call
460     ON_CALL(gatt_interface, GetOwningService(_, _))
461         .WillByDefault(Invoke(
462             [&](uint16_t conn_id, uint16_t handle) -> const gatt::Service* {
463               std::list<gatt::Service>& services = services_map[conn_id];
464               for (auto const& service : services) {
465                 if (service.handle <= handle && service.end_handle >= handle) {
466                   return &service;
467                 }
468               }
469 
470               return nullptr;
471             }));
472 
473     // default action for GetServices function call
474     ON_CALL(gatt_interface, GetServices(_))
475         .WillByDefault(WithArg<0>(
476             Invoke([&](uint16_t conn_id) -> std::list<gatt::Service>* {
477               return &services_map[conn_id];
478             })));
479 
480     // default action for RegisterForNotifications function call
481     ON_CALL(gatt_interface, RegisterForNotifications(gatt_if, _, _))
482         .WillByDefault(Return(GATT_SUCCESS));
483 
484     // default action for DeregisterForNotifications function call
485     ON_CALL(gatt_interface, DeregisterForNotifications(gatt_if, _, _))
486         .WillByDefault(Return(GATT_SUCCESS));
487 
488     // default action for WriteDescriptor function call
489     ON_CALL(gatt_queue, WriteDescriptor(_, _, _, _, _, _))
490         .WillByDefault(
491             Invoke([](uint16_t conn_id, uint16_t handle,
492                       std::vector<uint8_t> value, tGATT_WRITE_TYPE write_type,
493                       GATT_WRITE_OP_CB cb, void* cb_data) -> void {
494               if (cb)
495                 cb(conn_id, GATT_SUCCESS, handle, value.size(), value.data(),
496                    cb_data);
497             }));
498   }
499 
TearDown(void)500   void TearDown(void) override {
501     services_map.clear();
502     callbacks.reset();
503     CsisClient::CleanUp();
504     gatt::SetMockBtaGattInterface(nullptr);
505     bluetooth::manager::SetMockBtmInterface(nullptr);
506   }
507 
TestAppRegister(void)508   void TestAppRegister(void) {
509     BtaAppRegisterCallback app_register_callback;
510     EXPECT_CALL(gatt_interface, AppRegister(_, _, _))
511         .WillOnce(DoAll(SaveArg<0>(&gatt_callback),
512                         SaveArg<1>(&app_register_callback)));
513     CsisClient::Initialize(callbacks.get(),
514                            Bind(&btif_storage_load_bonded_csis_devices));
515     ASSERT_TRUE(gatt_callback);
516     ASSERT_TRUE(app_register_callback);
517     app_register_callback.Run(gatt_if, GATT_SUCCESS);
518     ASSERT_TRUE(CsisClient::IsCsisClientRunning());
519   }
520 
TestAppUnregister(void)521   void TestAppUnregister(void) {
522     EXPECT_CALL(gatt_interface, AppDeregister(gatt_if));
523     CsisClient::CleanUp();
524     ASSERT_FALSE(CsisClient::IsCsisClientRunning());
525     gatt_callback = nullptr;
526   }
527 
TestConnect(const RawAddress & address,bool encrypted=true)528   void TestConnect(const RawAddress& address, bool encrypted = true) {
529     // by default indicate link as encrypted
530     ON_CALL(btm_interface, GetSecurityFlagsByTransport(address, NotNull(), _))
531         .WillByDefault(
532             DoAll(SetArgPointee<1>(BTM_SEC_FLAG_ENCRYPTED), Return(encrypted)));
533 
534     EXPECT_CALL(gatt_interface,
535                 Open(gatt_if, address, BTM_BLE_DIRECT_CONNECTION, _));
536     CsisClient::Get()->Connect(address);
537     Mock::VerifyAndClearExpectations(&gatt_interface);
538     Mock::VerifyAndClearExpectations(&btm_interface);
539   }
540 
TestDisconnect(const RawAddress & address,uint16_t conn_id)541   void TestDisconnect(const RawAddress& address, uint16_t conn_id) {
542     if (conn_id != GATT_INVALID_CONN_ID) {
543       EXPECT_CALL(gatt_interface, Close(conn_id));
544       EXPECT_CALL(*callbacks, OnConnectionState(test_address,
545                                                 ConnectionState::DISCONNECTED));
546     } else {
547       EXPECT_CALL(gatt_interface, CancelOpen(_, address, _));
548     }
549     CsisClient::Get()->Disconnect(address);
550   }
551 
TestAddFromStorage(const RawAddress & address,uint16_t conn_id,std::vector<uint8_t> & storage_group_buf,std::vector<uint8_t> & storage_buf)552   void TestAddFromStorage(const RawAddress& address, uint16_t conn_id,
553                           std::vector<uint8_t>& storage_group_buf,
554                           std::vector<uint8_t>& storage_buf) {
555     EXPECT_CALL(*callbacks,
556                 OnConnectionState(address, ConnectionState::CONNECTED))
557         .Times(1);
558     EXPECT_CALL(*callbacks, OnDeviceAvailable(address, _, _, _, _))
559         .Times(AtLeast(1));
560 
561     EXPECT_CALL(gatt_interface,
562                 Open(gatt_if, address, BTM_BLE_DIRECT_CONNECTION, true))
563         .WillOnce(Invoke([this, conn_id](tGATT_IF client_if,
564                                          const RawAddress& remote_bda,
565                                          bool is_direct, bool opportunistic) {
566           InjectConnectedEvent(remote_bda, conn_id);
567           GetSearchCompleteEvent(conn_id);
568         }));
569 
570     DeviceGroups::AddFromStorage(address, storage_group_buf);
571     CsisClient::AddFromStorage(address, storage_buf);
572   }
573 
InjectEncryptionEvent(const RawAddress & test_address,uint16_t conn_id)574   void InjectEncryptionEvent(const RawAddress& test_address, uint16_t conn_id) {
575     tBTA_GATTC_ENC_CMPL_CB event_data = {
576         .client_if = static_cast<tGATT_IF>(conn_id),
577         .remote_bda = test_address,
578     };
579 
580     gatt_callback(BTA_GATTC_ENC_CMPL_CB_EVT, (tBTA_GATTC*)&event_data);
581   }
582 
InjectConnectedEvent(const RawAddress & address,uint16_t conn_id)583   void InjectConnectedEvent(const RawAddress& address, uint16_t conn_id) {
584     tBTA_GATTC_OPEN event_data = {
585         .status = GATT_SUCCESS,
586         .conn_id = conn_id,
587         .client_if = gatt_if,
588         .remote_bda = address,
589         .transport = GATT_TRANSPORT_LE,
590         .mtu = 240,
591     };
592 
593     gatt_callback(BTA_GATTC_OPEN_EVT, (tBTA_GATTC*)&event_data);
594   }
595 
InjectDisconnectedEvent(const RawAddress & address,uint16_t conn_id,tGATT_DISCONN_REASON reason=GATT_CONN_TERMINATE_PEER_USER)596   void InjectDisconnectedEvent(
597       const RawAddress& address, uint16_t conn_id,
598       tGATT_DISCONN_REASON reason = GATT_CONN_TERMINATE_PEER_USER) {
599     tBTA_GATTC_CLOSE event_data = {
600         .conn_id = conn_id,
601         .status = GATT_SUCCESS,
602         .client_if = gatt_if,
603         .remote_bda = address,
604         .reason = reason,
605     };
606 
607     gatt_callback(BTA_GATTC_CLOSE_EVT, (tBTA_GATTC*)&event_data);
608   }
609 
GetSearchCompleteEvent(uint16_t conn_id)610   void GetSearchCompleteEvent(uint16_t conn_id) {
611     tBTA_GATTC_SEARCH_CMPL event_data = {
612         .conn_id = conn_id,
613         .status = GATT_SUCCESS,
614     };
615 
616     gatt_callback(BTA_GATTC_SEARCH_CMPL_EVT, (tBTA_GATTC*)&event_data);
617   }
618 
TestReadCharacteristic(const RawAddress & address,uint16_t conn_id,std::vector<uint16_t> handles)619   void TestReadCharacteristic(const RawAddress& address, uint16_t conn_id,
620                               std::vector<uint16_t> handles) {
621     SetSampleDatabaseCsis(conn_id, 1);
622     TestAppRegister();
623     TestConnect(address);
624     InjectConnectedEvent(address, conn_id);
625 
626     EXPECT_CALL(gatt_queue, ReadCharacteristic(conn_id, _, _, _))
627         .WillRepeatedly(DoDefault());
628     for (auto const& handle : handles) {
629       EXPECT_CALL(gatt_queue, ReadCharacteristic(conn_id, handle, _, _))
630           .WillOnce(DoDefault());
631     }
632 
633     GetSearchCompleteEvent(conn_id);
634     TestAppUnregister();
635   }
636 
TestGattWriteCCC(uint16_t ccc_handle,GattStatus status,int deregister_times)637   void TestGattWriteCCC(uint16_t ccc_handle, GattStatus status,
638                         int deregister_times) {
639     SetSampleDatabaseCsis(1, 1);
640     TestAppRegister();
641     TestConnect(test_address);
642     InjectConnectedEvent(test_address, 1);
643 
644     auto WriteDescriptorCbGenerator = [](tGATT_STATUS status,
645                                          uint16_t ccc_handle) {
646       return [status, ccc_handle](uint16_t conn_id, uint16_t handle,
647                                   std::vector<uint8_t> value,
648                                   tGATT_WRITE_TYPE write_type,
649                                   GATT_WRITE_OP_CB cb, void* cb_data) -> void {
650         if (cb) {
651           if (ccc_handle) {
652             handle = ccc_handle;
653           }
654           cb(conn_id, status, handle, value.size(), value.data(), cb_data);
655         }
656       };
657     };
658 
659     // sirk, size, lock
660     EXPECT_CALL(gatt_queue, WriteDescriptor(_, _, _, _, _, _))
661         .Times(3)
662         .WillOnce(Invoke(WriteDescriptorCbGenerator(GATT_SUCCESS, 0)))
663         .WillOnce(Invoke(WriteDescriptorCbGenerator(GATT_SUCCESS, 0)))
664         .WillOnce(Invoke(WriteDescriptorCbGenerator(status, ccc_handle)));
665 
666     EXPECT_CALL(gatt_interface, DeregisterForNotifications(_, _, _))
667         .Times(deregister_times);
668 
669     GetSearchCompleteEvent(1);
670     Mock::VerifyAndClearExpectations(&gatt_interface);
671   }
672 
GetDisconnectedEvent(const RawAddress & address,uint16_t conn_id)673   void GetDisconnectedEvent(const RawAddress& address, uint16_t conn_id) {
674     tBTA_GATTC_CLOSE event_data = {
675         .conn_id = conn_id,
676         .status = GATT_SUCCESS,
677         .client_if = gatt_if,
678         .remote_bda = address,
679         .reason = GATT_CONN_TERMINATE_PEER_USER,
680     };
681 
682     gatt_callback(BTA_GATTC_CLOSE_EVT, (tBTA_GATTC*)&event_data);
683   }
684 
SetSampleCapIncludedDatabaseCsis(uint16_t conn_id,uint8_t rank,uint8_t sirk_msb=1)685   void SetSampleCapIncludedDatabaseCsis(uint16_t conn_id, uint8_t rank,
686                                         uint8_t sirk_msb = 1) {
687     set_sample_cap_included_database(conn_id, true, false, rank, sirk_msb);
688   }
SetSampleDatabaseCsis(uint16_t conn_id,uint8_t rank,uint8_t sirk_msb=1)689   void SetSampleDatabaseCsis(uint16_t conn_id, uint8_t rank,
690                              uint8_t sirk_msb = 1) {
691     set_sample_database(conn_id, true, false, rank, sirk_msb);
692   }
SetSampleDatabaseNoCsis(uint16_t conn_id,uint8_t rank)693   void SetSampleDatabaseNoCsis(uint16_t conn_id, uint8_t rank) {
694     set_sample_database(conn_id, false, false, rank);
695   }
SetSampleDatabaseCsisBroken(uint16_t conn_id,uint rank)696   void SetSampleDatabaseCsisBroken(uint16_t conn_id, uint rank) {
697     set_sample_database(conn_id, false, true, rank);
698   }
SetSampleDatabaseDoubleCsis(uint16_t conn_id,uint8_t rank_1,uint8_t rank_2)699   void SetSampleDatabaseDoubleCsis(uint16_t conn_id, uint8_t rank_1,
700                                    uint8_t rank_2) {
701     set_sample_database_double_csis(conn_id, rank_1, rank_2, false);
702   }
SetSampleDatabaseDoubleCsisBroken(uint16_t conn_id,uint8_t rank_1,uint8_t rank_2)703   void SetSampleDatabaseDoubleCsisBroken(uint16_t conn_id, uint8_t rank_1,
704                                          uint8_t rank_2) {
705     set_sample_database_double_csis(conn_id, rank_1, rank_2, true);
706   }
707 
708   std::unique_ptr<MockCsisCallbacks> callbacks;
709   std::unique_ptr<MockCsisCallbacks> lock_callback;
710   bluetooth::manager::MockBtmInterface btm_interface;
711   dm::MockBtaDmInterface dm_interface;
712   gatt::MockBtaGattInterface gatt_interface;
713   gatt::MockBtaGattQueue gatt_queue;
714   MockCsisLockCallback csis_lock_cb;
715   tBTA_GATTC_CBACK* gatt_callback;
716   const uint8_t gatt_if = 0xff;
717   std::map<uint16_t, std::list<gatt::Service>> services_map;
718 
719   const RawAddress test_address = GetTestAddress(0);
720   const RawAddress test_address2 = GetTestAddress(1);
721 };
722 
TEST_F(CsisClientTest,test_get_uninitialized)723 TEST_F(CsisClientTest, test_get_uninitialized) {
724   ASSERT_DEATH(CsisClient::Get(), "");
725 }
726 
TEST_F(CsisClientTest,test_initialize)727 TEST_F(CsisClientTest, test_initialize) {
728   CsisClient::Initialize(callbacks.get(), base::DoNothing());
729   ASSERT_TRUE(CsisClient::IsCsisClientRunning());
730   CsisClient::CleanUp();
731 }
732 
TEST_F(CsisClientTest,test_initialize_twice)733 TEST_F(CsisClientTest, test_initialize_twice) {
734   CsisClient::Initialize(callbacks.get(), base::DoNothing());
735   CsisClient* csis_p = CsisClient::Get();
736   CsisClient::Initialize(callbacks.get(), base::DoNothing());
737   ASSERT_EQ(csis_p, CsisClient::Get());
738   CsisClient::CleanUp();
739 }
740 
TEST_F(CsisClientTest,test_cleanup_initialized)741 TEST_F(CsisClientTest, test_cleanup_initialized) {
742   CsisClient::Initialize(callbacks.get(), base::DoNothing());
743   CsisClient::CleanUp();
744   ASSERT_FALSE(CsisClient::IsCsisClientRunning());
745 }
746 
TEST_F(CsisClientTest,test_cleanup_uninitialized)747 TEST_F(CsisClientTest, test_cleanup_uninitialized) {
748   CsisClient::CleanUp();
749   ASSERT_FALSE(CsisClient::IsCsisClientRunning());
750 }
751 
TEST_F(CsisClientTest,test_app_registration)752 TEST_F(CsisClientTest, test_app_registration) {
753   TestAppRegister();
754   TestAppUnregister();
755 }
756 
TEST_F(CsisClientTest,test_connect)757 TEST_F(CsisClientTest, test_connect) {
758   TestAppRegister();
759   TestConnect(GetTestAddress(0));
760   TestAppUnregister();
761 }
762 
TEST_F(CsisClientTest,test_disconnect_non_connected)763 TEST_F(CsisClientTest, test_disconnect_non_connected) {
764   TestAppRegister();
765   TestConnect(test_address);
766   TestDisconnect(test_address, GATT_INVALID_CONN_ID);
767   TestAppUnregister();
768 }
769 
TEST_F(CsisClientTest,test_disconnect_connected)770 TEST_F(CsisClientTest, test_disconnect_connected) {
771   TestAppRegister();
772   TestConnect(test_address);
773   InjectConnectedEvent(test_address, 1);
774   TestDisconnect(test_address, 1);
775   InjectDisconnectedEvent(test_address, 1);
776   TestAppUnregister();
777 }
778 
TEST_F(CsisClientTest,test_disconnected)779 TEST_F(CsisClientTest, test_disconnected) {
780   TestAppRegister();
781   TestConnect(test_address);
782   InjectConnectedEvent(test_address, 1);
783   EXPECT_CALL(*callbacks,
784               OnConnectionState(test_address, ConnectionState::DISCONNECTED));
785   InjectDisconnectedEvent(test_address, 1);
786 
787   TestAppUnregister();
788 }
789 
TEST_F(CsisClientTest,test_connect_after_remove)790 TEST_F(CsisClientTest, test_connect_after_remove) {
791   TestAppRegister();
792   TestConnect(test_address);
793   InjectConnectedEvent(test_address, 1);
794   CsisClient::Get()->RemoveDevice(test_address);
795 
796   EXPECT_CALL(*callbacks,
797               OnConnectionState(test_address, ConnectionState::DISCONNECTED));
798   ON_CALL(btm_interface, IsLinkKeyKnown(_, _)).WillByDefault(Return(false));
799   CsisClient::Get()->Connect(test_address);
800   Mock::VerifyAndClearExpectations(callbacks.get());
801 
802   TestAppUnregister();
803 }
804 
TEST_F(CsisClientTest,test_discovery_csis_found)805 TEST_F(CsisClientTest, test_discovery_csis_found) {
806   SetSampleDatabaseCsis(1, 1);
807   TestAppRegister();
808   TestConnect(test_address);
809   EXPECT_CALL(*callbacks,
810               OnConnectionState(test_address, ConnectionState::CONNECTED));
811   EXPECT_CALL(*callbacks, OnDeviceAvailable(test_address, _, _, _, _));
812   InjectConnectedEvent(test_address, 1);
813   GetSearchCompleteEvent(1);
814   Mock::VerifyAndClearExpectations(callbacks.get());
815   TestAppUnregister();
816 }
817 
TEST_F(CsisClientTest,test_discovery_csis_not_found)818 TEST_F(CsisClientTest, test_discovery_csis_not_found) {
819   SetSampleDatabaseNoCsis(1, 1);
820   TestAppRegister();
821   TestConnect(test_address);
822   EXPECT_CALL(gatt_interface, Close(1));
823   InjectConnectedEvent(test_address, 1);
824   GetSearchCompleteEvent(1);
825   Mock::VerifyAndClearExpectations(callbacks.get());
826   TestAppUnregister();
827 }
828 
TEST_F(CsisClientTest,test_discovery_csis_broken)829 TEST_F(CsisClientTest, test_discovery_csis_broken) {
830   SetSampleDatabaseCsisBroken(1, 1);
831   TestAppRegister();
832   TestConnect(test_address);
833   EXPECT_CALL(gatt_interface, Close(1));
834   InjectConnectedEvent(test_address, 1);
835   GetSearchCompleteEvent(1);
836   Mock::VerifyAndClearExpectations(callbacks.get());
837   TestAppUnregister();
838 }
839 
TEST_F(CsisClientTest,test_ccc_reg_fail_handle_not_found)840 TEST_F(CsisClientTest, test_ccc_reg_fail_handle_not_found) {
841   // service handle range: 0x0001 ~ 0x0030
842   uint16_t not_existed_ccc_handle = 0x0031;
843   TestGattWriteCCC(not_existed_ccc_handle, GATT_INVALID_HANDLE, 0);
844 }
845 
TEST_F(CsisClientTest,test_ccc_reg_fail_handle_found)846 TEST_F(CsisClientTest, test_ccc_reg_fail_handle_found) {
847   // kCsisLockUuid ccc handle
848   uint16_t existed_ccc_hande = 0x0028;
849   TestGattWriteCCC(existed_ccc_hande, GATT_INVALID_HANDLE, 1);
850 }
851 
TEST_F(CsisClientTest,test_ccc_reg_fail_out_of_sync)852 TEST_F(CsisClientTest, test_ccc_reg_fail_out_of_sync) {
853   // kCsisLockUuid ccc handle
854   uint16_t ccc_handle = 0x0028;
855   TestGattWriteCCC(ccc_handle, GATT_DATABASE_OUT_OF_SYNC, 0);
856 }
857 
858 class CsisClientCallbackTest : public CsisClientTest {
859  protected:
860   const RawAddress test_address = GetTestAddress(0);
861   uint16_t conn_id = 22;
862 
SetUp(void)863   void SetUp(void) override {
864     CsisClientTest::SetUp();
865     SetSampleDatabaseCsis(conn_id, 1);
866     TestAppRegister();
867     TestConnect(test_address);
868     InjectConnectedEvent(test_address, conn_id);
869     GetSearchCompleteEvent(conn_id);
870   }
871 
TearDown(void)872   void TearDown(void) override {
873     TestAppUnregister();
874     CsisClientTest::TearDown();
875   }
876 
GetNotificationEvent(uint16_t handle,std::vector<uint8_t> & value)877   void GetNotificationEvent(uint16_t handle, std::vector<uint8_t>& value) {
878     tBTA_GATTC_NOTIFY event_data = {
879         .conn_id = conn_id,
880         .bda = test_address,
881         .handle = handle,
882         .len = (uint8_t)value.size(),
883         .is_notify = true,
884     };
885 
886     std::copy(value.begin(), value.end(), event_data.value);
887     gatt_callback(BTA_GATTC_NOTIF_EVT, (tBTA_GATTC*)&event_data);
888   }
889 };
890 
TEST_F(CsisClientCallbackTest,test_on_group_lock_changed_group_not_found)891 TEST_F(CsisClientCallbackTest, test_on_group_lock_changed_group_not_found) {
892   bool callback_called = false;
893   EXPECT_CALL(
894       *callbacks,
895       OnGroupLockChanged(2, false, CsisGroupLockStatus::FAILED_INVALID_GROUP));
896   CsisClient::Get()->LockGroup(
897       2, true,
898       base::BindOnce(
899           [](bool* callback_called, int group_id, bool locked,
900              CsisGroupLockStatus status) {
901             if ((group_id == 2) &&
902                 (status == CsisGroupLockStatus::FAILED_INVALID_GROUP))
903               *callback_called = true;
904           },
905           &callback_called));
906   ASSERT_TRUE(callback_called);
907 }
908 
TEST_F(CsisClientTest,test_get_group_id)909 TEST_F(CsisClientTest, test_get_group_id) {
910   SetSampleDatabaseCsis(1, 1);
911   TestAppRegister();
912   TestConnect(test_address);
913   EXPECT_CALL(*callbacks,
914               OnConnectionState(test_address, ConnectionState::CONNECTED));
915   EXPECT_CALL(*callbacks, OnDeviceAvailable(test_address, _, _, _, _));
916   InjectConnectedEvent(test_address, 1);
917   GetSearchCompleteEvent(1);
918   int group_id = CsisClient::Get()->GetGroupId(test_address);
919   ASSERT_TRUE(group_id == 1);
920   TestAppUnregister();
921 }
922 
TEST_F(CsisClientTest,test_search_complete_before_encryption)923 TEST_F(CsisClientTest, test_search_complete_before_encryption) {
924   SetSampleDatabaseCsis(1, 1);
925   TestAppRegister();
926   TestConnect(test_address, false);
927   EXPECT_CALL(*callbacks,
928               OnConnectionState(test_address, ConnectionState::CONNECTED))
929       .Times(0);
930   EXPECT_CALL(*callbacks, OnDeviceAvailable(test_address, _, _, _, _)).Times(0);
931 
932   ON_CALL(btm_interface, BTM_IsEncrypted(test_address, _))
933       .WillByDefault(DoAll(Return(false)));
934 
935   InjectConnectedEvent(test_address, 1);
936   GetSearchCompleteEvent(1);
937   Mock::VerifyAndClearExpectations(callbacks.get());
938 
939   /* Incject encryption and expect device connection */
940   EXPECT_CALL(*callbacks,
941               OnConnectionState(test_address, ConnectionState::CONNECTED))
942       .Times(1);
943   EXPECT_CALL(*callbacks, OnDeviceAvailable(test_address, _, _, _, _)).Times(1);
944 
945   ON_CALL(btm_interface, BTM_IsEncrypted(test_address, _))
946       .WillByDefault(DoAll(Return(true)));
947   EXPECT_CALL(gatt_interface, ServiceSearchRequest(_, _)).Times(1);
948 
949   InjectEncryptionEvent(test_address, 1);
950   GetSearchCompleteEvent(1);
951 
952   Mock::VerifyAndClearExpectations(&gatt_interface);
953   Mock::VerifyAndClearExpectations(callbacks.get());
954 
955   TestAppUnregister();
956 }
957 
TEST_F(CsisClientTest,test_disconnect_when_link_key_is_gone)958 TEST_F(CsisClientTest, test_disconnect_when_link_key_is_gone) {
959   SetSampleDatabaseCsis(1, 1);
960   TestAppRegister();
961   TestConnect(test_address, false);
962   EXPECT_CALL(*callbacks,
963               OnConnectionState(test_address, ConnectionState::CONNECTED))
964       .Times(0);
965 
966   ON_CALL(btm_interface, BTM_IsEncrypted(test_address, _))
967       .WillByDefault(DoAll(Return(false)));
968   ON_CALL(btm_interface, SetEncryption(test_address, _, _, _, _))
969       .WillByDefault(Return(BTM_ERR_KEY_MISSING));
970 
971   EXPECT_CALL(gatt_interface, Close(1));
972 
973   InjectConnectedEvent(test_address, 1);
974 
975   Mock::VerifyAndClearExpectations(&gatt_interface);
976   Mock::VerifyAndClearExpectations(callbacks.get());
977 
978   TestAppUnregister();
979 }
980 
TEST_F(CsisClientTest,test_is_group_empty)981 TEST_F(CsisClientTest, test_is_group_empty) {
982   std::list<std::shared_ptr<CsisGroup>> csis_groups_;
983   auto g_1 = std::make_shared<CsisGroup>(666, bluetooth::Uuid::kEmpty);
984   csis_groups_.push_back(g_1);
985 
986   ASSERT_TRUE(g_1->IsEmpty());
987 }
988 
TEST_F(CsisClientTest,test_add_device_to_group)989 TEST_F(CsisClientTest, test_add_device_to_group) {
990   auto g_1 = std::make_shared<CsisGroup>(666, bluetooth::Uuid::kEmpty);
991   auto d_1 = std::make_shared<CsisDevice>();
992 
993   ASSERT_TRUE(g_1->IsEmpty());
994   g_1->AddDevice(d_1);
995   ASSERT_FALSE(g_1->IsEmpty());
996 }
997 
TEST_F(CsisClientTest,test_get_set_desired_size)998 TEST_F(CsisClientTest, test_get_set_desired_size) {
999   auto g_1 = std::make_shared<CsisGroup>(666, bluetooth::Uuid::kEmpty);
1000   g_1->SetDesiredSize(10);
1001   ASSERT_EQ(g_1->GetDesiredSize(), 10);
1002 }
1003 
TEST_F(CsisClientTest,test_is_device_in_the_group)1004 TEST_F(CsisClientTest, test_is_device_in_the_group) {
1005   auto g_1 = std::make_shared<CsisGroup>(666, bluetooth::Uuid::kEmpty);
1006   auto d_1 = std::make_shared<CsisDevice>();
1007   g_1->AddDevice(d_1);
1008   g_1->IsDeviceInTheGroup(d_1);
1009 }
1010 
TEST_F(CsisClientTest,test_get_current_size)1011 TEST_F(CsisClientTest, test_get_current_size) {
1012   const RawAddress test_address_1 = GetTestAddress(0);
1013   const RawAddress test_address_2 = GetTestAddress(1);
1014   const RawAddress test_address_3 = GetTestAddress(2);
1015   auto g_1 = std::make_shared<CsisGroup>(666, bluetooth::Uuid::kEmpty);
1016   auto d_1 = std::make_shared<CsisDevice>(test_address_1, true);
1017   auto d_2 = std::make_shared<CsisDevice>(test_address_2, true);
1018   auto d_3 = std::make_shared<CsisDevice>(test_address_3, true);
1019   g_1->AddDevice(d_1);
1020   g_1->AddDevice(d_2);
1021   g_1->AddDevice(d_3);
1022   ASSERT_EQ(3, g_1->GetCurrentSize());
1023 }
1024 
TEST_F(CsisClientTest,test_set_current_lock_state_unset)1025 TEST_F(CsisClientTest, test_set_current_lock_state_unset) {
1026   auto g_1 = std::make_shared<CsisGroup>(666, bluetooth::Uuid::kEmpty);
1027   g_1->SetCurrentLockState(CsisLockState::CSIS_STATE_UNSET);
1028   ASSERT_EQ(g_1->GetCurrentLockState(), CsisLockState::CSIS_STATE_UNSET);
1029 }
1030 
TEST_F(CsisClientTest,test_set_current_lock_state_locked)1031 TEST_F(CsisClientTest, test_set_current_lock_state_locked) {
1032   auto g_1 = std::make_shared<CsisGroup>(666, bluetooth::Uuid::kEmpty);
1033   g_1->SetCurrentLockState(CsisLockState::CSIS_STATE_LOCKED);
1034   ASSERT_EQ(g_1->GetCurrentLockState(), CsisLockState::CSIS_STATE_LOCKED);
1035 }
1036 
TEST_F(CsisClientTest,test_set_current_lock_state_unlocked)1037 TEST_F(CsisClientTest, test_set_current_lock_state_unlocked) {
1038   auto g_1 = std::make_shared<CsisGroup>(666, bluetooth::Uuid::kEmpty);
1039   g_1->SetCurrentLockState(CsisLockState::CSIS_STATE_UNLOCKED);
1040   ASSERT_EQ(g_1->GetCurrentLockState(), CsisLockState::CSIS_STATE_UNLOCKED);
1041 }
1042 
TEST_F(CsisClientTest,test_set_various_lock_states)1043 TEST_F(CsisClientTest, test_set_various_lock_states) {
1044   auto g_1 = std::make_shared<CsisGroup>(666, bluetooth::Uuid::kEmpty);
1045   g_1->SetCurrentLockState(CsisLockState::CSIS_STATE_UNLOCKED);
1046   ASSERT_EQ(g_1->GetCurrentLockState(), CsisLockState::CSIS_STATE_UNLOCKED);
1047   g_1->SetCurrentLockState(CsisLockState::CSIS_STATE_LOCKED);
1048   ASSERT_EQ(g_1->GetCurrentLockState(), CsisLockState::CSIS_STATE_LOCKED);
1049   g_1->SetCurrentLockState(CsisLockState::CSIS_STATE_UNSET);
1050   ASSERT_EQ(g_1->GetCurrentLockState(), CsisLockState::CSIS_STATE_UNSET);
1051 }
1052 
TEST_F(CsisClientTest,test_set_discovery_state_completed)1053 TEST_F(CsisClientTest, test_set_discovery_state_completed) {
1054   auto g_1 = std::make_shared<CsisGroup>(666, bluetooth::Uuid::kEmpty);
1055   g_1->SetDiscoveryState(CsisDiscoveryState::CSIS_DISCOVERY_COMPLETED);
1056   ASSERT_EQ(g_1->GetDiscoveryState(),
1057             CsisDiscoveryState::CSIS_DISCOVERY_COMPLETED);
1058 }
1059 
TEST_F(CsisClientTest,test_set_discovery_state_idle)1060 TEST_F(CsisClientTest, test_set_discovery_state_idle) {
1061   auto g_1 = std::make_shared<CsisGroup>(666, bluetooth::Uuid::kEmpty);
1062   g_1->SetDiscoveryState(CsisDiscoveryState::CSIS_DISCOVERY_IDLE);
1063   ASSERT_EQ(g_1->GetDiscoveryState(), CsisDiscoveryState::CSIS_DISCOVERY_IDLE);
1064 }
1065 
TEST_F(CsisClientTest,test_set_discovery_state_ongoing)1066 TEST_F(CsisClientTest, test_set_discovery_state_ongoing) {
1067   auto g_1 = std::make_shared<CsisGroup>(666, bluetooth::Uuid::kEmpty);
1068   g_1->SetDiscoveryState(CsisDiscoveryState::CSIS_DISCOVERY_ONGOING);
1069   ASSERT_EQ(g_1->GetDiscoveryState(),
1070             CsisDiscoveryState::CSIS_DISCOVERY_ONGOING);
1071 }
1072 
TEST_F(CsisClientTest,test_set_various_discovery_states)1073 TEST_F(CsisClientTest, test_set_various_discovery_states) {
1074   auto g_1 = std::make_shared<CsisGroup>(666, bluetooth::Uuid::kEmpty);
1075   g_1->SetDiscoveryState(CsisDiscoveryState::CSIS_DISCOVERY_COMPLETED);
1076   ASSERT_EQ(g_1->GetDiscoveryState(),
1077             CsisDiscoveryState::CSIS_DISCOVERY_COMPLETED);
1078   g_1->SetDiscoveryState(CsisDiscoveryState::CSIS_DISCOVERY_IDLE);
1079   ASSERT_EQ(g_1->GetDiscoveryState(), CsisDiscoveryState::CSIS_DISCOVERY_IDLE);
1080   g_1->SetDiscoveryState(CsisDiscoveryState::CSIS_DISCOVERY_ONGOING);
1081   ASSERT_EQ(g_1->GetDiscoveryState(),
1082             CsisDiscoveryState::CSIS_DISCOVERY_ONGOING);
1083 }
1084 
TEST_F(CsisClientTest,test_get_first_last_device)1085 TEST_F(CsisClientTest, test_get_first_last_device) {
1086   const RawAddress test_address_3 = GetTestAddress(3);
1087   const RawAddress test_address_4 = GetTestAddress(4);
1088   const RawAddress test_address_5 = GetTestAddress(5);
1089   auto g_1 = std::make_shared<CsisGroup>(666, bluetooth::Uuid::kEmpty);
1090   auto d_1 = std::make_shared<CsisDevice>(test_address_3, true);
1091   auto d_2 = std::make_shared<CsisDevice>(test_address_4, true);
1092   auto d_3 = std::make_shared<CsisDevice>(test_address_5, true);
1093   g_1->AddDevice(d_1);
1094   g_1->AddDevice(d_2);
1095   g_1->AddDevice(d_3);
1096   ASSERT_EQ(g_1->GetLastDevice(), d_3);
1097   ASSERT_EQ(g_1->GetFirstDevice(), d_1);
1098 }
1099 
TEST_F(CsisClientTest,test_get_set_sirk)1100 TEST_F(CsisClientTest, test_get_set_sirk) {
1101   auto g_1 = std::make_shared<CsisGroup>(666, bluetooth::Uuid::kEmpty);
1102   Octet16 sirk = {1};
1103   g_1->SetSirk(sirk);
1104   ASSERT_EQ(g_1->GetSirk(), sirk);
1105 }
1106 
TEST_F(CsisClientTest,test_not_open_duplicate_active_scan_while_bonding_set_member)1107 TEST_F(CsisClientTest,
1108        test_not_open_duplicate_active_scan_while_bonding_set_member) {
1109   uint16_t conn_id = 0x0001;
1110   EXPECT_CALL(dm_interface, BTA_DmBleCsisObserve(true, _)).Times(1);
1111   SetSampleDatabaseCsis(conn_id, 1, 1);
1112   TestAppRegister();
1113 
1114   // Here we handle background scan request
1115   Mock::VerifyAndClearExpectations(&dm_interface);
1116 
1117   TestConnect(test_address);
1118   InjectConnectedEvent(test_address, 1);
1119 
1120   auto ReadCharacteristicCbGenerator = []() {
1121     return [](uint16_t conn_id, uint16_t handle, GATT_READ_OP_CB cb,
1122               void* cb_data) -> void {
1123       std::vector<uint8_t> value;
1124       switch (handle) {
1125         case 0x0003:
1126           // device name
1127           value.resize(20);
1128           break;
1129         case 0x0021:
1130           // plain sirk
1131           value.resize(17);
1132           value.assign(17, 1);
1133           break;
1134         case 0x0024:
1135           // size
1136           value.resize(1);
1137           value.assign(1, 2);
1138           break;
1139         case 0x0027:
1140           // lock
1141           value.resize(2);
1142           break;
1143         case 0x0030:
1144           // rank
1145           value.resize(1);
1146           value.assign(1, 1);
1147           break;
1148         default:
1149           FAIL();
1150           return;
1151       }
1152       if (cb) {
1153         cb(conn_id, GATT_SUCCESS, handle, value.size(), value.data(), cb_data);
1154       }
1155     };
1156   };
1157 
1158   // We should read 4 times for sirk, rank, size, and lock characteristics
1159   EXPECT_CALL(gatt_queue, ReadCharacteristic(conn_id, _, _, _))
1160       .Times(4)
1161       .WillOnce(Invoke(ReadCharacteristicCbGenerator()))
1162       .WillOnce(Invoke(ReadCharacteristicCbGenerator()))
1163       .WillOnce(Invoke(ReadCharacteristicCbGenerator()))
1164       .WillOnce(Invoke(ReadCharacteristicCbGenerator()));
1165 
1166   // Here is actual active scan request for the first device
1167   tBTA_DM_SEARCH_CBACK* p_results_cb = nullptr;
1168   EXPECT_CALL(dm_interface, BTA_DmBleCsisObserve(true, _))
1169       .Times(1)
1170       .WillOnce(DoAll(SaveArg<1>(&p_results_cb)));
1171 
1172   GetSearchCompleteEvent(conn_id);
1173 
1174   Mock::VerifyAndClearExpectations(&dm_interface);
1175 
1176   // Simulate we find the set member
1177   tBTA_DM_SEARCH result;
1178   result.inq_res.include_rsi = true;
1179   std::vector<uint8_t> rsi = {0x07, 0x2e, 0x00, 0xed, 0x1a, 0x00, 0x00, 0x00};
1180   result.inq_res.p_eir = rsi.data();
1181   result.inq_res.eir_len = 8;
1182   result.inq_res.bd_addr = test_address2;
1183 
1184   // CSIS client should process set member event to JNI
1185   EXPECT_CALL(*callbacks, OnSetMemberAvailable(test_address2, 1));
1186 
1187   p_results_cb(BTA_DM_INQ_RES_EVT, &result);
1188 
1189   Mock::VerifyAndClearExpectations(&dm_interface);
1190 
1191   EXPECT_CALL(dm_interface, BTA_DmBleCsisObserve(true, _)).Times(0);
1192 
1193   // Simulate getting duplicate response from remote for the first device
1194   // At this momoment we should not open second active scan because the set
1195   // member is already cached and waiting for bonding
1196   GetSearchCompleteEvent(conn_id);
1197 
1198   Mock::VerifyAndClearExpectations(&dm_interface);
1199 }
1200 
TEST_F(CsisClientTest,test_csis_member_not_found)1201 TEST_F(CsisClientTest, test_csis_member_not_found) {
1202   EXPECT_CALL(dm_interface, BTA_DmBleCsisObserve(true, _)).Times(1);
1203   SetSampleDatabaseDoubleCsis(0x001, 1, 2);
1204   TestAppRegister();
1205 
1206   /* Here we handle Background Scan request */
1207   Mock::VerifyAndClearExpectations(&dm_interface);
1208 
1209   tBTA_DM_SEARCH_CBACK* p_results_cb = nullptr;
1210   /* Here is actual Active Scan request  */
1211   EXPECT_CALL(dm_interface, BTA_DmBleCsisObserve(true, _))
1212       .WillOnce(DoAll(SaveArg<1>(&p_results_cb)));
1213 
1214   TestConnect(test_address);
1215   InjectConnectedEvent(test_address, 1);
1216   GetSearchCompleteEvent(1);
1217 
1218   Mock::VerifyAndClearExpectations(&dm_interface);
1219   /* Verify that scanner has been called to start filtering  */
1220   ASSERT_EQ(1, get_func_call_count("set_empty_filter"));
1221 
1222   /* Check callback is not null and simulate no member found and scan
1223    * completed*/
1224   ASSERT_NE(p_results_cb, nullptr);
1225 
1226   tBTA_DM_SEARCH result;
1227   result.observe_cmpl.num_resps = 80;
1228 
1229   p_results_cb(BTA_DM_OBSERVE_CMPL_EVT, &result);
1230 
1231   /* Verify that scanner has been called to stop filtering  */
1232   ASSERT_EQ(2, get_func_call_count("set_empty_filter"));
1233 }
1234 
1235 class CsisMultiClientTest : public CsisClientTest {
1236  protected:
1237   const RawAddress test_address_1 = GetTestAddress(1);
1238   const RawAddress test_address_2 = GetTestAddress(2);
1239 
SetUp(void)1240   void SetUp(void) override {
1241     CsisClientTest::SetUp();
1242     TestAppRegister();
1243     SetSampleDatabaseDoubleCsis(0x001, 1, 2);
1244   }
1245 };
1246 
1247 class CsisMultiClientTestBroken : public CsisClientTest {
1248  protected:
1249   const RawAddress test_address_1 = GetTestAddress(1);
1250   const RawAddress test_address_2 = GetTestAddress(2);
1251 
SetUp(void)1252   void SetUp(void) override {
1253     CsisClientTest::SetUp();
1254     TestAppRegister();
1255     SetSampleDatabaseDoubleCsisBroken(0x001, 1, 2);
1256   }
1257 };
1258 
TEST_F(CsisMultiClientTest,test_add_multiple_instances)1259 TEST_F(CsisMultiClientTest, test_add_multiple_instances) {
1260   TestAppUnregister();
1261   CsisClientTest::TearDown();
1262 }
1263 
TEST_F(CsisMultiClientTest,test_cleanup_multiple_instances)1264 TEST_F(CsisMultiClientTest, test_cleanup_multiple_instances) {
1265   CsisClient::CleanUp();
1266   CsisClient::IsCsisClientRunning();
1267 }
1268 
TEST_F(CsisMultiClientTest,test_connect_multiple_instances)1269 TEST_F(CsisMultiClientTest, test_connect_multiple_instances) {
1270   TestConnect(GetTestAddress(0));
1271   TestAppUnregister();
1272 }
1273 
TEST_F(CsisMultiClientTest,test_disconnect_multiple_instances)1274 TEST_F(CsisMultiClientTest, test_disconnect_multiple_instances) {
1275   TestConnect(test_address);
1276   InjectConnectedEvent(test_address, 1);
1277   EXPECT_CALL(*callbacks,
1278               OnConnectionState(test_address, ConnectionState::DISCONNECTED));
1279   InjectDisconnectedEvent(test_address, 1);
1280 
1281   TestAppUnregister();
1282   CsisClientTest::TearDown();
1283 }
1284 
TEST_F(CsisMultiClientTest,test_lock_multiple_instances)1285 TEST_F(CsisMultiClientTest, test_lock_multiple_instances) {
1286   TestConnect(test_address);
1287   InjectConnectedEvent(test_address, 1);
1288   GetSearchCompleteEvent(1);
1289 
1290   EXPECT_CALL(*callbacks,
1291               OnGroupLockChanged(1, true, CsisGroupLockStatus::SUCCESS));
1292   EXPECT_CALL(*csis_lock_callback_mock,
1293               CsisGroupLockCb(1, true, CsisGroupLockStatus::SUCCESS));
1294   ON_CALL(gatt_queue, WriteCharacteristic(_, _, _, _, _, _))
1295       .WillByDefault(
1296           Invoke([](uint16_t conn_id, uint16_t handle,
1297                     std::vector<uint8_t> value, tGATT_WRITE_TYPE write_type,
1298                     GATT_WRITE_OP_CB cb, void* cb_data) -> void {
1299             if (cb)
1300               cb(conn_id, GATT_SUCCESS, handle, value.size(), value.data(),
1301                  cb_data);
1302           }));
1303   CsisClient::Get()->LockGroup(
1304       1, true,
1305       base::BindOnce([](int group_id, bool locked, CsisGroupLockStatus status) {
1306         csis_lock_callback_mock->CsisGroupLockCb(group_id, locked, status);
1307       }));
1308 
1309   EXPECT_CALL(*callbacks,
1310               OnGroupLockChanged(2, true, CsisGroupLockStatus::SUCCESS));
1311   EXPECT_CALL(*csis_lock_callback_mock,
1312               CsisGroupLockCb(2, true, CsisGroupLockStatus::SUCCESS));
1313   CsisClient::Get()->LockGroup(
1314       2, true,
1315       base::BindOnce([](int group_id, bool locked, CsisGroupLockStatus status) {
1316         csis_lock_callback_mock->CsisGroupLockCb(group_id, locked, status);
1317       }));
1318 }
1319 
TEST_F(CsisMultiClientTest,test_unlock_multiple_instances)1320 TEST_F(CsisMultiClientTest, test_unlock_multiple_instances) {
1321   TestConnect(test_address);
1322   InjectConnectedEvent(test_address, 1);
1323   GetSearchCompleteEvent(1);
1324 
1325   ON_CALL(gatt_queue, WriteCharacteristic(_, _, _, _, _, _))
1326       .WillByDefault(
1327           Invoke([](uint16_t conn_id, uint16_t handle,
1328                     std::vector<uint8_t> value, tGATT_WRITE_TYPE write_type,
1329                     GATT_WRITE_OP_CB cb, void* cb_data) -> void {
1330             if (cb)
1331               cb(conn_id, GATT_SUCCESS, handle, value.size(), value.data(),
1332                  cb_data);
1333           }));
1334   CsisClient::Get()->LockGroup(
1335       1, true,
1336       base::BindOnce([](int group_id, bool locked, CsisGroupLockStatus status) {
1337         csis_lock_callback_mock->CsisGroupLockCb(group_id, locked, status);
1338       }));
1339 
1340   EXPECT_CALL(*callbacks,
1341               OnGroupLockChanged(1, false, CsisGroupLockStatus::SUCCESS));
1342   EXPECT_CALL(*csis_lock_callback_mock,
1343               CsisGroupLockCb(1, false, CsisGroupLockStatus::SUCCESS));
1344   CsisClient::Get()->LockGroup(
1345       1, false,
1346       base::BindOnce([](int group_id, bool locked, CsisGroupLockStatus status) {
1347         csis_lock_callback_mock->CsisGroupLockCb(group_id, locked, status);
1348       }));
1349 }
1350 
TEST_F(CsisMultiClientTest,test_disconnect_locked_multiple_instances)1351 TEST_F(CsisMultiClientTest, test_disconnect_locked_multiple_instances) {
1352   TestConnect(test_address);
1353   InjectConnectedEvent(test_address, 1);
1354   GetSearchCompleteEvent(1);
1355 
1356   TestConnect(test_address2);
1357   InjectConnectedEvent(test_address2, 2);
1358   GetSearchCompleteEvent(2);
1359 
1360   EXPECT_CALL(*callbacks,
1361               OnGroupLockChanged(1, true, CsisGroupLockStatus::SUCCESS));
1362   EXPECT_CALL(*csis_lock_callback_mock,
1363               CsisGroupLockCb(1, true, CsisGroupLockStatus::SUCCESS));
1364   ON_CALL(gatt_queue, WriteCharacteristic(_, _, _, _, _, _))
1365       .WillByDefault(
1366           Invoke([](uint16_t conn_id, uint16_t handle,
1367                     std::vector<uint8_t> value, tGATT_WRITE_TYPE write_type,
1368                     GATT_WRITE_OP_CB cb, void* cb_data) -> void {
1369             if (cb)
1370               cb(conn_id, GATT_SUCCESS, handle, value.size(), value.data(),
1371                  cb_data);
1372           }));
1373   CsisClient::Get()->LockGroup(
1374       1, true,
1375       base::BindOnce([](int group_id, bool locked, CsisGroupLockStatus status) {
1376         csis_lock_callback_mock->CsisGroupLockCb(group_id, locked, status);
1377       }));
1378 
1379   EXPECT_CALL(*callbacks,
1380               OnGroupLockChanged(
1381                   1, false, CsisGroupLockStatus::LOCKED_GROUP_MEMBER_LOST));
1382   InjectDisconnectedEvent(test_address, 2, GATT_CONN_TIMEOUT);
1383 }
1384 
TEST_F(CsisMultiClientTest,test_discover_multiple_instances)1385 TEST_F(CsisMultiClientTest, test_discover_multiple_instances) {
1386   TestConnect(test_address);
1387   EXPECT_CALL(*callbacks,
1388               OnConnectionState(test_address, ConnectionState::CONNECTED))
1389       .Times(1);
1390   EXPECT_CALL(*callbacks, OnDeviceAvailable(test_address, _, _, _, _)).Times(2);
1391   InjectConnectedEvent(test_address, 1);
1392   GetSearchCompleteEvent(1);
1393   Mock::VerifyAndClearExpectations(callbacks.get());
1394   TestAppUnregister();
1395 }
1396 
TEST_F(CsisClientTest,test_storage_calls)1397 TEST_F(CsisClientTest, test_storage_calls) {
1398   SetSampleDatabaseCsis(1, 1);
1399 
1400   ASSERT_EQ(0, get_func_call_count("btif_storage_load_bonded_csis_devices"));
1401   TestAppRegister();
1402   ASSERT_EQ(1, get_func_call_count("btif_storage_load_bonded_csis_devices"));
1403 
1404   ASSERT_EQ(0, get_func_call_count("btif_storage_update_csis_info"));
1405   TestConnect(test_address);
1406   InjectConnectedEvent(test_address, 1);
1407   GetSearchCompleteEvent(1);
1408   ASSERT_EQ(1, get_func_call_count("btif_storage_update_csis_info"));
1409 
1410   ASSERT_EQ(0, get_func_call_count("btif_storage_remove_csis_device"));
1411   CsisClient::Get()->RemoveDevice(test_address);
1412   /* It is 0 because btif_csis_client.cc calls that */
1413   ASSERT_EQ(0, get_func_call_count("btif_storage_remove_csis_device"));
1414 
1415   TestAppUnregister();
1416 }
1417 
TEST_F(CsisClientTest,test_storage_content)1418 TEST_F(CsisClientTest, test_storage_content) {
1419   // Two devices in one set
1420   SetSampleCapIncludedDatabaseCsis(1, 1);
1421   SetSampleCapIncludedDatabaseCsis(2, 2);
1422   // Devices in the other set
1423   SetSampleCapIncludedDatabaseCsis(3, 1, 2);
1424   SetSampleCapIncludedDatabaseCsis(4, 1, 3);
1425 
1426   TestAppRegister();
1427   TestConnect(GetTestAddress(1));
1428   InjectConnectedEvent(GetTestAddress(1), 1);
1429   GetSearchCompleteEvent(1);
1430   ASSERT_EQ(1, CsisClient::Get()->GetGroupId(
1431                    GetTestAddress(1),
1432                    bluetooth::Uuid::From16Bit(UUID_COMMON_AUDIO_SERVICE)));
1433 
1434   TestConnect(GetTestAddress(2));
1435   InjectConnectedEvent(GetTestAddress(2), 2);
1436   GetSearchCompleteEvent(2);
1437   ASSERT_EQ(1, CsisClient::Get()->GetGroupId(
1438                    GetTestAddress(2),
1439                    bluetooth::Uuid::From16Bit(UUID_COMMON_AUDIO_SERVICE)));
1440 
1441   TestConnect(GetTestAddress(3));
1442   InjectConnectedEvent(GetTestAddress(3), 3);
1443   GetSearchCompleteEvent(3);
1444   ASSERT_EQ(2, CsisClient::Get()->GetGroupId(
1445                    GetTestAddress(3),
1446                    bluetooth::Uuid::From16Bit(UUID_COMMON_AUDIO_SERVICE)));
1447 
1448   std::vector<uint8_t> dev1_storage;
1449   std::vector<uint8_t> dev2_storage;
1450   std::vector<uint8_t> dev3_storage;
1451 
1452   // Store to byte buffer
1453   CsisClient::GetForStorage(GetTestAddress(1), dev1_storage);
1454   CsisClient::GetForStorage(GetTestAddress(2), dev2_storage);
1455   CsisClient::GetForStorage(GetTestAddress(3), dev3_storage);
1456 
1457   ASSERT_NE(0u, dev1_storage.size());
1458   ASSERT_NE(0u, dev2_storage.size());
1459   ASSERT_NE(0u, dev3_storage.size());
1460 
1461   std::vector<uint8_t> dev1_group_storage;
1462   std::vector<uint8_t> dev2_group_storage;
1463   std::vector<uint8_t> dev3_group_storage;
1464 
1465   DeviceGroups::GetForStorage(GetTestAddress(1), dev1_group_storage);
1466   DeviceGroups::GetForStorage(GetTestAddress(2), dev2_group_storage);
1467   DeviceGroups::GetForStorage(GetTestAddress(3), dev3_group_storage);
1468 
1469   ASSERT_NE(0u, dev1_group_storage.size());
1470   ASSERT_NE(0u, dev2_group_storage.size());
1471   ASSERT_NE(0u, dev3_group_storage.size());
1472 
1473   // Clean it up
1474   TestAppUnregister();
1475 
1476   // Reinitialize service
1477   TestAppRegister();
1478 
1479   // Restore dev1 from the byte buffer
1480   TestAddFromStorage(GetTestAddress(1), 1, dev1_group_storage, dev1_storage);
1481   ASSERT_EQ(1, CsisClient::Get()->GetGroupId(
1482                    GetTestAddress(1),
1483                    bluetooth::Uuid::From16Bit(UUID_COMMON_AUDIO_SERVICE)));
1484 
1485   // Restore dev2 from the byte buffer
1486   TestAddFromStorage(GetTestAddress(2), 2, dev2_group_storage, dev2_storage);
1487   ASSERT_EQ(1, CsisClient::Get()->GetGroupId(
1488                    GetTestAddress(2),
1489                    bluetooth::Uuid::From16Bit(UUID_COMMON_AUDIO_SERVICE)));
1490 
1491   // Restore dev3 from the byte buffer
1492   TestAddFromStorage(GetTestAddress(3), 3, dev3_group_storage, dev3_storage);
1493   ASSERT_EQ(2, CsisClient::Get()->GetGroupId(
1494                    GetTestAddress(3),
1495                    bluetooth::Uuid::From16Bit(UUID_COMMON_AUDIO_SERVICE)));
1496 
1497   // Restore not inerrogated dev4 - empty buffer but valid sirk for group 2
1498   std::vector<uint8_t> no_set_info;
1499   TestAddFromStorage(GetTestAddress(4), 4, no_set_info, no_set_info);
1500   ASSERT_EQ(3, CsisClient::Get()->GetGroupId(
1501                    GetTestAddress(4),
1502                    bluetooth::Uuid::From16Bit(UUID_COMMON_AUDIO_SERVICE)));
1503 
1504   TestAppUnregister();
1505 }
1506 
TEST_F(CsisClientTest,test_database_out_of_sync)1507 TEST_F(CsisClientTest, test_database_out_of_sync) {
1508   auto test_address = GetTestAddress(0);
1509   auto conn_id = 1;
1510 
1511   TestAppRegister();
1512   SetSampleDatabaseCsis(conn_id, 1);
1513   TestConnect(test_address);
1514   InjectConnectedEvent(test_address, conn_id);
1515   GetSearchCompleteEvent(conn_id);
1516   ASSERT_EQ(1, CsisClient::Get()->GetGroupId(
1517                    test_address, bluetooth::Uuid::From16Bit(0x0000)));
1518 
1519   // Simulated database changed on the remote side.
1520   ON_CALL(gatt_queue, WriteCharacteristic(_, _, _, _, _, _))
1521       .WillByDefault(
1522           Invoke([this](uint16_t conn_id, uint16_t handle,
1523                         std::vector<uint8_t> value, tGATT_WRITE_TYPE write_type,
1524                         GATT_WRITE_OP_CB cb, void* cb_data) {
1525             auto* svc = gatt::FindService(services_map[conn_id], handle);
1526             if (svc == nullptr) return;
1527 
1528             tGATT_STATUS status = GATT_DATABASE_OUT_OF_SYNC;
1529             if (cb)
1530               cb(conn_id, status, handle, value.size(), value.data(), cb_data);
1531           }));
1532 
1533   ON_CALL(gatt_interface, ServiceSearchRequest(_, _)).WillByDefault(Return());
1534   EXPECT_CALL(gatt_interface, ServiceSearchRequest(_, _));
1535   CsisClient::Get()->LockGroup(
1536       1, true,
1537       base::BindOnce([](int group_id, bool locked, CsisGroupLockStatus status) {
1538         csis_lock_callback_mock->CsisGroupLockCb(group_id, locked, status);
1539       }));
1540   TestAppUnregister();
1541 }
1542 
1543 }  // namespace
1544 }  // namespace internal
1545 }  // namespace csis
1546 }  // namespace bluetooth
1547