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 "bta/vc/devices.h"
19 
20 #include <com_android_bluetooth_flags.h>
21 #include <gmock/gmock.h>
22 #include <gtest/gtest.h>
23 #include <log/log.h>
24 
25 #include <list>
26 #include <map>
27 
28 #include "bta/test/common/bta_gatt_api_mock.h"
29 #include "bta/test/common/bta_gatt_queue_mock.h"
30 #include "bta/test/common/btm_api_mock.h"
31 #include "gatt/database_builder.h"
32 #include "stack/include/bt_uuid16.h"
33 #include "types/bluetooth/uuid.h"
34 #include "types/raw_address.h"
35 
36 // TODO(b/369381361) Enfore -Wmissing-prototypes
37 #pragma GCC diagnostic ignored "-Wmissing-prototypes"
38 
39 namespace bluetooth {
40 namespace vc {
41 namespace internal {
42 
43 using ::testing::_;
44 using ::testing::DoAll;
45 using ::testing::Invoke;
46 using ::testing::Mock;
47 using ::testing::NiceMock;
48 using ::testing::Return;
49 using ::testing::SaveArg;
50 using ::testing::SetArgPointee;
51 using ::testing::Test;
52 
GetTestAddress(int index)53 RawAddress GetTestAddress(int index) {
54   EXPECT_LT(index, UINT8_MAX);
55   RawAddress result = {{0xC0, 0xDE, 0xC0, 0xDE, 0x00, static_cast<uint8_t>(index)}};
56   return result;
57 }
58 
59 class VolumeControlDevicesTest : public ::testing::Test {
60 protected:
SetUp()61   void SetUp() override {
62     com::android::bluetooth::flags::provider_->leaudio_add_aics_support(true);
63     __android_log_set_minimum_priority(ANDROID_LOG_VERBOSE);
64     devices_ = new VolumeControlDevices();
65     gatt::SetMockBtaGattInterface(&gatt_interface);
66     gatt::SetMockBtaGattQueue(&gatt_queue);
67   }
68 
TearDown()69   void TearDown() override {
70     com::android::bluetooth::flags::provider_->reset_flags();
71 
72     gatt::SetMockBtaGattQueue(nullptr);
73     gatt::SetMockBtaGattInterface(nullptr);
74     delete devices_;
75   }
76 
77   VolumeControlDevices* devices_ = nullptr;
78   NiceMock<gatt::MockBtaGattInterface> gatt_interface;
79   NiceMock<gatt::MockBtaGattQueue> gatt_queue;
80 };
81 
TEST_F(VolumeControlDevicesTest,test_add)82 TEST_F(VolumeControlDevicesTest, test_add) {
83   RawAddress test_address_0 = GetTestAddress(0);
84   ASSERT_EQ((size_t)0, devices_->Size());
85   devices_->Add(test_address_0, true);
86   ASSERT_EQ((size_t)1, devices_->Size());
87 }
88 
TEST_F(VolumeControlDevicesTest,test_add_twice)89 TEST_F(VolumeControlDevicesTest, test_add_twice) {
90   RawAddress test_address_0 = GetTestAddress(0);
91   ASSERT_EQ((size_t)0, devices_->Size());
92   devices_->Add(test_address_0, true);
93   devices_->Add(test_address_0, true);
94   ASSERT_EQ((size_t)1, devices_->Size());
95 }
96 
TEST_F(VolumeControlDevicesTest,test_remove)97 TEST_F(VolumeControlDevicesTest, test_remove) {
98   RawAddress test_address_0 = GetTestAddress(0);
99   RawAddress test_address_1 = GetTestAddress(1);
100   devices_->Add(test_address_0, true);
101   devices_->Add(test_address_1, true);
102   ASSERT_EQ((size_t)2, devices_->Size());
103   devices_->Remove(test_address_0);
104   ASSERT_EQ((size_t)1, devices_->Size());
105 }
106 
TEST_F(VolumeControlDevicesTest,test_clear)107 TEST_F(VolumeControlDevicesTest, test_clear) {
108   RawAddress test_address_0 = GetTestAddress(0);
109   ASSERT_EQ((size_t)0, devices_->Size());
110   devices_->Add(test_address_0, true);
111   ASSERT_EQ((size_t)1, devices_->Size());
112   devices_->Clear();
113   ASSERT_EQ((size_t)0, devices_->Size());
114 }
115 
TEST_F(VolumeControlDevicesTest,test_find_by_address)116 TEST_F(VolumeControlDevicesTest, test_find_by_address) {
117   RawAddress test_address_0 = GetTestAddress(0);
118   RawAddress test_address_1 = GetTestAddress(1);
119   RawAddress test_address_2 = GetTestAddress(2);
120   devices_->Add(test_address_0, true);
121   devices_->Add(test_address_1, false);
122   devices_->Add(test_address_2, true);
123   VolumeControlDevice* device = devices_->FindByAddress(test_address_1);
124   ASSERT_NE(nullptr, device);
125   ASSERT_EQ(test_address_1, device->address);
126 }
127 
TEST_F(VolumeControlDevicesTest,test_find_by_conn_id)128 TEST_F(VolumeControlDevicesTest, test_find_by_conn_id) {
129   RawAddress test_address_0 = GetTestAddress(0);
130   devices_->Add(test_address_0, true);
131   VolumeControlDevice* test_device = devices_->FindByAddress(test_address_0);
132   test_device->connection_id = 0x0005;
133   ASSERT_NE(nullptr, devices_->FindByConnId(test_device->connection_id));
134 }
135 
TEST_F(VolumeControlDevicesTest,test_disconnect)136 TEST_F(VolumeControlDevicesTest, test_disconnect) {
137   RawAddress test_address_0 = GetTestAddress(0);
138   RawAddress test_address_1 = GetTestAddress(1);
139   devices_->Add(test_address_0, true);
140   devices_->Add(test_address_1, true);
141   VolumeControlDevice* test_device_0 = devices_->FindByAddress(test_address_0);
142   test_device_0->connection_id = 0x0005;
143   tGATT_IF gatt_if = 8;
144   EXPECT_CALL(gatt_interface, Close(test_device_0->connection_id));
145   devices_->Disconnect(gatt_if);
146 }
147 
TEST_F(VolumeControlDevicesTest,test_control_point_operation)148 TEST_F(VolumeControlDevicesTest, test_control_point_operation) {
149   uint8_t opcode = 50;
150   std::vector<RawAddress> devices;
151 
152   for (int i = 5; i > 0; i--) {
153     RawAddress test_address = GetTestAddress(i);
154     devices.push_back(test_address);
155     uint8_t change_counter = 10 * i;
156     uint16_t control_point_handle = 0x0020 + i;
157     uint16_t connection_id = i;
158     devices_->Add(test_address, true);
159     VolumeControlDevice* device = devices_->FindByAddress(test_address);
160     device->connection_id = connection_id;
161     device->change_counter = change_counter;
162     device->volume_control_point_handle = control_point_handle;
163     std::vector<uint8_t> data_expected({opcode, change_counter});
164 
165     EXPECT_CALL(gatt_queue, WriteCharacteristic(connection_id, control_point_handle, data_expected,
166                                                 GATT_WRITE, _, _));
167   }
168 
169   const std::vector<uint8_t>* arg = nullptr;
170   GATT_WRITE_OP_CB cb = nullptr;
171   void* cb_data = nullptr;
172   devices_->ControlPointOperation(devices, opcode, arg, cb, cb_data);
173 }
174 
TEST_F(VolumeControlDevicesTest,test_control_point_operation_args)175 TEST_F(VolumeControlDevicesTest, test_control_point_operation_args) {
176   uint8_t opcode = 60;
177   uint8_t arg_1 = 0x02;
178   uint8_t arg_2 = 0x05;
179   std::vector<RawAddress> devices;
180 
181   for (int i = 5; i > 0; i--) {
182     RawAddress test_address = GetTestAddress(i);
183     devices.push_back(test_address);
184     uint8_t change_counter = 10 * i;
185     uint16_t control_point_handle = 0x0020 + i;
186     uint16_t connection_id = i;
187     devices_->Add(test_address, true);
188     VolumeControlDevice* device = devices_->FindByAddress(test_address);
189     device->connection_id = connection_id;
190     device->change_counter = change_counter;
191     device->volume_control_point_handle = control_point_handle;
192     std::vector<uint8_t> data_expected({opcode, change_counter, arg_1, arg_2});
193 
194     EXPECT_CALL(gatt_queue, WriteCharacteristic(connection_id, control_point_handle, data_expected,
195                                                 GATT_WRITE, _, _));
196   }
197 
198   std::vector<uint8_t> arg({arg_1, arg_2});
199   GATT_WRITE_OP_CB cb = nullptr;
200   void* cb_data = nullptr;
201   devices_->ControlPointOperation(devices, opcode, &arg, cb, cb_data);
202 }
203 
TEST_F(VolumeControlDevicesTest,test_control_point_skip_not_connected)204 TEST_F(VolumeControlDevicesTest, test_control_point_skip_not_connected) {
205   RawAddress test_address = GetTestAddress(1);
206   devices_->Add(test_address, true);
207   VolumeControlDevice* device = devices_->FindByAddress(test_address);
208   device->connection_id = GATT_INVALID_CONN_ID;
209   uint16_t control_point_handle = 0x0020;
210   device->volume_control_point_handle = control_point_handle;
211 
212   EXPECT_CALL(gatt_queue, WriteCharacteristic(_, control_point_handle, _, _, _, _)).Times(0);
213 
214   uint8_t opcode = 5;
215   std::vector<RawAddress> devices = {test_address};
216   const std::vector<uint8_t>* arg = nullptr;
217   GATT_WRITE_OP_CB cb = nullptr;
218   void* cb_data = nullptr;
219   devices_->ControlPointOperation(devices, opcode, arg, cb, cb_data);
220 }
221 
222 class VolumeControlDeviceTest : public ::testing::Test {
223 protected:
SetUp()224   void SetUp() override {
225     com::android::bluetooth::flags::provider_->leaudio_add_aics_support(true);
226     __android_log_set_minimum_priority(ANDROID_LOG_VERBOSE);
227     device = new VolumeControlDevice(GetTestAddress(1), true);
228     gatt::SetMockBtaGattInterface(&gatt_interface);
229     gatt::SetMockBtaGattQueue(&gatt_queue);
230     bluetooth::manager::SetMockBtmInterface(&btm_interface);
231 
232     ON_CALL(gatt_interface, GetCharacteristic(_, _))
233             .WillByDefault(Invoke(
234                     [&](uint16_t /*conn_id*/, uint16_t handle) -> const gatt::Characteristic* {
235                       for (auto const& service : services) {
236                         for (auto const& characteristic : service.characteristics) {
237                           if (characteristic.value_handle == handle) {
238                             return &characteristic;
239                           }
240                         }
241                       }
242 
243                       return nullptr;
244                     }));
245 
246     ON_CALL(gatt_interface, GetOwningService(_, _))
247             .WillByDefault(
248                     Invoke([&](uint16_t /*conn_id*/, uint16_t handle) -> const gatt::Service* {
249                       for (auto const& service : services) {
250                         if (service.handle <= handle && service.end_handle >= handle) {
251                           return &service;
252                         }
253                       }
254 
255                       return nullptr;
256                     }));
257 
258     ON_CALL(gatt_interface, GetServices(_)).WillByDefault(Return(&services));
259 
260     ON_CALL(gatt_interface, RegisterForNotifications(_, _, _))
261             .WillByDefault(DoAll(Return(GATT_SUCCESS)));
262   }
263 
TearDown()264   void TearDown() override {
265     com::android::bluetooth::flags::provider_->reset_flags();
266     bluetooth::manager::SetMockBtmInterface(nullptr);
267     gatt::SetMockBtaGattQueue(nullptr);
268     gatt::SetMockBtaGattInterface(nullptr);
269     delete device;
270   }
271 
272   /* sample database 1xVCS, 2xAICS, 2xVOCS */
SetSampleDatabase1(void)273   void SetSampleDatabase1(void) {
274     gatt::DatabaseBuilder builder;
275     builder.AddService(0x0001, 0x0017, kVolumeControlUuid, true);
276     builder.AddIncludedService(0x0002, kVolumeAudioInputUuid, 0x0020, 0x002e);
277     builder.AddIncludedService(0x0003, kVolumeAudioInputUuid, 0x0040, 0x004f);
278     builder.AddIncludedService(0x0004, kVolumeOffsetUuid, 0x0060, 0x0069);
279     builder.AddIncludedService(0x0005, kVolumeOffsetUuid, 0x0080, 0x008b);
280     builder.AddCharacteristic(0x0010, 0x0011, kVolumeControlStateUuid,
281                               GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_NOTIFY);
282     builder.AddDescriptor(0x0012, Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
283     builder.AddCharacteristic(0x0013, 0x0014, kVolumeControlPointUuid, GATT_CHAR_PROP_BIT_WRITE);
284     builder.AddCharacteristic(0x0015, 0x0016, kVolumeFlagsUuid,
285                               GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_NOTIFY);
286     builder.AddDescriptor(0x0017, Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
287 
288     // First AICS
289     builder.AddService(0x0020, 0x002e, kVolumeAudioInputUuid, false);
290     builder.AddCharacteristic(0x0021, 0x0022, kVolumeAudioInputStateUuid, GATT_CHAR_PROP_BIT_READ);
291     builder.AddDescriptor(0x0023, Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
292     builder.AddCharacteristic(0x0024, 0x0025, kVolumeAudioInputGainSettingPropertiesUuid,
293                               GATT_CHAR_PROP_BIT_READ);
294     builder.AddCharacteristic(0x0026, 0x0027, kVolumeAudioInputTypeUuid, GATT_CHAR_PROP_BIT_READ);
295     builder.AddCharacteristic(0x0028, 0x0029, kVolumeAudioInputStatusUuid,
296                               GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_NOTIFY);
297     builder.AddDescriptor(0x002a, Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
298     builder.AddCharacteristic(0x002b, 0x002c, kVolumeAudioInputControlPointUuid,
299                               GATT_CHAR_PROP_BIT_WRITE);
300     builder.AddCharacteristic(0x002d, 0x002e, kVolumeAudioInputDescriptionUuid,
301                               GATT_CHAR_PROP_BIT_READ);
302 
303     // Second AICS
304     builder.AddService(0x0040, 0x004f, kVolumeAudioInputUuid, false);
305     builder.AddCharacteristic(0x0041, 0x0042, kVolumeAudioInputStateUuid,
306                               GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_NOTIFY);
307     builder.AddDescriptor(0x0043, Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
308     builder.AddCharacteristic(0x0044, 0x0045, kVolumeAudioInputGainSettingPropertiesUuid,
309                               GATT_CHAR_PROP_BIT_READ);
310     builder.AddCharacteristic(0x0046, 0x0047, kVolumeAudioInputTypeUuid, GATT_CHAR_PROP_BIT_READ);
311     builder.AddCharacteristic(0x0048, 0x0049, kVolumeAudioInputStatusUuid,
312                               GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_NOTIFY);
313     builder.AddDescriptor(0x004a, Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
314     builder.AddCharacteristic(0x004b, 0x004c, kVolumeAudioInputControlPointUuid,
315                               GATT_CHAR_PROP_BIT_WRITE);
316     builder.AddCharacteristic(
317             0x004d, 0x004e, kVolumeAudioInputDescriptionUuid,
318             GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_WRITE_NR | GATT_CHAR_PROP_BIT_NOTIFY);
319     builder.AddDescriptor(0x004f, Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
320 
321     // First VOCS
322     builder.AddService(0x0060, 0x0069, kVolumeOffsetUuid, false);
323     builder.AddCharacteristic(0x0061, 0x0062, kVolumeOffsetStateUuid,
324                               GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_NOTIFY);
325     builder.AddDescriptor(0x0063, Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
326     builder.AddCharacteristic(0x0064, 0x0065, kVolumeOffsetLocationUuid, GATT_CHAR_PROP_BIT_READ);
327     builder.AddCharacteristic(0x0066, 0x0067, kVolumeOffsetControlPointUuid,
328                               GATT_CHAR_PROP_BIT_WRITE);
329     builder.AddCharacteristic(0x0068, 0x0069, kVolumeOffsetOutputDescriptionUuid,
330                               GATT_CHAR_PROP_BIT_READ);
331 
332     // Second VOCS
333     builder.AddService(0x0080, 0x008b, kVolumeOffsetUuid, false);
334     builder.AddCharacteristic(0x0081, 0x0082, kVolumeOffsetStateUuid,
335                               GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_NOTIFY);
336     builder.AddDescriptor(0x0083, Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
337     builder.AddCharacteristic(
338             0x0084, 0x0085, kVolumeOffsetLocationUuid,
339             GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_WRITE_NR | GATT_CHAR_PROP_BIT_NOTIFY);
340     builder.AddDescriptor(0x0086, Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
341     builder.AddCharacteristic(0x0087, 0x0088, kVolumeOffsetControlPointUuid,
342                               GATT_CHAR_PROP_BIT_WRITE);
343     builder.AddCharacteristic(
344             0x0089, 0x008a, kVolumeOffsetOutputDescriptionUuid,
345             GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_WRITE_NR | GATT_CHAR_PROP_BIT_NOTIFY);
346     builder.AddDescriptor(0x008b, Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
347     builder.AddService(0x00a0, 0x00a3, Uuid::From16Bit(UUID_SERVCLASS_GATT_SERVER), true);
348     builder.AddCharacteristic(0x00a1, 0x00a2, Uuid::From16Bit(GATT_UUID_GATT_SRV_CHGD),
349                               GATT_CHAR_PROP_BIT_NOTIFY);
350     builder.AddDescriptor(0x00a3, Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
351     services = builder.Build().Services();
352     ASSERT_EQ(true, device->UpdateHandles());
353   }
354 
355   /* sample database no VCS */
SetSampleDatabase2(void)356   void SetSampleDatabase2(void) {
357     gatt::DatabaseBuilder builder;
358     builder.AddService(0x0001, 0x0003, Uuid::From16Bit(0x1800), true);
359     builder.AddCharacteristic(0x0002, 0x0003, Uuid::From16Bit(0x2a00), GATT_CHAR_PROP_BIT_READ);
360     services = builder.Build().Services();
361     ASSERT_EQ(false, device->UpdateHandles());
362   }
363 
364   VolumeControlDevice* device = nullptr;
365   NiceMock<gatt::MockBtaGattInterface> gatt_interface;
366   NiceMock<gatt::MockBtaGattQueue> gatt_queue;
367   NiceMock<bluetooth::manager::MockBtmInterface> btm_interface;
368   std::list<gatt::Service> services;
369 };
370 
TEST_F(VolumeControlDeviceTest,test_service_volume_control_not_found)371 TEST_F(VolumeControlDeviceTest, test_service_volume_control_not_found) {
372   SetSampleDatabase2();
373   ASSERT_EQ(false, device->HasHandles());
374 }
375 
TEST_F(VolumeControlDeviceTest,test_service_aics_incomplete)376 TEST_F(VolumeControlDeviceTest, test_service_aics_incomplete) {
377   gatt::DatabaseBuilder builder;
378   builder.AddService(0x0001, 0x000a, kVolumeControlUuid, true);
379   builder.AddIncludedService(0x0002, kVolumeAudioInputUuid, 0x000b, 0x0018);
380   builder.AddCharacteristic(0x0003, 0x0004, kVolumeControlStateUuid,
381                             GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_NOTIFY);
382   builder.AddDescriptor(0x0005, Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
383   builder.AddCharacteristic(0x0006, 0x0007, kVolumeControlPointUuid, GATT_CHAR_PROP_BIT_WRITE);
384   builder.AddCharacteristic(0x0008, 0x0009, kVolumeFlagsUuid,
385                             GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_NOTIFY);
386   builder.AddDescriptor(0x000a, Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
387   builder.AddService(0x000b, 0x0018, kVolumeAudioInputUuid, false);
388   builder.AddCharacteristic(0x000c, 0x000d, kVolumeAudioInputStateUuid,
389                             GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_NOTIFY);
390   builder.AddDescriptor(0x000e, Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
391   builder.AddCharacteristic(0x000f, 0x0010, kVolumeAudioInputGainSettingPropertiesUuid,
392                             GATT_CHAR_PROP_BIT_READ);
393   builder.AddCharacteristic(0x0011, 0x0012, kVolumeAudioInputTypeUuid, GATT_CHAR_PROP_BIT_READ);
394   builder.AddCharacteristic(0x0013, 0x0014, kVolumeAudioInputStatusUuid,
395                             GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_NOTIFY);
396   builder.AddDescriptor(0x0015, Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
397   /* no Audio Input Control Point characteristic */
398   builder.AddCharacteristic(0x0016, 0x0017, kVolumeAudioInputDescriptionUuid,
399                             GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_NOTIFY);
400   builder.AddDescriptor(0x0018, Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
401   services = builder.Build().Services();
402   ASSERT_EQ(true, device->UpdateHandles());
403   ASSERT_EQ((size_t)0, device->audio_inputs.Size());
404   ASSERT_EQ(0x0004, device->volume_state_handle);
405   ASSERT_EQ(0x0005, device->volume_state_ccc_handle);
406   ASSERT_EQ(0x0007, device->volume_control_point_handle);
407   ASSERT_EQ(0x0009, device->volume_flags_handle);
408   ASSERT_EQ(0x000a, device->volume_flags_ccc_handle);
409   ASSERT_EQ(true, device->HasHandles());
410 }
411 
TEST_F(VolumeControlDeviceTest,test_service_aics_found)412 TEST_F(VolumeControlDeviceTest, test_service_aics_found) {
413   gatt::DatabaseBuilder builder;
414   builder.AddService(0x0001, 0x000a, kVolumeControlUuid, true);
415   builder.AddIncludedService(0x0002, kVolumeAudioInputUuid, 0x000b, 0x001a);
416   builder.AddCharacteristic(0x0003, 0x0004, kVolumeControlStateUuid,
417                             GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_NOTIFY);
418   builder.AddDescriptor(0x0005, Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
419   builder.AddCharacteristic(0x0006, 0x0007, kVolumeControlPointUuid, GATT_CHAR_PROP_BIT_WRITE);
420   builder.AddCharacteristic(0x0008, 0x0009, kVolumeFlagsUuid,
421                             GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_NOTIFY);
422   builder.AddDescriptor(0x000a, Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
423   builder.AddService(0x000b, 0x001a, kVolumeAudioInputUuid, false);
424   builder.AddCharacteristic(0x000c, 0x000d, kVolumeAudioInputStateUuid,
425                             GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_NOTIFY);
426   builder.AddDescriptor(0x000e, Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
427   builder.AddCharacteristic(0x000f, 0x0010, kVolumeAudioInputGainSettingPropertiesUuid,
428                             GATT_CHAR_PROP_BIT_READ);
429   builder.AddCharacteristic(0x0011, 0x0012, kVolumeAudioInputTypeUuid, GATT_CHAR_PROP_BIT_READ);
430   builder.AddCharacteristic(0x0013, 0x0014, kVolumeAudioInputStatusUuid,
431                             GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_NOTIFY);
432   builder.AddDescriptor(0x0015, Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
433   builder.AddCharacteristic(0x0016, 0x0017, kVolumeAudioInputControlPointUuid,
434                             GATT_CHAR_PROP_BIT_WRITE);
435   builder.AddCharacteristic(0x0018, 0x0019, kVolumeAudioInputDescriptionUuid,
436                             GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_NOTIFY);
437   builder.AddDescriptor(0x001a, Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
438   services = builder.Build().Services();
439   ASSERT_EQ(true, device->UpdateHandles());
440   ASSERT_EQ((size_t)1, device->audio_inputs.Size());
441   VolumeAudioInput* input = device->audio_inputs.FindByServiceHandle(0x000b);
442   ASSERT_NE(nullptr, input);
443   ASSERT_EQ(0x000d, input->state_handle);
444   ASSERT_EQ(0x000e, input->state_ccc_handle);
445   ASSERT_EQ(0x0010, input->gain_setting_handle);
446   ASSERT_EQ(0x0012, input->type_handle);
447   ASSERT_EQ(0x0014, input->status_handle);
448   ASSERT_EQ(0x0015, input->status_ccc_handle);
449   ASSERT_EQ(0x0017, input->control_point_handle);
450   ASSERT_EQ(0x0019, input->description_handle);
451   ASSERT_EQ(0x001a, input->description_ccc_handle);
452   ASSERT_EQ(true, device->HasHandles());
453 }
454 
TEST_F(VolumeControlDeviceTest,test_service_volume_control_incomplete)455 TEST_F(VolumeControlDeviceTest, test_service_volume_control_incomplete) {
456   gatt::DatabaseBuilder builder;
457   builder.AddService(0x0001, 0x0006, kVolumeControlUuid, true);
458   builder.AddCharacteristic(0x0002, 0x0003, kVolumeControlStateUuid,
459                             GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_NOTIFY);
460   builder.AddDescriptor(0x0004, Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
461   builder.AddCharacteristic(0x0005, 0x0006, kVolumeControlPointUuid, GATT_CHAR_PROP_BIT_WRITE);
462   /* no Volume Control Flags characteristic */
463   services = builder.Build().Services();
464   ASSERT_EQ(false, device->UpdateHandles());
465   ASSERT_EQ(0x0000, device->volume_state_handle);
466   ASSERT_EQ(0x0000, device->volume_state_ccc_handle);
467   ASSERT_EQ(0x0000, device->volume_control_point_handle);
468   ASSERT_EQ(0x0000, device->volume_flags_handle);
469   ASSERT_EQ(0x0000, device->volume_flags_ccc_handle);
470   ASSERT_EQ(false, device->HasHandles());
471 }
472 
TEST_F(VolumeControlDeviceTest,test_service_vocs_incomplete)473 TEST_F(VolumeControlDeviceTest, test_service_vocs_incomplete) {
474   gatt::DatabaseBuilder builder;
475   builder.AddService(0x0001, 0x000a, kVolumeControlUuid, true);
476   builder.AddIncludedService(0x0002, kVolumeOffsetUuid, 0x000b, 0x0013);
477   builder.AddCharacteristic(0x0003, 0x0004, kVolumeControlStateUuid,
478                             GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_NOTIFY);
479   builder.AddDescriptor(0x0005, Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
480   builder.AddCharacteristic(0x0006, 0x0007, kVolumeControlPointUuid, GATT_CHAR_PROP_BIT_WRITE);
481   builder.AddCharacteristic(0x0008, 0x0009, kVolumeFlagsUuid,
482                             GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_NOTIFY);
483   builder.AddDescriptor(0x000a, Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
484   builder.AddService(0x000b, 0x0013, kVolumeOffsetUuid, false);
485   builder.AddCharacteristic(0x000c, 0x000d, kVolumeOffsetStateUuid,
486                             GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_NOTIFY);
487   builder.AddDescriptor(0x000e, Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
488   builder.AddCharacteristic(0x000f, 0x0010, kVolumeOffsetLocationUuid,
489                             GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_NOTIFY);
490   builder.AddDescriptor(0x0011, Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
491   builder.AddCharacteristic(0x0012, 0x0013, kVolumeOffsetControlPointUuid,
492                             GATT_CHAR_PROP_BIT_WRITE);
493   /* no Audio Output Description characteristic */
494   services = builder.Build().Services();
495   ASSERT_EQ(true, device->UpdateHandles());
496   ASSERT_EQ((size_t)0, device->audio_offsets.Size());
497   ASSERT_EQ(0x0004, device->volume_state_handle);
498   ASSERT_EQ(0x0005, device->volume_state_ccc_handle);
499   ASSERT_EQ(0x0007, device->volume_control_point_handle);
500   ASSERT_EQ(0x0009, device->volume_flags_handle);
501   ASSERT_EQ(0x000a, device->volume_flags_ccc_handle);
502   ASSERT_EQ(true, device->HasHandles());
503 }
504 
TEST_F(VolumeControlDeviceTest,test_service_vocs_found)505 TEST_F(VolumeControlDeviceTest, test_service_vocs_found) {
506   gatt::DatabaseBuilder builder;
507   builder.AddService(0x0001, 0x000a, kVolumeControlUuid, true);
508   builder.AddIncludedService(0x0002, kVolumeOffsetUuid, 0x000b, 0x0015);
509   builder.AddCharacteristic(0x0003, 0x0004, kVolumeControlStateUuid,
510                             GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_NOTIFY);
511   builder.AddDescriptor(0x0005, Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
512   builder.AddCharacteristic(0x0006, 0x0007, kVolumeControlPointUuid, GATT_CHAR_PROP_BIT_WRITE);
513   builder.AddCharacteristic(0x0008, 0x0009, kVolumeFlagsUuid,
514                             GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_NOTIFY);
515   builder.AddDescriptor(0x000a, Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
516   builder.AddService(0x000b, 0x0015, kVolumeOffsetUuid, false);
517   builder.AddCharacteristic(0x000c, 0x000d, kVolumeOffsetStateUuid,
518                             GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_NOTIFY);
519   builder.AddDescriptor(0x000e, Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
520   builder.AddCharacteristic(0x000f, 0x0010, kVolumeOffsetLocationUuid,
521                             GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_NOTIFY);
522   builder.AddDescriptor(0x0011, Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG));
523   builder.AddCharacteristic(0x0012, 0x0013, kVolumeOffsetControlPointUuid,
524                             GATT_CHAR_PROP_BIT_WRITE);
525   builder.AddCharacteristic(0x0014, 0x0015, kVolumeOffsetOutputDescriptionUuid,
526                             GATT_CHAR_PROP_BIT_READ);
527   services = builder.Build().Services();
528   ASSERT_EQ(true, device->UpdateHandles());
529   ASSERT_EQ((size_t)1, device->audio_offsets.Size());
530   VolumeOffset* offset = device->audio_offsets.FindByServiceHandle(0x000b);
531   ASSERT_NE(nullptr, offset);
532   ASSERT_EQ(0x000d, offset->state_handle);
533   ASSERT_EQ(0x000e, offset->state_ccc_handle);
534   ASSERT_EQ(0x0010, offset->audio_location_handle);
535   ASSERT_EQ(0x0011, offset->audio_location_ccc_handle);
536   ASSERT_EQ(0x0013, offset->control_point_handle);
537   ASSERT_EQ(0x0015, offset->audio_descr_handle);
538   ASSERT_EQ(0x0000, offset->audio_descr_ccc_handle);
539   ASSERT_EQ(true, device->HasHandles());
540 }
541 
TEST_F(VolumeControlDeviceTest,test_multiple_services_found)542 TEST_F(VolumeControlDeviceTest, test_multiple_services_found) {
543   SetSampleDatabase1();
544   ASSERT_EQ((size_t)2, device->audio_offsets.Size());
545   ASSERT_EQ((size_t)2, device->audio_inputs.Size());
546   VolumeAudioInput* input_1 = device->audio_inputs.FindById(0);
547   VolumeAudioInput* input_2 = device->audio_inputs.FindById(1);
548   ASSERT_NE(nullptr, input_1);
549   ASSERT_NE(nullptr, input_2);
550   ASSERT_NE(input_1->service_handle, input_2->service_handle);
551 
552   VolumeOffset* offset_1 = device->audio_offsets.FindById(1);
553   VolumeOffset* offset_2 = device->audio_offsets.FindById(2);
554   ASSERT_NE(nullptr, offset_1);
555   ASSERT_NE(nullptr, offset_2);
556   ASSERT_NE(offset_1->service_handle, offset_2->service_handle);
557 }
558 
TEST_F(VolumeControlDeviceTest,test_services_changed)559 TEST_F(VolumeControlDeviceTest, test_services_changed) {
560   SetSampleDatabase1();
561   ASSERT_NE((size_t)0, device->audio_offsets.Size());
562   ASSERT_NE((size_t)0, device->audio_inputs.Size());
563   ASSERT_NE(0, device->volume_state_handle);
564   ASSERT_NE(0, device->volume_control_point_handle);
565   ASSERT_NE(0, device->volume_flags_handle);
566   ASSERT_EQ(true, device->HasHandles());
567   SetSampleDatabase2();
568   ASSERT_EQ((size_t)0, device->audio_offsets.Size());
569   ASSERT_EQ((size_t)0, device->audio_inputs.Size());
570   ASSERT_EQ(0, device->volume_state_handle);
571   ASSERT_EQ(0, device->volume_control_point_handle);
572   ASSERT_EQ(0, device->volume_flags_handle);
573   ASSERT_EQ(false, device->HasHandles());
574 }
575 
TEST_F(VolumeControlDeviceTest,test_enqueue_initial_requests)576 TEST_F(VolumeControlDeviceTest, test_enqueue_initial_requests) {
577   SetSampleDatabase1();
578 
579   tGATT_IF gatt_if = 0x0001;
580   std::vector<uint8_t> register_for_notification_data({0x01, 0x00});
581 
582   std::map<uint16_t, uint16_t> expected_subscriptions{
583           {0x0011, 0x0012} /* volume control state */,
584           {0x0016, 0x0017} /* volume control flags */,
585           {0x0022, 0x0023} /* audio input state 1 */,
586           {0x0029, 0x002a} /* audio input status 1 */,
587           {0x0042, 0x0043} /* audio input state 2 */,
588           {0x0049, 0x004a} /* audio input status 2 */,
589           {0x004e, 0x004f} /* audio input descriptor 2 */,
590           {0x0062, 0x0063} /* volume offset state 1 */,
591           {0x0082, 0x0083} /* volume offset state 2 */,
592           {0x0085, 0x0086} /* volume offset location 2 */,
593           {0x008a, 0x008b} /* volume offset description 2 */};
594 
595   // Expected read for state and flags  Volume State
596   EXPECT_CALL(gatt_queue, ReadCharacteristic(_, 0x0011, _, _));
597   EXPECT_CALL(gatt_queue, ReadCharacteristic(_, 0x0016, _, _));
598 
599   for (auto const& handle_pair : expected_subscriptions) {
600     EXPECT_CALL(gatt_queue, WriteDescriptor(_, handle_pair.second, register_for_notification_data,
601                                             GATT_WRITE, _, _));
602     EXPECT_CALL(gatt_interface, RegisterForNotifications(gatt_if, _, handle_pair.first));
603   }
604 
605   auto chrc_read_cb = [](uint16_t /*conn_id*/, tGATT_STATUS /*status*/, uint16_t /*handle*/,
606                          uint16_t /*len*/, uint8_t* /*value*/, void* /*data*/) {};
607   auto cccd_write_cb = [](uint16_t /*conn_id*/, tGATT_STATUS /*status*/, uint16_t /*handle*/,
608                           uint16_t /*len*/, const uint8_t* /*value*/, void* /*data*/) {};
609   ASSERT_EQ(true, device->EnqueueInitialRequests(gatt_if, chrc_read_cb, cccd_write_cb));
610   Mock::VerifyAndClearExpectations(&gatt_queue);
611   Mock::VerifyAndClearExpectations(&gatt_interface);
612 }
613 
TEST_F(VolumeControlDeviceTest,test_device_ready)614 TEST_F(VolumeControlDeviceTest, test_device_ready) {
615   SetSampleDatabase1();
616 
617   // grab all the handles requested
618   std::vector<uint16_t> requested_handles;
619   ON_CALL(gatt_queue, WriteDescriptor(_, _, _, _, _, _))
620           .WillByDefault(Invoke(
621                   [&requested_handles](
622                           uint16_t /*conn_id*/, uint16_t handle, std::vector<uint8_t> /*value*/,
623                           tGATT_WRITE_TYPE /*write_type*/, GATT_WRITE_OP_CB /*cb*/,
624                           void* /*cb_data*/) -> void { requested_handles.push_back(handle); }));
625   ON_CALL(gatt_queue, ReadCharacteristic(_, _, _, _))
626           .WillByDefault(
627                   Invoke([&requested_handles](uint16_t /*conn_id*/, uint16_t handle,
628                                               GATT_READ_OP_CB /*cb*/, void* /*cb_data*/) -> void {
629                     requested_handles.push_back(handle);
630                   }));
631 
632   auto chrc_read_cb = [](uint16_t /*conn_id*/, tGATT_STATUS /*status*/, uint16_t /*handle*/,
633                          uint16_t /*len*/, uint8_t* /*value*/, void* /*data*/) {};
634   auto cccd_write_cb = [](uint16_t /*conn_id*/, tGATT_STATUS /*status*/, uint16_t /*handle*/,
635                           uint16_t /*len*/, const uint8_t* /*value*/, void* /*data*/) {};
636   ASSERT_EQ(true, device->EnqueueInitialRequests(0x0001, chrc_read_cb, cccd_write_cb));
637   ASSERT_NE((size_t)0, requested_handles.size());
638 
639   // indicate non-pending requests
640   ASSERT_EQ(false, device->device_ready);
641   device->VerifyReady(0xffff);
642 
643   for (uint16_t handle : requested_handles) {
644     ASSERT_EQ(false, device->device_ready);
645     device->VerifyReady(handle);
646   }
647 
648   ASSERT_EQ(true, device->device_ready);
649 }
650 
TEST_F(VolumeControlDeviceTest,test_enqueue_remaining_requests)651 TEST_F(VolumeControlDeviceTest, test_enqueue_remaining_requests) {
652   com::android::bluetooth::flags::provider_->le_ase_read_multiple_variable(false);
653 
654   SetSampleDatabase1();
655 
656   tGATT_IF gatt_if = 0x0001;
657 
658   std::vector<uint16_t> expected_to_read{
659           0x0022 /* audio input state 1 */,        0x0025 /* gain setting properties 1 */,
660           0x0027 /* audio input type 1 */,         0x0029 /* audio input status 1 */,
661           0x002e /* audio input description 1 */,  0x0042 /* audio input state 2 */,
662           0x0045 /* gain setting properties 2 */,  0x0047 /* audio input type 2 */,
663           0x0049 /* audio input status 2 */,       0x004e /* audio input description 2 */,
664           0x0062 /* audio output state 1 */,       0x0065 /* audio output location 1 */,
665           0x0069 /* audio output description 1 */, 0x0082 /* audio output state 1 */,
666           0x0085 /* audio output location 1 */,    0x008a /* audio output description 1 */};
667 
668   for (uint16_t handle : expected_to_read) {
669     EXPECT_CALL(gatt_queue, ReadCharacteristic(_, handle, _, _));
670   }
671 
672   EXPECT_CALL(gatt_queue, WriteDescriptor(_, _, _, GATT_WRITE, _, _)).Times(0);
673   EXPECT_CALL(gatt_interface, RegisterForNotifications(_, _, _)).Times(0);
674 
675   auto chrc_read_cb = [](uint16_t /*conn_id*/, tGATT_STATUS /*status*/, uint16_t /*handle*/,
676                          uint16_t /*len*/, uint8_t* /*value*/, void* /*data*/) {};
677   auto chrc_multi_read_cb = [](uint16_t /*conn_id*/, tGATT_STATUS /*status*/,
678                                tBTA_GATTC_MULTI& /*handles*/, uint16_t /*len*/, uint8_t* /*value*/,
679                                void* /*data*/) {};
680   auto cccd_write_cb = [](uint16_t /*conn_id*/, tGATT_STATUS /*status*/, uint16_t /*handle*/,
681                           uint16_t /*len*/, const uint8_t* /*value*/, void* /*data*/) {};
682   device->EnqueueRemainingRequests(gatt_if, chrc_read_cb, chrc_multi_read_cb, cccd_write_cb);
683   Mock::VerifyAndClearExpectations(&gatt_queue);
684   Mock::VerifyAndClearExpectations(&gatt_interface);
685 }
686 
TEST_F(VolumeControlDeviceTest,test_enqueue_remaining_requests_multiread)687 TEST_F(VolumeControlDeviceTest, test_enqueue_remaining_requests_multiread) {
688   com::android::bluetooth::flags::provider_->le_ase_read_multiple_variable(true);
689 
690   SetSampleDatabase1();
691 
692   tGATT_IF gatt_if = 0x0001;
693   std::vector<uint8_t> register_for_notification_data({0x01, 0x00});
694 
695   tBTA_GATTC_MULTI expected_to_read_part_1 = {
696           .num_attr = 10,
697           .handles = {0x0022 /* audio input state 1 */, 0x0025 /* gain setting properties 1 */,
698                       0x0027 /* audio input type 1 */, 0x0029 /* audio input status 1 */,
699                       0x002e /* audio input description 1 */, 0x0042 /* audio input state 2 */,
700                       0x0045 /* gain setting properties 2 */, 0x0047 /* audio input type 2 */,
701                       0x0049 /* audio input status 2 */, 0x004e /* audio input description 2 */},
702   };
703 
704   tBTA_GATTC_MULTI expected_to_read_part_2 = {
705           .num_attr = 6,
706           .handles = {0x0062 /* audio output state 1 */, 0x0065 /* audio output location 1 */,
707                       0x0069 /* audio output description 1 */, 0x0082 /* audio output state 1 */,
708                       0x0085 /* audio output location 1 */,
709                       0x008a /* audio output description 1 */},
710   };
711 
712   tBTA_GATTC_MULTI received_to_read_part_1{};
713   tBTA_GATTC_MULTI received_to_read_part_2{};
714 
715   {
716     testing::InSequence s;
717 
718     EXPECT_CALL(gatt_queue, ReadMultiCharacteristic(_, _, _, _))
719             .WillOnce(SaveArg<1>(&received_to_read_part_1));
720     EXPECT_CALL(gatt_queue, ReadMultiCharacteristic(_, _, _, _))
721             .WillOnce(SaveArg<1>(&received_to_read_part_2));
722   }
723   EXPECT_CALL(gatt_queue, WriteDescriptor(_, _, _, GATT_WRITE, _, _)).Times(0);
724   EXPECT_CALL(gatt_interface, RegisterForNotifications(_, _, _)).Times(0);
725 
726   auto chrc_read_cb = [](uint16_t /*conn_id*/, tGATT_STATUS /*status*/, uint16_t /*handle*/,
727                          uint16_t /*len*/, uint8_t* /*value*/, void* /*data*/) {};
728   auto chrc_multi_read_cb = [](uint16_t /*conn_id*/, tGATT_STATUS /*status*/,
729                                tBTA_GATTC_MULTI& /*handles*/, uint16_t /*len*/, uint8_t* /*value*/,
730                                void* /*data*/) {};
731   auto cccd_write_cb = [](uint16_t /*conn_id*/, tGATT_STATUS /*status*/, uint16_t /*handle*/,
732                           uint16_t /*len*/, const uint8_t* /*value*/, void* /*data*/) {};
733 
734   device->EnqueueRemainingRequests(gatt_if, chrc_read_cb, chrc_multi_read_cb, cccd_write_cb);
735 
736   Mock::VerifyAndClearExpectations(&gatt_queue);
737   Mock::VerifyAndClearExpectations(&gatt_interface);
738 
739   ASSERT_EQ(expected_to_read_part_1.num_attr, received_to_read_part_1.num_attr);
740   ASSERT_EQ(expected_to_read_part_2.num_attr, received_to_read_part_2.num_attr);
741 }
742 
TEST_F(VolumeControlDeviceTest,test_check_link_encrypted)743 TEST_F(VolumeControlDeviceTest, test_check_link_encrypted) {
744   ON_CALL(btm_interface, BTM_IsEncrypted(_, _)).WillByDefault(DoAll(Return(true)));
745   ASSERT_EQ(true, device->IsEncryptionEnabled());
746 
747   ON_CALL(btm_interface, BTM_IsEncrypted(_, _)).WillByDefault(DoAll(Return(false)));
748   ASSERT_NE(true, device->IsEncryptionEnabled());
749 }
750 
TEST_F(VolumeControlDeviceTest,test_control_point_operation)751 TEST_F(VolumeControlDeviceTest, test_control_point_operation) {
752   GATT_WRITE_OP_CB write_cb = [](uint16_t /*conn_id*/, tGATT_STATUS /*status*/, uint16_t /*handle*/,
753                                  uint16_t /*len*/, const uint8_t* /*value*/, void* /*data*/) {};
754   SetSampleDatabase1();
755   device->change_counter = 0x01;
756   std::vector<uint8_t> expected_data({0x03, 0x01});
757   EXPECT_CALL(gatt_queue,
758               WriteCharacteristic(_, 0x0014, expected_data, GATT_WRITE, write_cb, nullptr));
759   device->ControlPointOperation(0x03, nullptr, write_cb, nullptr);
760 }
761 
TEST_F(VolumeControlDeviceTest,test_control_point_operation_arg)762 TEST_F(VolumeControlDeviceTest, test_control_point_operation_arg) {
763   GATT_WRITE_OP_CB write_cb = [](uint16_t /*conn_id*/, tGATT_STATUS /*status*/, uint16_t /*handle*/,
764                                  uint16_t /*len*/, const uint8_t* /*value*/, void* /*data*/) {};
765   SetSampleDatabase1();
766   device->change_counter = 0x55;
767   std::vector<uint8_t> expected_data({0x01, 0x55, 0x02, 0x03});
768   EXPECT_CALL(gatt_queue,
769               WriteCharacteristic(_, 0x0014, expected_data, GATT_WRITE, write_cb, nullptr));
770   std::vector<uint8_t> arg({0x02, 0x03});
771   device->ControlPointOperation(0x01, &arg, write_cb, nullptr);
772 }
773 
TEST_F(VolumeControlDeviceTest,test_get_ext_audio_out_volume_offset)774 TEST_F(VolumeControlDeviceTest, test_get_ext_audio_out_volume_offset) {
775   GATT_READ_OP_CB read_cb = [](uint16_t /*conn_id*/, tGATT_STATUS /*status*/, uint16_t /*handle*/,
776                                uint16_t /*len*/, uint8_t* /*value*/, void* /*data*/) {};
777   SetSampleDatabase1();
778   EXPECT_CALL(gatt_queue, ReadCharacteristic(_, 0x0062, read_cb, nullptr));
779   device->GetExtAudioOutVolumeOffset(1, read_cb, nullptr);
780 }
781 
TEST_F(VolumeControlDeviceTest,test_get_ext_audio_out_location)782 TEST_F(VolumeControlDeviceTest, test_get_ext_audio_out_location) {
783   GATT_READ_OP_CB read_cb = [](uint16_t /*conn_id*/, tGATT_STATUS /*status*/, uint16_t /*handle*/,
784                                uint16_t /*len*/, uint8_t* /*value*/, void* /*data*/) {};
785   SetSampleDatabase1();
786   EXPECT_CALL(gatt_queue, ReadCharacteristic(_, 0x0085, read_cb, nullptr));
787   device->GetExtAudioOutLocation(2, read_cb, nullptr);
788 }
789 
TEST_F(VolumeControlDeviceTest,test_set_ext_audio_out_location)790 TEST_F(VolumeControlDeviceTest, test_set_ext_audio_out_location) {
791   SetSampleDatabase1();
792   std::vector<uint8_t> expected_data({0x44, 0x33, 0x22, 0x11});
793   EXPECT_CALL(gatt_queue,
794               WriteCharacteristic(_, 0x0085, expected_data, GATT_WRITE_NO_RSP, nullptr, nullptr));
795   device->SetExtAudioOutLocation(2, 0x11223344);
796 }
797 
TEST_F(VolumeControlDeviceTest,test_set_ext_audio_out_location_non_writable)798 TEST_F(VolumeControlDeviceTest, test_set_ext_audio_out_location_non_writable) {
799   SetSampleDatabase1();
800   EXPECT_CALL(gatt_queue, WriteCharacteristic(_, _, _, _, _, _)).Times(0);
801   device->SetExtAudioOutLocation(1, 0x11223344);
802 }
803 
TEST_F(VolumeControlDeviceTest,test_get_ext_audio_out_description)804 TEST_F(VolumeControlDeviceTest, test_get_ext_audio_out_description) {
805   GATT_READ_OP_CB read_cb = [](uint16_t /*conn_id*/, tGATT_STATUS /*status*/, uint16_t /*handle*/,
806                                uint16_t /*len*/, uint8_t* /*value*/, void* /*data*/) {};
807   SetSampleDatabase1();
808   EXPECT_CALL(gatt_queue, ReadCharacteristic(_, 0x008a, read_cb, nullptr));
809   device->GetExtAudioOutDescription(2, read_cb, nullptr);
810 }
811 
TEST_F(VolumeControlDeviceTest,test_set_ext_audio_out_description)812 TEST_F(VolumeControlDeviceTest, test_set_ext_audio_out_description) {
813   SetSampleDatabase1();
814   std::string descr = "right front";
815   std::vector<uint8_t> expected_data(descr.begin(), descr.end());
816   EXPECT_CALL(gatt_queue,
817               WriteCharacteristic(_, 0x008a, expected_data, GATT_WRITE_NO_RSP, nullptr, nullptr));
818   device->SetExtAudioOutDescription(2, descr);
819 }
820 
TEST_F(VolumeControlDeviceTest,test_set_ext_audio_out_description_non_writable)821 TEST_F(VolumeControlDeviceTest, test_set_ext_audio_out_description_non_writable) {
822   SetSampleDatabase1();
823   std::string descr = "left front";
824   EXPECT_CALL(gatt_queue, WriteCharacteristic(_, _, _, _, _, _)).Times(0);
825   device->SetExtAudioOutDescription(1, descr);
826 }
827 
TEST_F(VolumeControlDeviceTest,test_ext_audio_out_control_point_operation)828 TEST_F(VolumeControlDeviceTest, test_ext_audio_out_control_point_operation) {
829   GATT_WRITE_OP_CB write_cb = [](uint16_t /*conn_id*/, tGATT_STATUS /*status*/, uint16_t /*handle*/,
830                                  uint16_t /*len*/, const uint8_t* /*value*/, void* /*data*/) {};
831   SetSampleDatabase1();
832   VolumeOffset* offset = device->audio_offsets.FindById(1);
833   ASSERT_NE(nullptr, offset);
834   offset->change_counter = 0x09;
835   std::vector<uint8_t> expected_data({0x0b, 0x09});
836   EXPECT_CALL(gatt_queue,
837               WriteCharacteristic(_, 0x0067, expected_data, GATT_WRITE, write_cb, nullptr));
838   device->ExtAudioOutControlPointOperation(1, 0x0b, nullptr, write_cb, nullptr);
839 }
840 
TEST_F(VolumeControlDeviceTest,test_ext_audio_out_control_point_operation_arg)841 TEST_F(VolumeControlDeviceTest, test_ext_audio_out_control_point_operation_arg) {
842   GATT_WRITE_OP_CB write_cb = [](uint16_t /*conn_id*/, tGATT_STATUS /*status*/, uint16_t /*handle*/,
843                                  uint16_t /*len*/, const uint8_t* /*value*/, void* /*data*/) {};
844   SetSampleDatabase1();
845   VolumeOffset* offset = device->audio_offsets.FindById(1);
846   ASSERT_NE(nullptr, offset);
847   offset->change_counter = 0x09;
848   std::vector<uint8_t> expected_data({0x0b, 0x09, 0x01, 0x02, 0x03, 0x04});
849   std::vector<uint8_t> arg({0x01, 0x02, 0x03, 0x04});
850   EXPECT_CALL(gatt_queue,
851               WriteCharacteristic(_, 0x0067, expected_data, GATT_WRITE, write_cb, nullptr));
852   device->ExtAudioOutControlPointOperation(1, 0x0b, &arg, write_cb, nullptr);
853 }
854 
TEST_F(VolumeControlDeviceTest,test_get_ext_audio_in_state)855 TEST_F(VolumeControlDeviceTest, test_get_ext_audio_in_state) {
856   GATT_READ_OP_CB read_cb = [](uint16_t /*conn_id*/, tGATT_STATUS /*status*/, uint16_t /*handle*/,
857                                uint16_t /*len*/, uint8_t* /*value*/, void* /*data*/) {};
858   SetSampleDatabase1();
859   EXPECT_CALL(gatt_queue, ReadCharacteristic(_, 0x0022, read_cb, nullptr));
860   device->GetExtAudioInState(0, read_cb, nullptr);
861 }
862 
TEST_F(VolumeControlDeviceTest,test_get_ext_audio_in_status)863 TEST_F(VolumeControlDeviceTest, test_get_ext_audio_in_status) {
864   GATT_READ_OP_CB read_cb = [](uint16_t /*conn_id*/, tGATT_STATUS /*status*/, uint16_t /*handle*/,
865                                uint16_t /*len*/, uint8_t* /*value*/, void* /*data*/) {};
866   SetSampleDatabase1();
867   EXPECT_CALL(gatt_queue, ReadCharacteristic(_, 0x0049, read_cb, nullptr));
868   device->GetExtAudioInStatus(1, read_cb, nullptr);
869 }
870 
TEST_F(VolumeControlDeviceTest,test_get_ext_audio_in_gain_props)871 TEST_F(VolumeControlDeviceTest, test_get_ext_audio_in_gain_props) {
872   GATT_READ_OP_CB read_cb = [](uint16_t /*conn_id*/, tGATT_STATUS /*status*/, uint16_t /*handle*/,
873                                uint16_t /*len*/, uint8_t* /*value*/, void* /*data*/) {};
874   SetSampleDatabase1();
875   EXPECT_CALL(gatt_queue, ReadCharacteristic(_, 0x0025, read_cb, nullptr));
876   device->GetExtAudioInGainProps(0, read_cb, nullptr);
877 }
878 
TEST_F(VolumeControlDeviceTest,test_get_ext_audio_in_description)879 TEST_F(VolumeControlDeviceTest, test_get_ext_audio_in_description) {
880   GATT_READ_OP_CB read_cb = [](uint16_t /*conn_id*/, tGATT_STATUS /*status*/, uint16_t /*handle*/,
881                                uint16_t /*len*/, uint8_t* /*value*/, void* /*data*/) {};
882   SetSampleDatabase1();
883   EXPECT_CALL(gatt_queue, ReadCharacteristic(_, 0x002e, read_cb, nullptr));
884   device->GetExtAudioInDescription(0, read_cb, nullptr);
885 }
886 
TEST_F(VolumeControlDeviceTest,test_set_ext_audio_in_description)887 TEST_F(VolumeControlDeviceTest, test_set_ext_audio_in_description) {
888   SetSampleDatabase1();
889   std::string descr = "HDMI";
890   std::vector<uint8_t> expected_data(descr.begin(), descr.end());
891   EXPECT_CALL(gatt_queue,
892               WriteCharacteristic(_, 0x004e, expected_data, GATT_WRITE_NO_RSP, nullptr, nullptr));
893   device->SetExtAudioInDescription(1, descr);
894 }
895 
TEST_F(VolumeControlDeviceTest,test_set_ext_audio_in_description_non_writable)896 TEST_F(VolumeControlDeviceTest, test_set_ext_audio_in_description_non_writable) {
897   SetSampleDatabase1();
898   std::string descr = "AUX";
899   std::vector<uint8_t> expected_data(descr.begin(), descr.end());
900   EXPECT_CALL(gatt_queue, WriteCharacteristic(_, _, _, _, _, _)).Times(0);
901   device->SetExtAudioInDescription(0, descr);
902 }
903 
TEST_F(VolumeControlDeviceTest,test_ext_audio_in_control_point_operation)904 TEST_F(VolumeControlDeviceTest, test_ext_audio_in_control_point_operation) {
905   GATT_WRITE_OP_CB write_cb = [](uint16_t /*conn_id*/, tGATT_STATUS /*status*/, uint16_t /*handle*/,
906                                  uint16_t /*len*/, const uint8_t* /*value*/, void* /*data*/) {};
907   SetSampleDatabase1();
908   VolumeAudioInput* input = device->audio_inputs.FindById(1);
909   ASSERT_NE(nullptr, input);
910   input->change_counter = 0x11;
911   std::vector<uint8_t> expected_data({0x0c, 0x11});
912   EXPECT_CALL(gatt_queue,
913               WriteCharacteristic(_, 0x004c, expected_data, GATT_WRITE, write_cb, nullptr));
914   device->ExtAudioInControlPointOperation(1, 0x0c, nullptr, write_cb, nullptr);
915 }
916 
TEST_F(VolumeControlDeviceTest,test_ext_audio_in_control_point_operation_arg)917 TEST_F(VolumeControlDeviceTest, test_ext_audio_in_control_point_operation_arg) {
918   GATT_WRITE_OP_CB write_cb = [](uint16_t /*conn_id*/, tGATT_STATUS /*status*/, uint16_t /*handle*/,
919                                  uint16_t /*len*/, const uint8_t* /*value*/, void* /*data*/) {};
920   SetSampleDatabase1();
921   VolumeAudioInput* input = device->audio_inputs.FindById(1);
922   ASSERT_NE(nullptr, input);
923   input->change_counter = 0x12;
924   std::vector<uint8_t> expected_data({0x0d, 0x12, 0x01, 0x02, 0x03, 0x04});
925   std::vector<uint8_t> arg({0x01, 0x02, 0x03, 0x04});
926   EXPECT_CALL(gatt_queue,
927               WriteCharacteristic(_, 0x004c, expected_data, GATT_WRITE, write_cb, nullptr));
928   device->ExtAudioInControlPointOperation(1, 0x0d, &arg, write_cb, nullptr);
929 }
930 
931 }  // namespace internal
932 }  // namespace vc
933 }  // namespace bluetooth
934