1 /*
2 * Copyright (C) 2021 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <iostream>
18 #include <string>
19
20 #include <gtest/gtest.h>
21
22 #include <media/AidlConversion.h>
23 #include <media/AudioCommonTypes.h>
24
25 using namespace android;
26 using namespace android::aidl_utils;
27
28 using media::AudioDirectMode;
29 using media::AudioPortConfigFw;
30 using media::AudioPortDeviceExtSys;
31 using media::AudioPortFw;
32 using media::AudioPortRole;
33 using media::AudioPortType;
34 using media::audio::common::AudioChannelLayout;
35 using media::audio::common::AudioDevice;
36 using media::audio::common::AudioDeviceAddress;
37 using media::audio::common::AudioDeviceDescription;
38 using media::audio::common::AudioDeviceType;
39 using media::audio::common::AudioEncapsulationMetadataType;
40 using media::audio::common::AudioEncapsulationType;
41 using media::audio::common::AudioFormatDescription;
42 using media::audio::common::AudioFormatType;
43 using media::audio::common::AudioGain;
44 using media::audio::common::AudioGainConfig;
45 using media::audio::common::AudioGainMode;
46 using media::audio::common::AudioIoFlags;
47 using media::audio::common::AudioPortDeviceExt;
48 using media::audio::common::AudioProfile;
49 using media::audio::common::AudioStandard;
50 using media::audio::common::ExtraAudioDescriptor;
51 using media::audio::common::Int;
52 using media::audio::common::MicrophoneDynamicInfo;
53 using media::audio::common::MicrophoneInfo;
54 using media::audio::common::PcmType;
55
56 // Provide value printers for types generated from AIDL
57 // They need to be in the same namespace as the types we intend to print
58 namespace android::media {
59 #define DEFINE_PRINTING_TEMPLATES() \
60 template <typename P> \
61 std::enable_if_t<std::is_base_of_v<::android::Parcelable, P>, std::ostream&> operator<<( \
62 std::ostream& os, const P& p) { \
63 return os << p.toString(); \
64 } \
65 template <typename E> \
66 std::enable_if_t<std::is_enum_v<E>, std::ostream&> operator<<(std::ostream& os, const E& e) { \
67 return os << toString(e); \
68 }
69 DEFINE_PRINTING_TEMPLATES();
70
71 namespace audio::common {
72 DEFINE_PRINTING_TEMPLATES();
73 } // namespace audio::common
74 #undef DEFINE_PRINTING_TEMPLATES
75 } // namespace android::media
76
77 namespace {
78
79 template <typename T>
hash(const T & t)80 size_t hash(const T& t) {
81 return std::hash<T>{}(t);
82 }
83
make_ACL_None()84 AudioChannelLayout make_ACL_None() {
85 return AudioChannelLayout{};
86 }
87
make_ACL_Invalid()88 AudioChannelLayout make_ACL_Invalid() {
89 return AudioChannelLayout::make<AudioChannelLayout::Tag::invalid>(0);
90 }
91
make_ACL_Stereo()92 AudioChannelLayout make_ACL_Stereo() {
93 return AudioChannelLayout::make<AudioChannelLayout::Tag::layoutMask>(
94 AudioChannelLayout::LAYOUT_STEREO);
95 }
96
make_ACL_Tri()97 AudioChannelLayout make_ACL_Tri() {
98 return AudioChannelLayout::make<AudioChannelLayout::Tag::layoutMask>(
99 AudioChannelLayout::LAYOUT_TRI);
100 }
101
make_ACL_LayoutArbitrary()102 AudioChannelLayout make_ACL_LayoutArbitrary() {
103 return AudioChannelLayout::make<AudioChannelLayout::Tag::layoutMask>(
104 // Use channels that exist both for input and output,
105 // but doesn't form a known layout mask.
106 AudioChannelLayout::CHANNEL_FRONT_LEFT | AudioChannelLayout::CHANNEL_FRONT_RIGHT |
107 AudioChannelLayout::CHANNEL_TOP_SIDE_LEFT | AudioChannelLayout::CHANNEL_TOP_SIDE_RIGHT);
108 }
109
make_ACL_ChannelIndex2()110 AudioChannelLayout make_ACL_ChannelIndex2() {
111 return AudioChannelLayout::make<AudioChannelLayout::Tag::indexMask>(
112 AudioChannelLayout::INDEX_MASK_2);
113 }
114
make_ACL_ChannelIndexArbitrary()115 AudioChannelLayout make_ACL_ChannelIndexArbitrary() {
116 // Use channels 1 and 3.
117 return AudioChannelLayout::make<AudioChannelLayout::Tag::indexMask>(5);
118 }
119
make_ACL_VoiceCall()120 AudioChannelLayout make_ACL_VoiceCall() {
121 return AudioChannelLayout::make<AudioChannelLayout::Tag::voiceMask>(
122 AudioChannelLayout::VOICE_CALL_MONO);
123 }
124
make_AudioDeviceDescription(AudioDeviceType type,const std::string & connection="")125 AudioDeviceDescription make_AudioDeviceDescription(AudioDeviceType type,
126 const std::string& connection = "") {
127 AudioDeviceDescription result;
128 result.type = type;
129 result.connection = connection;
130 return result;
131 }
132
make_ADD_None()133 AudioDeviceDescription make_ADD_None() {
134 return AudioDeviceDescription{};
135 }
136
make_ADD_DefaultIn()137 AudioDeviceDescription make_ADD_DefaultIn() {
138 return make_AudioDeviceDescription(AudioDeviceType::IN_DEFAULT);
139 }
140
make_ADD_MicIn()141 AudioDeviceDescription make_ADD_MicIn() {
142 return make_AudioDeviceDescription(AudioDeviceType::IN_MICROPHONE);
143 }
144
make_ADD_RSubmixIn()145 AudioDeviceDescription make_ADD_RSubmixIn() {
146 return make_AudioDeviceDescription(AudioDeviceType::IN_SUBMIX,
147 AudioDeviceDescription::CONNECTION_VIRTUAL());
148 }
149
make_ADD_DefaultOut()150 AudioDeviceDescription make_ADD_DefaultOut() {
151 return make_AudioDeviceDescription(AudioDeviceType::OUT_DEFAULT);
152 }
153
make_ADD_WiredHeadset()154 AudioDeviceDescription make_ADD_WiredHeadset() {
155 return make_AudioDeviceDescription(AudioDeviceType::OUT_HEADSET,
156 AudioDeviceDescription::CONNECTION_ANALOG());
157 }
158
make_ADD_BtScoHeadset()159 AudioDeviceDescription make_ADD_BtScoHeadset() {
160 return make_AudioDeviceDescription(AudioDeviceType::OUT_HEADSET,
161 AudioDeviceDescription::CONNECTION_BT_SCO());
162 }
163
make_ADD_BtA2dpHeadphone()164 AudioDeviceDescription make_ADD_BtA2dpHeadphone() {
165 return make_AudioDeviceDescription(AudioDeviceType::OUT_HEADPHONE,
166 AudioDeviceDescription::CONNECTION_BT_A2DP());
167 }
168
make_ADD_BtLeHeadset()169 AudioDeviceDescription make_ADD_BtLeHeadset() {
170 return make_AudioDeviceDescription(AudioDeviceType::OUT_HEADSET,
171 AudioDeviceDescription::CONNECTION_BT_LE());
172 }
173
make_ADD_BtLeBroadcast()174 AudioDeviceDescription make_ADD_BtLeBroadcast() {
175 return make_AudioDeviceDescription(AudioDeviceType::OUT_BROADCAST,
176 AudioDeviceDescription::CONNECTION_BT_LE());
177 }
178
make_ADD_IpV4Device()179 AudioDeviceDescription make_ADD_IpV4Device() {
180 return make_AudioDeviceDescription(AudioDeviceType::OUT_DEVICE,
181 AudioDeviceDescription::CONNECTION_IP_V4());
182 }
183
make_ADD_UsbHeadset()184 AudioDeviceDescription make_ADD_UsbHeadset() {
185 return make_AudioDeviceDescription(AudioDeviceType::OUT_HEADSET,
186 AudioDeviceDescription::CONNECTION_USB());
187 }
188
make_AudioDevice(const AudioDeviceDescription & type,const AudioDeviceAddress & address)189 AudioDevice make_AudioDevice(const AudioDeviceDescription& type,
190 const AudioDeviceAddress& address) {
191 AudioDevice result;
192 result.type = type;
193 result.address = address;
194 return result;
195 }
196
make_AudioFormatDescription(AudioFormatType type)197 AudioFormatDescription make_AudioFormatDescription(AudioFormatType type) {
198 AudioFormatDescription result;
199 result.type = type;
200 return result;
201 }
202
make_AudioFormatDescription(PcmType pcm)203 AudioFormatDescription make_AudioFormatDescription(PcmType pcm) {
204 auto result = make_AudioFormatDescription(AudioFormatType::PCM);
205 result.pcm = pcm;
206 return result;
207 }
208
make_AudioFormatDescription(const std::string & encoding)209 AudioFormatDescription make_AudioFormatDescription(const std::string& encoding) {
210 AudioFormatDescription result;
211 result.encoding = encoding;
212 return result;
213 }
214
make_AudioFormatDescription(PcmType transport,const std::string & encoding)215 AudioFormatDescription make_AudioFormatDescription(PcmType transport, const std::string& encoding) {
216 auto result = make_AudioFormatDescription(encoding);
217 result.pcm = transport;
218 return result;
219 }
220
make_AFD_Default()221 AudioFormatDescription make_AFD_Default() {
222 return AudioFormatDescription{};
223 }
224
make_AFD_Invalid()225 AudioFormatDescription make_AFD_Invalid() {
226 return make_AudioFormatDescription(AudioFormatType::SYS_RESERVED_INVALID);
227 }
228
make_AFD_Pcm16Bit()229 AudioFormatDescription make_AFD_Pcm16Bit() {
230 return make_AudioFormatDescription(PcmType::INT_16_BIT);
231 }
232
make_AFD_Bitstream()233 AudioFormatDescription make_AFD_Bitstream() {
234 return make_AudioFormatDescription("example");
235 }
236
make_AFD_Encap()237 AudioFormatDescription make_AFD_Encap() {
238 return make_AudioFormatDescription(PcmType::INT_16_BIT, "example.encap");
239 }
240
make_AFD_Encap_with_Enc()241 AudioFormatDescription make_AFD_Encap_with_Enc() {
242 auto afd = make_AFD_Encap();
243 afd.encoding += "+example";
244 return afd;
245 }
246
make_TrackSecondaryOutputInfo()247 android::media::TrackSecondaryOutputInfo make_TrackSecondaryOutputInfo() {
248 android::media::TrackSecondaryOutputInfo result;
249 result.portId = 1;
250 result.secondaryOutputIds = {0, 5, 7};
251 return result;
252 }
253
make_ExtraAudioDescriptor(AudioStandard audioStandard,AudioEncapsulationType audioEncapsulationType)254 ExtraAudioDescriptor make_ExtraAudioDescriptor(AudioStandard audioStandard,
255 AudioEncapsulationType audioEncapsulationType) {
256 ExtraAudioDescriptor result;
257 result.standard = audioStandard;
258 result.audioDescriptor = {0xb4, 0xaf, 0x98, 0x1a};
259 result.encapsulationType = audioEncapsulationType;
260 return result;
261 }
262
263 } // namespace
264
265 // Verify that two independently constructed ADDs/AFDs have the same hash.
266 // This ensures that regardless of whether the ADD/AFD instance originates
267 // from, it can be correctly compared to other ADD/AFD instance. Thus,
268 // for example, a 16-bit integer format description provided by HAL
269 // is identical to the same format description constructed by the framework.
270 class HashIdentityTest : public ::testing::Test {
271 public:
272 template <typename T>
verifyHashIdentity(const std::vector<std::function<T ()>> & valueGens)273 void verifyHashIdentity(const std::vector<std::function<T()>>& valueGens) {
274 for (size_t i = 0; i < valueGens.size(); ++i) {
275 for (size_t j = 0; j < valueGens.size(); ++j) {
276 if (i == j) {
277 EXPECT_EQ(hash(valueGens[i]()), hash(valueGens[i]())) << i;
278 } else {
279 EXPECT_NE(hash(valueGens[i]()), hash(valueGens[j]())) << i << ", " << j;
280 }
281 }
282 }
283 }
284 };
285
TEST_F(HashIdentityTest,AudioChannelLayoutHashIdentity)286 TEST_F(HashIdentityTest, AudioChannelLayoutHashIdentity) {
287 verifyHashIdentity<AudioChannelLayout>({make_ACL_None, make_ACL_Invalid, make_ACL_Stereo,
288 make_ACL_LayoutArbitrary, make_ACL_ChannelIndex2,
289 make_ACL_ChannelIndexArbitrary, make_ACL_VoiceCall});
290 }
291
TEST_F(HashIdentityTest,AudioDeviceDescriptionHashIdentity)292 TEST_F(HashIdentityTest, AudioDeviceDescriptionHashIdentity) {
293 verifyHashIdentity<AudioDeviceDescription>({make_ADD_None, make_ADD_DefaultIn,
294 make_ADD_DefaultOut, make_ADD_WiredHeadset,
295 make_ADD_BtScoHeadset});
296 }
297
TEST_F(HashIdentityTest,AudioFormatDescriptionHashIdentity)298 TEST_F(HashIdentityTest, AudioFormatDescriptionHashIdentity) {
299 verifyHashIdentity<AudioFormatDescription>({make_AFD_Default, make_AFD_Invalid,
300 make_AFD_Pcm16Bit, make_AFD_Bitstream,
301 make_AFD_Encap, make_AFD_Encap_with_Enc});
302 }
303
304 using ChannelLayoutParam = std::tuple<AudioChannelLayout, bool /*isInput*/>;
305 class AudioChannelLayoutRoundTripTest : public testing::TestWithParam<ChannelLayoutParam> {};
TEST_P(AudioChannelLayoutRoundTripTest,Aidl2Legacy2Aidl)306 TEST_P(AudioChannelLayoutRoundTripTest, Aidl2Legacy2Aidl) {
307 const auto initial = std::get<0>(GetParam());
308 const bool isInput = std::get<1>(GetParam());
309 auto conv = aidl2legacy_AudioChannelLayout_audio_channel_mask_t(initial, isInput);
310 ASSERT_TRUE(conv.ok());
311 auto convBack = legacy2aidl_audio_channel_mask_t_AudioChannelLayout(conv.value(), isInput);
312 ASSERT_TRUE(convBack.ok());
313 EXPECT_EQ(initial, convBack.value());
314 }
315
316 INSTANTIATE_TEST_SUITE_P(
317 AudioChannelLayoutRoundTrip, AudioChannelLayoutRoundTripTest,
318 testing::Combine(
319 testing::Values(AudioChannelLayout{}, make_ACL_Invalid(), make_ACL_Stereo(),
320 make_ACL_Tri(), make_ACL_LayoutArbitrary(),
321 make_ACL_ChannelIndex2(), make_ACL_ChannelIndexArbitrary(),
322 AudioChannelLayout::make<AudioChannelLayout::Tag::layoutMask>(
323 AudioChannelLayout::CHANNEL_FRONT_LEFT),
324 AudioChannelLayout::make<AudioChannelLayout::Tag::layoutMask>(
325 AudioChannelLayout::CHANNEL_FRONT_RIGHT),
326 AudioChannelLayout::make<AudioChannelLayout::Tag::layoutMask>(
327 AudioChannelLayout::CHANNEL_BACK_CENTER),
328 AudioChannelLayout::make<AudioChannelLayout::Tag::layoutMask>(
329 AudioChannelLayout::CHANNEL_BACK_LEFT),
330 AudioChannelLayout::make<AudioChannelLayout::Tag::layoutMask>(
331 AudioChannelLayout::CHANNEL_BACK_RIGHT),
332 AudioChannelLayout::make<AudioChannelLayout::Tag::layoutMask>(
333 AudioChannelLayout::CHANNEL_FRONT_CENTER),
334 AudioChannelLayout::make<AudioChannelLayout::Tag::layoutMask>(
335 AudioChannelLayout::CHANNEL_LOW_FREQUENCY),
336 AudioChannelLayout::make<AudioChannelLayout::Tag::layoutMask>(
337 AudioChannelLayout::CHANNEL_TOP_SIDE_LEFT),
338 AudioChannelLayout::make<AudioChannelLayout::Tag::layoutMask>(
339 AudioChannelLayout::CHANNEL_TOP_SIDE_RIGHT)),
340 testing::Values(false, true)));
341 INSTANTIATE_TEST_SUITE_P(AudioChannelVoiceRoundTrip, AudioChannelLayoutRoundTripTest,
342 // In legacy constants the voice call is only defined for input.
343 testing::Combine(testing::Values(make_ACL_VoiceCall()),
344 testing::Values(true)));
345
346 INSTANTIATE_TEST_SUITE_P(
347 OutAudioChannelLayoutLayoutRoundTrip, AudioChannelLayoutRoundTripTest,
348 testing::Combine(
349 testing::Values(AudioChannelLayout::make<AudioChannelLayout::Tag::layoutMask>(
350 AudioChannelLayout::CHANNEL_FRONT_LEFT_OF_CENTER),
351 AudioChannelLayout::make<AudioChannelLayout::Tag::layoutMask>(
352 AudioChannelLayout::CHANNEL_FRONT_RIGHT_OF_CENTER),
353 AudioChannelLayout::make<AudioChannelLayout::Tag::layoutMask>(
354 AudioChannelLayout::CHANNEL_SIDE_LEFT),
355 AudioChannelLayout::make<AudioChannelLayout::Tag::layoutMask>(
356 AudioChannelLayout::CHANNEL_SIDE_RIGHT),
357 AudioChannelLayout::make<AudioChannelLayout::Tag::layoutMask>(
358 AudioChannelLayout::CHANNEL_TOP_CENTER),
359 AudioChannelLayout::make<AudioChannelLayout::Tag::layoutMask>(
360 AudioChannelLayout::CHANNEL_TOP_FRONT_LEFT),
361 AudioChannelLayout::make<AudioChannelLayout::Tag::layoutMask>(
362 AudioChannelLayout::CHANNEL_TOP_FRONT_CENTER),
363 AudioChannelLayout::make<AudioChannelLayout::Tag::layoutMask>(
364 AudioChannelLayout::CHANNEL_TOP_FRONT_RIGHT),
365 AudioChannelLayout::make<AudioChannelLayout::Tag::layoutMask>(
366 AudioChannelLayout::CHANNEL_TOP_BACK_LEFT),
367 AudioChannelLayout::make<AudioChannelLayout::Tag::layoutMask>(
368 AudioChannelLayout::CHANNEL_TOP_BACK_CENTER),
369 AudioChannelLayout::make<AudioChannelLayout::Tag::layoutMask>(
370 AudioChannelLayout::CHANNEL_TOP_BACK_RIGHT),
371 AudioChannelLayout::make<AudioChannelLayout::Tag::layoutMask>(
372 AudioChannelLayout::CHANNEL_BOTTOM_FRONT_LEFT),
373 AudioChannelLayout::make<AudioChannelLayout::Tag::layoutMask>(
374 AudioChannelLayout::CHANNEL_BOTTOM_FRONT_CENTER),
375 AudioChannelLayout::make<AudioChannelLayout::Tag::layoutMask>(
376 AudioChannelLayout::CHANNEL_BOTTOM_FRONT_RIGHT),
377 AudioChannelLayout::make<AudioChannelLayout::Tag::layoutMask>(
378 AudioChannelLayout::CHANNEL_LOW_FREQUENCY_2),
379 AudioChannelLayout::make<AudioChannelLayout::Tag::layoutMask>(
380 AudioChannelLayout::CHANNEL_FRONT_WIDE_LEFT),
381 AudioChannelLayout::make<AudioChannelLayout::Tag::layoutMask>(
382 AudioChannelLayout::CHANNEL_FRONT_WIDE_RIGHT),
383 AudioChannelLayout::make<AudioChannelLayout::Tag::layoutMask>(
384 AudioChannelLayout::CHANNEL_HAPTIC_A),
385 AudioChannelLayout::make<AudioChannelLayout::Tag::layoutMask>(
386 AudioChannelLayout::CHANNEL_HAPTIC_B)),
387 testing::Values(false)));
388
389 using ChannelLayoutEdgeCaseParam = std::tuple<int /*legacy*/, bool /*isInput*/, bool /*isValid*/>;
390 class AudioChannelLayoutEdgeCaseTest : public testing::TestWithParam<ChannelLayoutEdgeCaseParam> {};
TEST_P(AudioChannelLayoutEdgeCaseTest,Legacy2Aidl)391 TEST_P(AudioChannelLayoutEdgeCaseTest, Legacy2Aidl) {
392 const audio_channel_mask_t legacy = static_cast<audio_channel_mask_t>(std::get<0>(GetParam()));
393 const bool isInput = std::get<1>(GetParam());
394 const bool isValid = std::get<2>(GetParam());
395 auto conv = legacy2aidl_audio_channel_mask_t_AudioChannelLayout(legacy, isInput);
396 EXPECT_EQ(isValid, conv.ok());
397 }
398 INSTANTIATE_TEST_SUITE_P(
399 AudioChannelLayoutEdgeCase, AudioChannelLayoutEdgeCaseTest,
400 testing::Values(
401 // Valid legacy input masks.
402 std::make_tuple(AUDIO_CHANNEL_IN_VOICE_UPLINK_MONO, true, true),
403 std::make_tuple(AUDIO_CHANNEL_IN_VOICE_DNLINK_MONO, true, true),
404 std::make_tuple(AUDIO_CHANNEL_IN_VOICE_CALL_MONO, true, true),
405 // Valid legacy output masks.
406 std::make_tuple(
407 // This has the same numerical representation as Mask 'A' below
408 AUDIO_CHANNEL_OUT_FRONT_CENTER | AUDIO_CHANNEL_OUT_LOW_FREQUENCY |
409 AUDIO_CHANNEL_OUT_TOP_FRONT_RIGHT,
410 false, true),
411 std::make_tuple(
412 // This has the same numerical representation as Mask 'B' below
413 AUDIO_CHANNEL_OUT_FRONT_CENTER | AUDIO_CHANNEL_OUT_LOW_FREQUENCY |
414 AUDIO_CHANNEL_OUT_TOP_BACK_LEFT,
415 false, true),
416 // Invalid legacy input masks.
417 std::make_tuple(AUDIO_CHANNEL_IN_6, true, false),
418 std::make_tuple(AUDIO_CHANNEL_IN_6 | AUDIO_CHANNEL_IN_FRONT_PROCESSED, true, false),
419 std::make_tuple(AUDIO_CHANNEL_IN_PRESSURE | AUDIO_CHANNEL_IN_X_AXIS |
420 AUDIO_CHANNEL_IN_Y_AXIS | AUDIO_CHANNEL_IN_Z_AXIS,
421 true, false),
422 std::make_tuple( // Mask 'A'
423 AUDIO_CHANNEL_IN_STEREO | AUDIO_CHANNEL_IN_VOICE_UPLINK, true, false),
424 std::make_tuple( // Mask 'B'
425 AUDIO_CHANNEL_IN_STEREO | AUDIO_CHANNEL_IN_VOICE_DNLINK, true, false)));
426
427 class AudioDeviceDescriptionRoundTripTest : public testing::TestWithParam<AudioDeviceDescription> {
428 };
TEST_P(AudioDeviceDescriptionRoundTripTest,Aidl2Legacy2Aidl)429 TEST_P(AudioDeviceDescriptionRoundTripTest, Aidl2Legacy2Aidl) {
430 const auto initial = GetParam();
431 auto conv = aidl2legacy_AudioDeviceDescription_audio_devices_t(initial);
432 ASSERT_TRUE(conv.ok());
433 auto convBack = legacy2aidl_audio_devices_t_AudioDeviceDescription(conv.value());
434 ASSERT_TRUE(convBack.ok());
435 EXPECT_EQ(initial, convBack.value());
436 }
437 INSTANTIATE_TEST_SUITE_P(AudioDeviceDescriptionRoundTrip, AudioDeviceDescriptionRoundTripTest,
438 testing::Values(AudioDeviceDescription{}, make_ADD_DefaultIn(),
439 make_ADD_DefaultOut(), make_ADD_WiredHeadset(),
440 make_ADD_BtScoHeadset()));
441
442 class AudioDeviceRoundTripTest : public testing::TestWithParam<AudioDevice> {};
TEST_P(AudioDeviceRoundTripTest,Aidl2Legacy2Aidl)443 TEST_P(AudioDeviceRoundTripTest, Aidl2Legacy2Aidl) {
444 const auto initial = GetParam();
445 audio_devices_t legacyType;
446 String8 legacyAddress;
447 status_t status = aidl2legacy_AudioDevice_audio_device(initial, &legacyType, &legacyAddress);
448 ASSERT_EQ(OK, status);
449 auto convBack = legacy2aidl_audio_device_AudioDevice(legacyType, legacyAddress);
450 ASSERT_TRUE(convBack.ok());
451 EXPECT_EQ(initial, convBack.value());
452 }
453 INSTANTIATE_TEST_SUITE_P(
454 AudioDeviceRoundTrip, AudioDeviceRoundTripTest,
455 testing::Values(
456 make_AudioDevice(make_ADD_MicIn(),
457 AudioDeviceAddress::make<AudioDeviceAddress::Tag::id>("bottom")),
458 make_AudioDevice(make_ADD_RSubmixIn(),
459 AudioDeviceAddress::make<AudioDeviceAddress::Tag::id>("1:2-in-3")),
460 // The case of a "blueprint" device port for an external device.
461 make_AudioDevice(make_ADD_BtScoHeadset(),
462 AudioDeviceAddress::make<AudioDeviceAddress::Tag::id>("")),
463 make_AudioDevice(make_ADD_BtScoHeadset(),
464 AudioDeviceAddress::make<AudioDeviceAddress::Tag::mac>(
465 std::vector<uint8_t>{1, 2, 3, 4, 5, 6})),
466 // Another "blueprint"
467 make_AudioDevice(make_ADD_BtA2dpHeadphone(),
468 AudioDeviceAddress::make<AudioDeviceAddress::Tag::id>("")),
469 make_AudioDevice(make_ADD_BtA2dpHeadphone(),
470 AudioDeviceAddress::make<AudioDeviceAddress::Tag::mac>(
471 std::vector<uint8_t>{1, 2, 3, 4, 5, 6})),
472 make_AudioDevice(make_ADD_BtLeHeadset(),
473 AudioDeviceAddress::make<AudioDeviceAddress::Tag::mac>(
474 std::vector<uint8_t>{1, 2, 3, 4, 5, 6})),
475 make_AudioDevice(make_ADD_BtLeBroadcast(),
476 AudioDeviceAddress::make<AudioDeviceAddress::Tag::id>("42")),
477 make_AudioDevice(make_ADD_IpV4Device(),
478 AudioDeviceAddress::make<AudioDeviceAddress::Tag::ipv4>(
479 std::vector<uint8_t>{192, 168, 0, 1})),
480 make_AudioDevice(make_ADD_UsbHeadset(),
481 AudioDeviceAddress::make<AudioDeviceAddress::Tag::alsa>(
482 std::vector<int32_t>{1, 2}))));
483
484 class AudioFormatDescriptionRoundTripTest : public testing::TestWithParam<AudioFormatDescription> {
485 };
TEST_P(AudioFormatDescriptionRoundTripTest,Aidl2Legacy2Aidl)486 TEST_P(AudioFormatDescriptionRoundTripTest, Aidl2Legacy2Aidl) {
487 const auto initial = GetParam();
488 auto conv = aidl2legacy_AudioFormatDescription_audio_format_t(initial);
489 ASSERT_TRUE(conv.ok());
490 auto convBack = legacy2aidl_audio_format_t_AudioFormatDescription(conv.value());
491 ASSERT_TRUE(convBack.ok());
492 EXPECT_EQ(initial, convBack.value());
493 }
494 INSTANTIATE_TEST_SUITE_P(AudioFormatDescriptionRoundTrip, AudioFormatDescriptionRoundTripTest,
495 testing::Values(make_AFD_Invalid(), AudioFormatDescription{},
496 make_AFD_Pcm16Bit()));
497
createAudioPortConfigFw(const AudioChannelLayout & layout,const AudioFormatDescription & format,const AudioDeviceDescription & device)498 AudioPortConfigFw createAudioPortConfigFw(const AudioChannelLayout& layout,
499 const AudioFormatDescription& format,
500 const AudioDeviceDescription& device) {
501 const bool isInput = device.type < AudioDeviceType::OUT_DEFAULT;
502 AudioPortConfigFw result;
503 result.hal.id = 43;
504 result.hal.portId = 42;
505 Int sr44100;
506 sr44100.value = 44100;
507 result.hal.sampleRate = sr44100;
508 result.hal.channelMask = layout;
509 result.hal.format = format;
510 AudioGainConfig gain;
511 gain.mode = 1 << static_cast<int>(AudioGainMode::JOINT);
512 gain.values = std::vector<int32_t>({100});
513 result.hal.gain = gain;
514 AudioPortDeviceExt ext;
515 AudioDevice audioDevice;
516 audioDevice.type = device;
517 ext.device = audioDevice;
518 result.hal.ext = ext;
519 result.sys.role = isInput ? AudioPortRole::SOURCE : AudioPortRole::SINK;
520 result.sys.type = AudioPortType::DEVICE;
521 AudioPortDeviceExtSys sysDevice;
522 sysDevice.hwModule = 1;
523 result.sys.ext = sysDevice;
524 return result;
525 }
526
527 using AudioPortConfigParam =
528 std::tuple<AudioChannelLayout, AudioFormatDescription, AudioDeviceDescription>;
529 class AudioPortConfigRoundTripTest : public testing::TestWithParam<AudioPortConfigParam> {};
TEST_P(AudioPortConfigRoundTripTest,Aidl2Legacy2Aidl)530 TEST_P(AudioPortConfigRoundTripTest, Aidl2Legacy2Aidl) {
531 const AudioChannelLayout layout = std::get<0>(GetParam());
532 const AudioFormatDescription format = std::get<1>(GetParam());
533 const AudioDeviceDescription device = std::get<2>(GetParam());
534 const bool isInput = device.type < AudioDeviceType::OUT_DEFAULT;
535 AudioPortConfigFw initial = createAudioPortConfigFw(layout, format, device);
536 {
537 audio_port_config conv{};
538 int32_t portId = -1;
539 status_t status =
540 aidl2legacy_AudioPortConfig_audio_port_config(initial.hal, isInput, &conv, &portId);
541 ASSERT_EQ(OK, status);
542 EXPECT_NE(-1, portId);
543 auto convBack = legacy2aidl_audio_port_config_AudioPortConfig(conv, isInput, portId);
544 ASSERT_TRUE(convBack.ok());
545 EXPECT_EQ(initial.hal, convBack.value());
546 }
547 {
548 int32_t portId = -1;
549 auto conv = aidl2legacy_AudioPortConfigFw_audio_port_config(initial, &portId);
550 ASSERT_TRUE(conv.ok());
551 EXPECT_NE(-1, portId);
552 auto convBack = legacy2aidl_audio_port_config_AudioPortConfigFw(conv.value(), portId);
553 ASSERT_TRUE(convBack.ok());
554 EXPECT_EQ(initial, convBack.value());
555 }
556 }
557 INSTANTIATE_TEST_SUITE_P(
558 AudioPortConfig, AudioPortConfigRoundTripTest,
559 testing::Combine(testing::Values(make_ACL_Stereo(), make_ACL_ChannelIndex2()),
560 testing::Values(make_AFD_Pcm16Bit()),
561 testing::Values(make_ADD_DefaultIn(), make_ADD_DefaultOut(),
562 make_ADD_WiredHeadset())));
563
564 class AudioPortFwRoundTripTest : public testing::TestWithParam<AudioDeviceDescription> {
565 public:
createProfile(const AudioFormatDescription & format,const std::vector<AudioChannelLayout> & channelMasks,const std::vector<int32_t> & sampleRates)566 AudioProfile createProfile(const AudioFormatDescription& format,
567 const std::vector<AudioChannelLayout>& channelMasks,
568 const std::vector<int32_t>& sampleRates) {
569 AudioProfile profile;
570 profile.format = format;
571 profile.channelMasks = channelMasks;
572 profile.sampleRates = sampleRates;
573 return profile;
574 }
575 };
TEST_P(AudioPortFwRoundTripTest,Aidl2Legacy2Aidl)576 TEST_P(AudioPortFwRoundTripTest, Aidl2Legacy2Aidl) {
577 const AudioDeviceDescription device = GetParam();
578 const bool isInput = device.type < AudioDeviceType::OUT_DEFAULT;
579 AudioPortFw initial;
580 initial.hal.id = 42;
581 initial.hal.profiles.push_back(createProfile(
582 make_AFD_Pcm16Bit(), {make_ACL_Stereo(), make_ACL_ChannelIndex2()}, {44100, 48000}));
583 if (isInput) {
584 initial.hal.flags = AudioIoFlags::make<AudioIoFlags::Tag::input>(0);
585 } else {
586 initial.hal.flags = AudioIoFlags::make<AudioIoFlags::Tag::output>(0);
587 }
588 AudioGain initialGain;
589 initialGain.mode = 1 << static_cast<int>(AudioGainMode::JOINT);
590 initialGain.channelMask = make_ACL_Stereo();
591 initial.hal.gains.push_back(initialGain);
592 AudioPortDeviceExt initialExt;
593 AudioDevice initialDevice;
594 initialDevice.type = device;
595 initialExt.device = initialDevice;
596 initial.hal.ext = initialExt;
597 {
598 auto conv = aidl2legacy_AudioPort_audio_port_v7(initial.hal, isInput);
599 ASSERT_TRUE(conv.ok());
600 auto convBack = legacy2aidl_audio_port_v7_AudioPort(conv.value(), isInput);
601 ASSERT_TRUE(convBack.ok());
602 EXPECT_EQ(initial.hal, convBack.value());
603 }
604 initial.sys.role = isInput ? AudioPortRole::SOURCE : AudioPortRole::SINK;
605 initial.sys.type = AudioPortType::DEVICE;
606 initial.sys.profiles.resize(initial.hal.profiles.size());
607 initial.sys.gains.resize(initial.hal.gains.size());
608 initial.sys.activeConfig =
609 createAudioPortConfigFw(make_ACL_Stereo(), make_AFD_Pcm16Bit(), device);
610 initial.sys.activeConfig.hal.flags = initial.hal.flags;
611 AudioPortDeviceExtSys initialSysDevice;
612 initialSysDevice.hwModule = 1;
613 initial.sys.ext = initialSysDevice;
614 {
615 auto conv = aidl2legacy_AudioPortFw_audio_port_v7(initial);
616 ASSERT_TRUE(conv.ok());
617 auto convBack = legacy2aidl_audio_port_v7_AudioPortFw(conv.value());
618 ASSERT_TRUE(convBack.ok());
619 EXPECT_EQ(initial, convBack.value());
620 }
621 }
622 INSTANTIATE_TEST_SUITE_P(AudioPortFw, AudioPortFwRoundTripTest,
623 testing::Values(make_ADD_DefaultIn(), make_ADD_DefaultOut(),
624 make_ADD_WiredHeadset()));
625
626 class AudioDirectModeRoundTripTest : public testing::TestWithParam<AudioDirectMode> {};
TEST_P(AudioDirectModeRoundTripTest,Aidl2Legacy2Aidl)627 TEST_P(AudioDirectModeRoundTripTest, Aidl2Legacy2Aidl) {
628 const auto initial = GetParam();
629 auto conv = aidl2legacy_AudioDirectMode_audio_direct_mode_t(initial);
630 ASSERT_TRUE(conv.ok());
631 auto convBack = legacy2aidl_audio_direct_mode_t_AudioDirectMode(conv.value());
632 ASSERT_TRUE(convBack.ok());
633 EXPECT_EQ(initial, convBack.value());
634 }
635 INSTANTIATE_TEST_SUITE_P(AudioDirectMode, AudioDirectModeRoundTripTest,
636 testing::Values(AudioDirectMode::NONE, AudioDirectMode::OFFLOAD,
637 AudioDirectMode::OFFLOAD_GAPLESS,
638 AudioDirectMode::BITSTREAM));
639
640 class AudioStandardRoundTripTest : public testing::TestWithParam<AudioStandard> {};
TEST_P(AudioStandardRoundTripTest,Aidl2Legacy2Aidl)641 TEST_P(AudioStandardRoundTripTest, Aidl2Legacy2Aidl) {
642 const auto initial = GetParam();
643 auto conv = aidl2legacy_AudioStandard_audio_standard_t(initial);
644 ASSERT_TRUE(conv.ok());
645 auto convBack = legacy2aidl_audio_standard_t_AudioStandard(conv.value());
646 ASSERT_TRUE(convBack.ok());
647 EXPECT_EQ(initial, convBack.value());
648 }
649 INSTANTIATE_TEST_SUITE_P(AudioStandard, AudioStandardRoundTripTest,
650 testing::Values(AudioStandard::NONE, AudioStandard::EDID,
651 AudioStandard::SADB, AudioStandard::VSADB));
652
653 class AudioEncapsulationMetadataTypeRoundTripTest
654 : public testing::TestWithParam<AudioEncapsulationMetadataType> {};
TEST_P(AudioEncapsulationMetadataTypeRoundTripTest,Aidl2Legacy2Aidl)655 TEST_P(AudioEncapsulationMetadataTypeRoundTripTest, Aidl2Legacy2Aidl) {
656 const auto initial = GetParam();
657 auto conv =
658 aidl2legacy_AudioEncapsulationMetadataType_audio_encapsulation_metadata_type_t(initial);
659 ASSERT_TRUE(conv.ok());
660 auto convBack = legacy2aidl_audio_encapsulation_metadata_type_t_AudioEncapsulationMetadataType(
661 conv.value());
662 ASSERT_TRUE(convBack.ok());
663 EXPECT_EQ(initial, convBack.value());
664 }
665 INSTANTIATE_TEST_SUITE_P(AudioEncapsulationMetadataType,
666 AudioEncapsulationMetadataTypeRoundTripTest,
667 testing::Values(AudioEncapsulationMetadataType::NONE,
668 AudioEncapsulationMetadataType::FRAMEWORK_TUNER,
669 AudioEncapsulationMetadataType::DVB_AD_DESCRIPTOR));
670
671 class AudioGainModeRoundTripTest : public testing::TestWithParam<AudioGainMode> {};
TEST_P(AudioGainModeRoundTripTest,Aidl2Legacy2Aidl)672 TEST_P(AudioGainModeRoundTripTest, Aidl2Legacy2Aidl) {
673 const auto initial = GetParam();
674 auto conv = aidl2legacy_AudioGainMode_audio_gain_mode_t(initial);
675 ASSERT_TRUE(conv.ok());
676 auto convBack = legacy2aidl_audio_gain_mode_t_AudioGainMode(conv.value());
677 ASSERT_TRUE(convBack.ok());
678 EXPECT_EQ(initial, convBack.value());
679 }
680 INSTANTIATE_TEST_SUITE_P(AudioGainMode, AudioGainModeRoundTripTest,
681 testing::Values(AudioGainMode::JOINT, AudioGainMode::CHANNELS,
682 AudioGainMode::RAMP));
683
TEST(AudioTrackSecondaryOutputInfoRoundTripTest,Aidl2Legacy2Aidl)684 TEST(AudioTrackSecondaryOutputInfoRoundTripTest, Aidl2Legacy2Aidl) {
685 const auto initial = make_TrackSecondaryOutputInfo();
686 auto conv = aidl2legacy_TrackSecondaryOutputInfo_TrackSecondaryOutputInfoPair(initial);
687 ASSERT_TRUE(conv.ok());
688 auto convBack = legacy2aidl_TrackSecondaryOutputInfoPair_TrackSecondaryOutputInfo(conv.value());
689 ASSERT_TRUE(convBack.ok());
690 EXPECT_EQ(initial, convBack.value());
691 }
692
693 using ExtraAudioDescriptorParam = std::tuple<AudioStandard, AudioEncapsulationType>;
694 class ExtraAudioDescriptorRoundTripTest : public testing::TestWithParam<ExtraAudioDescriptorParam> {
695 };
TEST_P(ExtraAudioDescriptorRoundTripTest,Aidl2Legacy2Aidl)696 TEST_P(ExtraAudioDescriptorRoundTripTest, Aidl2Legacy2Aidl) {
697 ExtraAudioDescriptor initial =
698 make_ExtraAudioDescriptor(std::get<0>(GetParam()), std::get<1>(GetParam()));
699 auto conv = aidl2legacy_ExtraAudioDescriptor_audio_extra_audio_descriptor(initial);
700 ASSERT_TRUE(conv.ok());
701 auto convBack = legacy2aidl_audio_extra_audio_descriptor_ExtraAudioDescriptor(conv.value());
702 ASSERT_TRUE(convBack.ok());
703 EXPECT_EQ(initial, convBack.value());
704 }
705
706 INSTANTIATE_TEST_SUITE_P(
707 ExtraAudioDescriptor, ExtraAudioDescriptorRoundTripTest,
708 testing::Values(std::make_tuple(AudioStandard::NONE, AudioEncapsulationType::NONE),
709 std::make_tuple(AudioStandard::EDID, AudioEncapsulationType::NONE),
710 std::make_tuple(AudioStandard::EDID, AudioEncapsulationType::IEC61937),
711 std::make_tuple(AudioStandard::SADB, AudioEncapsulationType::NONE),
712 std::make_tuple(AudioStandard::SADB, AudioEncapsulationType::IEC61937),
713 std::make_tuple(AudioStandard::VSADB, AudioEncapsulationType::NONE),
714 std::make_tuple(AudioStandard::VSADB, AudioEncapsulationType::IEC61937)));
715
TEST(AudioPortSessionExtRoundTripTest,Aidl2Legacy2Aidl)716 TEST(AudioPortSessionExtRoundTripTest, Aidl2Legacy2Aidl) {
717 const int32_t initial = 7;
718 auto conv = aidl2legacy_int32_t_audio_port_session_ext(initial);
719 ASSERT_TRUE(conv.ok());
720 auto convBack = legacy2aidl_audio_port_session_ext_int32_t(conv.value());
721 ASSERT_TRUE(convBack.ok());
722 EXPECT_EQ(initial, convBack.value());
723 }
724
725 class AudioGainTest : public testing::TestWithParam<bool> {};
TEST_P(AudioGainTest,Legacy2Aidl2Legacy)726 TEST_P(AudioGainTest, Legacy2Aidl2Legacy) {
727 audio_port_v7 port;
728 port.num_gains = 2;
729 port.gains[0] = {.mode = AUDIO_GAIN_MODE_JOINT,
730 .channel_mask = AUDIO_CHANNEL_IN_STEREO,
731 .min_value = -3200,
732 .max_value = 600,
733 .default_value = 0,
734 .step_value = 100,
735 .min_ramp_ms = 10,
736 .max_ramp_ms = 20};
737 port.gains[1] = {.mode = AUDIO_GAIN_MODE_JOINT,
738 .channel_mask = AUDIO_CHANNEL_IN_MONO,
739 .min_value = -8800,
740 .max_value = 4000,
741 .default_value = 0,
742 .step_value = 100,
743 .min_ramp_ms = 192,
744 .max_ramp_ms = 224};
745
746 const auto isInput = GetParam();
747 for (int i = 0; i < port.num_gains; i++) {
748 auto initial = port.gains[i];
749 auto conv = legacy2aidl_audio_gain_AudioGain(initial, isInput);
750 ASSERT_TRUE(conv.ok());
751 auto convBack = aidl2legacy_AudioGain_audio_gain(conv.value(), isInput);
752 ASSERT_TRUE(convBack.ok());
753 EXPECT_EQ(initial.mode, convBack.value().mode);
754 EXPECT_EQ(initial.channel_mask, convBack.value().channel_mask);
755 EXPECT_EQ(initial.min_value, convBack.value().min_value);
756 EXPECT_EQ(initial.max_value, convBack.value().max_value);
757 EXPECT_EQ(initial.default_value, convBack.value().default_value);
758 EXPECT_EQ(initial.step_value, convBack.value().step_value);
759 EXPECT_EQ(initial.min_ramp_ms, convBack.value().min_ramp_ms);
760 EXPECT_EQ(initial.max_ramp_ms, convBack.value().max_ramp_ms);
761 }
762 }
763 INSTANTIATE_TEST_SUITE_P(AudioGain, AudioGainTest, testing::Values(true, false));
764
TEST(AudioMicrophoneInfoFw,Aidl2Legacy2Aidl)765 TEST(AudioMicrophoneInfoFw, Aidl2Legacy2Aidl) {
766 media::MicrophoneInfoFw initial{};
767 // HALs must return at least 1 element in channelMapping. The zero value is 'UNUSED'.
768 initial.dynamic.channelMapping.resize(1);
769 auto conv = aidl2legacy_MicrophoneInfoFw_audio_microphone_characteristic_t(initial);
770 ASSERT_TRUE(conv.ok());
771 auto convBack = legacy2aidl_audio_microphone_characteristic_t_MicrophoneInfoFw(conv.value());
772 ASSERT_TRUE(convBack.ok());
773 EXPECT_EQ(initial, convBack.value());
774 }
775
TEST(AudioMicrophoneInfoFw,UnknownValues)776 TEST(AudioMicrophoneInfoFw, UnknownValues) {
777 {
778 media::MicrophoneInfoFw initial;
779 initial.dynamic.channelMapping.resize(1);
780 initial.info.indexInTheGroup = MicrophoneInfo::INDEX_IN_THE_GROUP_UNKNOWN;
781 auto conv = aidl2legacy_MicrophoneInfoFw_audio_microphone_characteristic_t(initial);
782 ASSERT_TRUE(conv.ok());
783 auto convBack =
784 legacy2aidl_audio_microphone_characteristic_t_MicrophoneInfoFw(conv.value());
785 ASSERT_TRUE(convBack.ok());
786 EXPECT_EQ(initial, convBack.value());
787 }
788 for (const auto f : {&audio_microphone_characteristic_t::sensitivity,
789 &audio_microphone_characteristic_t::max_spl,
790 &audio_microphone_characteristic_t::min_spl}) {
791 audio_microphone_characteristic_t mic{};
792 if (f == &audio_microphone_characteristic_t::sensitivity) {
793 mic.*f = AUDIO_MICROPHONE_SENSITIVITY_UNKNOWN;
794 } else {
795 mic.*f = AUDIO_MICROPHONE_SPL_UNKNOWN;
796 }
797 auto aidl = legacy2aidl_audio_microphone_characteristic_t_MicrophoneInfoFw(mic);
798 ASSERT_TRUE(aidl.ok());
799 EXPECT_FALSE(aidl.value().info.sensitivity.has_value());
800 }
801 for (const auto f : {&audio_microphone_characteristic_t::geometric_location,
802 &audio_microphone_characteristic_t::orientation}) {
803 for (const auto c : {&audio_microphone_coordinate::x, &audio_microphone_coordinate::y,
804 &audio_microphone_coordinate::z}) {
805 audio_microphone_characteristic_t mic{};
806 mic.*f.*c = AUDIO_MICROPHONE_COORDINATE_UNKNOWN;
807 auto conv = legacy2aidl_audio_microphone_characteristic_t_MicrophoneInfoFw(mic);
808 ASSERT_TRUE(conv.ok());
809 const auto& aidl = conv.value();
810 if (f == &audio_microphone_characteristic_t::geometric_location) {
811 EXPECT_FALSE(aidl.info.position.has_value());
812 EXPECT_TRUE(aidl.info.orientation.has_value());
813 } else {
814 EXPECT_TRUE(aidl.info.position.has_value());
815 EXPECT_FALSE(aidl.info.orientation.has_value());
816 }
817 }
818 }
819 }
820
TEST(AudioMicrophoneInfoFw,ChannelMapping)821 TEST(AudioMicrophoneInfoFw, ChannelMapping) {
822 audio_microphone_characteristic_t mic{};
823 mic.channel_mapping[1] = AUDIO_MICROPHONE_CHANNEL_MAPPING_DIRECT;
824 mic.channel_mapping[3] = AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED;
825 auto conv = legacy2aidl_audio_microphone_characteristic_t_MicrophoneInfoFw(mic);
826 ASSERT_TRUE(conv.ok());
827 const auto& aidl = conv.value();
828 EXPECT_EQ(4, aidl.dynamic.channelMapping.size());
829 EXPECT_EQ(MicrophoneDynamicInfo::ChannelMapping::UNUSED, aidl.dynamic.channelMapping[0]);
830 EXPECT_EQ(MicrophoneDynamicInfo::ChannelMapping::DIRECT, aidl.dynamic.channelMapping[1]);
831 EXPECT_EQ(MicrophoneDynamicInfo::ChannelMapping::UNUSED, aidl.dynamic.channelMapping[2]);
832 EXPECT_EQ(MicrophoneDynamicInfo::ChannelMapping::PROCESSED, aidl.dynamic.channelMapping[3]);
833 }
834