blob: 629091277403aa99ea6239dc8b70008dec3af694 [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
24#include <aidl/android/media/audio/common/AudioHalEngineConfig.h>
25#include <system/audio-base-utils.h>
26
27#include "core-impl/AudioPolicyConfigXmlConverter.h"
28
29using aidl::android::media::audio::common::AudioHalEngineConfig;
30using aidl::android::media::audio::common::AudioHalVolumeCurve;
31using aidl::android::media::audio::common::AudioHalVolumeGroup;
32using aidl::android::media::audio::common::AudioStreamType;
33
34namespace xsd = android::audio::policy::configuration;
35
36namespace aidl::android::hardware::audio::core::internal {
37
38static const int kDefaultVolumeIndexMin = 0;
39static const int kDefaultVolumeIndexMax = 100;
40static const int KVolumeIndexDeferredToAudioService = -1;
41/**
42 * Valid curve points take the form "<index>,<attenuationMb>", where the index
43 * must be in the range [0,100]. kInvalidCurvePointIndex is used to indicate
44 * that a point was formatted incorrectly (e.g. if a vendor accidentally typed a
45 * '.' instead of a ',' in their XML) -- using such a curve point will result in
46 * failed VTS tests.
47 */
48static const int8_t kInvalidCurvePointIndex = -1;
49
50AudioHalVolumeCurve::CurvePoint AudioPolicyConfigXmlConverter::convertCurvePointToAidl(
51 const std::string& xsdcCurvePoint) {
52 AudioHalVolumeCurve::CurvePoint aidlCurvePoint{};
53 if (sscanf(xsdcCurvePoint.c_str(), "%" SCNd8 ",%d", &aidlCurvePoint.index,
54 &aidlCurvePoint.attenuationMb) != 2) {
55 aidlCurvePoint.index = kInvalidCurvePointIndex;
56 }
57 return aidlCurvePoint;
58}
59
60AudioHalVolumeCurve AudioPolicyConfigXmlConverter::convertVolumeCurveToAidl(
61 const xsd::Volume& xsdcVolumeCurve) {
62 AudioHalVolumeCurve aidlVolumeCurve;
63 aidlVolumeCurve.deviceCategory =
64 static_cast<AudioHalVolumeCurve::DeviceCategory>(xsdcVolumeCurve.getDeviceCategory());
65 if (xsdcVolumeCurve.hasRef()) {
66 if (mVolumesReferenceMap.empty()) {
67 mVolumesReferenceMap = generateReferenceMap<xsd::Volumes, xsd::Reference>(
68 getXsdcConfig()->getVolumes());
69 }
70 aidlVolumeCurve.curvePoints =
71 convertCollectionToAidl<std::string, AudioHalVolumeCurve::CurvePoint>(
72 mVolumesReferenceMap.at(xsdcVolumeCurve.getRef()).getPoint(),
73 std::bind(&AudioPolicyConfigXmlConverter::convertCurvePointToAidl, this,
74 std::placeholders::_1));
75 } else {
76 aidlVolumeCurve.curvePoints =
77 convertCollectionToAidl<std::string, AudioHalVolumeCurve::CurvePoint>(
78 xsdcVolumeCurve.getPoint(),
79 std::bind(&AudioPolicyConfigXmlConverter::convertCurvePointToAidl, this,
80 std::placeholders::_1));
81 }
82 return aidlVolumeCurve;
83}
84
85void AudioPolicyConfigXmlConverter::mapStreamToVolumeCurve(const xsd::Volume& xsdcVolumeCurve) {
86 mStreamToVolumeCurvesMap[xsdcVolumeCurve.getStream()].push_back(
87 convertVolumeCurveToAidl(xsdcVolumeCurve));
88}
89
90const AudioHalEngineConfig& AudioPolicyConfigXmlConverter::getAidlEngineConfig() {
91 if (mAidlEngineConfig.volumeGroups.empty() && getXsdcConfig() &&
92 getXsdcConfig()->hasVolumes()) {
93 parseVolumes();
94 }
95 return mAidlEngineConfig;
96}
97
98void AudioPolicyConfigXmlConverter::mapStreamsToVolumeCurves() {
99 if (getXsdcConfig()->hasVolumes()) {
100 for (const xsd::Volumes& xsdcWrapperType : getXsdcConfig()->getVolumes()) {
101 for (const xsd::Volume& xsdcVolume : xsdcWrapperType.getVolume()) {
102 mapStreamToVolumeCurve(xsdcVolume);
103 }
104 }
105 }
106}
107
108void AudioPolicyConfigXmlConverter::addVolumeGroupstoEngineConfig() {
109 for (const auto& [xsdcStream, volumeCurves] : mStreamToVolumeCurvesMap) {
110 AudioHalVolumeGroup volumeGroup;
111 volumeGroup.name = xsd::toString(xsdcStream);
112 if (static_cast<int>(xsdcStream) >= AUDIO_STREAM_PUBLIC_CNT) {
113 volumeGroup.minIndex = kDefaultVolumeIndexMin;
114 volumeGroup.maxIndex = kDefaultVolumeIndexMax;
115 } else {
116 volumeGroup.minIndex = KVolumeIndexDeferredToAudioService;
117 volumeGroup.maxIndex = KVolumeIndexDeferredToAudioService;
118 }
119 volumeGroup.volumeCurves = volumeCurves;
120 mAidlEngineConfig.volumeGroups.push_back(std::move(volumeGroup));
121 }
122}
123
124void AudioPolicyConfigXmlConverter::parseVolumes() {
125 if (mStreamToVolumeCurvesMap.empty() && getXsdcConfig()->hasVolumes()) {
126 mapStreamsToVolumeCurves();
127 addVolumeGroupstoEngineConfig();
128 }
129}
130} // namespace aidl::android::hardware::audio::core::internal