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