xref: /aosp_15_r20/frameworks/av/media/audioaidlconversion/AidlConversionNdk.cpp (revision ec779b8e0859a360c3d303172224686826e6e0e1)
1 /*
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 <sstream>
18 #include <utility>
19 
20 #include <system/audio.h>
21 #define LOG_TAG "AidlConversionNdk"
22 //#define LOG_NDEBUG 0
23 #include <utils/Log.h>
24 #include <utils/Errors.h>
25 
26 #include <media/AidlConversionCppNdk.h>
27 #include <media/AidlConversionNdk.h>
28 #include <Utils.h>
29 
30 ////////////////////////////////////////////////////////////////////////////////////////////////////
31 // AIDL NDK backend to legacy audio data structure conversion utilities.
32 
33 namespace aidl {
34 namespace android {
35 
36 using hardware::audio::common::PlaybackTrackMetadata;
37 using hardware::audio::common::RecordTrackMetadata;
38 using hardware::audio::common::SourceMetadata;
39 using ::android::BAD_VALUE;
40 using ::android::OK;
41 
42 namespace {
43 
combineString(const std::vector<std::string> & v,char separator,std::string * result)44 ::android::status_t combineString(
45         const std::vector<std::string>& v, char separator, std::string* result) {
46     std::ostringstream oss;
47     for (const auto& s : v) {
48         if (oss.tellp() > 0) {
49             oss << separator;
50         }
51         if (s.find(separator) == std::string::npos) {
52             oss << s;
53         } else {
54             ALOGE("%s: string \"%s\" contains separator character \"%c\"",
55                     __func__, s.c_str(), separator);
56             return BAD_VALUE;
57         }
58     }
59     *result = oss.str();
60     return OK;
61 }
62 
splitString(const std::string & s,char separator)63 std::vector<std::string> splitString(const std::string& s, char separator) {
64     std::istringstream iss(s);
65     std::string t;
66     std::vector<std::string> result;
67     while (std::getline(iss, t, separator)) {
68         result.push_back(std::move(t));
69     }
70     return result;
71 }
72 
filterOutNonVendorTags(const std::vector<std::string> & tags)73 std::vector<std::string> filterOutNonVendorTags(const std::vector<std::string>& tags) {
74     std::vector<std::string> result;
75     std::copy_if(tags.begin(), tags.end(), std::back_inserter(result),
76             ::aidl::android::hardware::audio::common::maybeVendorExtension);
77     return result;
78 }
79 
80 }  // namespace
81 
82 // buffer_provider_t is not supported thus skipped
aidl2legacy_AudioConfig_buffer_config_t(const media::audio::common::AudioConfig & aidl,bool isInput)83 ConversionResult<buffer_config_t> aidl2legacy_AudioConfig_buffer_config_t(
84         const media::audio::common::AudioConfig& aidl, bool isInput) {
85     buffer_config_t legacy;
86 
87     legacy.samplingRate = VALUE_OR_RETURN(convertIntegral<uint32_t>(aidl.base.sampleRate));
88     legacy.mask |= EFFECT_CONFIG_SMP_RATE;
89 
90     legacy.channels = VALUE_OR_RETURN(
91             aidl2legacy_AudioChannelLayout_audio_channel_mask_t(aidl.base.channelMask, isInput));
92     legacy.mask |= EFFECT_CONFIG_CHANNELS;
93 
94     legacy.format =
95             VALUE_OR_RETURN(aidl2legacy_AudioFormatDescription_audio_format_t(aidl.base.format));
96     legacy.mask |= EFFECT_CONFIG_FORMAT;
97     legacy.buffer.frameCount = aidl.frameCount;
98 
99     // TODO: add accessMode and mask
100     return legacy;
101 }
102 
103 ConversionResult<media::audio::common::AudioConfig>
legacy2aidl_buffer_config_t_AudioConfig(const buffer_config_t & legacy,bool isInput)104 legacy2aidl_buffer_config_t_AudioConfig(const buffer_config_t& legacy, bool isInput) {
105     media::audio::common::AudioConfig aidl;
106 
107     if (legacy.mask & EFFECT_CONFIG_SMP_RATE) {
108         aidl.base.sampleRate = VALUE_OR_RETURN(convertIntegral<int32_t>(legacy.samplingRate));
109     }
110     if (legacy.mask & EFFECT_CONFIG_CHANNELS) {
111         aidl.base.channelMask = VALUE_OR_RETURN(legacy2aidl_audio_channel_mask_t_AudioChannelLayout(
112                 static_cast<audio_channel_mask_t>(legacy.channels), isInput));
113     }
114     if (legacy.mask & EFFECT_CONFIG_FORMAT) {
115         aidl.base.format = VALUE_OR_RETURN(legacy2aidl_audio_format_t_AudioFormatDescription(
116                 static_cast<audio_format_t>(legacy.format)));
117     }
118     aidl.frameCount = legacy.buffer.frameCount;
119 
120     // TODO: add accessMode and mask
121     return aidl;
122 }
123 
aidl2legacy_AudioAttributesTags(const std::vector<std::string> & aidl,char * legacy)124 ::android::status_t aidl2legacy_AudioAttributesTags(
125         const std::vector<std::string>& aidl, char* legacy) {
126     std::string aidlTags;
127     RETURN_STATUS_IF_ERROR(combineString(
128                     filterOutNonVendorTags(aidl), AUDIO_ATTRIBUTES_TAGS_SEPARATOR, &aidlTags));
129     RETURN_STATUS_IF_ERROR(aidl2legacy_string(aidlTags, legacy, AUDIO_ATTRIBUTES_TAGS_MAX_SIZE));
130     return OK;
131 }
132 
legacy2aidl_AudioAttributesTags(const char * legacy)133 ConversionResult<std::vector<std::string>> legacy2aidl_AudioAttributesTags(const char* legacy) {
134     std::string legacyTags = VALUE_OR_RETURN(legacy2aidl_string(
135                     legacy, AUDIO_ATTRIBUTES_TAGS_MAX_SIZE));
136     return filterOutNonVendorTags(splitString(legacyTags, AUDIO_ATTRIBUTES_TAGS_SEPARATOR));
137 }
138 
139 ConversionResult<playback_track_metadata_v7>
aidl2legacy_PlaybackTrackMetadata_playback_track_metadata_v7(const PlaybackTrackMetadata & aidl)140 aidl2legacy_PlaybackTrackMetadata_playback_track_metadata_v7(const PlaybackTrackMetadata& aidl) {
141     playback_track_metadata_v7 legacy;
142     legacy.base.usage = VALUE_OR_RETURN(aidl2legacy_AudioUsage_audio_usage_t(aidl.usage));
143     legacy.base.content_type = VALUE_OR_RETURN(aidl2legacy_AudioContentType_audio_content_type_t(
144                     aidl.contentType));
145     legacy.base.gain = aidl.gain;
146     legacy.channel_mask = VALUE_OR_RETURN(aidl2legacy_AudioChannelLayout_audio_channel_mask_t(
147                     aidl.channelMask, false /*isInput*/));
148     RETURN_IF_ERROR(aidl2legacy_AudioAttributesTags(aidl.tags, legacy.tags));
149     return legacy;
150 }
151 
152 ConversionResult<PlaybackTrackMetadata>
legacy2aidl_playback_track_metadata_v7_PlaybackTrackMetadata(const playback_track_metadata_v7 & legacy)153 legacy2aidl_playback_track_metadata_v7_PlaybackTrackMetadata(
154         const playback_track_metadata_v7& legacy) {
155     PlaybackTrackMetadata aidl;
156     aidl.usage = VALUE_OR_RETURN(legacy2aidl_audio_usage_t_AudioUsage(legacy.base.usage));
157     aidl.contentType = VALUE_OR_RETURN(legacy2aidl_audio_content_type_t_AudioContentType(
158                     legacy.base.content_type));
159     aidl.gain = legacy.base.gain;
160     aidl.channelMask = VALUE_OR_RETURN(legacy2aidl_audio_channel_mask_t_AudioChannelLayout(
161                     legacy.channel_mask, false /*isInput*/));
162     aidl.tags = VALUE_OR_RETURN(legacy2aidl_AudioAttributesTags(legacy.tags));
163     return aidl;
164 }
165 
166 ConversionResult<record_track_metadata_v7>
aidl2legacy_RecordTrackMetadata_record_track_metadata_v7(const RecordTrackMetadata & aidl)167 aidl2legacy_RecordTrackMetadata_record_track_metadata_v7(const RecordTrackMetadata& aidl) {
168     record_track_metadata_v7 legacy;
169     legacy.base.source = VALUE_OR_RETURN(aidl2legacy_AudioSource_audio_source_t(aidl.source));
170     legacy.base.gain = aidl.gain;
171     if (aidl.destinationDevice.has_value()) {
172         RETURN_IF_ERROR(aidl2legacy_AudioDevice_audio_device(aidl.destinationDevice.value(),
173                         &legacy.base.dest_device, legacy.base.dest_device_address));
174     } else {
175         legacy.base.dest_device = AUDIO_DEVICE_NONE;
176     }
177     legacy.channel_mask = VALUE_OR_RETURN(aidl2legacy_AudioChannelLayout_audio_channel_mask_t(
178                     aidl.channelMask, true /*isInput*/));
179     RETURN_IF_ERROR(aidl2legacy_AudioAttributesTags(aidl.tags, legacy.tags));
180     return legacy;
181 }
182 
183 ConversionResult<RecordTrackMetadata>
legacy2aidl_record_track_metadata_v7_RecordTrackMetadata(const record_track_metadata_v7 & legacy)184 legacy2aidl_record_track_metadata_v7_RecordTrackMetadata(const record_track_metadata_v7& legacy) {
185     RecordTrackMetadata aidl;
186     aidl.source = VALUE_OR_RETURN(legacy2aidl_audio_source_t_AudioSource(legacy.base.source));
187     aidl.gain = legacy.base.gain;
188     if (legacy.base.dest_device != AUDIO_DEVICE_NONE) {
189         aidl.destinationDevice = VALUE_OR_RETURN(legacy2aidl_audio_device_AudioDevice(
190                         legacy.base.dest_device, legacy.base.dest_device_address));
191     }
192     aidl.channelMask = VALUE_OR_RETURN(legacy2aidl_audio_channel_mask_t_AudioChannelLayout(
193                     legacy.channel_mask, true /*isInput*/));
194     aidl.tags = VALUE_OR_RETURN(legacy2aidl_AudioAttributesTags(legacy.tags));
195     return aidl;
196 }
197 
198 // static
199 ConversionResult<SourceMetadata>
legacy2aidl_playback_track_metadata_v7_SourceMetadata(const std::vector<playback_track_metadata_v7_t> & legacy)200 legacy2aidl_playback_track_metadata_v7_SourceMetadata(
201         const std::vector<playback_track_metadata_v7_t>& legacy) {
202     SourceMetadata aidl;
203     aidl.tracks = VALUE_OR_RETURN(
204             convertContainer<std::vector<PlaybackTrackMetadata>>(
205                     legacy,
206                     legacy2aidl_playback_track_metadata_v7_PlaybackTrackMetadata));
207     return aidl;
208 }
209 
210 }  // namespace android
211 }  // aidl
212