Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2a1cf618 authored by Mikhail Naganov's avatar Mikhail Naganov
Browse files

Remove AudioAttributesInternal and media.AudioFlag

There exist equivalent types from the stable package
android.media.audio.common. Switch to these types
and remove duplicates.

Update aidl<->legacy conversions to allow non-vendor
tags within AudioAttributes. Non-vendor tags only get
filtered out on the HAL boundary: cpp<->ndk.

Bug: 281850726
Test: atest audioclient_serialization_tests
Test: atest audio_aidl_ndk_conversion_tests
Test: atest audiorouting_tests
Test: atest audiosystem_tests
Merged-In: If1ff43110c54613c5c29b42a2dc3e5d832708c28
Change-Id: If1ff43110c54613c5c29b42a2dc3e5d832708c28
parent f6d3bbe1
Loading
Loading
Loading
Loading
+7 −30
Original line number Diff line number Diff line
@@ -19,7 +19,6 @@
#include <algorithm>
#include <map>
#include <sstream>
#include <regex>
#include <utility>
#include <vector>

@@ -101,12 +100,6 @@ using media::audio::common::PcmType;

namespace {

bool isVendorExtension(const std::string& s) {
    // Must be the same as defined in AudioAttributes.aidl and {Playback|Record}TrackMetadata.aidl
    static const std::regex vendorExtension("VX_[A-Z0-9]{3,}_[_A-Z0-9]+");
    return std::regex_match(s.begin(), s.end(), vendorExtension);
}

std::vector<std::string> splitString(const std::string& s, char separator) {
    std::istringstream iss(s);
    std::string t;
@@ -1815,11 +1808,6 @@ legacy2aidl_audio_usage_t_AudioUsage(audio_usage_t legacy) {
    return unexpected(BAD_VALUE);
}

namespace {

// TODO(b/281850726): Expose publicly once android.media.AudioFlag is removed.
// Until that, `legacy2aidl_audio_flags_mask_t_AudioFlag` function is ambiguous.

ConversionResult<audio_flags_mask_t>
aidl2legacy_AudioFlag_audio_flags_mask_t(AudioFlag aidl) {
    switch (aidl) {
@@ -1921,8 +1909,6 @@ legacy2aidl_audio_flags_mask_t_int32_t_mask(audio_flags_mask_t legacy) {
            enumToMask_bitmask<int32_t, AudioFlag>);
}

}  // namespace

ConversionResult<std::string>
aidl2legacy_AudioTags_string(const std::vector<std::string>& aidl) {
    std::ostringstream tagsBuffer;
@@ -1931,29 +1917,20 @@ aidl2legacy_AudioTags_string(const std::vector<std::string>& aidl) {
        if (hasValue) {
            tagsBuffer << AUDIO_ATTRIBUTES_TAGS_SEPARATOR;
        }
        if (isVendorExtension(tag)) {
            // Note: with the current regex for vendor tags: VX_[A-Z0-9]{3,}_[_A-Z0-9]+
            // it's impossible to create a vendor tag that would contain the separator, but in case
            // the criteria changes, we double check it here.
        if (strchr(tag.c_str(), AUDIO_ATTRIBUTES_TAGS_SEPARATOR) == nullptr) {
            tagsBuffer << tag;
            hasValue = true;
        } else {
                ALOGE("Vendor extension tag is ill-formed: \"%s\"", tag.c_str());
            ALOGE("Tag is ill-formed: \"%s\"", tag.c_str());
            return unexpected(BAD_VALUE);
        }
    }
    }
    return tagsBuffer.str();
}

ConversionResult<std::vector<std::string>>
legacy2aidl_string_AudioTags(const std::string& legacy) {
    auto allTags = splitString(legacy, AUDIO_ATTRIBUTES_TAGS_SEPARATOR);
    std::vector<std::string> result;
    std::copy_if(std::make_move_iterator(allTags.begin()), std::make_move_iterator(allTags.end()),
                    std::back_inserter(result), isVendorExtension);
    return result;
    return splitString(legacy, AUDIO_ATTRIBUTES_TAGS_SEPARATOR);
}

ConversionResult<audio_attributes_t>
+62 −4
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@
 */

#include <algorithm>
#include <regex>
#include <type_traits>

#define LOG_TAG "AidlConversionNdkCpp"
@@ -34,6 +35,24 @@ namespace android {

namespace {

bool isVendorExtension(const std::string& s) {
    // Per definition in AudioAttributes.aidl and {Playback|Record}TrackMetadata.aidl
    static const std::regex vendorExtension("VX_[A-Z0-9]{3,}_[_A-Z0-9]+");
    return std::regex_match(s.begin(), s.end(), vendorExtension);
}

inline bool isNotVendorExtension(const std::string& s) { return !isVendorExtension(s); }

void filterOutNonVendorTagsInPlace(std::vector<std::string>& tags) {
    if (std::find_if(tags.begin(), tags.end(), isNotVendorExtension) == tags.end()) {
        return;
    }
    std::vector<std::string> temp;
    temp.reserve(tags.size());
    std::copy_if(tags.begin(), tags.end(), std::back_inserter(temp), isVendorExtension);
    tags = std::move(temp);
}

// cpp2ndk and ndk2cpp are universal converters which work for any type,
// however they are not the most efficient way to convert due to extra
// marshaling / unmarshaling step.
@@ -100,11 +119,14 @@ template<typename CppEnum, typename NdkEnum>
}  // namespace

#define GENERATE_CONVERTERS(packageName, className) \
    ConversionResult<::aidl::packageName::className> cpp2ndk_##className( \
    GENERATE_CONVERTERS_IMPL(packageName, _, className)

#define GENERATE_CONVERTERS_IMPL(packageName, prefix, className)        \
    ConversionResult<::aidl::packageName::className> cpp2ndk##prefix##className( \
            const ::packageName::className& cpp) {                      \
        return cpp2ndk<::aidl::packageName::className>(cpp);            \
    }                                                                   \
    ConversionResult<::packageName::className> ndk2cpp_##className(     \
    ConversionResult<::packageName::className> ndk2cpp##prefix##className( \
            const ::aidl::packageName::className& ndk) {                \
        return ndk2cpp<::packageName::className>(ndk);                  \
    }
@@ -120,10 +142,46 @@ template<typename CppEnum, typename NdkEnum>
}

GENERATE_CONVERTERS(android::media::audio::common, AudioFormatDescription);
GENERATE_CONVERTERS(android::media::audio::common, AudioHalEngineConfig);
GENERATE_CONVERTERS_IMPL(android::media::audio::common, _Impl_, AudioHalEngineConfig);
GENERATE_CONVERTERS(android::media::audio::common, AudioMMapPolicyInfo);
GENERATE_ENUM_CONVERTERS(android::media::audio::common, AudioMMapPolicyType);
GENERATE_ENUM_CONVERTERS(android::media::audio::common, AudioMode);
GENERATE_CONVERTERS(android::media::audio::common, AudioPort);

namespace {

// Filter out all AudioAttributes tags that do not conform to the vendor extension pattern.
template<typename T>
void filterOutNonVendorTags(T& audioHalEngineConfig) {
    for (auto& strategy : audioHalEngineConfig.productStrategies) {
        for (auto& group : strategy.attributesGroups) {
            for (auto& attr : group.attributes) {
                filterOutNonVendorTagsInPlace(attr.tags);
            }
        }
    }
}

}  // namespace

ConversionResult<::aidl::android::media::audio::common::AudioHalEngineConfig>
cpp2ndk_AudioHalEngineConfig(const ::android::media::audio::common::AudioHalEngineConfig& cpp) {
    auto conv = cpp2ndk_Impl_AudioHalEngineConfig(cpp);
    if (conv.ok()) {
        filterOutNonVendorTags(conv.value());
    }
    return conv;
}

ConversionResult<::android::media::audio::common::AudioHalEngineConfig>
ndk2cpp_AudioHalEngineConfig(
        const ::aidl::android::media::audio::common::AudioHalEngineConfig& ndk) {
    auto conv = ndk2cpp_Impl_AudioHalEngineConfig(ndk);
    if (conv.ok()) {
        filterOutNonVendorTags(conv.value());
    }
    return conv;
}


}  // namespace android
+10 −0
Original line number Diff line number Diff line
@@ -357,6 +357,16 @@ ConversionResult<audio_usage_t> aidl2legacy_AudioUsage_audio_usage_t(
ConversionResult<media::audio::common::AudioUsage> legacy2aidl_audio_usage_t_AudioUsage(
        audio_usage_t legacy);

ConversionResult<audio_flags_mask_t>
aidl2legacy_AudioFlag_audio_flags_mask_t(media::audio::common::AudioFlag aidl);
ConversionResult<media::audio::common::AudioFlag>
legacy2aidl_audio_flags_mask_t_AudioFlag(audio_flags_mask_t legacy);

ConversionResult<audio_flags_mask_t>
aidl2legacy_int32_t_audio_flags_mask_t_mask(int32_t aidl);
ConversionResult<int32_t>
legacy2aidl_audio_flags_mask_t_int32_t_mask(audio_flags_mask_t legacy);

ConversionResult<std::string>
aidl2legacy_AudioTags_string(const std::vector<std::string>& aidl);
ConversionResult<std::vector<std::string>>
+19 −13
Original line number Diff line number Diff line
@@ -107,25 +107,31 @@ INSTANTIATE_TEST_SUITE_P(AudioTagsRoundTrip, AudioTagsRoundTripTest,
                std::vector<std::string>{"VX_GOOGLE_41"},
                std::vector<std::string>{"VX_GOOGLE_41", "VX_GOOGLE_42"}));

