blob: 2f1282a3064cd33539c390ea033a6789ce58fd4c [file] [log] [blame]
Lorena Torres-Huertabc585bd2022-10-23 20:41:35 +00001/*
2 * Copyright (C) 2022 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 <fcntl.h>
18#include <inttypes.h>
19#include <unistd.h>
20
21#include <functional>
22#include <unordered_map>
23
Lorena Torres-Huertaaa8f76a2022-12-12 18:17:10 +000024#define LOG_TAG "AHAL_ApmXmlConverter"
25#include <android-base/logging.h>
26
Lorena Torres-Huertabc585bd2022-10-23 20:41:35 +000027#include <aidl/android/media/audio/common/AudioHalEngineConfig.h>
Lorena Torres-Huertaaa8f76a2022-12-12 18:17:10 +000028#include <media/stagefright/foundation/MediaDefs.h>
Lorena Torres-Huertabc585bd2022-10-23 20:41:35 +000029#include <system/audio-base-utils.h>
30
Lorena Torres-Huertaaa8f76a2022-12-12 18:17:10 +000031#include "core-impl/AidlConversionXsdc.h"
Lorena Torres-Huertabc585bd2022-10-23 20:41:35 +000032#include "core-impl/AudioPolicyConfigXmlConverter.h"
Lorena Torres-Huerta394e2522022-12-20 02:21:41 +000033#include "core-impl/XsdcConversion.h"
Lorena Torres-Huertabc585bd2022-10-23 20:41:35 +000034
Lorena Torres-Huertaaa8f76a2022-12-12 18:17:10 +000035using aidl::android::media::audio::common::AudioFormatDescription;
Lorena Torres-Huertabc585bd2022-10-23 20:41:35 +000036using aidl::android::media::audio::common::AudioHalEngineConfig;
37using aidl::android::media::audio::common::AudioHalVolumeCurve;
38using aidl::android::media::audio::common::AudioHalVolumeGroup;
39using aidl::android::media::audio::common::AudioStreamType;
40
Lorena Torres-Huerta394e2522022-12-20 02:21:41 +000041namespace ap_xsd = android::audio::policy::configuration;
Lorena Torres-Huertabc585bd2022-10-23 20:41:35 +000042
43namespace aidl::android::hardware::audio::core::internal {
44
45static const int kDefaultVolumeIndexMin = 0;
46static const int kDefaultVolumeIndexMax = 100;
47static const int KVolumeIndexDeferredToAudioService = -1;
Lorena Torres-Huertabc585bd2022-10-23 20:41:35 +000048
Lorena Torres-Huerta394e2522022-12-20 02:21:41 +000049ConversionResult<AudioHalVolumeCurve> AudioPolicyConfigXmlConverter::convertVolumeCurveToAidl(
50 const ap_xsd::Volume& xsdcVolumeCurve) {
Lorena Torres-Huertabc585bd2022-10-23 20:41:35 +000051 AudioHalVolumeCurve aidlVolumeCurve;
52 aidlVolumeCurve.deviceCategory =
53 static_cast<AudioHalVolumeCurve::DeviceCategory>(xsdcVolumeCurve.getDeviceCategory());
54 if (xsdcVolumeCurve.hasRef()) {
55 if (mVolumesReferenceMap.empty()) {
Lorena Torres-Huerta394e2522022-12-20 02:21:41 +000056 mVolumesReferenceMap = generateReferenceMap<ap_xsd::Volumes, ap_xsd::Reference>(
Lorena Torres-Huertabc585bd2022-10-23 20:41:35 +000057 getXsdcConfig()->getVolumes());
58 }
Lorena Torres-Huerta394e2522022-12-20 02:21:41 +000059 aidlVolumeCurve.curvePoints = VALUE_OR_FATAL(
60 (convertCollectionToAidl<std::string, AudioHalVolumeCurve::CurvePoint>(
Lorena Torres-Huertabc585bd2022-10-23 20:41:35 +000061 mVolumesReferenceMap.at(xsdcVolumeCurve.getRef()).getPoint(),
Lorena Torres-Huerta394e2522022-12-20 02:21:41 +000062 &convertCurvePointToAidl)));
Lorena Torres-Huertabc585bd2022-10-23 20:41:35 +000063 } else {
Lorena Torres-Huerta394e2522022-12-20 02:21:41 +000064 aidlVolumeCurve.curvePoints = VALUE_OR_FATAL(
65 (convertCollectionToAidl<std::string, AudioHalVolumeCurve::CurvePoint>(
66 xsdcVolumeCurve.getPoint(), &convertCurvePointToAidl)));
Lorena Torres-Huertabc585bd2022-10-23 20:41:35 +000067 }
68 return aidlVolumeCurve;
69}
70
Lorena Torres-Huerta394e2522022-12-20 02:21:41 +000071void AudioPolicyConfigXmlConverter::mapStreamToVolumeCurve(const ap_xsd::Volume& xsdcVolumeCurve) {
Lorena Torres-Huertabc585bd2022-10-23 20:41:35 +000072 mStreamToVolumeCurvesMap[xsdcVolumeCurve.getStream()].push_back(
Lorena Torres-Huerta394e2522022-12-20 02:21:41 +000073 VALUE_OR_FATAL(convertVolumeCurveToAidl(xsdcVolumeCurve)));
Lorena Torres-Huertabc585bd2022-10-23 20:41:35 +000074}
75
Lorena Torres-Huertaaa8f76a2022-12-12 18:17:10 +000076const SurroundSoundConfig& AudioPolicyConfigXmlConverter::getSurroundSoundConfig() {
77 static const SurroundSoundConfig aidlSurroundSoundConfig = [this]() {
78 if (auto xsdcConfig = getXsdcConfig(); xsdcConfig && xsdcConfig->hasSurroundSound()) {
79 auto configConv = xsdc2aidl_SurroundSoundConfig(*xsdcConfig->getFirstSurroundSound());
80 if (configConv.ok()) {
81 return configConv.value();
82 }
83 LOG(ERROR) << "There was an error converting surround formats to AIDL: "
84 << configConv.error();
85 }
86 LOG(WARNING) << "Audio policy config does not have <surroundSound> section, using default";
87 return getDefaultSurroundSoundConfig();
88 }();
89 return aidlSurroundSoundConfig;
90}
91
Lorena Torres-Huerta394e2522022-12-20 02:21:41 +000092std::unique_ptr<AudioPolicyConfigXmlConverter::ModuleConfigs>
93AudioPolicyConfigXmlConverter::releaseModuleConfigs() {
94 return std::move(mModuleConfigurations);
95}
96
Lorena Torres-Huertabc585bd2022-10-23 20:41:35 +000097const AudioHalEngineConfig& AudioPolicyConfigXmlConverter::getAidlEngineConfig() {
98 if (mAidlEngineConfig.volumeGroups.empty() && getXsdcConfig() &&
99 getXsdcConfig()->hasVolumes()) {
100 parseVolumes();
101 }
102 return mAidlEngineConfig;
103}
104
Lorena Torres-Huertaaa8f76a2022-12-12 18:17:10 +0000105// static
106const SurroundSoundConfig& AudioPolicyConfigXmlConverter::getDefaultSurroundSoundConfig() {
107 // Provide a config similar to the one used by the framework by default
108 // (see AudioPolicyConfig::setDefaultSurroundFormats).
109#define ENCODED_FORMAT(format) \
110 AudioFormatDescription { \
111 .encoding = ::android::format \
112 }
113#define SIMPLE_FORMAT(format) \
114 SurroundSoundConfig::SurroundFormatFamily { \
115 .primaryFormat = ENCODED_FORMAT(format) \
116 }
117
118 static const SurroundSoundConfig defaultConfig = {
119 .formatFamilies = {
120 SIMPLE_FORMAT(MEDIA_MIMETYPE_AUDIO_AC3),
121 SIMPLE_FORMAT(MEDIA_MIMETYPE_AUDIO_EAC3),
122 SIMPLE_FORMAT(MEDIA_MIMETYPE_AUDIO_DTS),
123 SIMPLE_FORMAT(MEDIA_MIMETYPE_AUDIO_DTS_HD),
124 SIMPLE_FORMAT(MEDIA_MIMETYPE_AUDIO_DTS_HD_MA),
Mikhail Naganov724b24f2023-07-06 09:58:14 -0700125 SIMPLE_FORMAT(MEDIA_MIMETYPE_AUDIO_DTS_UHD_P1),
Lorena Torres-Huertaaa8f76a2022-12-12 18:17:10 +0000126 SIMPLE_FORMAT(MEDIA_MIMETYPE_AUDIO_DTS_UHD_P2),
127 SIMPLE_FORMAT(MEDIA_MIMETYPE_AUDIO_DOLBY_TRUEHD),
128 SIMPLE_FORMAT(MEDIA_MIMETYPE_AUDIO_EAC3_JOC),
129 SurroundSoundConfig::SurroundFormatFamily{
130 .primaryFormat = ENCODED_FORMAT(MEDIA_MIMETYPE_AUDIO_AAC_LC),
131 .subFormats =
132 {
133 ENCODED_FORMAT(MEDIA_MIMETYPE_AUDIO_AAC_HE_V1),
134 ENCODED_FORMAT(MEDIA_MIMETYPE_AUDIO_AAC_HE_V2),
135 ENCODED_FORMAT(MEDIA_MIMETYPE_AUDIO_AAC_ELD),
136 ENCODED_FORMAT(MEDIA_MIMETYPE_AUDIO_AAC_XHE),
137 }},
138 SIMPLE_FORMAT(MEDIA_MIMETYPE_AUDIO_AC4),
139 }};
140#undef SIMPLE_FORMAT
141#undef ENCODED_FORMAT
142
143 return defaultConfig;
144}
145
Lorena Torres-Huertabc585bd2022-10-23 20:41:35 +0000146void AudioPolicyConfigXmlConverter::mapStreamsToVolumeCurves() {
147 if (getXsdcConfig()->hasVolumes()) {
Lorena Torres-Huerta394e2522022-12-20 02:21:41 +0000148 for (const ap_xsd::Volumes& xsdcWrapperType : getXsdcConfig()->getVolumes()) {
149 for (const ap_xsd::Volume& xsdcVolume : xsdcWrapperType.getVolume()) {
Lorena Torres-Huertabc585bd2022-10-23 20:41:35 +0000150 mapStreamToVolumeCurve(xsdcVolume);
151 }
152 }
153 }
154}
155
156void AudioPolicyConfigXmlConverter::addVolumeGroupstoEngineConfig() {
157 for (const auto& [xsdcStream, volumeCurves] : mStreamToVolumeCurvesMap) {
158 AudioHalVolumeGroup volumeGroup;
Lorena Torres-Huerta394e2522022-12-20 02:21:41 +0000159 volumeGroup.name = ap_xsd::toString(xsdcStream);
Lorena Torres-Huertabc585bd2022-10-23 20:41:35 +0000160 if (static_cast<int>(xsdcStream) >= AUDIO_STREAM_PUBLIC_CNT) {
161 volumeGroup.minIndex = kDefaultVolumeIndexMin;
162 volumeGroup.maxIndex = kDefaultVolumeIndexMax;
163 } else {
164 volumeGroup.minIndex = KVolumeIndexDeferredToAudioService;
165 volumeGroup.maxIndex = KVolumeIndexDeferredToAudioService;
166 }
167 volumeGroup.volumeCurves = volumeCurves;
168 mAidlEngineConfig.volumeGroups.push_back(std::move(volumeGroup));
169 }
170}
171
172void AudioPolicyConfigXmlConverter::parseVolumes() {
173 if (mStreamToVolumeCurvesMap.empty() && getXsdcConfig()->hasVolumes()) {
174 mapStreamsToVolumeCurves();
175 addVolumeGroupstoEngineConfig();
176 }
177}
Lorena Torres-Huerta394e2522022-12-20 02:21:41 +0000178
179void AudioPolicyConfigXmlConverter::init() {
180 if (!getXsdcConfig()->hasModules()) return;
181 for (const ap_xsd::Modules& xsdcModulesType : getXsdcConfig()->getModules()) {
182 if (!xsdcModulesType.has_module()) continue;
183 for (const ap_xsd::Modules::Module& xsdcModule : xsdcModulesType.get_module()) {
184 // 'primary' in the XML schema used by HIDL is equivalent to 'default' module.
185 const std::string name =
186 xsdcModule.getName() != "primary" ? xsdcModule.getName() : "default";
Mikhail Naganovfc35ca32023-10-02 17:08:12 -0700187 if (name != "r_submix") {
188 mModuleConfigurations->emplace_back(
189 name, VALUE_OR_FATAL(convertModuleConfigToAidl(xsdcModule)));
190 } else {
191 // See the note on the 'getRSubmixConfiguration' function.
192 mModuleConfigurations->emplace_back(name, nullptr);
193 }
Lorena Torres-Huerta394e2522022-12-20 02:21:41 +0000194 }
195 }
196}
Mikhail Naganovfc35ca32023-10-02 17:08:12 -0700197
Lorena Torres-Huertabc585bd2022-10-23 20:41:35 +0000198} // namespace aidl::android::hardware::audio::core::internal