xref: /aosp_15_r20/hardware/interfaces/audio/aidl/default/XsdcConversion.cpp (revision 4d7e907c777eeecc4c5bd7cf640a754fac206ff7)
1*4d7e907cSAndroid Build Coastguard Worker /*
2*4d7e907cSAndroid Build Coastguard Worker  * Copyright (C) 2024 The Android Open Source Project
3*4d7e907cSAndroid Build Coastguard Worker  *
4*4d7e907cSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*4d7e907cSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*4d7e907cSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*4d7e907cSAndroid Build Coastguard Worker  *
8*4d7e907cSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*4d7e907cSAndroid Build Coastguard Worker  *
10*4d7e907cSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*4d7e907cSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*4d7e907cSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*4d7e907cSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*4d7e907cSAndroid Build Coastguard Worker  * limitations under the License.
15*4d7e907cSAndroid Build Coastguard Worker  */
16*4d7e907cSAndroid Build Coastguard Worker 
17*4d7e907cSAndroid Build Coastguard Worker #include <inttypes.h>
18*4d7e907cSAndroid Build Coastguard Worker 
19*4d7e907cSAndroid Build Coastguard Worker #include <unordered_set>
20*4d7e907cSAndroid Build Coastguard Worker 
21*4d7e907cSAndroid Build Coastguard Worker #define LOG_TAG "AHAL_Config"
22*4d7e907cSAndroid Build Coastguard Worker #include <android-base/logging.h>
23*4d7e907cSAndroid Build Coastguard Worker #include <android-base/strings.h>
24*4d7e907cSAndroid Build Coastguard Worker #include <android/binder_enums.h>
25*4d7e907cSAndroid Build Coastguard Worker 
26*4d7e907cSAndroid Build Coastguard Worker #include <aidl/android/media/audio/common/AudioPort.h>
27*4d7e907cSAndroid Build Coastguard Worker #include <aidl/android/media/audio/common/AudioPortConfig.h>
28*4d7e907cSAndroid Build Coastguard Worker #include <media/AidlConversionCppNdk.h>
29*4d7e907cSAndroid Build Coastguard Worker #include <media/TypeConverter.h>
30*4d7e907cSAndroid Build Coastguard Worker #include <media/convert.h>
31*4d7e907cSAndroid Build Coastguard Worker #include <utils/FastStrcmp.h>
32*4d7e907cSAndroid Build Coastguard Worker 
33*4d7e907cSAndroid Build Coastguard Worker #include <Utils.h>
34*4d7e907cSAndroid Build Coastguard Worker 
35*4d7e907cSAndroid Build Coastguard Worker #include "core-impl/XmlConverter.h"
36*4d7e907cSAndroid Build Coastguard Worker #include "core-impl/XsdcConversion.h"
37*4d7e907cSAndroid Build Coastguard Worker 
38*4d7e907cSAndroid Build Coastguard Worker using aidl::android::hardware::audio::common::iequals;
39*4d7e907cSAndroid Build Coastguard Worker using aidl::android::hardware::audio::common::isValidAudioMode;
40*4d7e907cSAndroid Build Coastguard Worker using aidl::android::hardware::audio::common::kValidAudioModes;
41*4d7e907cSAndroid Build Coastguard Worker using aidl::android::media::audio::common::AudioChannelLayout;
42*4d7e907cSAndroid Build Coastguard Worker using aidl::android::media::audio::common::AudioContentType;
43*4d7e907cSAndroid Build Coastguard Worker using aidl::android::media::audio::common::AudioDevice;
44*4d7e907cSAndroid Build Coastguard Worker using aidl::android::media::audio::common::AudioDeviceAddress;
45*4d7e907cSAndroid Build Coastguard Worker using aidl::android::media::audio::common::AudioDeviceDescription;
46*4d7e907cSAndroid Build Coastguard Worker using aidl::android::media::audio::common::AudioDeviceType;
47*4d7e907cSAndroid Build Coastguard Worker using aidl::android::media::audio::common::AudioFormatDescription;
48*4d7e907cSAndroid Build Coastguard Worker using aidl::android::media::audio::common::AudioFormatType;
49*4d7e907cSAndroid Build Coastguard Worker using aidl::android::media::audio::common::AudioGain;
50*4d7e907cSAndroid Build Coastguard Worker using aidl::android::media::audio::common::AudioHalCapCriterion;
51*4d7e907cSAndroid Build Coastguard Worker using aidl::android::media::audio::common::AudioHalCapCriterionType;
52*4d7e907cSAndroid Build Coastguard Worker using aidl::android::media::audio::common::AudioHalCapCriterionV2;
53*4d7e907cSAndroid Build Coastguard Worker using aidl::android::media::audio::common::AudioHalVolumeCurve;
54*4d7e907cSAndroid Build Coastguard Worker using aidl::android::media::audio::common::AudioIoFlags;
55*4d7e907cSAndroid Build Coastguard Worker using aidl::android::media::audio::common::AudioMode;
56*4d7e907cSAndroid Build Coastguard Worker using aidl::android::media::audio::common::AudioPolicyForceUse;
57*4d7e907cSAndroid Build Coastguard Worker using aidl::android::media::audio::common::AudioPort;
58*4d7e907cSAndroid Build Coastguard Worker using aidl::android::media::audio::common::AudioPortConfig;
59*4d7e907cSAndroid Build Coastguard Worker using aidl::android::media::audio::common::AudioPortDeviceExt;
60*4d7e907cSAndroid Build Coastguard Worker using aidl::android::media::audio::common::AudioPortExt;
61*4d7e907cSAndroid Build Coastguard Worker using aidl::android::media::audio::common::AudioPortMixExt;
62*4d7e907cSAndroid Build Coastguard Worker using aidl::android::media::audio::common::AudioProfile;
63*4d7e907cSAndroid Build Coastguard Worker using aidl::android::media::audio::common::AudioSource;
64*4d7e907cSAndroid Build Coastguard Worker using aidl::android::media::audio::common::AudioStreamType;
65*4d7e907cSAndroid Build Coastguard Worker using aidl::android::media::audio::common::AudioUsage;
66*4d7e907cSAndroid Build Coastguard Worker using android::BAD_VALUE;
67*4d7e907cSAndroid Build Coastguard Worker using android::base::unexpected;
68*4d7e907cSAndroid Build Coastguard Worker using android::utilities::convertTo;
69*4d7e907cSAndroid Build Coastguard Worker using ndk::enum_range;
70*4d7e907cSAndroid Build Coastguard Worker 
71*4d7e907cSAndroid Build Coastguard Worker namespace ap_xsd = android::audio::policy::configuration;
72*4d7e907cSAndroid Build Coastguard Worker namespace eng_xsd = android::audio::policy::engine::configuration;
73*4d7e907cSAndroid Build Coastguard Worker 
74*4d7e907cSAndroid Build Coastguard Worker namespace aidl::android::hardware::audio::core::internal {
75*4d7e907cSAndroid Build Coastguard Worker 
76*4d7e907cSAndroid Build Coastguard Worker static constexpr const char kXsdcForceConfigForCommunication[] = "ForceUseForCommunication";
77*4d7e907cSAndroid Build Coastguard Worker static constexpr const char kXsdcForceConfigForMedia[] = "ForceUseForMedia";
78*4d7e907cSAndroid Build Coastguard Worker static constexpr const char kXsdcForceConfigForRecord[] = "ForceUseForRecord";
79*4d7e907cSAndroid Build Coastguard Worker static constexpr const char kXsdcForceConfigForDock[] = "ForceUseForDock";
80*4d7e907cSAndroid Build Coastguard Worker static constexpr const char kXsdcForceConfigForSystem[] = "ForceUseForSystem";
81*4d7e907cSAndroid Build Coastguard Worker static constexpr const char kXsdcForceConfigForHdmiSystemAudio[] = "ForceUseForHdmiSystemAudio";
82*4d7e907cSAndroid Build Coastguard Worker static constexpr const char kXsdcForceConfigForEncodedSurround[] = "ForceUseForEncodedSurround";
83*4d7e907cSAndroid Build Coastguard Worker static constexpr const char kXsdcForceConfigForVibrateRinging[] = "ForceUseForVibrateRinging";
84*4d7e907cSAndroid Build Coastguard Worker 
assertNonEmpty(const std::string & s)85*4d7e907cSAndroid Build Coastguard Worker inline ConversionResult<std::string> assertNonEmpty(const std::string& s) {
86*4d7e907cSAndroid Build Coastguard Worker     if (s.empty()) {
87*4d7e907cSAndroid Build Coastguard Worker         LOG(ERROR) << __func__ << " Review Audio Policy config: "
88*4d7e907cSAndroid Build Coastguard Worker                    << " empty string is not valid.";
89*4d7e907cSAndroid Build Coastguard Worker         return unexpected(BAD_VALUE);
90*4d7e907cSAndroid Build Coastguard Worker     }
91*4d7e907cSAndroid Build Coastguard Worker     return s;
92*4d7e907cSAndroid Build Coastguard Worker }
93*4d7e907cSAndroid Build Coastguard Worker 
94*4d7e907cSAndroid Build Coastguard Worker #define NON_EMPTY_STRING_OR_FATAL(s) VALUE_OR_FATAL(assertNonEmpty(s))
95*4d7e907cSAndroid Build Coastguard Worker 
convertAudioFlagsToAidl(const std::vector<eng_xsd::FlagType> & xsdcFlagTypeVec)96*4d7e907cSAndroid Build Coastguard Worker ConversionResult<int32_t> convertAudioFlagsToAidl(
97*4d7e907cSAndroid Build Coastguard Worker         const std::vector<eng_xsd::FlagType>& xsdcFlagTypeVec) {
98*4d7e907cSAndroid Build Coastguard Worker     int legacyFlagMask = 0;
99*4d7e907cSAndroid Build Coastguard Worker     for (const eng_xsd::FlagType& xsdcFlagType : xsdcFlagTypeVec) {
100*4d7e907cSAndroid Build Coastguard Worker         if (xsdcFlagType != eng_xsd::FlagType::AUDIO_FLAG_NONE) {
101*4d7e907cSAndroid Build Coastguard Worker             audio_flags_mask_t legacyFlag = AUDIO_FLAG_NONE;
102*4d7e907cSAndroid Build Coastguard Worker             if (!::android::AudioFlagConverter::fromString(eng_xsd::toString(xsdcFlagType),
103*4d7e907cSAndroid Build Coastguard Worker                                                            legacyFlag)) {
104*4d7e907cSAndroid Build Coastguard Worker                 LOG(ERROR) << __func__ << " Review Audio Policy config, "
105*4d7e907cSAndroid Build Coastguard Worker                            << eng_xsd::toString(xsdcFlagType) << " is not a valid flag.";
106*4d7e907cSAndroid Build Coastguard Worker                 return unexpected(BAD_VALUE);
107*4d7e907cSAndroid Build Coastguard Worker             }
108*4d7e907cSAndroid Build Coastguard Worker             legacyFlagMask |= static_cast<int>(legacyFlag);
109*4d7e907cSAndroid Build Coastguard Worker         }
110*4d7e907cSAndroid Build Coastguard Worker     }
111*4d7e907cSAndroid Build Coastguard Worker     ConversionResult<int32_t> result = legacy2aidl_audio_flags_mask_t_int32_t_mask(
112*4d7e907cSAndroid Build Coastguard Worker             static_cast<audio_flags_mask_t>(legacyFlagMask));
113*4d7e907cSAndroid Build Coastguard Worker     if (!result.ok()) {
114*4d7e907cSAndroid Build Coastguard Worker         LOG(ERROR) << __func__ << " Review Audio Policy config, " << legacyFlagMask
115*4d7e907cSAndroid Build Coastguard Worker                    << " has invalid flag(s).";
116*4d7e907cSAndroid Build Coastguard Worker         return unexpected(BAD_VALUE);
117*4d7e907cSAndroid Build Coastguard Worker     }
118*4d7e907cSAndroid Build Coastguard Worker     return result;
119*4d7e907cSAndroid Build Coastguard Worker }
120*4d7e907cSAndroid Build Coastguard Worker 
convertAudioStreamTypeToAidl(const eng_xsd::Stream & xsdcStream)121*4d7e907cSAndroid Build Coastguard Worker ConversionResult<AudioStreamType> convertAudioStreamTypeToAidl(const eng_xsd::Stream& xsdcStream) {
122*4d7e907cSAndroid Build Coastguard Worker     audio_stream_type_t legacyStreamType;
123*4d7e907cSAndroid Build Coastguard Worker     if (!::android::StreamTypeConverter::fromString(eng_xsd::toString(xsdcStream),
124*4d7e907cSAndroid Build Coastguard Worker                                                     legacyStreamType)) {
125*4d7e907cSAndroid Build Coastguard Worker         LOG(ERROR) << __func__ << " Review Audio Policy config, " << eng_xsd::toString(xsdcStream)
126*4d7e907cSAndroid Build Coastguard Worker                    << " is not a valid audio stream type.";
127*4d7e907cSAndroid Build Coastguard Worker         return unexpected(BAD_VALUE);
128*4d7e907cSAndroid Build Coastguard Worker     }
129*4d7e907cSAndroid Build Coastguard Worker     ConversionResult<AudioStreamType> result =
130*4d7e907cSAndroid Build Coastguard Worker             legacy2aidl_audio_stream_type_t_AudioStreamType(legacyStreamType);
131*4d7e907cSAndroid Build Coastguard Worker     if (!result.ok()) {
132*4d7e907cSAndroid Build Coastguard Worker         LOG(ERROR) << __func__ << " Review Audio Policy config, " << legacyStreamType
133*4d7e907cSAndroid Build Coastguard Worker                    << " is not a valid audio stream type.";
134*4d7e907cSAndroid Build Coastguard Worker         return unexpected(BAD_VALUE);
135*4d7e907cSAndroid Build Coastguard Worker     }
136*4d7e907cSAndroid Build Coastguard Worker     return result;
137*4d7e907cSAndroid Build Coastguard Worker }
138*4d7e907cSAndroid Build Coastguard Worker 
convertAudioSourceToAidl(const eng_xsd::SourceEnumType & xsdcSourceType)139*4d7e907cSAndroid Build Coastguard Worker ConversionResult<AudioSource> convertAudioSourceToAidl(
140*4d7e907cSAndroid Build Coastguard Worker         const eng_xsd::SourceEnumType& xsdcSourceType) {
141*4d7e907cSAndroid Build Coastguard Worker     audio_source_t legacySourceType;
142*4d7e907cSAndroid Build Coastguard Worker     if (!::android::SourceTypeConverter::fromString(eng_xsd::toString(xsdcSourceType),
143*4d7e907cSAndroid Build Coastguard Worker                                                     legacySourceType)) {
144*4d7e907cSAndroid Build Coastguard Worker         LOG(ERROR) << __func__ << " Review Audio Policy config, "
145*4d7e907cSAndroid Build Coastguard Worker                    << eng_xsd::toString(xsdcSourceType) << " is not a valid audio source.";
146*4d7e907cSAndroid Build Coastguard Worker         return unexpected(BAD_VALUE);
147*4d7e907cSAndroid Build Coastguard Worker     }
148*4d7e907cSAndroid Build Coastguard Worker     ConversionResult<AudioSource> result = legacy2aidl_audio_source_t_AudioSource(legacySourceType);
149*4d7e907cSAndroid Build Coastguard Worker     if (!result.ok()) {
150*4d7e907cSAndroid Build Coastguard Worker         LOG(ERROR) << __func__ << " Review Audio Policy config, " << legacySourceType
151*4d7e907cSAndroid Build Coastguard Worker                    << " is not a valid audio source.";
152*4d7e907cSAndroid Build Coastguard Worker         return unexpected(BAD_VALUE);
153*4d7e907cSAndroid Build Coastguard Worker     }
154*4d7e907cSAndroid Build Coastguard Worker     return result;
155*4d7e907cSAndroid Build Coastguard Worker }
156*4d7e907cSAndroid Build Coastguard Worker 
convertAudioContentTypeToAidl(const eng_xsd::ContentType & xsdcContentType)157*4d7e907cSAndroid Build Coastguard Worker ConversionResult<AudioContentType> convertAudioContentTypeToAidl(
158*4d7e907cSAndroid Build Coastguard Worker         const eng_xsd::ContentType& xsdcContentType) {
159*4d7e907cSAndroid Build Coastguard Worker     audio_content_type_t legacyContentType;
160*4d7e907cSAndroid Build Coastguard Worker     if (!::android::AudioContentTypeConverter::fromString(eng_xsd::toString(xsdcContentType),
161*4d7e907cSAndroid Build Coastguard Worker                                                           legacyContentType)) {
162*4d7e907cSAndroid Build Coastguard Worker         LOG(ERROR) << __func__ << " Review Audio Policy config, "
163*4d7e907cSAndroid Build Coastguard Worker                    << eng_xsd::toString(xsdcContentType) << " is not a valid audio content type.";
164*4d7e907cSAndroid Build Coastguard Worker         return unexpected(BAD_VALUE);
165*4d7e907cSAndroid Build Coastguard Worker     }
166*4d7e907cSAndroid Build Coastguard Worker     ConversionResult<AudioContentType> result =
167*4d7e907cSAndroid Build Coastguard Worker             legacy2aidl_audio_content_type_t_AudioContentType(legacyContentType);
168*4d7e907cSAndroid Build Coastguard Worker     if (!result.ok()) {
169*4d7e907cSAndroid Build Coastguard Worker         LOG(ERROR) << __func__ << " Review Audio Policy config, " << legacyContentType
170*4d7e907cSAndroid Build Coastguard Worker                    << " is not a valid audio content type.";
171*4d7e907cSAndroid Build Coastguard Worker         return unexpected(BAD_VALUE);
172*4d7e907cSAndroid Build Coastguard Worker     }
173*4d7e907cSAndroid Build Coastguard Worker     return result;
174*4d7e907cSAndroid Build Coastguard Worker }
175*4d7e907cSAndroid Build Coastguard Worker 
convertAudioUsageToAidl(const eng_xsd::UsageEnumType & xsdcUsage)176*4d7e907cSAndroid Build Coastguard Worker ConversionResult<AudioUsage> convertAudioUsageToAidl(const eng_xsd::UsageEnumType& xsdcUsage) {
177*4d7e907cSAndroid Build Coastguard Worker     audio_usage_t legacyUsage;
178*4d7e907cSAndroid Build Coastguard Worker     if (!::android::UsageTypeConverter::fromString(eng_xsd::toString(xsdcUsage), legacyUsage)) {
179*4d7e907cSAndroid Build Coastguard Worker         LOG(ERROR) << __func__ << " Review Audio Policy config, not a valid audio usage.";
180*4d7e907cSAndroid Build Coastguard Worker         return unexpected(BAD_VALUE);
181*4d7e907cSAndroid Build Coastguard Worker     }
182*4d7e907cSAndroid Build Coastguard Worker     ConversionResult<AudioUsage> result = legacy2aidl_audio_usage_t_AudioUsage(legacyUsage);
183*4d7e907cSAndroid Build Coastguard Worker     if (!result.ok()) {
184*4d7e907cSAndroid Build Coastguard Worker         LOG(ERROR) << __func__ << " Review Audio Policy config, not a valid audio usage.";
185*4d7e907cSAndroid Build Coastguard Worker         return unexpected(BAD_VALUE);
186*4d7e907cSAndroid Build Coastguard Worker     }
187*4d7e907cSAndroid Build Coastguard Worker     return result;
188*4d7e907cSAndroid Build Coastguard Worker }
189*4d7e907cSAndroid Build Coastguard Worker 
convertAudioFormatToAidl(const std::string & xsdcFormat)190*4d7e907cSAndroid Build Coastguard Worker ConversionResult<AudioFormatDescription> convertAudioFormatToAidl(const std::string& xsdcFormat) {
191*4d7e907cSAndroid Build Coastguard Worker     audio_format_t legacyFormat = ::android::formatFromString(xsdcFormat, AUDIO_FORMAT_DEFAULT);
192*4d7e907cSAndroid Build Coastguard Worker     ConversionResult<AudioFormatDescription> result =
193*4d7e907cSAndroid Build Coastguard Worker             legacy2aidl_audio_format_t_AudioFormatDescription(legacyFormat);
194*4d7e907cSAndroid Build Coastguard Worker     if ((legacyFormat == AUDIO_FORMAT_DEFAULT && xsdcFormat.compare("AUDIO_FORMAT_DEFAULT") != 0) ||
195*4d7e907cSAndroid Build Coastguard Worker         !result.ok()) {
196*4d7e907cSAndroid Build Coastguard Worker         LOG(ERROR) << __func__ << " Review Audio Policy config: " << xsdcFormat
197*4d7e907cSAndroid Build Coastguard Worker                    << " is not a valid audio format.";
198*4d7e907cSAndroid Build Coastguard Worker         return unexpected(BAD_VALUE);
199*4d7e907cSAndroid Build Coastguard Worker     }
200*4d7e907cSAndroid Build Coastguard Worker     return result;
201*4d7e907cSAndroid Build Coastguard Worker }
202*4d7e907cSAndroid Build Coastguard Worker 
getAttachedDevices(const ap_xsd::Modules::Module & moduleConfig)203*4d7e907cSAndroid Build Coastguard Worker std::unordered_set<std::string> getAttachedDevices(const ap_xsd::Modules::Module& moduleConfig) {
204*4d7e907cSAndroid Build Coastguard Worker     std::unordered_set<std::string> attachedDeviceSet;
205*4d7e907cSAndroid Build Coastguard Worker     if (moduleConfig.hasAttachedDevices()) {
206*4d7e907cSAndroid Build Coastguard Worker         for (const ap_xsd::AttachedDevices& attachedDevices : moduleConfig.getAttachedDevices()) {
207*4d7e907cSAndroid Build Coastguard Worker             if (attachedDevices.hasItem()) {
208*4d7e907cSAndroid Build Coastguard Worker                 attachedDeviceSet.insert(attachedDevices.getItem().begin(),
209*4d7e907cSAndroid Build Coastguard Worker                                          attachedDevices.getItem().end());
210*4d7e907cSAndroid Build Coastguard Worker             }
211*4d7e907cSAndroid Build Coastguard Worker         }
212*4d7e907cSAndroid Build Coastguard Worker     }
213*4d7e907cSAndroid Build Coastguard Worker     return attachedDeviceSet;
214*4d7e907cSAndroid Build Coastguard Worker }
215*4d7e907cSAndroid Build Coastguard Worker 
convertDeviceTypeToAidl(const std::string & xType)216*4d7e907cSAndroid Build Coastguard Worker ConversionResult<AudioDeviceDescription> convertDeviceTypeToAidl(const std::string& xType) {
217*4d7e907cSAndroid Build Coastguard Worker     audio_devices_t legacyDeviceType = AUDIO_DEVICE_NONE;
218*4d7e907cSAndroid Build Coastguard Worker     ::android::DeviceConverter::fromString(xType, legacyDeviceType);
219*4d7e907cSAndroid Build Coastguard Worker     ConversionResult<AudioDeviceDescription> result =
220*4d7e907cSAndroid Build Coastguard Worker             legacy2aidl_audio_devices_t_AudioDeviceDescription(legacyDeviceType);
221*4d7e907cSAndroid Build Coastguard Worker     if ((legacyDeviceType == AUDIO_DEVICE_NONE) || !result.ok()) {
222*4d7e907cSAndroid Build Coastguard Worker         LOG(ERROR) << __func__ << " Review Audio Policy config: " << xType
223*4d7e907cSAndroid Build Coastguard Worker                    << " is not a valid device type.";
224*4d7e907cSAndroid Build Coastguard Worker         return unexpected(BAD_VALUE);
225*4d7e907cSAndroid Build Coastguard Worker     }
226*4d7e907cSAndroid Build Coastguard Worker     return result;
227*4d7e907cSAndroid Build Coastguard Worker }
228*4d7e907cSAndroid Build Coastguard Worker 
createAudioDevice(const ap_xsd::DevicePorts::DevicePort & xDevicePort)229*4d7e907cSAndroid Build Coastguard Worker ConversionResult<AudioDevice> createAudioDevice(
230*4d7e907cSAndroid Build Coastguard Worker         const ap_xsd::DevicePorts::DevicePort& xDevicePort) {
231*4d7e907cSAndroid Build Coastguard Worker     AudioDevice device = {
232*4d7e907cSAndroid Build Coastguard Worker             .type = VALUE_OR_FATAL(convertDeviceTypeToAidl(xDevicePort.getType())),
233*4d7e907cSAndroid Build Coastguard Worker             .address = xDevicePort.hasAddress()
234*4d7e907cSAndroid Build Coastguard Worker                                ? AudioDeviceAddress::make<AudioDeviceAddress::Tag::id>(
235*4d7e907cSAndroid Build Coastguard Worker                                          xDevicePort.getAddress())
236*4d7e907cSAndroid Build Coastguard Worker                                : AudioDeviceAddress{}};
237*4d7e907cSAndroid Build Coastguard Worker     if (device.type.type == AudioDeviceType::IN_MICROPHONE && device.type.connection.empty()) {
238*4d7e907cSAndroid Build Coastguard Worker         device.address = "bottom";
239*4d7e907cSAndroid Build Coastguard Worker     } else if (device.type.type == AudioDeviceType::IN_MICROPHONE_BACK &&
240*4d7e907cSAndroid Build Coastguard Worker                device.type.connection.empty()) {
241*4d7e907cSAndroid Build Coastguard Worker         device.address = "back";
242*4d7e907cSAndroid Build Coastguard Worker     }
243*4d7e907cSAndroid Build Coastguard Worker     return device;
244*4d7e907cSAndroid Build Coastguard Worker }
245*4d7e907cSAndroid Build Coastguard Worker 
createAudioPortExt(const ap_xsd::DevicePorts::DevicePort & xDevicePort,const std::string & xDefaultOutputDevice)246*4d7e907cSAndroid Build Coastguard Worker ConversionResult<AudioPortExt> createAudioPortExt(
247*4d7e907cSAndroid Build Coastguard Worker         const ap_xsd::DevicePorts::DevicePort& xDevicePort,
248*4d7e907cSAndroid Build Coastguard Worker         const std::string& xDefaultOutputDevice) {
249*4d7e907cSAndroid Build Coastguard Worker     AudioPortDeviceExt deviceExt = {
250*4d7e907cSAndroid Build Coastguard Worker             .device = VALUE_OR_FATAL(createAudioDevice(xDevicePort)),
251*4d7e907cSAndroid Build Coastguard Worker             .flags = (xDevicePort.getTagName() == xDefaultOutputDevice)
252*4d7e907cSAndroid Build Coastguard Worker                              ? 1 << AudioPortDeviceExt::FLAG_INDEX_DEFAULT_DEVICE
253*4d7e907cSAndroid Build Coastguard Worker                              : 0,
254*4d7e907cSAndroid Build Coastguard Worker             .encodedFormats =
255*4d7e907cSAndroid Build Coastguard Worker                     xDevicePort.hasEncodedFormats()
256*4d7e907cSAndroid Build Coastguard Worker                             ? VALUE_OR_FATAL(
257*4d7e907cSAndroid Build Coastguard Worker                                       (convertCollectionToAidl<std::string, AudioFormatDescription>(
258*4d7e907cSAndroid Build Coastguard Worker                                               xDevicePort.getEncodedFormats(),
259*4d7e907cSAndroid Build Coastguard Worker                                               &convertAudioFormatToAidl)))
260*4d7e907cSAndroid Build Coastguard Worker                             : std::vector<AudioFormatDescription>{},
261*4d7e907cSAndroid Build Coastguard Worker     };
262*4d7e907cSAndroid Build Coastguard Worker     return AudioPortExt::make<AudioPortExt::Tag::device>(deviceExt);
263*4d7e907cSAndroid Build Coastguard Worker }
264*4d7e907cSAndroid Build Coastguard Worker 
createAudioPortExt(const ap_xsd::MixPorts::MixPort & xMixPort)265*4d7e907cSAndroid Build Coastguard Worker ConversionResult<AudioPortExt> createAudioPortExt(const ap_xsd::MixPorts::MixPort& xMixPort) {
266*4d7e907cSAndroid Build Coastguard Worker     AudioPortMixExt mixExt = {
267*4d7e907cSAndroid Build Coastguard Worker             .maxOpenStreamCount =
268*4d7e907cSAndroid Build Coastguard Worker                     xMixPort.hasMaxOpenCount() ? static_cast<int>(xMixPort.getMaxOpenCount()) : 0,
269*4d7e907cSAndroid Build Coastguard Worker             .maxActiveStreamCount = xMixPort.hasMaxActiveCount()
270*4d7e907cSAndroid Build Coastguard Worker                                             ? static_cast<int>(xMixPort.getMaxActiveCount())
271*4d7e907cSAndroid Build Coastguard Worker                                             : 1,
272*4d7e907cSAndroid Build Coastguard Worker             .recommendedMuteDurationMs =
273*4d7e907cSAndroid Build Coastguard Worker                     xMixPort.hasRecommendedMuteDurationMs()
274*4d7e907cSAndroid Build Coastguard Worker                             ? static_cast<int>(xMixPort.getRecommendedMuteDurationMs())
275*4d7e907cSAndroid Build Coastguard Worker                             : 0};
276*4d7e907cSAndroid Build Coastguard Worker     return AudioPortExt::make<AudioPortExt::Tag::mix>(mixExt);
277*4d7e907cSAndroid Build Coastguard Worker }
278*4d7e907cSAndroid Build Coastguard Worker 
convertGainModeToAidl(const std::vector<ap_xsd::AudioGainMode> & gainModeVec)279*4d7e907cSAndroid Build Coastguard Worker ConversionResult<int> convertGainModeToAidl(const std::vector<ap_xsd::AudioGainMode>& gainModeVec) {
280*4d7e907cSAndroid Build Coastguard Worker     int gainModeMask = 0;
281*4d7e907cSAndroid Build Coastguard Worker     for (const ap_xsd::AudioGainMode& gainMode : gainModeVec) {
282*4d7e907cSAndroid Build Coastguard Worker         audio_gain_mode_t legacyGainMode;
283*4d7e907cSAndroid Build Coastguard Worker         if (::android::GainModeConverter::fromString(ap_xsd::toString(gainMode), legacyGainMode)) {
284*4d7e907cSAndroid Build Coastguard Worker             gainModeMask |= static_cast<int>(legacyGainMode);
285*4d7e907cSAndroid Build Coastguard Worker         }
286*4d7e907cSAndroid Build Coastguard Worker     }
287*4d7e907cSAndroid Build Coastguard Worker     return gainModeMask;
288*4d7e907cSAndroid Build Coastguard Worker }
289*4d7e907cSAndroid Build Coastguard Worker 
convertChannelMaskToAidl(const ap_xsd::AudioChannelMask & xChannelMask)290*4d7e907cSAndroid Build Coastguard Worker ConversionResult<AudioChannelLayout> convertChannelMaskToAidl(
291*4d7e907cSAndroid Build Coastguard Worker         const ap_xsd::AudioChannelMask& xChannelMask) {
292*4d7e907cSAndroid Build Coastguard Worker     std::string xChannelMaskLiteral = ap_xsd::toString(xChannelMask);
293*4d7e907cSAndroid Build Coastguard Worker     audio_channel_mask_t legacyChannelMask = ::android::channelMaskFromString(xChannelMaskLiteral);
294*4d7e907cSAndroid Build Coastguard Worker     ConversionResult<AudioChannelLayout> result =
295*4d7e907cSAndroid Build Coastguard Worker             legacy2aidl_audio_channel_mask_t_AudioChannelLayout(
296*4d7e907cSAndroid Build Coastguard Worker                     legacyChannelMask,
297*4d7e907cSAndroid Build Coastguard Worker                     /* isInput= */ xChannelMaskLiteral.find("AUDIO_CHANNEL_IN_") == 0);
298*4d7e907cSAndroid Build Coastguard Worker     if ((legacyChannelMask == AUDIO_CHANNEL_INVALID) || !result.ok()) {
299*4d7e907cSAndroid Build Coastguard Worker         LOG(ERROR) << __func__ << " Review Audio Policy config: " << xChannelMaskLiteral
300*4d7e907cSAndroid Build Coastguard Worker                    << " is not a valid audio channel mask.";
301*4d7e907cSAndroid Build Coastguard Worker         return unexpected(BAD_VALUE);
302*4d7e907cSAndroid Build Coastguard Worker     }
303*4d7e907cSAndroid Build Coastguard Worker     return result;
304*4d7e907cSAndroid Build Coastguard Worker }
305*4d7e907cSAndroid Build Coastguard Worker 
convertGainToAidl(const ap_xsd::Gains::Gain & xGain)306*4d7e907cSAndroid Build Coastguard Worker ConversionResult<AudioGain> convertGainToAidl(const ap_xsd::Gains::Gain& xGain) {
307*4d7e907cSAndroid Build Coastguard Worker     return AudioGain{
308*4d7e907cSAndroid Build Coastguard Worker             .mode = VALUE_OR_FATAL(convertGainModeToAidl(xGain.getMode())),
309*4d7e907cSAndroid Build Coastguard Worker             .channelMask =
310*4d7e907cSAndroid Build Coastguard Worker                     xGain.hasChannel_mask()
311*4d7e907cSAndroid Build Coastguard Worker                             ? VALUE_OR_FATAL(convertChannelMaskToAidl(xGain.getChannel_mask()))
312*4d7e907cSAndroid Build Coastguard Worker                             : AudioChannelLayout{},
313*4d7e907cSAndroid Build Coastguard Worker             .minValue = xGain.hasMinValueMB() ? xGain.getMinValueMB() : 0,
314*4d7e907cSAndroid Build Coastguard Worker             .maxValue = xGain.hasMaxValueMB() ? xGain.getMaxValueMB() : 0,
315*4d7e907cSAndroid Build Coastguard Worker             .defaultValue = xGain.hasDefaultValueMB() ? xGain.getDefaultValueMB() : 0,
316*4d7e907cSAndroid Build Coastguard Worker             .stepValue = xGain.hasStepValueMB() ? xGain.getStepValueMB() : 0,
317*4d7e907cSAndroid Build Coastguard Worker             .minRampMs = xGain.hasMinRampMs() ? xGain.getMinRampMs() : 0,
318*4d7e907cSAndroid Build Coastguard Worker             .maxRampMs = xGain.hasMaxRampMs() ? xGain.getMaxRampMs() : 0,
319*4d7e907cSAndroid Build Coastguard Worker             .useForVolume = xGain.hasUseForVolume() ? xGain.getUseForVolume() : false,
320*4d7e907cSAndroid Build Coastguard Worker     };
321*4d7e907cSAndroid Build Coastguard Worker }
322*4d7e907cSAndroid Build Coastguard Worker 
convertAudioProfileToAidl(const ap_xsd::Profile & xProfile)323*4d7e907cSAndroid Build Coastguard Worker ConversionResult<AudioProfile> convertAudioProfileToAidl(const ap_xsd::Profile& xProfile) {
324*4d7e907cSAndroid Build Coastguard Worker     return AudioProfile{
325*4d7e907cSAndroid Build Coastguard Worker             .format = xProfile.hasFormat()
326*4d7e907cSAndroid Build Coastguard Worker                               ? VALUE_OR_FATAL(convertAudioFormatToAidl(xProfile.getFormat()))
327*4d7e907cSAndroid Build Coastguard Worker                               : AudioFormatDescription{},
328*4d7e907cSAndroid Build Coastguard Worker             .channelMasks =
329*4d7e907cSAndroid Build Coastguard Worker                     xProfile.hasChannelMasks()
330*4d7e907cSAndroid Build Coastguard Worker                             ? VALUE_OR_FATAL((convertCollectionToAidl<ap_xsd::AudioChannelMask,
331*4d7e907cSAndroid Build Coastguard Worker                                                                       AudioChannelLayout>(
332*4d7e907cSAndroid Build Coastguard Worker                                       xProfile.getChannelMasks(), &convertChannelMaskToAidl)))
333*4d7e907cSAndroid Build Coastguard Worker                             : std::vector<AudioChannelLayout>{},
334*4d7e907cSAndroid Build Coastguard Worker             .sampleRates = xProfile.hasSamplingRates()
335*4d7e907cSAndroid Build Coastguard Worker                                    ? VALUE_OR_FATAL((convertCollectionToAidl<int64_t, int>(
336*4d7e907cSAndroid Build Coastguard Worker                                              xProfile.getSamplingRates(),
337*4d7e907cSAndroid Build Coastguard Worker                                              [](const int64_t x) -> int { return x; })))
338*4d7e907cSAndroid Build Coastguard Worker                                    : std::vector<int>{}};
339*4d7e907cSAndroid Build Coastguard Worker }
340*4d7e907cSAndroid Build Coastguard Worker 
convertIoFlagsToAidl(const std::vector<ap_xsd::AudioInOutFlag> & flags,const ap_xsd::Role role,bool flagsForMixPort)341*4d7e907cSAndroid Build Coastguard Worker ConversionResult<AudioIoFlags> convertIoFlagsToAidl(
342*4d7e907cSAndroid Build Coastguard Worker         const std::vector<ap_xsd::AudioInOutFlag>& flags, const ap_xsd::Role role,
343*4d7e907cSAndroid Build Coastguard Worker         bool flagsForMixPort) {
344*4d7e907cSAndroid Build Coastguard Worker     int legacyFlagMask = 0;
345*4d7e907cSAndroid Build Coastguard Worker     if ((role == ap_xsd::Role::sink && flagsForMixPort) ||
346*4d7e907cSAndroid Build Coastguard Worker         (role == ap_xsd::Role::source && !flagsForMixPort)) {
347*4d7e907cSAndroid Build Coastguard Worker         for (const ap_xsd::AudioInOutFlag& flag : flags) {
348*4d7e907cSAndroid Build Coastguard Worker             audio_input_flags_t legacyFlag;
349*4d7e907cSAndroid Build Coastguard Worker             if (::android::InputFlagConverter::fromString(ap_xsd::toString(flag), legacyFlag)) {
350*4d7e907cSAndroid Build Coastguard Worker                 legacyFlagMask |= static_cast<int>(legacyFlag);
351*4d7e907cSAndroid Build Coastguard Worker             }
352*4d7e907cSAndroid Build Coastguard Worker         }
353*4d7e907cSAndroid Build Coastguard Worker         return AudioIoFlags::make<AudioIoFlags::Tag::input>(
354*4d7e907cSAndroid Build Coastguard Worker                 VALUE_OR_FATAL(legacy2aidl_audio_input_flags_t_int32_t_mask(
355*4d7e907cSAndroid Build Coastguard Worker                         static_cast<audio_input_flags_t>(legacyFlagMask))));
356*4d7e907cSAndroid Build Coastguard Worker     } else {
357*4d7e907cSAndroid Build Coastguard Worker         for (const ap_xsd::AudioInOutFlag& flag : flags) {
358*4d7e907cSAndroid Build Coastguard Worker             audio_output_flags_t legacyFlag;
359*4d7e907cSAndroid Build Coastguard Worker             if (::android::OutputFlagConverter::fromString(ap_xsd::toString(flag), legacyFlag)) {
360*4d7e907cSAndroid Build Coastguard Worker                 legacyFlagMask |= static_cast<int>(legacyFlag);
361*4d7e907cSAndroid Build Coastguard Worker             }
362*4d7e907cSAndroid Build Coastguard Worker         }
363*4d7e907cSAndroid Build Coastguard Worker         return AudioIoFlags::make<AudioIoFlags::Tag::output>(
364*4d7e907cSAndroid Build Coastguard Worker                 VALUE_OR_FATAL(legacy2aidl_audio_output_flags_t_int32_t_mask(
365*4d7e907cSAndroid Build Coastguard Worker                         static_cast<audio_output_flags_t>(legacyFlagMask))));
366*4d7e907cSAndroid Build Coastguard Worker     }
367*4d7e907cSAndroid Build Coastguard Worker }
368*4d7e907cSAndroid Build Coastguard Worker 
convertDevicePortToAidl(const ap_xsd::DevicePorts::DevicePort & xDevicePort,const std::string & xDefaultOutputDevice,int32_t & nextPortId)369*4d7e907cSAndroid Build Coastguard Worker ConversionResult<AudioPort> convertDevicePortToAidl(
370*4d7e907cSAndroid Build Coastguard Worker         const ap_xsd::DevicePorts::DevicePort& xDevicePort, const std::string& xDefaultOutputDevice,
371*4d7e907cSAndroid Build Coastguard Worker         int32_t& nextPortId) {
372*4d7e907cSAndroid Build Coastguard Worker     return AudioPort{
373*4d7e907cSAndroid Build Coastguard Worker             .id = nextPortId++,
374*4d7e907cSAndroid Build Coastguard Worker             .name = NON_EMPTY_STRING_OR_FATAL(xDevicePort.getTagName()),
375*4d7e907cSAndroid Build Coastguard Worker             .profiles = VALUE_OR_FATAL((convertCollectionToAidl<ap_xsd::Profile, AudioProfile>(
376*4d7e907cSAndroid Build Coastguard Worker                     xDevicePort.getProfile(), convertAudioProfileToAidl))),
377*4d7e907cSAndroid Build Coastguard Worker             .flags = VALUE_OR_FATAL(convertIoFlagsToAidl({}, xDevicePort.getRole(), false)),
378*4d7e907cSAndroid Build Coastguard Worker             .gains = VALUE_OR_FATAL(
379*4d7e907cSAndroid Build Coastguard Worker                     (convertWrappedCollectionToAidl<ap_xsd::Gains, ap_xsd::Gains::Gain, AudioGain>(
380*4d7e907cSAndroid Build Coastguard Worker                             xDevicePort.getGains(), &ap_xsd::Gains::getGain, convertGainToAidl))),
381*4d7e907cSAndroid Build Coastguard Worker 
382*4d7e907cSAndroid Build Coastguard Worker             .ext = VALUE_OR_FATAL(createAudioPortExt(xDevicePort, xDefaultOutputDevice))};
383*4d7e907cSAndroid Build Coastguard Worker }
384*4d7e907cSAndroid Build Coastguard Worker 
convertDevicePortsInModuleToAidl(const ap_xsd::Modules::Module & xModuleConfig,int32_t & nextPortId)385*4d7e907cSAndroid Build Coastguard Worker ConversionResult<std::vector<AudioPort>> convertDevicePortsInModuleToAidl(
386*4d7e907cSAndroid Build Coastguard Worker         const ap_xsd::Modules::Module& xModuleConfig, int32_t& nextPortId) {
387*4d7e907cSAndroid Build Coastguard Worker     std::vector<AudioPort> audioPortVec;
388*4d7e907cSAndroid Build Coastguard Worker     std::vector<ap_xsd::DevicePorts> xDevicePortsVec = xModuleConfig.getDevicePorts();
389*4d7e907cSAndroid Build Coastguard Worker     if (xDevicePortsVec.size() > 1) {
390*4d7e907cSAndroid Build Coastguard Worker         LOG(ERROR) << __func__ << "Having multiple '<devicePorts>' elements is not allowed, found: "
391*4d7e907cSAndroid Build Coastguard Worker                    << xDevicePortsVec.size();
392*4d7e907cSAndroid Build Coastguard Worker         return unexpected(BAD_VALUE);
393*4d7e907cSAndroid Build Coastguard Worker     }
394*4d7e907cSAndroid Build Coastguard Worker     if (!xDevicePortsVec.empty()) {
395*4d7e907cSAndroid Build Coastguard Worker         const std::string xDefaultOutputDevice = xModuleConfig.hasDefaultOutputDevice()
396*4d7e907cSAndroid Build Coastguard Worker                                                          ? xModuleConfig.getDefaultOutputDevice()
397*4d7e907cSAndroid Build Coastguard Worker                                                          : "";
398*4d7e907cSAndroid Build Coastguard Worker         audioPortVec.reserve(xDevicePortsVec[0].getDevicePort().size());
399*4d7e907cSAndroid Build Coastguard Worker         for (const ap_xsd::DevicePorts& xDevicePortsType : xDevicePortsVec) {
400*4d7e907cSAndroid Build Coastguard Worker             for (const ap_xsd::DevicePorts::DevicePort& xDevicePort :
401*4d7e907cSAndroid Build Coastguard Worker                  xDevicePortsType.getDevicePort()) {
402*4d7e907cSAndroid Build Coastguard Worker                 audioPortVec.push_back(VALUE_OR_FATAL(
403*4d7e907cSAndroid Build Coastguard Worker                         convertDevicePortToAidl(xDevicePort, xDefaultOutputDevice, nextPortId)));
404*4d7e907cSAndroid Build Coastguard Worker             }
405*4d7e907cSAndroid Build Coastguard Worker         }
406*4d7e907cSAndroid Build Coastguard Worker     }
407*4d7e907cSAndroid Build Coastguard Worker     const std::unordered_set<std::string> xAttachedDeviceSet = getAttachedDevices(xModuleConfig);
408*4d7e907cSAndroid Build Coastguard Worker     for (const auto& port : audioPortVec) {
409*4d7e907cSAndroid Build Coastguard Worker         const auto& devicePort = port.ext.get<AudioPortExt::device>();
410*4d7e907cSAndroid Build Coastguard Worker         if (xAttachedDeviceSet.count(port.name) != devicePort.device.type.connection.empty()) {
411*4d7e907cSAndroid Build Coastguard Worker             LOG(ERROR) << __func__ << ": Review Audio Policy config: <attachedDevices> "
412*4d7e907cSAndroid Build Coastguard Worker                        << "list is incorrect or devicePort \"" << port.name
413*4d7e907cSAndroid Build Coastguard Worker                        << "\" type= " << devicePort.device.type.toString() << " is incorrect.";
414*4d7e907cSAndroid Build Coastguard Worker             return unexpected(BAD_VALUE);
415*4d7e907cSAndroid Build Coastguard Worker         }
416*4d7e907cSAndroid Build Coastguard Worker     }
417*4d7e907cSAndroid Build Coastguard Worker     return audioPortVec;
418*4d7e907cSAndroid Build Coastguard Worker }
419*4d7e907cSAndroid Build Coastguard Worker 
convertMixPortToAidl(const ap_xsd::MixPorts::MixPort & xMixPort,int32_t & nextPortId)420*4d7e907cSAndroid Build Coastguard Worker ConversionResult<AudioPort> convertMixPortToAidl(const ap_xsd::MixPorts::MixPort& xMixPort,
421*4d7e907cSAndroid Build Coastguard Worker                                                  int32_t& nextPortId) {
422*4d7e907cSAndroid Build Coastguard Worker     return AudioPort{
423*4d7e907cSAndroid Build Coastguard Worker             .id = nextPortId++,
424*4d7e907cSAndroid Build Coastguard Worker             .name = NON_EMPTY_STRING_OR_FATAL(xMixPort.getName()),
425*4d7e907cSAndroid Build Coastguard Worker             .profiles = VALUE_OR_FATAL((convertCollectionToAidl<ap_xsd::Profile, AudioProfile>(
426*4d7e907cSAndroid Build Coastguard Worker                     xMixPort.getProfile(), convertAudioProfileToAidl))),
427*4d7e907cSAndroid Build Coastguard Worker             .flags = xMixPort.hasFlags()
428*4d7e907cSAndroid Build Coastguard Worker                              ? VALUE_OR_FATAL(convertIoFlagsToAidl(xMixPort.getFlags(),
429*4d7e907cSAndroid Build Coastguard Worker                                                                    xMixPort.getRole(), true))
430*4d7e907cSAndroid Build Coastguard Worker                              : VALUE_OR_FATAL(convertIoFlagsToAidl({}, xMixPort.getRole(), true)),
431*4d7e907cSAndroid Build Coastguard Worker             .gains = VALUE_OR_FATAL(
432*4d7e907cSAndroid Build Coastguard Worker                     (convertWrappedCollectionToAidl<ap_xsd::Gains, ap_xsd::Gains::Gain, AudioGain>(
433*4d7e907cSAndroid Build Coastguard Worker                             xMixPort.getGains(), &ap_xsd::Gains::getGain, &convertGainToAidl))),
434*4d7e907cSAndroid Build Coastguard Worker             .ext = VALUE_OR_FATAL(createAudioPortExt(xMixPort)),
435*4d7e907cSAndroid Build Coastguard Worker     };
436*4d7e907cSAndroid Build Coastguard Worker }
437*4d7e907cSAndroid Build Coastguard Worker 
convertMixPortsInModuleToAidl(const ap_xsd::Modules::Module & xModuleConfig,int32_t & nextPortId)438*4d7e907cSAndroid Build Coastguard Worker ConversionResult<std::vector<AudioPort>> convertMixPortsInModuleToAidl(
439*4d7e907cSAndroid Build Coastguard Worker         const ap_xsd::Modules::Module& xModuleConfig, int32_t& nextPortId) {
440*4d7e907cSAndroid Build Coastguard Worker     std::vector<AudioPort> audioPortVec;
441*4d7e907cSAndroid Build Coastguard Worker     std::vector<ap_xsd::MixPorts> xMixPortsVec = xModuleConfig.getMixPorts();
442*4d7e907cSAndroid Build Coastguard Worker     if (xMixPortsVec.size() > 1) {
443*4d7e907cSAndroid Build Coastguard Worker         LOG(ERROR) << __func__ << "Having multiple '<mixPorts>' elements is not allowed, found: "
444*4d7e907cSAndroid Build Coastguard Worker                    << xMixPortsVec.size();
445*4d7e907cSAndroid Build Coastguard Worker         return unexpected(BAD_VALUE);
446*4d7e907cSAndroid Build Coastguard Worker     }
447*4d7e907cSAndroid Build Coastguard Worker     if (!xMixPortsVec.empty()) {
448*4d7e907cSAndroid Build Coastguard Worker         audioPortVec.reserve(xMixPortsVec[0].getMixPort().size());
449*4d7e907cSAndroid Build Coastguard Worker         for (const ap_xsd::MixPorts& xMixPortsType : xMixPortsVec) {
450*4d7e907cSAndroid Build Coastguard Worker             for (const ap_xsd::MixPorts::MixPort& xMixPort : xMixPortsType.getMixPort()) {
451*4d7e907cSAndroid Build Coastguard Worker                 audioPortVec.push_back(VALUE_OR_FATAL(convertMixPortToAidl(xMixPort, nextPortId)));
452*4d7e907cSAndroid Build Coastguard Worker             }
453*4d7e907cSAndroid Build Coastguard Worker         }
454*4d7e907cSAndroid Build Coastguard Worker     }
455*4d7e907cSAndroid Build Coastguard Worker     return audioPortVec;
456*4d7e907cSAndroid Build Coastguard Worker }
457*4d7e907cSAndroid Build Coastguard Worker 
getSinkPortId(const ap_xsd::Routes::Route & xRoute,const std::unordered_map<std::string,int32_t> & portMap)458*4d7e907cSAndroid Build Coastguard Worker ConversionResult<int32_t> getSinkPortId(const ap_xsd::Routes::Route& xRoute,
459*4d7e907cSAndroid Build Coastguard Worker                                         const std::unordered_map<std::string, int32_t>& portMap) {
460*4d7e907cSAndroid Build Coastguard Worker     auto portMapIter = portMap.find(xRoute.getSink());
461*4d7e907cSAndroid Build Coastguard Worker     if (portMapIter == portMap.end()) {
462*4d7e907cSAndroid Build Coastguard Worker         LOG(ERROR) << __func__ << " Review Audio Policy config: audio route"
463*4d7e907cSAndroid Build Coastguard Worker                    << "has sink: " << xRoute.getSink()
464*4d7e907cSAndroid Build Coastguard Worker                    << " which is neither a device port nor mix port.";
465*4d7e907cSAndroid Build Coastguard Worker         return unexpected(BAD_VALUE);
466*4d7e907cSAndroid Build Coastguard Worker     }
467*4d7e907cSAndroid Build Coastguard Worker     return portMapIter->second;
468*4d7e907cSAndroid Build Coastguard Worker }
469*4d7e907cSAndroid Build Coastguard Worker 
getSourcePortIds(const ap_xsd::Routes::Route & xRoute,const std::unordered_map<std::string,int32_t> & portMap)470*4d7e907cSAndroid Build Coastguard Worker ConversionResult<std::vector<int32_t>> getSourcePortIds(
471*4d7e907cSAndroid Build Coastguard Worker         const ap_xsd::Routes::Route& xRoute,
472*4d7e907cSAndroid Build Coastguard Worker         const std::unordered_map<std::string, int32_t>& portMap) {
473*4d7e907cSAndroid Build Coastguard Worker     std::vector<int32_t> sourcePortIds;
474*4d7e907cSAndroid Build Coastguard Worker     for (const std::string& rawSource : ::android::base::Split(xRoute.getSources(), ",")) {
475*4d7e907cSAndroid Build Coastguard Worker         const std::string source = ::android::base::Trim(rawSource);
476*4d7e907cSAndroid Build Coastguard Worker         auto portMapIter = portMap.find(source);
477*4d7e907cSAndroid Build Coastguard Worker         if (portMapIter == portMap.end()) {
478*4d7e907cSAndroid Build Coastguard Worker             LOG(ERROR) << __func__ << " Review Audio Policy config: audio route"
479*4d7e907cSAndroid Build Coastguard Worker                        << "has source \"" << source
480*4d7e907cSAndroid Build Coastguard Worker                        << "\" which is neither a device port nor mix port.";
481*4d7e907cSAndroid Build Coastguard Worker             return unexpected(BAD_VALUE);
482*4d7e907cSAndroid Build Coastguard Worker         }
483*4d7e907cSAndroid Build Coastguard Worker         sourcePortIds.push_back(portMapIter->second);
484*4d7e907cSAndroid Build Coastguard Worker     }
485*4d7e907cSAndroid Build Coastguard Worker     return sourcePortIds;
486*4d7e907cSAndroid Build Coastguard Worker }
487*4d7e907cSAndroid Build Coastguard Worker 
convertRouteToAidl(const ap_xsd::Routes::Route & xRoute,const std::vector<AudioPort> & aidlAudioPorts)488*4d7e907cSAndroid Build Coastguard Worker ConversionResult<AudioRoute> convertRouteToAidl(const ap_xsd::Routes::Route& xRoute,
489*4d7e907cSAndroid Build Coastguard Worker                                                 const std::vector<AudioPort>& aidlAudioPorts) {
490*4d7e907cSAndroid Build Coastguard Worker     std::unordered_map<std::string, int32_t> portMap;
491*4d7e907cSAndroid Build Coastguard Worker     for (const AudioPort& port : aidlAudioPorts) {
492*4d7e907cSAndroid Build Coastguard Worker         portMap.insert({port.name, port.id});
493*4d7e907cSAndroid Build Coastguard Worker     }
494*4d7e907cSAndroid Build Coastguard Worker     return AudioRoute{.sourcePortIds = VALUE_OR_FATAL(getSourcePortIds(xRoute, portMap)),
495*4d7e907cSAndroid Build Coastguard Worker                       .sinkPortId = VALUE_OR_FATAL(getSinkPortId(xRoute, portMap)),
496*4d7e907cSAndroid Build Coastguard Worker                       .isExclusive = (xRoute.getType() == ap_xsd::MixType::mux)};
497*4d7e907cSAndroid Build Coastguard Worker }
498*4d7e907cSAndroid Build Coastguard Worker 
convertRoutesInModuleToAidl(const ap_xsd::Modules::Module & xModuleConfig,const std::vector<AudioPort> & aidlAudioPorts)499*4d7e907cSAndroid Build Coastguard Worker ConversionResult<std::vector<AudioRoute>> convertRoutesInModuleToAidl(
500*4d7e907cSAndroid Build Coastguard Worker         const ap_xsd::Modules::Module& xModuleConfig,
501*4d7e907cSAndroid Build Coastguard Worker         const std::vector<AudioPort>& aidlAudioPorts) {
502*4d7e907cSAndroid Build Coastguard Worker     std::vector<AudioRoute> audioRouteVec;
503*4d7e907cSAndroid Build Coastguard Worker     std::vector<ap_xsd::Routes> xRoutesVec = xModuleConfig.getRoutes();
504*4d7e907cSAndroid Build Coastguard Worker     if (!xRoutesVec.empty()) {
505*4d7e907cSAndroid Build Coastguard Worker         /*
506*4d7e907cSAndroid Build Coastguard Worker          * xRoutesVec likely only contains one element; that is, it's
507*4d7e907cSAndroid Build Coastguard Worker          * likely that all ap_xsd::Routes::MixPort types that we need to convert
508*4d7e907cSAndroid Build Coastguard Worker          * are inside of xRoutesVec[0].
509*4d7e907cSAndroid Build Coastguard Worker          */
510*4d7e907cSAndroid Build Coastguard Worker         audioRouteVec.reserve(xRoutesVec[0].getRoute().size());
511*4d7e907cSAndroid Build Coastguard Worker         for (const ap_xsd::Routes& xRoutesType : xRoutesVec) {
512*4d7e907cSAndroid Build Coastguard Worker             for (const ap_xsd::Routes::Route& xRoute : xRoutesType.getRoute()) {
513*4d7e907cSAndroid Build Coastguard Worker                 audioRouteVec.push_back(VALUE_OR_FATAL(convertRouteToAidl(xRoute, aidlAudioPorts)));
514*4d7e907cSAndroid Build Coastguard Worker             }
515*4d7e907cSAndroid Build Coastguard Worker         }
516*4d7e907cSAndroid Build Coastguard Worker     }
517*4d7e907cSAndroid Build Coastguard Worker     return audioRouteVec;
518*4d7e907cSAndroid Build Coastguard Worker }
519*4d7e907cSAndroid Build Coastguard Worker 
convertModuleConfigToAidl(const ap_xsd::Modules::Module & xModuleConfig)520*4d7e907cSAndroid Build Coastguard Worker ConversionResult<std::unique_ptr<Module::Configuration>> convertModuleConfigToAidl(
521*4d7e907cSAndroid Build Coastguard Worker         const ap_xsd::Modules::Module& xModuleConfig) {
522*4d7e907cSAndroid Build Coastguard Worker     auto result = std::make_unique<Module::Configuration>();
523*4d7e907cSAndroid Build Coastguard Worker     auto& aidlModuleConfig = *result;
524*4d7e907cSAndroid Build Coastguard Worker     std::vector<AudioPort> devicePorts = VALUE_OR_FATAL(
525*4d7e907cSAndroid Build Coastguard Worker             convertDevicePortsInModuleToAidl(xModuleConfig, aidlModuleConfig.nextPortId));
526*4d7e907cSAndroid Build Coastguard Worker 
527*4d7e907cSAndroid Build Coastguard Worker     // The XML config does not specify the default input device.
528*4d7e907cSAndroid Build Coastguard Worker     // Assign the first attached input device as the default.
529*4d7e907cSAndroid Build Coastguard Worker     for (auto& port : devicePorts) {
530*4d7e907cSAndroid Build Coastguard Worker         if (port.flags.getTag() != AudioIoFlags::input) continue;
531*4d7e907cSAndroid Build Coastguard Worker         auto& deviceExt = port.ext.get<AudioPortExt::device>();
532*4d7e907cSAndroid Build Coastguard Worker         if (!deviceExt.device.type.connection.empty()) continue;
533*4d7e907cSAndroid Build Coastguard Worker         deviceExt.flags |= 1 << AudioPortDeviceExt::FLAG_INDEX_DEFAULT_DEVICE;
534*4d7e907cSAndroid Build Coastguard Worker         break;
535*4d7e907cSAndroid Build Coastguard Worker     }
536*4d7e907cSAndroid Build Coastguard Worker 
537*4d7e907cSAndroid Build Coastguard Worker     std::vector<AudioPort> mixPorts = VALUE_OR_FATAL(
538*4d7e907cSAndroid Build Coastguard Worker             convertMixPortsInModuleToAidl(xModuleConfig, aidlModuleConfig.nextPortId));
539*4d7e907cSAndroid Build Coastguard Worker     aidlModuleConfig.ports.reserve(devicePorts.size() + mixPorts.size());
540*4d7e907cSAndroid Build Coastguard Worker     aidlModuleConfig.ports.insert(aidlModuleConfig.ports.end(), devicePorts.begin(),
541*4d7e907cSAndroid Build Coastguard Worker                                   devicePorts.end());
542*4d7e907cSAndroid Build Coastguard Worker     aidlModuleConfig.ports.insert(aidlModuleConfig.ports.end(), mixPorts.begin(), mixPorts.end());
543*4d7e907cSAndroid Build Coastguard Worker 
544*4d7e907cSAndroid Build Coastguard Worker     aidlModuleConfig.routes =
545*4d7e907cSAndroid Build Coastguard Worker             VALUE_OR_FATAL(convertRoutesInModuleToAidl(xModuleConfig, aidlModuleConfig.ports));
546*4d7e907cSAndroid Build Coastguard Worker     return result;
547*4d7e907cSAndroid Build Coastguard Worker }
548*4d7e907cSAndroid Build Coastguard Worker 
convertTelephonyModeToAidl(const std::string & xsdcModeCriterionType)549*4d7e907cSAndroid Build Coastguard Worker ConversionResult<AudioMode> convertTelephonyModeToAidl(const std::string& xsdcModeCriterionType) {
550*4d7e907cSAndroid Build Coastguard Worker     const auto it = std::find_if(kValidAudioModes.begin(), kValidAudioModes.end(),
551*4d7e907cSAndroid Build Coastguard Worker                                  [&xsdcModeCriterionType](const auto& mode) {
552*4d7e907cSAndroid Build Coastguard Worker                                      return toString(mode) == xsdcModeCriterionType;
553*4d7e907cSAndroid Build Coastguard Worker                                  });
554*4d7e907cSAndroid Build Coastguard Worker     if (it == kValidAudioModes.end()) {
555*4d7e907cSAndroid Build Coastguard Worker         LOG(ERROR) << __func__ << " invalid mode " << xsdcModeCriterionType;
556*4d7e907cSAndroid Build Coastguard Worker         return unexpected(BAD_VALUE);
557*4d7e907cSAndroid Build Coastguard Worker     }
558*4d7e907cSAndroid Build Coastguard Worker     return *it;
559*4d7e907cSAndroid Build Coastguard Worker }
560*4d7e907cSAndroid Build Coastguard Worker 
convertDeviceAddressToAidl(const std::string & xsdcAddress)561*4d7e907cSAndroid Build Coastguard Worker ConversionResult<AudioDeviceAddress> convertDeviceAddressToAidl(const std::string& xsdcAddress) {
562*4d7e907cSAndroid Build Coastguard Worker     return AudioDeviceAddress::make<AudioDeviceAddress::Tag::id>(xsdcAddress);
563*4d7e907cSAndroid Build Coastguard Worker }
564*4d7e907cSAndroid Build Coastguard Worker 
getCriterionTypeByName(const std::string & name,const std::vector<eng_xsd::CriterionTypesType> & xsdcCriterionTypesVec)565*4d7e907cSAndroid Build Coastguard Worker ConversionResult<eng_xsd::CriterionTypeType> getCriterionTypeByName(
566*4d7e907cSAndroid Build Coastguard Worker         const std::string& name,
567*4d7e907cSAndroid Build Coastguard Worker         const std::vector<eng_xsd::CriterionTypesType>& xsdcCriterionTypesVec) {
568*4d7e907cSAndroid Build Coastguard Worker     for (const auto& xsdCriterionTypes : xsdcCriterionTypesVec) {
569*4d7e907cSAndroid Build Coastguard Worker         for (const auto& xsdcCriterionType : xsdCriterionTypes.getCriterion_type()) {
570*4d7e907cSAndroid Build Coastguard Worker             if (xsdcCriterionType.getName() == name) {
571*4d7e907cSAndroid Build Coastguard Worker                 return xsdcCriterionType;
572*4d7e907cSAndroid Build Coastguard Worker             }
573*4d7e907cSAndroid Build Coastguard Worker         }
574*4d7e907cSAndroid Build Coastguard Worker     }
575*4d7e907cSAndroid Build Coastguard Worker     LOG(ERROR) << __func__ << " failed to find criterion type " << name;
576*4d7e907cSAndroid Build Coastguard Worker     return unexpected(BAD_VALUE);
577*4d7e907cSAndroid Build Coastguard Worker }
578*4d7e907cSAndroid Build Coastguard Worker 
579*4d7e907cSAndroid Build Coastguard Worker ConversionResult<std::vector<std::optional<AudioHalCapCriterionV2>>>
convertCapCriteriaCollectionToAidl(const std::vector<eng_xsd::CriteriaType> & xsdcCriteriaVec,const std::vector<eng_xsd::CriterionTypesType> & xsdcCriterionTypesVec)580*4d7e907cSAndroid Build Coastguard Worker convertCapCriteriaCollectionToAidl(
581*4d7e907cSAndroid Build Coastguard Worker         const std::vector<eng_xsd::CriteriaType>& xsdcCriteriaVec,
582*4d7e907cSAndroid Build Coastguard Worker         const std::vector<eng_xsd::CriterionTypesType>& xsdcCriterionTypesVec) {
583*4d7e907cSAndroid Build Coastguard Worker     std::vector<std::optional<AudioHalCapCriterionV2>> resultAidlCriterionVec;
584*4d7e907cSAndroid Build Coastguard Worker     if (xsdcCriteriaVec.empty() || xsdcCriterionTypesVec.empty()) {
585*4d7e907cSAndroid Build Coastguard Worker         LOG(ERROR) << __func__ << " empty criteria/criterionTypes";
586*4d7e907cSAndroid Build Coastguard Worker         return unexpected(BAD_VALUE);
587*4d7e907cSAndroid Build Coastguard Worker     }
588*4d7e907cSAndroid Build Coastguard Worker     for (const auto& xsdCriteria : xsdcCriteriaVec) {
589*4d7e907cSAndroid Build Coastguard Worker         for (const auto& xsdcCriterion : xsdCriteria.getCriterion()) {
590*4d7e907cSAndroid Build Coastguard Worker             resultAidlCriterionVec.push_back(
591*4d7e907cSAndroid Build Coastguard Worker                     std::optional<AudioHalCapCriterionV2>(VALUE_OR_FATAL(
592*4d7e907cSAndroid Build Coastguard Worker                             convertCapCriterionV2ToAidl(xsdcCriterion, xsdcCriterionTypesVec))));
593*4d7e907cSAndroid Build Coastguard Worker         }
594*4d7e907cSAndroid Build Coastguard Worker     }
595*4d7e907cSAndroid Build Coastguard Worker     return resultAidlCriterionVec;
596*4d7e907cSAndroid Build Coastguard Worker }
597*4d7e907cSAndroid Build Coastguard Worker 
convertDevicesToAidl(const eng_xsd::CriterionTypeType & xsdcDeviceCriterionType)598*4d7e907cSAndroid Build Coastguard Worker ConversionResult<std::vector<AudioDeviceDescription>> convertDevicesToAidl(
599*4d7e907cSAndroid Build Coastguard Worker         const eng_xsd::CriterionTypeType& xsdcDeviceCriterionType) {
600*4d7e907cSAndroid Build Coastguard Worker     if (xsdcDeviceCriterionType.getValues().empty()) {
601*4d7e907cSAndroid Build Coastguard Worker         LOG(ERROR) << __func__ << " no values provided";
602*4d7e907cSAndroid Build Coastguard Worker         return unexpected(BAD_VALUE);
603*4d7e907cSAndroid Build Coastguard Worker     }
604*4d7e907cSAndroid Build Coastguard Worker     std::vector<AudioDeviceDescription> aidlDevices;
605*4d7e907cSAndroid Build Coastguard Worker     for (eng_xsd::ValuesType xsdcValues : xsdcDeviceCriterionType.getValues()) {
606*4d7e907cSAndroid Build Coastguard Worker         aidlDevices.reserve(xsdcValues.getValue().size());
607*4d7e907cSAndroid Build Coastguard Worker         for (const eng_xsd::ValueType& xsdcValue : xsdcValues.getValue()) {
608*4d7e907cSAndroid Build Coastguard Worker             if (!xsdcValue.hasAndroid_type()) {
609*4d7e907cSAndroid Build Coastguard Worker                 LOG(ERROR) << __func__ << " empty android type";
610*4d7e907cSAndroid Build Coastguard Worker                 return unexpected(BAD_VALUE);
611*4d7e907cSAndroid Build Coastguard Worker             }
612*4d7e907cSAndroid Build Coastguard Worker             uint32_t integerValue;
613*4d7e907cSAndroid Build Coastguard Worker             if (!convertTo(xsdcValue.getAndroid_type(), integerValue)) {
614*4d7e907cSAndroid Build Coastguard Worker                 LOG(ERROR) << __func__ << " failed to convert android type "
615*4d7e907cSAndroid Build Coastguard Worker                            << xsdcValue.getAndroid_type();
616*4d7e907cSAndroid Build Coastguard Worker                 return unexpected(BAD_VALUE);
617*4d7e907cSAndroid Build Coastguard Worker             }
618*4d7e907cSAndroid Build Coastguard Worker             aidlDevices.push_back(
619*4d7e907cSAndroid Build Coastguard Worker                     VALUE_OR_RETURN(legacy2aidl_audio_devices_t_AudioDeviceDescription(
620*4d7e907cSAndroid Build Coastguard Worker                             static_cast<audio_devices_t>(integerValue))));
621*4d7e907cSAndroid Build Coastguard Worker         }
622*4d7e907cSAndroid Build Coastguard Worker     }
623*4d7e907cSAndroid Build Coastguard Worker     return aidlDevices;
624*4d7e907cSAndroid Build Coastguard Worker }
625*4d7e907cSAndroid Build Coastguard Worker 
convertDeviceAddressesToAidl(const eng_xsd::CriterionTypeType & xsdcDeviceAddressesCriterionType)626*4d7e907cSAndroid Build Coastguard Worker ConversionResult<std::vector<AudioDeviceAddress>> convertDeviceAddressesToAidl(
627*4d7e907cSAndroid Build Coastguard Worker         const eng_xsd::CriterionTypeType& xsdcDeviceAddressesCriterionType) {
628*4d7e907cSAndroid Build Coastguard Worker     if (xsdcDeviceAddressesCriterionType.getValues().empty()) {
629*4d7e907cSAndroid Build Coastguard Worker         LOG(ERROR) << __func__ << " no values provided";
630*4d7e907cSAndroid Build Coastguard Worker         return unexpected(BAD_VALUE);
631*4d7e907cSAndroid Build Coastguard Worker     }
632*4d7e907cSAndroid Build Coastguard Worker     std::vector<AudioDeviceAddress> aidlDeviceAddresses;
633*4d7e907cSAndroid Build Coastguard Worker     for (eng_xsd::ValuesType xsdcValues : xsdcDeviceAddressesCriterionType.getValues()) {
634*4d7e907cSAndroid Build Coastguard Worker         aidlDeviceAddresses.reserve(xsdcValues.getValue().size());
635*4d7e907cSAndroid Build Coastguard Worker         for (const eng_xsd::ValueType& xsdcValue : xsdcValues.getValue()) {
636*4d7e907cSAndroid Build Coastguard Worker             aidlDeviceAddresses.push_back(
637*4d7e907cSAndroid Build Coastguard Worker                     AudioDeviceAddress::make<AudioDeviceAddress::Tag::id>(xsdcValue.getLiteral()));
638*4d7e907cSAndroid Build Coastguard Worker         }
639*4d7e907cSAndroid Build Coastguard Worker     }
640*4d7e907cSAndroid Build Coastguard Worker     return aidlDeviceAddresses;
641*4d7e907cSAndroid Build Coastguard Worker }
642*4d7e907cSAndroid Build Coastguard Worker 
convertAudioModeToAidl(const std::string & xsdcAudioModeType)643*4d7e907cSAndroid Build Coastguard Worker ConversionResult<AudioMode> convertAudioModeToAidl(const std::string& xsdcAudioModeType) {
644*4d7e907cSAndroid Build Coastguard Worker     const auto it = std::find_if(enum_range<AudioMode>().begin(), enum_range<AudioMode>().end(),
645*4d7e907cSAndroid Build Coastguard Worker                                  [&](const auto v) { return toString(v) == xsdcAudioModeType; });
646*4d7e907cSAndroid Build Coastguard Worker     if (it == enum_range<AudioMode>().end()) {
647*4d7e907cSAndroid Build Coastguard Worker         LOG(ERROR) << __func__ << " invalid audio mode " << xsdcAudioModeType;
648*4d7e907cSAndroid Build Coastguard Worker         return unexpected(BAD_VALUE);
649*4d7e907cSAndroid Build Coastguard Worker     }
650*4d7e907cSAndroid Build Coastguard Worker     return *it;
651*4d7e907cSAndroid Build Coastguard Worker }
652*4d7e907cSAndroid Build Coastguard Worker 
convertTelephonyModesToAidl(const eng_xsd::CriterionTypeType & xsdcTelephonyModeCriterionType)653*4d7e907cSAndroid Build Coastguard Worker ConversionResult<std::vector<AudioMode>> convertTelephonyModesToAidl(
654*4d7e907cSAndroid Build Coastguard Worker         const eng_xsd::CriterionTypeType& xsdcTelephonyModeCriterionType) {
655*4d7e907cSAndroid Build Coastguard Worker     if (xsdcTelephonyModeCriterionType.getValues().empty()) {
656*4d7e907cSAndroid Build Coastguard Worker         LOG(ERROR) << __func__ << " no values provided";
657*4d7e907cSAndroid Build Coastguard Worker         return unexpected(BAD_VALUE);
658*4d7e907cSAndroid Build Coastguard Worker     }
659*4d7e907cSAndroid Build Coastguard Worker     std::vector<AudioMode> aidlAudioModes;
660*4d7e907cSAndroid Build Coastguard Worker     for (eng_xsd::ValuesType xsdcValues : xsdcTelephonyModeCriterionType.getValues()) {
661*4d7e907cSAndroid Build Coastguard Worker         aidlAudioModes.reserve(xsdcValues.getValue().size());
662*4d7e907cSAndroid Build Coastguard Worker         for (const eng_xsd::ValueType& xsdcValue : xsdcValues.getValue()) {
663*4d7e907cSAndroid Build Coastguard Worker             aidlAudioModes.push_back(
664*4d7e907cSAndroid Build Coastguard Worker                     VALUE_OR_RETURN(convertAudioModeToAidl(xsdcValue.getLiteral())));
665*4d7e907cSAndroid Build Coastguard Worker         }
666*4d7e907cSAndroid Build Coastguard Worker     }
667*4d7e907cSAndroid Build Coastguard Worker     return aidlAudioModes;
668*4d7e907cSAndroid Build Coastguard Worker }
669*4d7e907cSAndroid Build Coastguard Worker 
convertForceUseConfigsToAidl(const std::string & criterionValue,const eng_xsd::CriterionTypeType & xsdcForcedConfigCriterionType)670*4d7e907cSAndroid Build Coastguard Worker ConversionResult<std::vector<AudioPolicyForceUse>> convertForceUseConfigsToAidl(
671*4d7e907cSAndroid Build Coastguard Worker         const std::string& criterionValue,
672*4d7e907cSAndroid Build Coastguard Worker         const eng_xsd::CriterionTypeType& xsdcForcedConfigCriterionType) {
673*4d7e907cSAndroid Build Coastguard Worker     if (xsdcForcedConfigCriterionType.getValues().empty()) {
674*4d7e907cSAndroid Build Coastguard Worker         LOG(ERROR) << __func__ << " no values provided";
675*4d7e907cSAndroid Build Coastguard Worker         return unexpected(BAD_VALUE);
676*4d7e907cSAndroid Build Coastguard Worker     }
677*4d7e907cSAndroid Build Coastguard Worker     std::vector<AudioPolicyForceUse> aidlForcedConfigs;
678*4d7e907cSAndroid Build Coastguard Worker     for (eng_xsd::ValuesType xsdcValues : xsdcForcedConfigCriterionType.getValues()) {
679*4d7e907cSAndroid Build Coastguard Worker         aidlForcedConfigs.reserve(xsdcValues.getValue().size());
680*4d7e907cSAndroid Build Coastguard Worker         for (const eng_xsd::ValueType& xsdcValue : xsdcValues.getValue()) {
681*4d7e907cSAndroid Build Coastguard Worker             aidlForcedConfigs.push_back(
682*4d7e907cSAndroid Build Coastguard Worker                     VALUE_OR_RETURN(convertForceUseToAidl(criterionValue, xsdcValue.getLiteral())));
683*4d7e907cSAndroid Build Coastguard Worker         }
684*4d7e907cSAndroid Build Coastguard Worker     }
685*4d7e907cSAndroid Build Coastguard Worker     return aidlForcedConfigs;
686*4d7e907cSAndroid Build Coastguard Worker }
687*4d7e907cSAndroid Build Coastguard Worker 
688*4d7e907cSAndroid Build Coastguard Worker template <typename T>
convertForceUseForcedConfigToAidl(const std::string & xsdcForcedConfigCriterionType)689*4d7e907cSAndroid Build Coastguard Worker ConversionResult<T> convertForceUseForcedConfigToAidl(
690*4d7e907cSAndroid Build Coastguard Worker         const std::string& xsdcForcedConfigCriterionType) {
691*4d7e907cSAndroid Build Coastguard Worker     const auto it = std::find_if(enum_range<T>().begin(), enum_range<T>().end(), [&](const auto v) {
692*4d7e907cSAndroid Build Coastguard Worker         return toString(v) == xsdcForcedConfigCriterionType;
693*4d7e907cSAndroid Build Coastguard Worker     });
694*4d7e907cSAndroid Build Coastguard Worker     if (it == enum_range<T>().end()) {
695*4d7e907cSAndroid Build Coastguard Worker         LOG(ERROR) << __func__ << " invalid forced config " << xsdcForcedConfigCriterionType;
696*4d7e907cSAndroid Build Coastguard Worker         return unexpected(BAD_VALUE);
697*4d7e907cSAndroid Build Coastguard Worker     }
698*4d7e907cSAndroid Build Coastguard Worker     return *it;
699*4d7e907cSAndroid Build Coastguard Worker }
700*4d7e907cSAndroid Build Coastguard Worker 
convertForceUseToAidl(const std::string & xsdcCriterionName,const std::string & xsdcCriterionValue)701*4d7e907cSAndroid Build Coastguard Worker ConversionResult<AudioPolicyForceUse> convertForceUseToAidl(const std::string& xsdcCriterionName,
702*4d7e907cSAndroid Build Coastguard Worker                                                             const std::string& xsdcCriterionValue) {
703*4d7e907cSAndroid Build Coastguard Worker     if (!fastcmp<strncmp>(xsdcCriterionName.c_str(), kXsdcForceConfigForCommunication,
704*4d7e907cSAndroid Build Coastguard Worker                           strlen(kXsdcForceConfigForCommunication))) {
705*4d7e907cSAndroid Build Coastguard Worker         const auto deviceCategory = VALUE_OR_RETURN(
706*4d7e907cSAndroid Build Coastguard Worker                 convertForceUseForcedConfigToAidl<AudioPolicyForceUse::CommunicationDeviceCategory>(
707*4d7e907cSAndroid Build Coastguard Worker                         xsdcCriterionValue));
708*4d7e907cSAndroid Build Coastguard Worker         return AudioPolicyForceUse::make<AudioPolicyForceUse::forCommunication>(deviceCategory);
709*4d7e907cSAndroid Build Coastguard Worker     }
710*4d7e907cSAndroid Build Coastguard Worker     if (!fasticmp<strncmp>(xsdcCriterionName.c_str(), kXsdcForceConfigForMedia,
711*4d7e907cSAndroid Build Coastguard Worker             strlen(kXsdcForceConfigForMedia))) {
712*4d7e907cSAndroid Build Coastguard Worker         const auto deviceCategory = VALUE_OR_RETURN(
713*4d7e907cSAndroid Build Coastguard Worker                 convertForceUseForcedConfigToAidl<AudioPolicyForceUse::MediaDeviceCategory>(
714*4d7e907cSAndroid Build Coastguard Worker                         xsdcCriterionValue));
715*4d7e907cSAndroid Build Coastguard Worker         return AudioPolicyForceUse::make<AudioPolicyForceUse::forMedia>(deviceCategory);
716*4d7e907cSAndroid Build Coastguard Worker     }
717*4d7e907cSAndroid Build Coastguard Worker     if (!fasticmp<strncmp>(xsdcCriterionName.c_str(), kXsdcForceConfigForRecord,
718*4d7e907cSAndroid Build Coastguard Worker             strlen(kXsdcForceConfigForRecord))) {
719*4d7e907cSAndroid Build Coastguard Worker         const auto deviceCategory = VALUE_OR_RETURN(
720*4d7e907cSAndroid Build Coastguard Worker                 convertForceUseForcedConfigToAidl<AudioPolicyForceUse::CommunicationDeviceCategory>(
721*4d7e907cSAndroid Build Coastguard Worker                         xsdcCriterionValue));
722*4d7e907cSAndroid Build Coastguard Worker         return AudioPolicyForceUse::make<AudioPolicyForceUse::forRecord>(deviceCategory);
723*4d7e907cSAndroid Build Coastguard Worker     }
724*4d7e907cSAndroid Build Coastguard Worker     if (!fasticmp<strncmp>(xsdcCriterionName.c_str(), kXsdcForceConfigForDock,
725*4d7e907cSAndroid Build Coastguard Worker                            strlen(kXsdcForceConfigForDock))) {
726*4d7e907cSAndroid Build Coastguard Worker         const auto dockType =
727*4d7e907cSAndroid Build Coastguard Worker                 VALUE_OR_RETURN(convertForceUseForcedConfigToAidl<AudioPolicyForceUse::DockType>(
728*4d7e907cSAndroid Build Coastguard Worker                         xsdcCriterionValue));
729*4d7e907cSAndroid Build Coastguard Worker         return AudioPolicyForceUse::make<AudioPolicyForceUse::dock>(dockType);
730*4d7e907cSAndroid Build Coastguard Worker     }
731*4d7e907cSAndroid Build Coastguard Worker     if (!fasticmp<strncmp>(xsdcCriterionName.c_str(), kXsdcForceConfigForSystem,
732*4d7e907cSAndroid Build Coastguard Worker             strlen(kXsdcForceConfigForSystem))) {
733*4d7e907cSAndroid Build Coastguard Worker         return AudioPolicyForceUse::make<AudioPolicyForceUse::systemSounds>(xsdcCriterionValue ==
734*4d7e907cSAndroid Build Coastguard Worker                                                                             "SYSTEM_ENFORCED");
735*4d7e907cSAndroid Build Coastguard Worker     }
736*4d7e907cSAndroid Build Coastguard Worker     if (!fasticmp<strncmp>(xsdcCriterionName.c_str(), kXsdcForceConfigForHdmiSystemAudio,
737*4d7e907cSAndroid Build Coastguard Worker             strlen(kXsdcForceConfigForHdmiSystemAudio))) {
738*4d7e907cSAndroid Build Coastguard Worker         return AudioPolicyForceUse::make<AudioPolicyForceUse::hdmiSystemAudio>(
739*4d7e907cSAndroid Build Coastguard Worker                 xsdcCriterionValue == "HDMI_SYSTEM_AUDIO_ENFORCED");
740*4d7e907cSAndroid Build Coastguard Worker     }
741*4d7e907cSAndroid Build Coastguard Worker     if (!fasticmp<strncmp>(xsdcCriterionName.c_str(), kXsdcForceConfigForEncodedSurround,
742*4d7e907cSAndroid Build Coastguard Worker             strlen(kXsdcForceConfigForEncodedSurround))) {
743*4d7e907cSAndroid Build Coastguard Worker         const auto encodedSurround = VALUE_OR_RETURN(
744*4d7e907cSAndroid Build Coastguard Worker                 convertForceUseForcedConfigToAidl<AudioPolicyForceUse::EncodedSurroundConfig>(
745*4d7e907cSAndroid Build Coastguard Worker                         xsdcCriterionValue));
746*4d7e907cSAndroid Build Coastguard Worker         return AudioPolicyForceUse::make<AudioPolicyForceUse::encodedSurround>(encodedSurround);
747*4d7e907cSAndroid Build Coastguard Worker     }
748*4d7e907cSAndroid Build Coastguard Worker     if (!fasticmp<strncmp>(xsdcCriterionName.c_str(), kXsdcForceConfigForVibrateRinging,
749*4d7e907cSAndroid Build Coastguard Worker             strlen(kXsdcForceConfigForVibrateRinging))) {
750*4d7e907cSAndroid Build Coastguard Worker         const auto deviceCategory = VALUE_OR_RETURN(
751*4d7e907cSAndroid Build Coastguard Worker                 convertForceUseForcedConfigToAidl<AudioPolicyForceUse::CommunicationDeviceCategory>(
752*4d7e907cSAndroid Build Coastguard Worker                         xsdcCriterionValue));
753*4d7e907cSAndroid Build Coastguard Worker         return AudioPolicyForceUse::make<AudioPolicyForceUse::forVibrateRinging>(deviceCategory);
754*4d7e907cSAndroid Build Coastguard Worker     }
755*4d7e907cSAndroid Build Coastguard Worker     LOG(ERROR) << __func__ << " unrecognized force use " << xsdcCriterionName;
756*4d7e907cSAndroid Build Coastguard Worker     return unexpected(BAD_VALUE);
757*4d7e907cSAndroid Build Coastguard Worker }
758*4d7e907cSAndroid Build Coastguard Worker 
convertCapCriterionV2ToAidl(const eng_xsd::CriterionType & xsdcCriterion,const std::vector<eng_xsd::CriterionTypesType> & xsdcCriterionTypesVec)759*4d7e907cSAndroid Build Coastguard Worker ConversionResult<AudioHalCapCriterionV2> convertCapCriterionV2ToAidl(
760*4d7e907cSAndroid Build Coastguard Worker         const eng_xsd::CriterionType& xsdcCriterion,
761*4d7e907cSAndroid Build Coastguard Worker         const std::vector<eng_xsd::CriterionTypesType>& xsdcCriterionTypesVec) {
762*4d7e907cSAndroid Build Coastguard Worker     eng_xsd::CriterionTypeType xsdcCriterionType =
763*4d7e907cSAndroid Build Coastguard Worker             VALUE_OR_RETURN(getCriterionTypeByName(xsdcCriterion.getType(), xsdcCriterionTypesVec));
764*4d7e907cSAndroid Build Coastguard Worker     std::string defaultLiteralValue =
765*4d7e907cSAndroid Build Coastguard Worker             xsdcCriterion.has_default() ? xsdcCriterion.get_default() : "";
766*4d7e907cSAndroid Build Coastguard Worker     using Tag = AudioHalCapCriterionV2::Tag;
767*4d7e907cSAndroid Build Coastguard Worker     if (iequals(xsdcCriterion.getName(), toString(Tag::availableInputDevices))) {
768*4d7e907cSAndroid Build Coastguard Worker         return AudioHalCapCriterionV2::make<Tag::availableInputDevices>(
769*4d7e907cSAndroid Build Coastguard Worker                 VALUE_OR_RETURN(convertDevicesToAidl(xsdcCriterionType)));
770*4d7e907cSAndroid Build Coastguard Worker     }
771*4d7e907cSAndroid Build Coastguard Worker     if (iequals(xsdcCriterion.getName(), toString(Tag::availableOutputDevices))) {
772*4d7e907cSAndroid Build Coastguard Worker         return AudioHalCapCriterionV2::make<Tag::availableOutputDevices>(
773*4d7e907cSAndroid Build Coastguard Worker                 VALUE_OR_RETURN(convertDevicesToAidl(xsdcCriterionType)));
774*4d7e907cSAndroid Build Coastguard Worker     }
775*4d7e907cSAndroid Build Coastguard Worker     if (iequals(xsdcCriterion.getName(), toString(Tag::availableInputDevicesAddresses))) {
776*4d7e907cSAndroid Build Coastguard Worker         return AudioHalCapCriterionV2::make<Tag::availableInputDevicesAddresses>(
777*4d7e907cSAndroid Build Coastguard Worker                 VALUE_OR_RETURN(convertDeviceAddressesToAidl(xsdcCriterionType)));
778*4d7e907cSAndroid Build Coastguard Worker     }
779*4d7e907cSAndroid Build Coastguard Worker     if (iequals(xsdcCriterion.getName(), toString(Tag::availableOutputDevicesAddresses))) {
780*4d7e907cSAndroid Build Coastguard Worker         return AudioHalCapCriterionV2::make<Tag::availableOutputDevicesAddresses>(
781*4d7e907cSAndroid Build Coastguard Worker                 VALUE_OR_RETURN(convertDeviceAddressesToAidl(xsdcCriterionType)));
782*4d7e907cSAndroid Build Coastguard Worker     }
783*4d7e907cSAndroid Build Coastguard Worker     if (iequals(xsdcCriterion.getName(), toString(Tag::telephonyMode))) {
784*4d7e907cSAndroid Build Coastguard Worker         return AudioHalCapCriterionV2::make<Tag::telephonyMode>(
785*4d7e907cSAndroid Build Coastguard Worker                 VALUE_OR_RETURN(convertTelephonyModesToAidl(xsdcCriterionType)));
786*4d7e907cSAndroid Build Coastguard Worker     }
787*4d7e907cSAndroid Build Coastguard Worker     if (!fastcmp<strncmp>(xsdcCriterion.getName().c_str(), kXsdcForceConfigForUse,
788*4d7e907cSAndroid Build Coastguard Worker             strlen(kXsdcForceConfigForUse))) {
789*4d7e907cSAndroid Build Coastguard Worker         return AudioHalCapCriterionV2::make<Tag::forceConfigForUse>(VALUE_OR_RETURN(
790*4d7e907cSAndroid Build Coastguard Worker                 convertForceUseConfigsToAidl(xsdcCriterion.getName(), xsdcCriterionType)));
791*4d7e907cSAndroid Build Coastguard Worker     }
792*4d7e907cSAndroid Build Coastguard Worker     LOG(ERROR) << __func__ << " unrecognized criterion " << xsdcCriterion.getName();
793*4d7e907cSAndroid Build Coastguard Worker     return unexpected(BAD_VALUE);
794*4d7e907cSAndroid Build Coastguard Worker }
795*4d7e907cSAndroid Build Coastguard Worker 
convertCapCriterionToAidl(const eng_xsd::CriterionType & xsdcCriterion)796*4d7e907cSAndroid Build Coastguard Worker ConversionResult<AudioHalCapCriterion> convertCapCriterionToAidl(
797*4d7e907cSAndroid Build Coastguard Worker         const eng_xsd::CriterionType& xsdcCriterion) {
798*4d7e907cSAndroid Build Coastguard Worker     AudioHalCapCriterion aidlCapCriterion;
799*4d7e907cSAndroid Build Coastguard Worker     aidlCapCriterion.name = xsdcCriterion.getName();
800*4d7e907cSAndroid Build Coastguard Worker     aidlCapCriterion.criterionTypeName = xsdcCriterion.getType();
801*4d7e907cSAndroid Build Coastguard Worker     aidlCapCriterion.defaultLiteralValue =
802*4d7e907cSAndroid Build Coastguard Worker             xsdcCriterion.has_default() ? xsdcCriterion.get_default() : "";
803*4d7e907cSAndroid Build Coastguard Worker     return aidlCapCriterion;
804*4d7e907cSAndroid Build Coastguard Worker }
805*4d7e907cSAndroid Build Coastguard Worker 
convertCurvePointToAidl(const std::string & xsdcCurvePoint)806*4d7e907cSAndroid Build Coastguard Worker ConversionResult<AudioHalVolumeCurve::CurvePoint> convertCurvePointToAidl(
807*4d7e907cSAndroid Build Coastguard Worker         const std::string& xsdcCurvePoint) {
808*4d7e907cSAndroid Build Coastguard Worker     AudioHalVolumeCurve::CurvePoint aidlCurvePoint{};
809*4d7e907cSAndroid Build Coastguard Worker     if ((sscanf(xsdcCurvePoint.c_str(), "%" SCNd8 ",%d", &aidlCurvePoint.index,
810*4d7e907cSAndroid Build Coastguard Worker                 &aidlCurvePoint.attenuationMb) != 2) ||
811*4d7e907cSAndroid Build Coastguard Worker         (aidlCurvePoint.index < AudioHalVolumeCurve::CurvePoint::MIN_INDEX) ||
812*4d7e907cSAndroid Build Coastguard Worker         (aidlCurvePoint.index > AudioHalVolumeCurve::CurvePoint::MAX_INDEX)) {
813*4d7e907cSAndroid Build Coastguard Worker         LOG(ERROR) << __func__ << " Review Audio Policy config: volume curve point:"
814*4d7e907cSAndroid Build Coastguard Worker                    << "\"" << xsdcCurvePoint << "\" is invalid";
815*4d7e907cSAndroid Build Coastguard Worker         return unexpected(BAD_VALUE);
816*4d7e907cSAndroid Build Coastguard Worker     }
817*4d7e907cSAndroid Build Coastguard Worker     return aidlCurvePoint;
818*4d7e907cSAndroid Build Coastguard Worker }
819*4d7e907cSAndroid Build Coastguard Worker }  // namespace aidl::android::hardware::audio::core::internal
820