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