TEST(AudioTags, NonVendorTags) {
TEST(AudioTags, NonVendorTagsAllowed) {
    const std::string separator(1, AUDIO_ATTRIBUTES_TAGS_SEPARATOR);
    const std::vector<std::string> initial{
        "random_string", "random" + separator + "string", "VX_GOOGLE_42"};
    const std::vector<std::string> initial{"random_string", "VX_GOOGLE_42"};
    auto conv = aidl2legacy_AudioTags_string(initial);
    ASSERT_TRUE(conv.ok());
    EXPECT_EQ("VX_GOOGLE_42", conv.value());
    EXPECT_EQ("random_string" + separator + "VX_GOOGLE_42", conv.value());
}

TEST(AudioTags, IllFormedAidlTag) {
    const std::string separator(1, AUDIO_ATTRIBUTES_TAGS_SEPARATOR);
    {
        const std::vector<std::string> initial{"VX_GOOGLE" + separator + "42", "VX_GOOGLE_42"};
        auto conv = aidl2legacy_AudioTags_string(initial);
    // Note: with the current regex for vendor tags: VX_[A-Z0-9]{3,}_[_A-Z0-9]+
    // it's impossible to create a vendor tag that would contain the separator, but in case
    // the criteria changes, we ensure that either such tags get filtered out or an error happens.
        if (conv.ok()) {
            EXPECT_EQ("VX_GOOGLE_42", conv.value());
    } else {
        EXPECT_FALSE(conv.ok()) << conv.value();
        }
        // Failing this conversion is also OK. The result depends on whether the conversion
        // only passes through vendor tags.
    }
    {
        const std::vector<std::string> initial{
            "random_string", "random" + separator + "string", "VX_GOOGLE_42"};
        auto conv = aidl2legacy_AudioTags_string(initial);
        if (conv.ok()) {
            EXPECT_EQ("VX_GOOGLE_42", conv.value());
        }
    }
}
+0 −123
Original line number Diff line number Diff line
@@ -480,129 +480,6 @@ ConversionResult<media::AudioClient> legacy2aidl_AudioClient_AudioClient(
    return aidl;
}

ConversionResult<audio_flags_mask_t>
aidl2legacy_AudioFlag_audio_flags_mask_t(media::AudioFlag aidl) {
    switch (aidl) {
        case media::AudioFlag::AUDIBILITY_ENFORCED:
            return AUDIO_FLAG_AUDIBILITY_ENFORCED;
        case media::AudioFlag::SECURE:
            return AUDIO_FLAG_SECURE;
        case media::AudioFlag::SCO:
            return AUDIO_FLAG_SCO;
        case media::AudioFlag::BEACON:
            return AUDIO_FLAG_BEACON;
        case media::AudioFlag::HW_AV_SYNC:
            return AUDIO_FLAG_HW_AV_SYNC;
        case media::AudioFlag::HW_HOTWORD:
            return AUDIO_FLAG_HW_HOTWORD;
        case media::AudioFlag::BYPASS_INTERRUPTION_POLICY:
            return AUDIO_FLAG_BYPASS_INTERRUPTION_POLICY;
        case media::AudioFlag::BYPASS_MUTE:
            return AUDIO_FLAG_BYPASS_MUTE;
        case media::AudioFlag::LOW_LATENCY:
            return AUDIO_FLAG_LOW_LATENCY;
        case media::AudioFlag::DEEP_BUFFER:
            return AUDIO_FLAG_DEEP_BUFFER;
        case media::AudioFlag::NO_MEDIA_PROJECTION:
            return AUDIO_FLAG_NO_MEDIA_PROJECTION;
        case media::AudioFlag::MUTE_HAPTIC:
            return AUDIO_FLAG_MUTE_HAPTIC;
        case media::AudioFlag::NO_SYSTEM_CAPTURE:
            return AUDIO_FLAG_NO_SYSTEM_CAPTURE;
        case media::AudioFlag::CAPTURE_PRIVATE:
            return AUDIO_FLAG_CAPTURE_PRIVATE;
        case media::AudioFlag::CONTENT_SPATIALIZED:
            return AUDIO_FLAG_CONTENT_SPATIALIZED;
        case media::AudioFlag::NEVER_SPATIALIZE:
            return AUDIO_FLAG_NEVER_SPATIALIZE;
        case media::AudioFlag::CALL_REDIRECTION:
            return AUDIO_FLAG_CALL_REDIRECTION;
    }
    return unexpected(BAD_VALUE);
}

ConversionResult<media::AudioFlag>
legacy2aidl_audio_flags_mask_t_AudioFlag(audio_flags_mask_t legacy) {
    switch (legacy) {
        case AUDIO_FLAG_NONE:
            return unexpected(BAD_VALUE);
        case AUDIO_FLAG_AUDIBILITY_ENFORCED:
            return media::AudioFlag::AUDIBILITY_ENFORCED;
        case AUDIO_FLAG_SECURE:
            return media::AudioFlag::SECURE;
        case AUDIO_FLAG_SCO:
            return media::AudioFlag::SCO;
        case AUDIO_FLAG_BEACON:
            return media::AudioFlag::BEACON;
        case AUDIO_FLAG_HW_AV_SYNC:
            return media::AudioFlag::HW_AV_SYNC;
        case AUDIO_FLAG_HW_HOTWORD:
            return media::AudioFlag::HW_HOTWORD;
        case AUDIO_FLAG_BYPASS_INTERRUPTION_POLICY:
            return media::AudioFlag::BYPASS_INTERRUPTION_POLICY;
        case AUDIO_FLAG_BYPASS_MUTE:
            return media::AudioFlag::BYPASS_MUTE;
        case AUDIO_FLAG_LOW_LATENCY:
            return media::AudioFlag::LOW_LATENCY;
        case AUDIO_FLAG_DEEP_BUFFER:
            return media::AudioFlag::DEEP_BUFFER;
        case AUDIO_FLAG_NO_MEDIA_PROJECTION:
            return media::AudioFlag::NO_MEDIA_PROJECTION;
        case AUDIO_FLAG_MUTE_HAPTIC:
            return media::AudioFlag::MUTE_HAPTIC;
        case AUDIO_FLAG_NO_SYSTEM_CAPTURE:
            return media::AudioFlag::NO_SYSTEM_CAPTURE;
        case AUDIO_FLAG_CAPTURE_PRIVATE:
            return media::AudioFlag::CAPTURE_PRIVATE;
        case AUDIO_FLAG_CONTENT_SPATIALIZED:
            return media::AudioFlag::CONTENT_SPATIALIZED;
        case AUDIO_FLAG_NEVER_SPATIALIZE:
            return media::AudioFlag::NEVER_SPATIALIZE;
        case AUDIO_FLAG_CALL_REDIRECTION:
            return media::AudioFlag::CALL_REDIRECTION;
    }
    return unexpected(BAD_VALUE);
}

ConversionResult<audio_flags_mask_t>
aidl2legacy_int32_t_audio_flags_mask_t_mask(int32_t aidl) {
    return convertBitmask<audio_flags_mask_t, int32_t, audio_flags_mask_t, media::AudioFlag>(
            aidl, aidl2legacy_AudioFlag_audio_flags_mask_t, indexToEnum_index<media::AudioFlag>,
            enumToMask_bitmask<audio_flags_mask_t, audio_flags_mask_t>);
}

ConversionResult<int32_t>
legacy2aidl_audio_flags_mask_t_int32_t_mask(audio_flags_mask_t legacy) {
    return convertBitmask<int32_t, audio_flags_mask_t, media::AudioFlag, audio_flags_mask_t>(
            legacy, legacy2aidl_audio_flags_mask_t_AudioFlag,
            indexToEnum_bitmask<audio_flags_mask_t>,
            enumToMask_index<int32_t, media::AudioFlag>);
}

ConversionResult<audio_attributes_t>
aidl2legacy_AudioAttributesInternal_audio_attributes_t(const media::AudioAttributesInternal& aidl) {
    audio_attributes_t legacy;
    legacy.content_type = VALUE_OR_RETURN(
            aidl2legacy_AudioContentType_audio_content_type_t(aidl.contentType));
    legacy.usage = VALUE_OR_RETURN(aidl2legacy_AudioUsage_audio_usage_t(aidl.usage));
    legacy.source = VALUE_OR_RETURN(aidl2legacy_AudioSource_audio_source_t(aidl.source));
    legacy.flags = VALUE_OR_RETURN(aidl2legacy_int32_t_audio_flags_mask_t_mask(aidl.flags));
    RETURN_IF_ERROR(aidl2legacy_string(aidl.tags, legacy.tags, sizeof(legacy.tags)));
    return legacy;
}

ConversionResult<media::AudioAttributesInternal>
legacy2aidl_audio_attributes_t_AudioAttributesInternal(const audio_attributes_t& legacy) {
    media::AudioAttributesInternal aidl;
    aidl.contentType = VALUE_OR_RETURN(
            legacy2aidl_audio_content_type_t_AudioContentType(legacy.content_type));
    aidl.usage = VALUE_OR_RETURN(legacy2aidl_audio_usage_t_AudioUsage(legacy.usage));
    aidl.source = VALUE_OR_RETURN(legacy2aidl_audio_source_t_AudioSource(legacy.source));
    aidl.flags = VALUE_OR_RETURN(legacy2aidl_audio_flags_mask_t_int32_t_mask(legacy.flags));
    aidl.tags = VALUE_OR_RETURN(legacy2aidl_string(legacy.tags, sizeof(legacy.tags)));
    return aidl;
}

ConversionResult<sp<IMemory>>
aidl2legacy_SharedFileRegion_IMemory(const media::SharedFileRegion& aidl) {
    sp<IMemory> legacy;
Loading