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 <gmock/gmock.h>
20 #include <gtest/gtest.h>
21
22 #include "bind_helpers.h"
23 #include "bta_gatt_api_mock.h"
24 #include "bta_gatt_queue_mock.h"
25 #include "bta_vc_api.h"
26 #include "btm_api_mock.h"
27 #include "gatt/database_builder.h"
28 #include "hardware/bt_gatt_types.h"
29 #include "mock_csis_client.h"
30 #include "stack/include/bt_uuid16.h"
31 #include "test/common/mock_functions.h"
32 #include "types.h"
33 #include "types/bluetooth/uuid.h"
34 #include "types/raw_address.h"
btif_storage_add_volume_control(const RawAddress & addr,bool auto_conn)35 void btif_storage_add_volume_control(const RawAddress& addr, bool auto_conn) {}
36
37 namespace bluetooth {
38 namespace vc {
39 namespace internal {
40 namespace {
41
42 using base::Bind;
43 using base::Unretained;
44
45 using bluetooth::vc::ConnectionState;
46 using bluetooth::vc::VolumeControlCallbacks;
47
48 using testing::_;
49 using testing::DoAll;
50 using testing::DoDefault;
51 using testing::Invoke;
52 using testing::Mock;
53 using testing::NotNull;
54 using testing::Return;
55 using testing::SaveArg;
56 using testing::SetArgPointee;
57 using testing::WithArg;
58
GetTestAddress(int index)59 RawAddress GetTestAddress(int index) {
60 EXPECT_LT(index, UINT8_MAX);
61 RawAddress result = {
62 {0xC0, 0xDE, 0xC0, 0xDE, 0x00, static_cast<uint8_t>(index)}};
63 return result;
64 }
65
66 class MockVolumeControlCallbacks : public VolumeControlCallbacks {
67 public:
68 MockVolumeControlCallbacks() = default;
69 MockVolumeControlCallbacks(const MockVolumeControlCallbacks&) = delete;
70 MockVolumeControlCallbacks& operator=(const MockVolumeControlCallbacks&) =
71 delete;
72
73 ~MockVolumeControlCallbacks() override = default;
74
75 MOCK_METHOD((void), OnConnectionState,
76 (ConnectionState state, const RawAddress& address), (override));
77 MOCK_METHOD((void), OnDeviceAvailable,
78 (const RawAddress& address, uint8_t num_offset), (override));
79 MOCK_METHOD((void), OnVolumeStateChanged,
80 (const RawAddress& address, uint8_t volume, bool mute,
81 bool isAutonomous),
82 (override));
83 MOCK_METHOD((void), OnGroupVolumeStateChanged,
84 (int group_id, uint8_t volume, bool mute, bool isAutonomous),
85 (override));
86 MOCK_METHOD((void), OnExtAudioOutVolumeOffsetChanged,
87 (const RawAddress& address, uint8_t ext_output_id,
88 int16_t offset),
89 (override));
90 MOCK_METHOD((void), OnExtAudioOutLocationChanged,
91 (const RawAddress& address, uint8_t ext_output_id,
92 uint32_t location),
93 (override));
94 MOCK_METHOD((void), OnExtAudioOutDescriptionChanged,
95 (const RawAddress& address, uint8_t ext_output_id,
96 std::string descr),
97 (override));
98 };
99
100 class VolumeControlTest : public ::testing::Test {
101 private:
set_sample_database(uint16_t conn_id,bool vcs,bool vcs_broken,bool aics,bool aics_broken,bool vocs,bool vocs_broken)102 void set_sample_database(uint16_t conn_id, bool vcs, bool vcs_broken,
103 bool aics, bool aics_broken, bool vocs,
104 bool vocs_broken) {
105 gatt::DatabaseBuilder builder;
106 builder.AddService(0x0001, 0x0003, Uuid::From16Bit(0x1800), true);
107 builder.AddCharacteristic(0x0002, 0x0003, Uuid::From16Bit(0x2a00),
108 GATT_CHAR_PROP_BIT_READ);
109 /* 0x0004-0x000f RFU */
110 if (vcs) {
111 /* VCS */
112 builder.AddService(0x0010, 0x0026, kVolumeControlUuid, true);
113 if (aics) {
114 /* TODO Place holder */
115 }
116 if (vocs) {
117 builder.AddIncludedService(0x0013, kVolumeOffsetUuid, 0x0070, 0x0079);
118 builder.AddIncludedService(0x0014, kVolumeOffsetUuid, 0x0080, 0x008b);
119 }
120 /* 0x0015-0x001f RFU */
121 builder.AddCharacteristic(
122 0x0020, 0x0021, kVolumeControlStateUuid,
123 GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_NOTIFY);
124 builder.AddDescriptor(0x0022,
125 Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
126 if (!vcs_broken) {
127 builder.AddCharacteristic(0x0023, 0x0024, kVolumeControlPointUuid,
128 GATT_CHAR_PROP_BIT_WRITE);
129 }
130 builder.AddCharacteristic(0x0025, 0x0026, kVolumeFlagsUuid,
131 GATT_CHAR_PROP_BIT_READ);
132 /* 0x0027-0x002f RFU */
133 if (aics) {
134 /* TODO Place holder for AICS */
135 }
136 if (vocs) {
137 /* VOCS 1st instance */
138 builder.AddService(0x0070, 0x0079, kVolumeOffsetUuid, false);
139 builder.AddCharacteristic(
140 0x0071, 0x0072, kVolumeOffsetStateUuid,
141 GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_NOTIFY);
142 builder.AddDescriptor(0x0073,
143 Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
144 builder.AddCharacteristic(0x0074, 0x0075, kVolumeOffsetLocationUuid,
145 GATT_CHAR_PROP_BIT_READ);
146 builder.AddCharacteristic(0x0076, 0x0077, kVolumeOffsetControlPointUuid,
147 GATT_CHAR_PROP_BIT_WRITE);
148 builder.AddCharacteristic(0x0078, 0x0079,
149 kVolumeOffsetOutputDescriptionUuid,
150 GATT_CHAR_PROP_BIT_READ);
151 /* 0x007a-0x007f RFU */
152
153 /* VOCS 2nd instance */
154 builder.AddService(0x0080, 0x008b, kVolumeOffsetUuid, false);
155 builder.AddCharacteristic(
156 0x0081, 0x0082, kVolumeOffsetStateUuid,
157 GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_NOTIFY);
158 builder.AddDescriptor(0x0083,
159 Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
160 if (!vocs_broken) {
161 builder.AddCharacteristic(0x0084, 0x0085, kVolumeOffsetLocationUuid,
162 GATT_CHAR_PROP_BIT_READ |
163 GATT_CHAR_PROP_BIT_WRITE_NR |
164 GATT_CHAR_PROP_BIT_NOTIFY);
165 builder.AddDescriptor(0x0086,
166 Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
167 }
168 builder.AddCharacteristic(0x0087, 0x0088, kVolumeOffsetControlPointUuid,
169 GATT_CHAR_PROP_BIT_WRITE);
170 builder.AddCharacteristic(
171 0x0089, 0x008a, kVolumeOffsetOutputDescriptionUuid,
172 GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_WRITE_NR |
173 GATT_CHAR_PROP_BIT_NOTIFY);
174 builder.AddDescriptor(0x008b,
175 Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
176 }
177 }
178 /* 0x008c-0x008f RFU */
179
180 /* GATTS */
181 builder.AddService(0x0090, 0x0093,
182 Uuid::From16Bit(UUID_SERVCLASS_GATT_SERVER), true);
183 builder.AddCharacteristic(0x0091, 0x0092,
184 Uuid::From16Bit(GATT_UUID_GATT_SRV_CHGD),
185 GATT_CHAR_PROP_BIT_NOTIFY);
186 builder.AddDescriptor(0x0093,
187 Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
188 services_map[conn_id] = builder.Build().Services();
189
190 ON_CALL(gatt_queue, ReadCharacteristic(conn_id, _, _, _))
191 .WillByDefault(Invoke([&](uint16_t conn_id, uint16_t handle,
192 GATT_READ_OP_CB cb, void* cb_data) -> void {
193 std::vector<uint8_t> value;
194
195 switch (handle) {
196 case 0x0003:
197 /* device name */
198 value.resize(20);
199 break;
200
201 case 0x0021:
202 /* volume state */
203 value.resize(3);
204 break;
205
206 case 0x0026:
207 /* volume flags */
208 value.resize(1);
209 break;
210
211 case 0x0072: // 1st VOCS instance
212 case 0x0082: // 2nd VOCS instance
213 /* offset state */
214 value.resize(3);
215 break;
216
217 case 0x0075: // 1st VOCS instance
218 case 0x0085: // 2nd VOCS instance
219 /* offset location */
220 value.resize(4);
221 break;
222
223 case 0x0079: // 1st VOCS instance
224 case 0x008a: // 2nd VOCS instance
225 /* offset output description */
226 value.resize(10);
227 break;
228
229 default:
230 ASSERT_TRUE(false);
231 return;
232 }
233
234 if (do_not_respond_to_reads) return;
235 cb(conn_id, GATT_SUCCESS, handle, value.size(), value.data(),
236 cb_data);
237 }));
238 }
239
240 protected:
241 bool do_not_respond_to_reads = false;
242
SetUp(void)243 void SetUp(void) override {
244 bluetooth::manager::SetMockBtmInterface(&btm_interface);
245 MockCsisClient::SetMockInstanceForTesting(&mock_csis_client_module_);
246 gatt::SetMockBtaGattInterface(&gatt_interface);
247 gatt::SetMockBtaGattQueue(&gatt_queue);
248 callbacks.reset(new MockVolumeControlCallbacks());
249 reset_mock_function_count_map();
250
251 ON_CALL(btm_interface, IsLinkKeyKnown(_, _))
252 .WillByDefault(DoAll(Return(true)));
253
254 // default action for GetCharacteristic function call
255 ON_CALL(gatt_interface, GetCharacteristic(_, _))
256 .WillByDefault(
257 Invoke([&](uint16_t conn_id,
258 uint16_t handle) -> const gatt::Characteristic* {
259 std::list<gatt::Service>& services = services_map[conn_id];
260 for (auto const& service : services) {
261 for (auto const& characteristic : service.characteristics) {
262 if (characteristic.value_handle == handle) {
263 return &characteristic;
264 }
265 }
266 }
267
268 return nullptr;
269 }));
270
271 // default action for GetOwningService function call
272 ON_CALL(gatt_interface, GetOwningService(_, _))
273 .WillByDefault(Invoke(
274 [&](uint16_t conn_id, uint16_t handle) -> const gatt::Service* {
275 std::list<gatt::Service>& services = services_map[conn_id];
276 for (auto const& service : services) {
277 if (service.handle <= handle && service.end_handle >= handle) {
278 return &service;
279 }
280 }
281
282 return nullptr;
283 }));
284
285 // default action for GetServices function call
286 ON_CALL(gatt_interface, GetServices(_))
287 .WillByDefault(WithArg<0>(
288 Invoke([&](uint16_t conn_id) -> std::list<gatt::Service>* {
289 return &services_map[conn_id];
290 })));
291
292 // default action for RegisterForNotifications function call
293 ON_CALL(gatt_interface, RegisterForNotifications(gatt_if, _, _))
294 .WillByDefault(Return(GATT_SUCCESS));
295
296 // default action for DeregisterForNotifications function call
297 ON_CALL(gatt_interface, DeregisterForNotifications(gatt_if, _, _))
298 .WillByDefault(Return(GATT_SUCCESS));
299
300 // default action for WriteDescriptor function call
301 ON_CALL(gatt_queue, WriteDescriptor(_, _, _, _, _, _))
302 .WillByDefault(
303 Invoke([](uint16_t conn_id, uint16_t handle,
304 std::vector<uint8_t> value, tGATT_WRITE_TYPE write_type,
305 GATT_WRITE_OP_CB cb, void* cb_data) -> void {
306 if (cb)
307 cb(conn_id, GATT_SUCCESS, handle, value.size(), value.data(),
308 cb_data);
309 }));
310 }
311
TearDown(void)312 void TearDown(void) override {
313 services_map.clear();
314 callbacks.reset();
315 gatt::SetMockBtaGattQueue(nullptr);
316 gatt::SetMockBtaGattInterface(nullptr);
317 bluetooth::manager::SetMockBtmInterface(nullptr);
318 }
319
TestAppRegister(void)320 void TestAppRegister(void) {
321 BtaAppRegisterCallback app_register_callback;
322 EXPECT_CALL(gatt_interface, AppRegister(_, _, _))
323 .WillOnce(DoAll(SaveArg<0>(&gatt_callback),
324 SaveArg<1>(&app_register_callback)));
325 VolumeControl::Initialize(callbacks.get(), base::DoNothing());
326 ASSERT_TRUE(gatt_callback);
327 ASSERT_TRUE(app_register_callback);
328 app_register_callback.Run(gatt_if, GATT_SUCCESS);
329 ASSERT_TRUE(VolumeControl::IsVolumeControlRunning());
330 }
331
TestAppUnregister(void)332 void TestAppUnregister(void) {
333 EXPECT_CALL(gatt_interface, AppDeregister(gatt_if));
334 VolumeControl::CleanUp();
335 ASSERT_FALSE(VolumeControl::IsVolumeControlRunning());
336 gatt_callback = nullptr;
337 }
338
TestConnect(const RawAddress & address)339 void TestConnect(const RawAddress& address) {
340 // by default indicate link as encrypted
341 ON_CALL(btm_interface, BTM_IsEncrypted(address, _))
342 .WillByDefault(DoAll(Return(true)));
343
344 EXPECT_CALL(gatt_interface,
345 Open(gatt_if, address, BTM_BLE_DIRECT_CONNECTION, true));
346 VolumeControl::Get()->Connect(address);
347 Mock::VerifyAndClearExpectations(&gatt_interface);
348 }
349
TestRemove(const RawAddress & address,uint16_t conn_id)350 void TestRemove(const RawAddress& address, uint16_t conn_id) {
351 EXPECT_CALL(gatt_interface, CancelOpen(gatt_if, address, false));
352 if (conn_id) {
353 EXPECT_CALL(gatt_interface, Close(conn_id));
354 } else {
355 EXPECT_CALL(gatt_interface, Close(conn_id)).Times(0);
356 }
357 VolumeControl::Get()->Remove(address);
358 Mock::VerifyAndClearExpectations(&gatt_interface);
359 }
360
TestDisconnect(const RawAddress & address,uint16_t conn_id)361 void TestDisconnect(const RawAddress& address, uint16_t conn_id) {
362 if (conn_id) {
363 EXPECT_CALL(gatt_interface, Close(conn_id));
364 } else {
365 EXPECT_CALL(gatt_interface, Close(conn_id)).Times(0);
366 }
367 VolumeControl::Get()->Disconnect(address);
368 Mock::VerifyAndClearExpectations(&gatt_interface);
369 }
370
TestAddFromStorage(const RawAddress & address)371 void TestAddFromStorage(const RawAddress& address) {
372 // by default indicate link as encrypted
373 ON_CALL(btm_interface, BTM_IsEncrypted(address, _))
374 .WillByDefault(DoAll(Return(true)));
375
376 EXPECT_CALL(gatt_interface,
377 Open(gatt_if, address, BTM_BLE_DIRECT_CONNECTION, true));
378 VolumeControl::Get()->AddFromStorage(address);
379 }
380
TestSubscribeNotifications(const RawAddress & address,uint16_t conn_id,std::map<uint16_t,uint16_t> & handle_pairs)381 void TestSubscribeNotifications(const RawAddress& address, uint16_t conn_id,
382 std::map<uint16_t, uint16_t>& handle_pairs) {
383 SetSampleDatabase(conn_id);
384 TestAppRegister();
385 TestConnect(address);
386 GetConnectedEvent(address, conn_id);
387
388 EXPECT_CALL(gatt_queue, WriteDescriptor(_, _, _, _, _, _))
389 .WillRepeatedly(DoDefault());
390 EXPECT_CALL(gatt_interface, RegisterForNotifications(_, _, _))
391 .WillRepeatedly(DoDefault());
392
393 std::vector<uint8_t> notify_value({0x01, 0x00});
394 for (auto const& handles : handle_pairs) {
395 EXPECT_CALL(gatt_queue, WriteDescriptor(conn_id, handles.second,
396 notify_value, GATT_WRITE, _, _))
397 .WillOnce(DoDefault());
398 EXPECT_CALL(gatt_interface,
399 RegisterForNotifications(gatt_if, address, handles.first))
400 .WillOnce(DoDefault());
401 }
402
403 GetSearchCompleteEvent(conn_id);
404 TestAppUnregister();
405 }
406
TestReadCharacteristic(const RawAddress & address,uint16_t conn_id,std::vector<uint16_t> handles)407 void TestReadCharacteristic(const RawAddress& address, uint16_t conn_id,
408 std::vector<uint16_t> handles) {
409 SetSampleDatabase(conn_id);
410 TestAppRegister();
411 TestConnect(address);
412 GetConnectedEvent(address, conn_id);
413
414 EXPECT_CALL(gatt_queue, ReadCharacteristic(conn_id, _, _, _))
415 .WillRepeatedly(DoDefault());
416 for (auto const& handle : handles) {
417 EXPECT_CALL(gatt_queue, ReadCharacteristic(conn_id, handle, _, _))
418 .WillOnce(DoDefault());
419 }
420
421 GetSearchCompleteEvent(conn_id);
422 TestAppUnregister();
423 }
424
GetConnectedEvent(const RawAddress & address,uint16_t conn_id)425 void GetConnectedEvent(const RawAddress& address, uint16_t conn_id) {
426 tBTA_GATTC_OPEN event_data = {
427 .status = GATT_SUCCESS,
428 .conn_id = conn_id,
429 .client_if = gatt_if,
430 .remote_bda = address,
431 .transport = GATT_TRANSPORT_LE,
432 .mtu = 240,
433 };
434
435 gatt_callback(BTA_GATTC_OPEN_EVT, (tBTA_GATTC*)&event_data);
436 }
437
GetDisconnectedEvent(const RawAddress & address,uint16_t conn_id)438 void GetDisconnectedEvent(const RawAddress& address, uint16_t conn_id) {
439 tBTA_GATTC_CLOSE event_data = {
440 .conn_id = conn_id,
441 .status = GATT_SUCCESS,
442 .client_if = gatt_if,
443 .remote_bda = address,
444 .reason = GATT_CONN_TERMINATE_PEER_USER,
445 };
446
447 gatt_callback(BTA_GATTC_CLOSE_EVT, (tBTA_GATTC*)&event_data);
448 }
449
GetSearchCompleteEvent(uint16_t conn_id)450 void GetSearchCompleteEvent(uint16_t conn_id) {
451 tBTA_GATTC_SEARCH_CMPL event_data = {
452 .conn_id = conn_id,
453 .status = GATT_SUCCESS,
454 };
455
456 gatt_callback(BTA_GATTC_SEARCH_CMPL_EVT, (tBTA_GATTC*)&event_data);
457 }
458
GetEncryptionCompleteEvt(const RawAddress & bda)459 void GetEncryptionCompleteEvt(const RawAddress& bda) {
460 tBTA_GATTC cb_data{};
461
462 cb_data.enc_cmpl.client_if = gatt_if;
463 cb_data.enc_cmpl.remote_bda = bda;
464 gatt_callback(BTA_GATTC_ENC_CMPL_CB_EVT, &cb_data);
465 }
466
SetEncryptionResult(const RawAddress & address,bool success)467 void SetEncryptionResult(const RawAddress& address, bool success) {
468 ON_CALL(btm_interface, BTM_IsEncrypted(address, _))
469 .WillByDefault(DoAll(Return(false)));
470 ON_CALL(btm_interface, IsLinkKeyKnown(address, _))
471 .WillByDefault(DoAll(Return(true)));
472 ON_CALL(btm_interface, SetEncryption(address, _, _, _, BTM_BLE_SEC_ENCRYPT))
473 .WillByDefault(Invoke(
474 [&success, this](const RawAddress& bd_addr, tBT_TRANSPORT transport,
475 tBTM_SEC_CALLBACK* p_callback, void* p_ref_data,
476 tBTM_BLE_SEC_ACT sec_act) -> tBTM_STATUS {
477 if (p_callback) {
478 p_callback(bd_addr, transport, p_ref_data,
479 success ? BTM_SUCCESS : BTM_FAILED_ON_SECURITY);
480 }
481 GetEncryptionCompleteEvt(bd_addr);
482 return BTM_SUCCESS;
483 }));
484 EXPECT_CALL(btm_interface,
485 SetEncryption(address, _, _, _, BTM_BLE_SEC_ENCRYPT))
486 .Times(1);
487 }
488
SetSampleDatabaseVCS(uint16_t conn_id)489 void SetSampleDatabaseVCS(uint16_t conn_id) {
490 set_sample_database(conn_id, true, false, false, false, false, false);
491 }
492
SetSampleDatabaseNoVCS(uint16_t conn_id)493 void SetSampleDatabaseNoVCS(uint16_t conn_id) {
494 set_sample_database(conn_id, false, false, true, false, true, false);
495 }
496
SetSampleDatabaseVCSBroken(uint16_t conn_id)497 void SetSampleDatabaseVCSBroken(uint16_t conn_id) {
498 set_sample_database(conn_id, true, true, true, false, true, false);
499 }
500
SetSampleDatabaseVOCS(uint16_t conn_id)501 void SetSampleDatabaseVOCS(uint16_t conn_id) {
502 set_sample_database(conn_id, true, false, false, false, true, false);
503 }
504
SetSampleDatabaseVOCSBroken(uint16_t conn_id)505 void SetSampleDatabaseVOCSBroken(uint16_t conn_id) {
506 set_sample_database(conn_id, true, false, true, false, true, true);
507 }
508
SetSampleDatabase(uint16_t conn_id)509 void SetSampleDatabase(uint16_t conn_id) {
510 set_sample_database(conn_id, true, false, true, false, true, false);
511 }
512
513 std::unique_ptr<MockVolumeControlCallbacks> callbacks;
514 bluetooth::manager::MockBtmInterface btm_interface;
515 MockCsisClient mock_csis_client_module_;
516 gatt::MockBtaGattInterface gatt_interface;
517 gatt::MockBtaGattQueue gatt_queue;
518 tBTA_GATTC_CBACK* gatt_callback;
519 const uint8_t gatt_if = 0xff;
520 std::map<uint16_t, std::list<gatt::Service>> services_map;
521 };
522
TEST_F(VolumeControlTest,test_get_uninitialized)523 TEST_F(VolumeControlTest, test_get_uninitialized) {
524 ASSERT_DEATH(VolumeControl::Get(), "");
525 }
526
TEST_F(VolumeControlTest,test_initialize)527 TEST_F(VolumeControlTest, test_initialize) {
528 bool init_cb_called = false;
529 BtaAppRegisterCallback app_register_callback;
530 EXPECT_CALL(gatt_interface, AppRegister(_, _, _))
531 .WillOnce(DoAll(SaveArg<0>(&gatt_callback),
532 SaveArg<1>(&app_register_callback)));
533 VolumeControl::Initialize(
534 callbacks.get(),
535 base::Bind([](bool* init_cb_called) { *init_cb_called = true; },
536 &init_cb_called));
537 ASSERT_TRUE(gatt_callback);
538 ASSERT_TRUE(app_register_callback);
539 app_register_callback.Run(gatt_if, GATT_SUCCESS);
540 ASSERT_TRUE(init_cb_called);
541
542 ASSERT_TRUE(VolumeControl::IsVolumeControlRunning());
543 VolumeControl::CleanUp();
544 }
545
TEST_F(VolumeControlTest,test_initialize_twice)546 TEST_F(VolumeControlTest, test_initialize_twice) {
547 VolumeControl::Initialize(callbacks.get(), base::DoNothing());
548 VolumeControl* volume_control_p = VolumeControl::Get();
549 VolumeControl::Initialize(callbacks.get(), base::DoNothing());
550 ASSERT_EQ(volume_control_p, VolumeControl::Get());
551 VolumeControl::CleanUp();
552 }
553
TEST_F(VolumeControlTest,test_cleanup_initialized)554 TEST_F(VolumeControlTest, test_cleanup_initialized) {
555 VolumeControl::Initialize(callbacks.get(), base::DoNothing());
556 VolumeControl::CleanUp();
557 ASSERT_FALSE(VolumeControl::IsVolumeControlRunning());
558 }
559
TEST_F(VolumeControlTest,test_cleanup_uninitialized)560 TEST_F(VolumeControlTest, test_cleanup_uninitialized) {
561 VolumeControl::CleanUp();
562 ASSERT_FALSE(VolumeControl::IsVolumeControlRunning());
563 }
564
TEST_F(VolumeControlTest,test_app_registration)565 TEST_F(VolumeControlTest, test_app_registration) {
566 TestAppRegister();
567 TestAppUnregister();
568 }
569
TEST_F(VolumeControlTest,test_connect)570 TEST_F(VolumeControlTest, test_connect) {
571 TestAppRegister();
572 TestConnect(GetTestAddress(0));
573 TestAppUnregister();
574 }
575
TEST_F(VolumeControlTest,test_connect_after_remove)576 TEST_F(VolumeControlTest, test_connect_after_remove) {
577 TestAppRegister();
578
579 const RawAddress test_address = GetTestAddress(0);
580 uint16_t conn_id = 1;
581
582 TestConnect(test_address);
583 GetConnectedEvent(test_address, conn_id);
584 Mock::VerifyAndClearExpectations(callbacks.get());
585
586 EXPECT_CALL(*callbacks,
587 OnConnectionState(ConnectionState::DISCONNECTED, test_address))
588 .Times(1);
589
590 TestRemove(test_address, conn_id);
591 Mock::VerifyAndClearExpectations(callbacks.get());
592
593 EXPECT_CALL(*callbacks,
594 OnConnectionState(ConnectionState::DISCONNECTED, test_address))
595 .Times(1);
596 ON_CALL(btm_interface, IsLinkKeyKnown(_, _))
597 .WillByDefault(DoAll(Return(false)));
598
599 VolumeControl::Get()->Connect(test_address);
600 Mock::VerifyAndClearExpectations(callbacks.get());
601 TestAppUnregister();
602 }
603
TEST_F(VolumeControlTest,test_reconnect_after_interrupted_discovery)604 TEST_F(VolumeControlTest, test_reconnect_after_interrupted_discovery) {
605 const RawAddress test_address = GetTestAddress(0);
606
607 // Initial connection - no callback calls yet as we want to disconnect in the
608 // middle
609 SetSampleDatabaseVOCS(1);
610 TestAppRegister();
611 TestConnect(test_address);
612 EXPECT_CALL(*callbacks,
613 OnConnectionState(ConnectionState::CONNECTED, test_address))
614 .Times(0);
615 EXPECT_CALL(*callbacks, OnDeviceAvailable(test_address, 2)).Times(0);
616 GetConnectedEvent(test_address, 1);
617 Mock::VerifyAndClearExpectations(callbacks.get());
618
619 // Remote disconnects in the middle of the service discovery
620 EXPECT_CALL(*callbacks,
621 OnConnectionState(ConnectionState::DISCONNECTED, test_address));
622 GetDisconnectedEvent(test_address, 1);
623 Mock::VerifyAndClearExpectations(callbacks.get());
624
625 // This time let the service discovery pass
626 ON_CALL(gatt_interface, ServiceSearchRequest(_, _))
627 .WillByDefault(Invoke(
628 [&](uint16_t conn_id, const bluetooth::Uuid* p_srvc_uuid) -> void {
629 if (*p_srvc_uuid == kVolumeControlUuid)
630 GetSearchCompleteEvent(conn_id);
631 }));
632
633 // Remote is being connected by another GATT client
634 EXPECT_CALL(*callbacks,
635 OnConnectionState(ConnectionState::CONNECTED, test_address));
636 EXPECT_CALL(*callbacks, OnDeviceAvailable(test_address, 2));
637 GetConnectedEvent(test_address, 1);
638 Mock::VerifyAndClearExpectations(callbacks.get());
639
640 // Request connect when the remote was already connected by another service
641 EXPECT_CALL(*callbacks, OnDeviceAvailable(test_address, 2)).Times(0);
642 EXPECT_CALL(*callbacks,
643 OnConnectionState(ConnectionState::CONNECTED, test_address));
644 VolumeControl::Get()->Connect(test_address);
645 // The GetConnectedEvent(test_address, 1); should not be triggered here, since
646 // GATT implementation will not send this event for the already connected
647 // device
648 Mock::VerifyAndClearExpectations(callbacks.get());
649
650 TestAppUnregister();
651 }
652
TEST_F(VolumeControlTest,test_reconnect_after_timeout)653 TEST_F(VolumeControlTest, test_reconnect_after_timeout) {
654 const RawAddress address = GetTestAddress(0);
655
656 // Initial connection
657 SetSampleDatabaseVOCS(1);
658 TestAppRegister();
659
660 EXPECT_CALL(*callbacks,
661 OnConnectionState(ConnectionState::CONNECTED, address))
662 .Times(0);
663 TestConnect(address);
664
665 // Disconnect not connected device - upper layer times out and needs a
666 // disconnection event to leave the transient Connecting state
667 EXPECT_CALL(*callbacks,
668 OnConnectionState(ConnectionState::DISCONNECTED, address));
669 EXPECT_CALL(gatt_interface, CancelOpen(gatt_if, address, false)).Times(0);
670 TestDisconnect(address, 0);
671
672 // Above the device was not connected and we got Disconnect request from the
673 // upper layer - it means it has timed-out but still wants to connect, thus
674 // native is still doing background or opportunistic connect. Let the remote
675 // device reconnect now.
676 ON_CALL(gatt_interface, ServiceSearchRequest(_, _))
677 .WillByDefault(Invoke(
678 [&](uint16_t conn_id, const bluetooth::Uuid* p_srvc_uuid) -> void {
679 if (*p_srvc_uuid == kVolumeControlUuid)
680 GetSearchCompleteEvent(conn_id);
681 }));
682 EXPECT_CALL(*callbacks,
683 OnConnectionState(ConnectionState::CONNECTED, address));
684 EXPECT_CALL(*callbacks, OnDeviceAvailable(address, 2));
685 GetConnectedEvent(address, 1);
686 Mock::VerifyAndClearExpectations(callbacks.get());
687
688 // Make sure that the upper layer gets the disconnection event even if not
689 // connecting actively anymore due to the mentioned time-out mechanism.
690 EXPECT_CALL(*callbacks,
691 OnConnectionState(ConnectionState::DISCONNECTED, address));
692 GetDisconnectedEvent(address, 1);
693 Mock::VerifyAndClearExpectations(callbacks.get());
694 TestAppUnregister();
695 }
696
TEST_F(VolumeControlTest,test_add_from_storage)697 TEST_F(VolumeControlTest, test_add_from_storage) {
698 TestAppRegister();
699 TestAddFromStorage(GetTestAddress(0));
700 TestAppUnregister();
701 }
702
TEST_F(VolumeControlTest,test_remove_non_connected)703 TEST_F(VolumeControlTest, test_remove_non_connected) {
704 const RawAddress test_address = GetTestAddress(0);
705 TestAppRegister();
706 TestConnect(test_address);
707 EXPECT_CALL(*callbacks,
708 OnConnectionState(ConnectionState::DISCONNECTED, test_address));
709 TestRemove(test_address, 0);
710 TestAppUnregister();
711 }
712
TEST_F(VolumeControlTest,test_remove_connected)713 TEST_F(VolumeControlTest, test_remove_connected) {
714 const RawAddress test_address = GetTestAddress(0);
715 TestAppRegister();
716 TestConnect(test_address);
717 GetConnectedEvent(test_address, 1);
718 EXPECT_CALL(*callbacks,
719 OnConnectionState(ConnectionState::DISCONNECTED, test_address));
720 TestDisconnect(test_address, 1);
721 TestAppUnregister();
722 }
723
TEST_F(VolumeControlTest,test_disconnect_non_connected)724 TEST_F(VolumeControlTest, test_disconnect_non_connected) {
725 const RawAddress test_address = GetTestAddress(0);
726 TestAppRegister();
727 TestConnect(test_address);
728 EXPECT_CALL(*callbacks,
729 OnConnectionState(ConnectionState::DISCONNECTED, test_address));
730 TestDisconnect(test_address, 0);
731 TestAppUnregister();
732 }
733
TEST_F(VolumeControlTest,test_disconnect_connected)734 TEST_F(VolumeControlTest, test_disconnect_connected) {
735 const RawAddress test_address = GetTestAddress(0);
736 TestAppRegister();
737 TestConnect(test_address);
738 GetConnectedEvent(test_address, 1);
739 EXPECT_CALL(*callbacks,
740 OnConnectionState(ConnectionState::DISCONNECTED, test_address));
741 TestDisconnect(test_address, 1);
742 TestAppUnregister();
743 }
744
TEST_F(VolumeControlTest,test_disconnected)745 TEST_F(VolumeControlTest, test_disconnected) {
746 const RawAddress test_address = GetTestAddress(0);
747 TestAppRegister();
748 TestConnect(test_address);
749 GetConnectedEvent(test_address, 1);
750 EXPECT_CALL(*callbacks,
751 OnConnectionState(ConnectionState::DISCONNECTED, test_address));
752 GetDisconnectedEvent(test_address, 1);
753 TestAppUnregister();
754 }
755
TEST_F(VolumeControlTest,test_disconnected_while_autoconnect)756 TEST_F(VolumeControlTest, test_disconnected_while_autoconnect) {
757 const RawAddress test_address = GetTestAddress(0);
758 TestAppRegister();
759 TestAddFromStorage(test_address);
760 GetConnectedEvent(test_address, 1);
761 // autoconnect - don't indicate disconnection
762 EXPECT_CALL(*callbacks,
763 OnConnectionState(ConnectionState::DISCONNECTED, test_address))
764 .Times(0);
765 GetDisconnectedEvent(test_address, 1);
766 TestAppUnregister();
767 }
768
TEST_F(VolumeControlTest,test_disconnect_when_link_key_gone)769 TEST_F(VolumeControlTest, test_disconnect_when_link_key_gone) {
770 const RawAddress test_address = GetTestAddress(0);
771 TestAppRegister();
772 TestAddFromStorage(test_address);
773
774 ON_CALL(btm_interface, BTM_IsEncrypted(test_address, _))
775 .WillByDefault(DoAll(Return(false)));
776 ON_CALL(btm_interface,
777 SetEncryption(test_address, _, _, _, BTM_BLE_SEC_ENCRYPT))
778 .WillByDefault(Return(BTM_ERR_KEY_MISSING));
779
780 // autoconnect - don't indicate disconnection
781 EXPECT_CALL(*callbacks,
782 OnConnectionState(ConnectionState::DISCONNECTED, test_address))
783 .Times(0);
784 EXPECT_CALL(gatt_interface, Close(1));
785 GetConnectedEvent(test_address, 1);
786 Mock::VerifyAndClearExpectations(&btm_interface);
787 TestAppUnregister();
788 }
789
TEST_F(VolumeControlTest,test_reconnect_after_encryption_failed)790 TEST_F(VolumeControlTest, test_reconnect_after_encryption_failed) {
791 const RawAddress test_address = GetTestAddress(0);
792 TestAppRegister();
793 TestAddFromStorage(test_address);
794 SetEncryptionResult(test_address, false);
795 // autoconnect - don't indicate disconnection
796 EXPECT_CALL(*callbacks,
797 OnConnectionState(ConnectionState::DISCONNECTED, test_address))
798 .Times(0);
799 GetConnectedEvent(test_address, 1);
800 Mock::VerifyAndClearExpectations(&btm_interface);
801 SetEncryptionResult(test_address, true);
802 GetConnectedEvent(test_address, 1);
803 TestAppUnregister();
804 }
805
TEST_F(VolumeControlTest,test_service_discovery_completed_before_encryption)806 TEST_F(VolumeControlTest, test_service_discovery_completed_before_encryption) {
807 const RawAddress test_address = GetTestAddress(0);
808 SetSampleDatabaseVCS(1);
809 TestAppRegister();
810 TestConnect(test_address);
811
812 ON_CALL(btm_interface, BTM_IsEncrypted(test_address, _))
813 .WillByDefault(DoAll(Return(false)));
814 ON_CALL(btm_interface, IsLinkKeyKnown(test_address, _))
815 .WillByDefault(DoAll(Return(true)));
816 ON_CALL(btm_interface, SetEncryption(test_address, _, _, _, _))
817 .WillByDefault(Return(BTM_SUCCESS));
818
819 EXPECT_CALL(*callbacks,
820 OnConnectionState(ConnectionState::CONNECTED, test_address))
821 .Times(0);
822 uint16_t conn_id = 1;
823 GetConnectedEvent(test_address, conn_id);
824 GetSearchCompleteEvent(conn_id);
825 Mock::VerifyAndClearExpectations(&btm_interface);
826 Mock::VerifyAndClearExpectations(callbacks.get());
827
828 EXPECT_CALL(*callbacks,
829 OnConnectionState(ConnectionState::CONNECTED, test_address))
830 .Times(1);
831
832 ON_CALL(btm_interface, BTM_IsEncrypted(test_address, _))
833 .WillByDefault(DoAll(Return(true)));
834 EXPECT_CALL(gatt_interface, ServiceSearchRequest(_, _));
835
836 GetEncryptionCompleteEvt(test_address);
837 GetSearchCompleteEvent(conn_id);
838
839 Mock::VerifyAndClearExpectations(callbacks.get());
840 Mock::VerifyAndClearExpectations(&gatt_interface);
841
842 TestAppUnregister();
843 }
844
TEST_F(VolumeControlTest,test_discovery_vcs_found)845 TEST_F(VolumeControlTest, test_discovery_vcs_found) {
846 const RawAddress test_address = GetTestAddress(0);
847 SetSampleDatabaseVCS(1);
848 TestAppRegister();
849 TestConnect(test_address);
850 EXPECT_CALL(*callbacks, OnDeviceAvailable(test_address, _));
851 EXPECT_CALL(*callbacks,
852 OnConnectionState(ConnectionState::CONNECTED, test_address));
853 GetConnectedEvent(test_address, 1);
854 GetSearchCompleteEvent(1);
855 Mock::VerifyAndClearExpectations(callbacks.get());
856 TestAppUnregister();
857 }
858
TEST_F(VolumeControlTest,test_discovery_vcs_not_found)859 TEST_F(VolumeControlTest, test_discovery_vcs_not_found) {
860 const RawAddress test_address = GetTestAddress(0);
861 SetSampleDatabaseNoVCS(1);
862 TestAppRegister();
863 TestConnect(test_address);
864 EXPECT_CALL(*callbacks,
865 OnConnectionState(ConnectionState::DISCONNECTED, test_address));
866 GetConnectedEvent(test_address, 1);
867
868 GetSearchCompleteEvent(1);
869 Mock::VerifyAndClearExpectations(callbacks.get());
870 TestAppUnregister();
871 }
872
TEST_F(VolumeControlTest,test_discovery_vcs_broken)873 TEST_F(VolumeControlTest, test_discovery_vcs_broken) {
874 const RawAddress test_address = GetTestAddress(0);
875 SetSampleDatabaseVCSBroken(1);
876 TestAppRegister();
877 TestConnect(test_address);
878 EXPECT_CALL(*callbacks,
879 OnConnectionState(ConnectionState::DISCONNECTED, test_address));
880 GetConnectedEvent(test_address, 1);
881 GetSearchCompleteEvent(1);
882 Mock::VerifyAndClearExpectations(callbacks.get());
883 TestAppUnregister();
884 }
885
TEST_F(VolumeControlTest,test_subscribe_vcs_volume_state)886 TEST_F(VolumeControlTest, test_subscribe_vcs_volume_state) {
887 std::map<uint16_t, uint16_t> handles({{0x0021, 0x0022}});
888 TestSubscribeNotifications(GetTestAddress(0), 1, handles);
889 }
890
TEST_F(VolumeControlTest,test_subscribe_vocs_offset_state)891 TEST_F(VolumeControlTest, test_subscribe_vocs_offset_state) {
892 std::map<uint16_t, uint16_t> handles({{0x0072, 0x0073}, {0x0082, 0x0083}});
893 TestSubscribeNotifications(GetTestAddress(0), 1, handles);
894 }
895
TEST_F(VolumeControlTest,test_subscribe_vocs_offset_location)896 TEST_F(VolumeControlTest, test_subscribe_vocs_offset_location) {
897 std::map<uint16_t, uint16_t> handles({{0x0085, 0x0086}});
898 TestSubscribeNotifications(GetTestAddress(0), 1, handles);
899 }
900
TEST_F(VolumeControlTest,test_subscribe_vocs_output_description)901 TEST_F(VolumeControlTest, test_subscribe_vocs_output_description) {
902 std::map<uint16_t, uint16_t> handles({{0x008a, 0x008b}});
903 TestSubscribeNotifications(GetTestAddress(0), 1, handles);
904 }
905
TEST_F(VolumeControlTest,test_read_vcs_volume_state)906 TEST_F(VolumeControlTest, test_read_vcs_volume_state) {
907 const RawAddress test_address = GetTestAddress(0);
908 EXPECT_CALL(*callbacks, OnVolumeStateChanged(test_address, _, _, false));
909 std::vector<uint16_t> handles({0x0021});
910 TestReadCharacteristic(test_address, 1, handles);
911 }
912
TEST_F(VolumeControlTest,test_read_vcs_volume_flags)913 TEST_F(VolumeControlTest, test_read_vcs_volume_flags) {
914 std::vector<uint16_t> handles({0x0026});
915 TestReadCharacteristic(GetTestAddress(0), 1, handles);
916 }
917
TEST_F(VolumeControlTest,test_read_vocs_volume_offset)918 TEST_F(VolumeControlTest, test_read_vocs_volume_offset) {
919 const RawAddress test_address = GetTestAddress(0);
920 EXPECT_CALL(*callbacks, OnExtAudioOutVolumeOffsetChanged(test_address, 1, _));
921 EXPECT_CALL(*callbacks, OnExtAudioOutVolumeOffsetChanged(test_address, 2, _));
922 std::vector<uint16_t> handles({0x0072, 0x0082});
923 TestReadCharacteristic(test_address, 1, handles);
924 }
925
TEST_F(VolumeControlTest,test_read_vocs_offset_location)926 TEST_F(VolumeControlTest, test_read_vocs_offset_location) {
927 const RawAddress test_address = GetTestAddress(0);
928 EXPECT_CALL(*callbacks, OnExtAudioOutLocationChanged(test_address, 1, _));
929 EXPECT_CALL(*callbacks, OnExtAudioOutLocationChanged(test_address, 2, _));
930 std::vector<uint16_t> handles({0x0075, 0x0085});
931 TestReadCharacteristic(test_address, 1, handles);
932 }
933
TEST_F(VolumeControlTest,test_read_vocs_output_description)934 TEST_F(VolumeControlTest, test_read_vocs_output_description) {
935 const RawAddress test_address = GetTestAddress(0);
936 EXPECT_CALL(*callbacks, OnExtAudioOutDescriptionChanged(test_address, 1, _));
937 EXPECT_CALL(*callbacks, OnExtAudioOutDescriptionChanged(test_address, 2, _));
938 std::vector<uint16_t> handles({0x0079, 0x008a});
939 TestReadCharacteristic(test_address, 1, handles);
940 }
941
TEST_F(VolumeControlTest,test_discovery_vocs_found)942 TEST_F(VolumeControlTest, test_discovery_vocs_found) {
943 const RawAddress test_address = GetTestAddress(0);
944 SetSampleDatabaseVOCS(1);
945 TestAppRegister();
946 TestConnect(test_address);
947 EXPECT_CALL(*callbacks,
948 OnConnectionState(ConnectionState::CONNECTED, test_address));
949 EXPECT_CALL(*callbacks, OnDeviceAvailable(test_address, 2));
950 GetConnectedEvent(test_address, 1);
951 GetSearchCompleteEvent(1);
952 Mock::VerifyAndClearExpectations(callbacks.get());
953 TestAppUnregister();
954 }
955
TEST_F(VolumeControlTest,test_discovery_vocs_not_found)956 TEST_F(VolumeControlTest, test_discovery_vocs_not_found) {
957 const RawAddress test_address = GetTestAddress(0);
958 SetSampleDatabaseVCS(1);
959 TestAppRegister();
960 TestConnect(test_address);
961 EXPECT_CALL(*callbacks,
962 OnConnectionState(ConnectionState::CONNECTED, test_address));
963 EXPECT_CALL(*callbacks, OnDeviceAvailable(test_address, 0));
964 GetConnectedEvent(test_address, 1);
965 GetSearchCompleteEvent(1);
966 Mock::VerifyAndClearExpectations(callbacks.get());
967 TestAppUnregister();
968 }
969
TEST_F(VolumeControlTest,test_discovery_vocs_broken)970 TEST_F(VolumeControlTest, test_discovery_vocs_broken) {
971 const RawAddress test_address = GetTestAddress(0);
972 SetSampleDatabaseVOCSBroken(1);
973 TestAppRegister();
974 TestConnect(test_address);
975 EXPECT_CALL(*callbacks,
976 OnConnectionState(ConnectionState::CONNECTED, test_address));
977 EXPECT_CALL(*callbacks, OnDeviceAvailable(test_address, 1));
978 GetConnectedEvent(test_address, 1);
979 GetSearchCompleteEvent(1);
980 Mock::VerifyAndClearExpectations(callbacks.get());
981 TestAppUnregister();
982 }
983
TEST_F(VolumeControlTest,test_read_vcs_database_out_of_sync)984 TEST_F(VolumeControlTest, test_read_vcs_database_out_of_sync) {
985 const RawAddress test_address = GetTestAddress(0);
986 EXPECT_CALL(*callbacks, OnVolumeStateChanged(test_address, _, _, false));
987 std::vector<uint16_t> handles({0x0021});
988 uint16_t conn_id = 1;
989
990 SetSampleDatabase(conn_id);
991 TestAppRegister();
992 TestConnect(test_address);
993 GetConnectedEvent(test_address, conn_id);
994
995 EXPECT_CALL(gatt_queue, ReadCharacteristic(conn_id, _, _, _))
996 .WillRepeatedly(DoDefault());
997 for (auto const& handle : handles) {
998 EXPECT_CALL(gatt_queue, ReadCharacteristic(conn_id, handle, _, _))
999 .WillOnce(DoDefault());
1000 }
1001 GetSearchCompleteEvent(conn_id);
1002
1003 /* Simulate database change on the remote side. */
1004 ON_CALL(gatt_queue, WriteCharacteristic(_, _, _, _, _, _))
1005 .WillByDefault(
1006 Invoke([this](uint16_t conn_id, uint16_t handle,
1007 std::vector<uint8_t> value, tGATT_WRITE_TYPE write_type,
1008 GATT_WRITE_OP_CB cb, void* cb_data) {
1009 auto* svc = gatt::FindService(services_map[conn_id], handle);
1010 if (svc == nullptr) return;
1011
1012 tGATT_STATUS status = GATT_DATABASE_OUT_OF_SYNC;
1013 if (cb)
1014 cb(conn_id, status, handle, value.size(), value.data(), cb_data);
1015 }));
1016
1017 ON_CALL(gatt_interface, ServiceSearchRequest(_, _)).WillByDefault(Return());
1018 EXPECT_CALL(gatt_interface, ServiceSearchRequest(_, _));
1019 VolumeControl::Get()->SetVolume(test_address, 15);
1020 Mock::VerifyAndClearExpectations(&gatt_interface);
1021 TestAppUnregister();
1022 }
1023
1024 class VolumeControlCallbackTest : public VolumeControlTest {
1025 protected:
1026 const RawAddress test_address = GetTestAddress(0);
1027 uint16_t conn_id = 22;
1028
SetUp(void)1029 void SetUp(void) override {
1030 VolumeControlTest::SetUp();
1031 SetSampleDatabase(conn_id);
1032 TestAppRegister();
1033 TestConnect(test_address);
1034 GetConnectedEvent(test_address, conn_id);
1035 GetSearchCompleteEvent(conn_id);
1036 }
1037
TearDown(void)1038 void TearDown(void) override {
1039 TestAppUnregister();
1040 VolumeControlTest::TearDown();
1041 }
1042
GetNotificationEvent(uint16_t handle,std::vector<uint8_t> & value)1043 void GetNotificationEvent(uint16_t handle, std::vector<uint8_t>& value) {
1044 tBTA_GATTC_NOTIFY event_data = {
1045 .conn_id = conn_id,
1046 .bda = test_address,
1047 .handle = handle,
1048 .len = (uint8_t)value.size(),
1049 .is_notify = true,
1050 };
1051
1052 std::copy(value.begin(), value.end(), event_data.value);
1053 gatt_callback(BTA_GATTC_NOTIF_EVT, (tBTA_GATTC*)&event_data);
1054 }
1055 };
1056
TEST_F(VolumeControlCallbackTest,test_volume_state_changed_stress)1057 TEST_F(VolumeControlCallbackTest, test_volume_state_changed_stress) {
1058 std::vector<uint8_t> value({0x03, 0x01, 0x02});
1059 EXPECT_CALL(*callbacks, OnVolumeStateChanged(test_address, 0x03, true, true));
1060 GetNotificationEvent(0x0021, value);
1061 }
1062
TEST_F(VolumeControlCallbackTest,test_volume_state_changed_malformed)1063 TEST_F(VolumeControlCallbackTest, test_volume_state_changed_malformed) {
1064 EXPECT_CALL(*callbacks, OnVolumeStateChanged(test_address, _, _, _)).Times(0);
1065 std::vector<uint8_t> too_short({0x03, 0x01});
1066 GetNotificationEvent(0x0021, too_short);
1067 std::vector<uint8_t> too_long({0x03, 0x01, 0x02, 0x03});
1068 GetNotificationEvent(0x0021, too_long);
1069 }
1070
TEST_F(VolumeControlCallbackTest,test_volume_offset_changed)1071 TEST_F(VolumeControlCallbackTest, test_volume_offset_changed) {
1072 std::vector<uint8_t> value({0x04, 0x05, 0x06});
1073 EXPECT_CALL(*callbacks,
1074 OnExtAudioOutVolumeOffsetChanged(test_address, 2, 0x0504));
1075 GetNotificationEvent(0x0082, value);
1076 }
1077
TEST_F(VolumeControlCallbackTest,test_volume_offset_changed_malformed)1078 TEST_F(VolumeControlCallbackTest, test_volume_offset_changed_malformed) {
1079 EXPECT_CALL(*callbacks, OnExtAudioOutVolumeOffsetChanged(test_address, 2, _))
1080 .Times(0);
1081 std::vector<uint8_t> too_short({0x04});
1082 GetNotificationEvent(0x0082, too_short);
1083 std::vector<uint8_t> too_long({0x04, 0x05, 0x06, 0x07});
1084 GetNotificationEvent(0x0082, too_long);
1085 }
1086
TEST_F(VolumeControlCallbackTest,test_offset_location_changed)1087 TEST_F(VolumeControlCallbackTest, test_offset_location_changed) {
1088 std::vector<uint8_t> value({0x01, 0x02, 0x03, 0x04});
1089 EXPECT_CALL(*callbacks,
1090 OnExtAudioOutLocationChanged(test_address, 2, 0x04030201));
1091 GetNotificationEvent(0x0085, value);
1092 }
1093
TEST_F(VolumeControlCallbackTest,test_offset_location_changed_malformed)1094 TEST_F(VolumeControlCallbackTest, test_offset_location_changed_malformed) {
1095 EXPECT_CALL(*callbacks, OnExtAudioOutLocationChanged(test_address, 2, _))
1096 .Times(0);
1097 std::vector<uint8_t> too_short({0x04});
1098 GetNotificationEvent(0x0085, too_short);
1099 std::vector<uint8_t> too_long({0x04, 0x05, 0x06});
1100 GetNotificationEvent(0x0085, too_long);
1101 }
1102
TEST_F(VolumeControlCallbackTest,test_audio_output_description_changed)1103 TEST_F(VolumeControlCallbackTest, test_audio_output_description_changed) {
1104 std::string descr = "left";
1105 std::vector<uint8_t> value(descr.begin(), descr.end());
1106 EXPECT_CALL(*callbacks,
1107 OnExtAudioOutDescriptionChanged(test_address, 2, descr));
1108 GetNotificationEvent(0x008a, value);
1109 }
1110
1111 class VolumeControlValueGetTest : public VolumeControlTest {
1112 protected:
1113 const RawAddress test_address = GetTestAddress(0);
1114 uint16_t conn_id = 22;
1115 GATT_READ_OP_CB cb;
1116 void* cb_data;
1117 uint16_t handle;
1118
SetUp(void)1119 void SetUp(void) override {
1120 VolumeControlTest::SetUp();
1121 SetSampleDatabase(conn_id);
1122 TestAppRegister();
1123 TestConnect(test_address);
1124 GetConnectedEvent(test_address, conn_id);
1125 GetSearchCompleteEvent(conn_id);
1126 EXPECT_CALL(gatt_queue, ReadCharacteristic(conn_id, _, _, _))
1127 .WillOnce(
1128 DoAll(SaveArg<1>(&handle), SaveArg<2>(&cb), SaveArg<3>(&cb_data)));
1129 }
1130
TearDown(void)1131 void TearDown(void) override {
1132 TestAppUnregister();
1133 cb = nullptr;
1134 cb_data = nullptr;
1135 handle = 0;
1136 VolumeControlTest::TearDown();
1137 }
1138 };
1139
TEST_F(VolumeControlValueGetTest,test_get_ext_audio_out_volume_offset)1140 TEST_F(VolumeControlValueGetTest, test_get_ext_audio_out_volume_offset) {
1141 VolumeControl::Get()->GetExtAudioOutVolumeOffset(test_address, 1);
1142 EXPECT_TRUE(cb);
1143 std::vector<uint8_t> value({0x01, 0x02, 0x03});
1144 EXPECT_CALL(*callbacks,
1145 OnExtAudioOutVolumeOffsetChanged(test_address, 1, 0x0201));
1146 cb(conn_id, GATT_SUCCESS, handle, (uint16_t)value.size(), value.data(),
1147 cb_data);
1148 }
1149
TEST_F(VolumeControlValueGetTest,test_get_ext_audio_out_location)1150 TEST_F(VolumeControlValueGetTest, test_get_ext_audio_out_location) {
1151 VolumeControl::Get()->GetExtAudioOutLocation(test_address, 2);
1152 EXPECT_TRUE(cb);
1153 std::vector<uint8_t> value({0x01, 0x02, 0x03, 0x04});
1154 EXPECT_CALL(*callbacks,
1155 OnExtAudioOutLocationChanged(test_address, 2, 0x04030201));
1156 cb(conn_id, GATT_SUCCESS, handle, (uint16_t)value.size(), value.data(),
1157 cb_data);
1158 }
1159
TEST_F(VolumeControlValueGetTest,test_get_ext_audio_out_description)1160 TEST_F(VolumeControlValueGetTest, test_get_ext_audio_out_description) {
1161 VolumeControl::Get()->GetExtAudioOutDescription(test_address, 2);
1162 EXPECT_TRUE(cb);
1163 std::string descr = "right";
1164 std::vector<uint8_t> value(descr.begin(), descr.end());
1165 EXPECT_CALL(*callbacks,
1166 OnExtAudioOutDescriptionChanged(test_address, 2, descr));
1167 cb(conn_id, GATT_SUCCESS, handle, (uint16_t)value.size(), value.data(),
1168 cb_data);
1169 }
1170
1171 class VolumeControlValueSetTest : public VolumeControlTest {
1172 protected:
1173 const RawAddress test_address = GetTestAddress(0);
1174 uint16_t conn_id = 22;
1175
SetUp(void)1176 void SetUp(void) override {
1177 VolumeControlTest::SetUp();
1178 SetSampleDatabase(conn_id);
1179 TestAppRegister();
1180 TestConnect(test_address);
1181 GetConnectedEvent(test_address, conn_id);
1182 GetSearchCompleteEvent(conn_id);
1183
1184 ON_CALL(gatt_queue,
1185 WriteCharacteristic(conn_id, 0x0024, _, GATT_WRITE, _, _))
1186 .WillByDefault([this](uint16_t conn_id, uint16_t handle,
1187 std::vector<uint8_t> value,
1188 tGATT_WRITE_TYPE write_type, GATT_WRITE_OP_CB cb,
1189 void* cb_data) {
1190 uint8_t write_rsp;
1191
1192 std::vector<uint8_t> ntf_value(
1193 {value[0], 0, static_cast<uint8_t>(value[1] + 1)});
1194 switch (value[0]) {
1195 case 0x06: // mute
1196 ntf_value[1] = 1;
1197 break;
1198 case 0x05: // unmute
1199 break;
1200 case 0x04: // set abs. volume
1201 ntf_value[0] = value[2];
1202 ntf_value[1] = (value[2] ? 0 : 1);
1203 break;
1204 case 0x03: // unmute rel. up
1205 break;
1206 case 0x02: // unmute rel. down
1207 break;
1208 case 0x01: // rel. up
1209 break;
1210 case 0x00: // rel. down
1211 break;
1212 default:
1213 break;
1214 }
1215 GetNotificationEvent(0x0021, ntf_value);
1216 cb(conn_id, GATT_SUCCESS, 0x0024, 0, &write_rsp, cb_data);
1217 });
1218 }
1219
GetNotificationEvent(uint16_t handle,std::vector<uint8_t> & value)1220 void GetNotificationEvent(uint16_t handle, std::vector<uint8_t>& value) {
1221 tBTA_GATTC_NOTIFY event_data = {
1222 .conn_id = conn_id,
1223 .bda = test_address,
1224 .handle = handle,
1225 .len = (uint8_t)value.size(),
1226 .is_notify = true,
1227 };
1228
1229 std::copy(value.begin(), value.end(), event_data.value);
1230 gatt_callback(BTA_GATTC_NOTIF_EVT, (tBTA_GATTC*)&event_data);
1231 }
1232
TearDown(void)1233 void TearDown(void) override {
1234 TestAppUnregister();
1235 VolumeControlTest::TearDown();
1236 }
1237 };
1238
TEST_F(VolumeControlValueSetTest,test_volume_operation_failed)1239 TEST_F(VolumeControlValueSetTest, test_volume_operation_failed) {
1240 const std::vector<uint8_t> vol_x10({0x04, 0x00, 0x10});
1241 EXPECT_CALL(gatt_queue,
1242 WriteCharacteristic(conn_id, 0x0024, vol_x10, GATT_WRITE, _, _))
1243 .Times(1);
1244 ON_CALL(gatt_queue, WriteCharacteristic(_, _, _, _, _, _))
1245 .WillByDefault(
1246 Invoke([this](uint16_t conn_id, uint16_t handle,
1247 std::vector<uint8_t> value, tGATT_WRITE_TYPE write_type,
1248 GATT_WRITE_OP_CB cb, void* cb_data) {
1249 auto* svc = gatt::FindService(services_map[conn_id], handle);
1250 if (svc == nullptr) return;
1251
1252 tGATT_STATUS status = GATT_ERROR;
1253 if (cb)
1254 cb(conn_id, status, handle, value.size(), value.data(), cb_data);
1255 }));
1256 ASSERT_EQ(0, get_func_call_count("alarm_set_on_mloop"));
1257 ASSERT_EQ(0, get_func_call_count("alarm_cancel"));
1258
1259 VolumeControl::Get()->SetVolume(test_address, 0x10);
1260 Mock::VerifyAndClearExpectations(&gatt_queue);
1261
1262 ASSERT_EQ(1, get_func_call_count("alarm_set_on_mloop"));
1263 ASSERT_EQ(1, get_func_call_count("alarm_cancel"));
1264 }
1265
TEST_F(VolumeControlValueSetTest,test_volume_operation_failed_due_to_device_disconnection)1266 TEST_F(VolumeControlValueSetTest,
1267 test_volume_operation_failed_due_to_device_disconnection) {
1268 const std::vector<uint8_t> vol_x10({0x04, 0x00, 0x10});
1269 EXPECT_CALL(gatt_queue,
1270 WriteCharacteristic(conn_id, 0x0024, vol_x10, GATT_WRITE, _, _))
1271 .Times(1);
1272 ON_CALL(gatt_queue, WriteCharacteristic(_, _, _, _, _, _))
1273 .WillByDefault(Invoke(
1274 [](uint16_t conn_id, uint16_t handle, std::vector<uint8_t> value,
1275 tGATT_WRITE_TYPE write_type, GATT_WRITE_OP_CB cb, void* cb_data) {
1276 /* Do nothing */
1277 }));
1278
1279 ASSERT_EQ(0, get_func_call_count("alarm_set_on_mloop"));
1280 ASSERT_EQ(0, get_func_call_count("alarm_cancel"));
1281
1282 VolumeControl::Get()->SetVolume(test_address, 0x10);
1283 Mock::VerifyAndClearExpectations(&gatt_queue);
1284
1285 EXPECT_CALL(*callbacks,
1286 OnConnectionState(ConnectionState::DISCONNECTED, test_address));
1287 GetDisconnectedEvent(test_address, conn_id);
1288 Mock::VerifyAndClearExpectations(callbacks.get());
1289
1290 ASSERT_EQ(1, get_func_call_count("alarm_set_on_mloop"));
1291 ASSERT_EQ(1, get_func_call_count("alarm_cancel"));
1292 }
1293
TEST_F(VolumeControlValueSetTest,test_set_volume)1294 TEST_F(VolumeControlValueSetTest, test_set_volume) {
1295 const std::vector<uint8_t> vol_x10({0x04, 0x00, 0x10});
1296 EXPECT_CALL(gatt_queue,
1297 WriteCharacteristic(conn_id, 0x0024, vol_x10, GATT_WRITE, _, _))
1298 .Times(1);
1299 VolumeControl::Get()->SetVolume(test_address, 0x10);
1300
1301 // Same volume level should not be applied twice
1302 const std::vector<uint8_t> vol_x10_2({0x04, 0x01, 0x10});
1303 EXPECT_CALL(gatt_queue,
1304 WriteCharacteristic(conn_id, 0x0024, vol_x10_2, GATT_WRITE, _, _))
1305 .Times(0);
1306 VolumeControl::Get()->SetVolume(test_address, 0x10);
1307
1308 const std::vector<uint8_t> vol_x20({0x04, 0x01, 0x20});
1309 EXPECT_CALL(gatt_queue,
1310 WriteCharacteristic(conn_id, 0x0024, vol_x20, GATT_WRITE, _, _))
1311 .Times(1);
1312 VolumeControl::Get()->SetVolume(test_address, 0x20);
1313 }
1314
TEST_F(VolumeControlValueSetTest,test_set_volume_stress)1315 TEST_F(VolumeControlValueSetTest, test_set_volume_stress) {
1316 uint8_t n = 100;
1317 uint8_t change_cnt = 0;
1318 uint8_t vol = 1;
1319
1320 for (uint8_t i = 1; i < n; i++) {
1321 const std::vector<uint8_t> vol_x10({0x04, change_cnt, vol});
1322 EXPECT_CALL(gatt_queue,
1323 WriteCharacteristic(conn_id, 0x0024, vol_x10, GATT_WRITE, _, _))
1324 .Times(1);
1325 VolumeControl::Get()->SetVolume(test_address, vol);
1326 Mock::VerifyAndClearExpectations(&gatt_queue);
1327 change_cnt++;
1328 vol++;
1329 }
1330 }
1331
TEST_F(VolumeControlValueSetTest,test_set_volume_stress_2)1332 TEST_F(VolumeControlValueSetTest, test_set_volume_stress_2) {
1333 uint8_t change_cnt = 0;
1334 uint8_t vol = 1;
1335
1336 // In this test we simulate notification coming later and operations will be
1337 // queued
1338 ON_CALL(gatt_queue, WriteCharacteristic(conn_id, 0x0024, _, GATT_WRITE, _, _))
1339 .WillByDefault([](uint16_t conn_id, uint16_t handle,
1340 std::vector<uint8_t> value, tGATT_WRITE_TYPE write_type,
1341 GATT_WRITE_OP_CB cb, void* cb_data) {
1342 uint8_t write_rsp;
1343
1344 switch (value[0]) {
1345 case 0x04: // set abs. volume
1346 break;
1347 default:
1348 break;
1349 }
1350 cb(conn_id, GATT_SUCCESS, handle, 0, &write_rsp, cb_data);
1351 });
1352
1353 const std::vector<uint8_t> vol_x10({0x04, /*change_cnt*/ 0, 0x10});
1354 std::vector<uint8_t> ntf_value_x10({0x10, 0, 1});
1355 const std::vector<uint8_t> vol_x11({0x04, /*change_cnt*/ 1, 0x11});
1356 std::vector<uint8_t> ntf_value_x11({0x11, 0, 2});
1357 const std::vector<uint8_t> vol_x12({0x04, /*change_cnt*/ 2, 0x12});
1358 std::vector<uint8_t> ntf_value_x12({0x12, 0, 3});
1359 const std::vector<uint8_t> vol_x13({0x04, /*change_cnt*/ 3, 0x13});
1360 std::vector<uint8_t> ntf_value_x13({0x13, 0, 4});
1361
1362 EXPECT_CALL(gatt_queue,
1363 WriteCharacteristic(conn_id, 0x0024, vol_x10, GATT_WRITE, _, _))
1364 .Times(1);
1365 EXPECT_CALL(gatt_queue,
1366 WriteCharacteristic(conn_id, 0x0024, vol_x11, GATT_WRITE, _, _))
1367 .Times(1);
1368 EXPECT_CALL(gatt_queue,
1369 WriteCharacteristic(conn_id, 0x0024, vol_x12, GATT_WRITE, _, _))
1370 .Times(1);
1371 EXPECT_CALL(gatt_queue,
1372 WriteCharacteristic(conn_id, 0x0024, vol_x13, GATT_WRITE, _, _))
1373 .Times(1);
1374
1375 VolumeControl::Get()->SetVolume(test_address, 0x10);
1376 VolumeControl::Get()->SetVolume(test_address, 0x11);
1377 GetNotificationEvent(0x0021, ntf_value_x10);
1378 GetNotificationEvent(0x0021, ntf_value_x11);
1379 VolumeControl::Get()->SetVolume(test_address, 0x12);
1380 VolumeControl::Get()->SetVolume(test_address, 0x13);
1381 GetNotificationEvent(0x0021, ntf_value_x12);
1382 GetNotificationEvent(0x0021, ntf_value_x13);
1383
1384 Mock::VerifyAndClearExpectations(&gatt_queue);
1385 }
1386
TEST_F(VolumeControlValueSetTest,test_set_volume_stress_3)1387 TEST_F(VolumeControlValueSetTest, test_set_volume_stress_3) {
1388 uint8_t change_cnt = 0;
1389 uint8_t vol = 1;
1390
1391 /* In this test we simulate notification coming later and operations will be
1392 * queued but some will be removed from the queue
1393 */
1394 ON_CALL(gatt_queue, WriteCharacteristic(conn_id, 0x0024, _, GATT_WRITE, _, _))
1395 .WillByDefault([](uint16_t conn_id, uint16_t handle,
1396 std::vector<uint8_t> value, tGATT_WRITE_TYPE write_type,
1397 GATT_WRITE_OP_CB cb, void* cb_data) {
1398 uint8_t write_rsp;
1399
1400 switch (value[0]) {
1401 case 0x04: // set abs. volume
1402 break;
1403 default:
1404 break;
1405 }
1406 cb(conn_id, GATT_SUCCESS, handle, 0, &write_rsp, cb_data);
1407 });
1408
1409 const std::vector<uint8_t> vol_x10({0x04, /*change_cnt*/ 0, 0x10});
1410 std::vector<uint8_t> ntf_value_x10({0x10, 0, 1});
1411 const std::vector<uint8_t> vol_x11({0x04, /*change_cnt*/ 1, 0x11});
1412 std::vector<uint8_t> ntf_value_x11({0x11, 0, 2});
1413 const std::vector<uint8_t> vol_x12({0x04, /*change_cnt*/ 1, 0x12});
1414 std::vector<uint8_t> ntf_value_x12({0x12, 0, 3});
1415 const std::vector<uint8_t> vol_x13({0x04, /*change_cnt*/ 1, 0x13});
1416 std::vector<uint8_t> ntf_value_x13({0x13, 0, 4});
1417
1418 EXPECT_CALL(gatt_queue,
1419 WriteCharacteristic(conn_id, 0x0024, vol_x10, GATT_WRITE, _, _))
1420 .Times(1);
1421
1422 // Those two belowe will be removed from the queue
1423 EXPECT_CALL(gatt_queue,
1424 WriteCharacteristic(conn_id, 0x0024, vol_x11, GATT_WRITE, _, _))
1425 .Times(0);
1426 EXPECT_CALL(gatt_queue,
1427 WriteCharacteristic(conn_id, 0x0024, vol_x12, GATT_WRITE, _, _))
1428 .Times(0);
1429
1430 // This one shall be sent with a change count 1.
1431 EXPECT_CALL(gatt_queue,
1432 WriteCharacteristic(conn_id, 0x0024, vol_x13, GATT_WRITE, _, _))
1433 .Times(1);
1434
1435 VolumeControl::Get()->SetVolume(test_address, 0x10);
1436 VolumeControl::Get()->SetVolume(test_address, 0x11);
1437 VolumeControl::Get()->SetVolume(test_address, 0x12);
1438 VolumeControl::Get()->SetVolume(test_address, 0x13);
1439 GetNotificationEvent(0x0021, ntf_value_x10);
1440 GetNotificationEvent(0x0021, ntf_value_x11);
1441 GetNotificationEvent(0x0021, ntf_value_x12);
1442 GetNotificationEvent(0x0021, ntf_value_x13);
1443
1444 Mock::VerifyAndClearExpectations(&gatt_queue);
1445 }
1446
TEST_F(VolumeControlValueSetTest,test_mute_unmute)1447 TEST_F(VolumeControlValueSetTest, test_mute_unmute) {
1448 std::vector<uint8_t> mute_x0({0x06, 0x00});
1449 EXPECT_CALL(gatt_queue,
1450 WriteCharacteristic(conn_id, 0x0024, mute_x0, GATT_WRITE, _, _))
1451 .Times(1);
1452 // Don't mute when already muted
1453 std::vector<uint8_t> mute_x1({0x06, 0x01});
1454 EXPECT_CALL(gatt_queue,
1455 WriteCharacteristic(conn_id, 0x0024, mute_x1, GATT_WRITE, _, _))
1456 .Times(0);
1457 VolumeControl::Get()->Mute(test_address);
1458 VolumeControl::Get()->Mute(test_address);
1459
1460 // Needs to be muted to unmute
1461 std::vector<uint8_t> unmute_x1({0x05, 0x01});
1462 EXPECT_CALL(gatt_queue,
1463 WriteCharacteristic(conn_id, 0x0024, unmute_x1, GATT_WRITE, _, _))
1464 .Times(1);
1465 // Don't unmute when already unmuted
1466 std::vector<uint8_t> unmute_x2({0x05, 0x02});
1467 EXPECT_CALL(gatt_queue,
1468 WriteCharacteristic(conn_id, 0x0024, unmute_x2, GATT_WRITE, _, _))
1469 .Times(0);
1470 VolumeControl::Get()->UnMute(test_address);
1471 VolumeControl::Get()->UnMute(test_address);
1472 }
1473
TEST_F(VolumeControlValueSetTest,test_set_ext_audio_out_volume_offset)1474 TEST_F(VolumeControlValueSetTest, test_set_ext_audio_out_volume_offset) {
1475 std::vector<uint8_t> expected_data({0x01, 0x00, 0x34, 0x12});
1476 EXPECT_CALL(gatt_queue, WriteCharacteristic(conn_id, 0x0088, expected_data,
1477 GATT_WRITE, _, _));
1478 VolumeControl::Get()->SetExtAudioOutVolumeOffset(test_address, 2, 0x1234);
1479 }
1480
TEST_F(VolumeControlValueSetTest,test_set_ext_audio_out_location)1481 TEST_F(VolumeControlValueSetTest, test_set_ext_audio_out_location) {
1482 std::vector<uint8_t> expected_data({0x44, 0x33, 0x22, 0x11});
1483 EXPECT_CALL(gatt_queue, WriteCharacteristic(conn_id, 0x0085, expected_data,
1484 GATT_WRITE_NO_RSP, _, _));
1485 VolumeControl::Get()->SetExtAudioOutLocation(test_address, 2, 0x11223344);
1486 }
1487
TEST_F(VolumeControlValueSetTest,test_set_ext_audio_out_location_non_writable)1488 TEST_F(VolumeControlValueSetTest,
1489 test_set_ext_audio_out_location_non_writable) {
1490 EXPECT_CALL(gatt_queue, WriteCharacteristic(_, _, _, _, _, _)).Times(0);
1491 VolumeControl::Get()->SetExtAudioOutLocation(test_address, 1, 0x11223344);
1492 }
1493
TEST_F(VolumeControlValueSetTest,test_set_ext_audio_out_description)1494 TEST_F(VolumeControlValueSetTest, test_set_ext_audio_out_description) {
1495 std::string descr = "right front";
1496 std::vector<uint8_t> expected_data(descr.begin(), descr.end());
1497 EXPECT_CALL(gatt_queue, WriteCharacteristic(conn_id, 0x008a, expected_data,
1498 GATT_WRITE_NO_RSP, _, _));
1499 VolumeControl::Get()->SetExtAudioOutDescription(test_address, 2, descr);
1500 }
1501
TEST_F(VolumeControlValueSetTest,test_set_ext_audio_out_description_non_writable)1502 TEST_F(VolumeControlValueSetTest,
1503 test_set_ext_audio_out_description_non_writable) {
1504 std::string descr = "left front";
1505 EXPECT_CALL(gatt_queue, WriteCharacteristic(_, _, _, _, _, _)).Times(0);
1506 VolumeControl::Get()->SetExtAudioOutDescription(test_address, 1, descr);
1507 }
1508
1509 class VolumeControlCsis : public VolumeControlTest {
1510 protected:
1511 const RawAddress test_address_1 = GetTestAddress(0);
1512 const RawAddress test_address_2 = GetTestAddress(1);
1513 std::vector<RawAddress> csis_group = {test_address_1, test_address_2};
1514
1515 uint16_t conn_id_1 = 22;
1516 uint16_t conn_id_2 = 33;
1517 int group_id = 5;
1518
SetUp(void)1519 void SetUp(void) override {
1520 VolumeControlTest::SetUp();
1521
1522 ON_CALL(mock_csis_client_module_, Get())
1523 .WillByDefault(Return(&mock_csis_client_module_));
1524
1525 // Report working CSIS
1526 ON_CALL(mock_csis_client_module_, IsCsisClientRunning())
1527 .WillByDefault(Return(true));
1528
1529 ON_CALL(mock_csis_client_module_, GetDeviceList(_))
1530 .WillByDefault(Return(csis_group));
1531
1532 ON_CALL(mock_csis_client_module_, GetGroupId(_, _))
1533 .WillByDefault(Return(group_id));
1534
1535 SetSampleDatabase(conn_id_1);
1536 SetSampleDatabase(conn_id_2);
1537
1538 TestAppRegister();
1539 }
1540
TearDown(void)1541 void TearDown(void) override {
1542 TestAppUnregister();
1543 VolumeControlTest::TearDown();
1544 }
1545
GetNotificationEvent(uint16_t conn_id,const RawAddress & test_address,uint16_t handle,std::vector<uint8_t> & value)1546 void GetNotificationEvent(uint16_t conn_id, const RawAddress& test_address,
1547 uint16_t handle, std::vector<uint8_t>& value) {
1548 tBTA_GATTC_NOTIFY event_data = {
1549 .conn_id = conn_id,
1550 .bda = test_address,
1551 .handle = handle,
1552 .len = (uint8_t)value.size(),
1553 .is_notify = true,
1554 };
1555
1556 std::copy(value.begin(), value.end(), event_data.value);
1557 gatt_callback(BTA_GATTC_NOTIF_EVT, (tBTA_GATTC*)&event_data);
1558 }
1559 };
1560
TEST_F(VolumeControlCsis,test_set_volume)1561 TEST_F(VolumeControlCsis, test_set_volume) {
1562 TestConnect(test_address_1);
1563 GetConnectedEvent(test_address_1, conn_id_1);
1564 GetSearchCompleteEvent(conn_id_1);
1565 TestConnect(test_address_2);
1566 GetConnectedEvent(test_address_2, conn_id_2);
1567 GetSearchCompleteEvent(conn_id_2);
1568
1569 /* Set value for the group */
1570 EXPECT_CALL(gatt_queue,
1571 WriteCharacteristic(conn_id_1, 0x0024, _, GATT_WRITE, _, _));
1572 EXPECT_CALL(gatt_queue,
1573 WriteCharacteristic(conn_id_2, 0x0024, _, GATT_WRITE, _, _));
1574
1575 VolumeControl::Get()->SetVolume(group_id, 10);
1576
1577 /* Now inject notification and make sure callback is sent up to Java layer */
1578 EXPECT_CALL(*callbacks,
1579 OnGroupVolumeStateChanged(group_id, 0x03, true, false));
1580
1581 std::vector<uint8_t> value({0x03, 0x01, 0x02});
1582 GetNotificationEvent(conn_id_1, test_address_1, 0x0021, value);
1583 GetNotificationEvent(conn_id_2, test_address_2, 0x0021, value);
1584
1585 /* Verify exactly one operation with this exact value is queued for each
1586 * device */
1587 EXPECT_CALL(gatt_queue,
1588 WriteCharacteristic(conn_id_1, 0x0024, _, GATT_WRITE, _, _))
1589 .Times(1);
1590 EXPECT_CALL(gatt_queue,
1591 WriteCharacteristic(conn_id_2, 0x0024, _, GATT_WRITE, _, _))
1592 .Times(1);
1593 VolumeControl::Get()->SetVolume(test_address_1, 20);
1594 VolumeControl::Get()->SetVolume(test_address_2, 20);
1595 VolumeControl::Get()->SetVolume(test_address_1, 20);
1596 VolumeControl::Get()->SetVolume(test_address_2, 20);
1597
1598 std::vector<uint8_t> value2({20, 0x00, 0x03});
1599 GetNotificationEvent(conn_id_1, test_address_1, 0x0021, value2);
1600 GetNotificationEvent(conn_id_2, test_address_2, 0x0021, value2);
1601 }
1602
TEST_F(VolumeControlCsis,test_set_volume_device_not_ready)1603 TEST_F(VolumeControlCsis, test_set_volume_device_not_ready) {
1604 /* Make sure we did not get responds to the initial reads,
1605 * so that the device was not marked as ready yet.
1606 */
1607 do_not_respond_to_reads = true;
1608
1609 TestConnect(test_address_1);
1610 GetConnectedEvent(test_address_1, conn_id_1);
1611 GetSearchCompleteEvent(conn_id_1);
1612 TestConnect(test_address_2);
1613 GetConnectedEvent(test_address_2, conn_id_2);
1614 GetSearchCompleteEvent(conn_id_2);
1615
1616 /* Set value for the group */
1617 EXPECT_CALL(gatt_queue,
1618 WriteCharacteristic(conn_id_1, 0x0024, _, GATT_WRITE, _, _))
1619 .Times(0);
1620 EXPECT_CALL(gatt_queue,
1621 WriteCharacteristic(conn_id_2, 0x0024, _, GATT_WRITE, _, _))
1622 .Times(0);
1623
1624 VolumeControl::Get()->SetVolume(group_id, 10);
1625 }
1626
TEST_F(VolumeControlCsis,autonomus_test_set_volume)1627 TEST_F(VolumeControlCsis, autonomus_test_set_volume) {
1628 TestConnect(test_address_1);
1629 GetConnectedEvent(test_address_1, conn_id_1);
1630 GetSearchCompleteEvent(conn_id_1);
1631 TestConnect(test_address_2);
1632 GetConnectedEvent(test_address_2, conn_id_2);
1633 GetSearchCompleteEvent(conn_id_2);
1634
1635 /* Now inject notification and make sure callback is sent up to Java layer */
1636 EXPECT_CALL(*callbacks,
1637 OnGroupVolumeStateChanged(group_id, 0x03, false, true));
1638
1639 std::vector<uint8_t> value({0x03, 0x00, 0x02});
1640 GetNotificationEvent(conn_id_1, test_address_1, 0x0021, value);
1641 GetNotificationEvent(conn_id_2, test_address_2, 0x0021, value);
1642 }
1643
TEST_F(VolumeControlCsis,autonomus_single_device_test_set_volume)1644 TEST_F(VolumeControlCsis, autonomus_single_device_test_set_volume) {
1645 TestConnect(test_address_1);
1646 GetConnectedEvent(test_address_1, conn_id_1);
1647 GetSearchCompleteEvent(conn_id_1);
1648 TestConnect(test_address_2);
1649 GetConnectedEvent(test_address_2, conn_id_2);
1650 GetSearchCompleteEvent(conn_id_2);
1651
1652 /* Disconnect one device. */
1653 EXPECT_CALL(*callbacks,
1654 OnConnectionState(ConnectionState::DISCONNECTED, test_address_1));
1655 GetDisconnectedEvent(test_address_1, conn_id_1);
1656
1657 /* Now inject notification and make sure callback is sent up to Java layer */
1658 EXPECT_CALL(*callbacks,
1659 OnGroupVolumeStateChanged(group_id, 0x03, false, true));
1660
1661 std::vector<uint8_t> value({0x03, 0x00, 0x02});
1662 GetNotificationEvent(conn_id_2, test_address_2, 0x0021, value);
1663 }
1664
1665 } // namespace
1666 } // namespace internal
1667 } // namespace vc
1668 } // namespace bluetooth
1669