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

Commit 778bc1f6 authored by Mikhail Naganov's avatar Mikhail Naganov
Browse files

audiopolicy: Move surround configuration to xml

Move the configuration for supported surround formats
into APM xml config file.

Bug: 116356348
Test: on elfin
Change-Id: Ifba218fa2c03136a3a59eeee8077b00fba77c069
parent b4e880ab
Loading
Loading
Loading
Loading
+33 −0
Original line number Diff line number Diff line
@@ -16,6 +16,9 @@

#pragma once

#include <unordered_map>
#include <unordered_set>

#include <AudioGain.h>
#include <VolumeCurve.h>
#include <AudioPort.h>
@@ -145,6 +148,35 @@ public:
        inProfile->addAudioProfile(micProfile);
        inProfile->addSupportedDevice(defaultInputDevice);
        module->addInputProfile(inProfile);

        setDefaultSurroundFormats();
    }

    // Surround formats, with an optional list of subformats that are equivalent from users' POV.
    using SurroundFormats = std::unordered_map<audio_format_t, std::unordered_set<audio_format_t>>;

    const SurroundFormats &getSurroundFormats() const
    {
        return mSurroundFormats;
    }

    void setSurroundFormats(const SurroundFormats &surroundFormats)
    {
        mSurroundFormats = surroundFormats;
    }

    void setDefaultSurroundFormats()
    {
        mSurroundFormats = {
            {AUDIO_FORMAT_AC3, {}},
            {AUDIO_FORMAT_E_AC3, {}},
            {AUDIO_FORMAT_DTS, {}},
            {AUDIO_FORMAT_DTS_HD, {}},
            {AUDIO_FORMAT_AAC_LC, {
                    AUDIO_FORMAT_AAC_HE_V1, AUDIO_FORMAT_AAC_HE_V2, AUDIO_FORMAT_AAC_ELD,
                    AUDIO_FORMAT_AAC_XHE}},
            {AUDIO_FORMAT_DOLBY_TRUEHD, {}},
            {AUDIO_FORMAT_E_AC3_JOC, {}}};
    }

private:
@@ -158,6 +190,7 @@ private:
    // DEVICE_CATEGORY_SPEAKER path to boost soft sounds, used to adjust volume curves accordingly.
    // Note: remove also speaker_drc_enabled from global configuration of XML config file.
    bool mIsSpeakerDrcEnabled;
    SurroundFormats mSurroundFormats;
};

} // namespace android
+2 −0
Original line number Diff line number Diff line
@@ -407,6 +407,8 @@ status_t ConfigParsingUtils::loadConfig(const char *path, AudioPolicyConfig &con

    config.setHwModules(hwModules);

    config.setDefaultSurroundFormats();

    config_free(root);
    free(root);
    free(data);
+93 −9
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@

#include <memory>
#include <string>
#include <utility>

#include <hidl/Status.h>
#include <libxml/parser.h>
@@ -41,7 +42,7 @@ using hardware::Status;
using utilities::convertTo;

template<typename E, typename C>
struct BaseSerializerTraits {
struct AndroidCollectionTraits {
    typedef sp<E> Element;
    typedef C Collection;
    typedef void* PtrSerializingCtx;
@@ -51,7 +52,19 @@ struct BaseSerializerTraits {
    }
};

struct AudioGainTraits : public BaseSerializerTraits<AudioGain, AudioGainCollection>
template<typename C>
struct StdCollectionTraits {
    typedef C Collection;
    typedef typename C::value_type Element;
    typedef void* PtrSerializingCtx;

    static status_t addElementToCollection(const Element &element, Collection *collection) {
        auto pair = collection->insert(element);
        return pair.second ? NO_ERROR : BAD_VALUE;
    }
};

struct AudioGainTraits : public AndroidCollectionTraits<AudioGain, AudioGainCollection>
{
    static constexpr const char *tag = "gain";
    static constexpr const char *collectionTag = "gains";
@@ -79,7 +92,7 @@ struct AudioGainTraits : public BaseSerializerTraits<AudioGain, AudioGainCollect

// A profile section contains a name,  one audio format and the list of supported sampling rates
// and channel masks for this format
struct AudioProfileTraits : public BaseSerializerTraits<AudioProfile, AudioProfileVector>
struct AudioProfileTraits : public AndroidCollectionTraits<AudioProfile, AudioProfileVector>
{
    static constexpr const char *tag = "profile";
    static constexpr const char *collectionTag = "profiles";
@@ -94,7 +107,7 @@ struct AudioProfileTraits : public BaseSerializerTraits<AudioProfile, AudioProfi
    static Return<Element> deserialize(const xmlNode *cur, PtrSerializingCtx serializingContext);
};

struct MixPortTraits : public BaseSerializerTraits<IOProfile, IOProfileCollection>
struct MixPortTraits : public AndroidCollectionTraits<IOProfile, IOProfileCollection>
{
    static constexpr const char *tag = "mixPort";
    static constexpr const char *collectionTag = "mixPorts";
@@ -113,7 +126,7 @@ struct MixPortTraits : public BaseSerializerTraits<IOProfile, IOProfileCollectio
    // Children: GainTraits
};

struct DevicePortTraits : public BaseSerializerTraits<DeviceDescriptor, DeviceVector>
struct DevicePortTraits : public AndroidCollectionTraits<DeviceDescriptor, DeviceVector>
{
    static constexpr const char *tag = "devicePort";
    static constexpr const char *collectionTag = "devicePorts";
@@ -133,7 +146,7 @@ struct DevicePortTraits : public BaseSerializerTraits<DeviceDescriptor, DeviceVe
    // Children: GainTraits (optional)
};

struct RouteTraits : public BaseSerializerTraits<AudioRoute, AudioRouteVector>
struct RouteTraits : public AndroidCollectionTraits<AudioRoute, AudioRouteVector>
{
    static constexpr const char *tag = "route";
    static constexpr const char *collectionTag = "routes";
@@ -152,7 +165,7 @@ struct RouteTraits : public BaseSerializerTraits<AudioRoute, AudioRouteVector>
    static Return<Element> deserialize(const xmlNode *cur, PtrSerializingCtx serializingContext);
};

struct ModuleTraits : public BaseSerializerTraits<HwModule, HwModuleCollection>
struct ModuleTraits : public AndroidCollectionTraits<HwModule, HwModuleCollection>
{
    static constexpr const char *tag = "module";
    static constexpr const char *collectionTag = "modules";
@@ -186,7 +199,7 @@ struct GlobalConfigTraits
    static status_t deserialize(const xmlNode *root, AudioPolicyConfig *config);
};

struct VolumeTraits : public BaseSerializerTraits<VolumeCurve, VolumeCurvesCollection>
struct VolumeTraits : public AndroidCollectionTraits<VolumeCurve, VolumeCurvesCollection>
{
    static constexpr const char *tag = "volume";
    static constexpr const char *collectionTag = "volumes";
@@ -205,6 +218,28 @@ struct VolumeTraits : public BaseSerializerTraits<VolumeCurve, VolumeCurvesColle
    // No Children
};

struct SurroundSoundTraits
{
    static constexpr const char *tag = "surroundSound";

    static status_t deserialize(const xmlNode *root, AudioPolicyConfig *config);
    // Children: SurroundSoundFormatTraits
};

struct SurroundSoundFormatTraits : public StdCollectionTraits<AudioPolicyConfig::SurroundFormats>
{
    static constexpr const char *tag = "format";
    static constexpr const char *collectionTag = "formats";

    struct Attributes
    {
        static constexpr const char *name = "name";
        static constexpr const char *subformats = "subformats";
    };

    static Return<Element> deserialize(const xmlNode *cur, PtrSerializingCtx serializingContext);
};

class PolicySerializer
{
public:
@@ -224,7 +259,7 @@ private:

    const std::string mVersion;

    // Children: ModulesTraits, VolumeTraits
    // Children: ModulesTraits, VolumeTraits, SurroundSoundTraits (optional)
};

template <class T>
@@ -721,6 +756,52 @@ Return<VolumeTraits::Element> VolumeTraits::deserialize(const xmlNode *cur,
    return volCurve;
}

status_t SurroundSoundTraits::deserialize(const xmlNode *root, AudioPolicyConfig *config)
{
    config->setDefaultSurroundFormats();

    for (const xmlNode *cur = root->xmlChildrenNode; cur != NULL; cur = cur->next) {
        if (!xmlStrcmp(cur->name, reinterpret_cast<const xmlChar*>(tag))) {
            AudioPolicyConfig::SurroundFormats formats;
            status_t status = deserializeCollection<SurroundSoundFormatTraits>(
                    cur, &formats, nullptr);
            if (status == NO_ERROR) {
                config->setSurroundFormats(formats);
            }
            return NO_ERROR;
        }
    }
    return NO_ERROR;
}

Return<SurroundSoundFormatTraits::Element> SurroundSoundFormatTraits::deserialize(
        const xmlNode *cur, PtrSerializingCtx /*serializingContext*/)
{
    std::string formatLiteral = getXmlAttribute(cur, Attributes::name);
    if (formatLiteral.empty()) {
        ALOGE("%s: No %s found for a surround format", __func__, Attributes::name);
        return Status::fromStatusT(BAD_VALUE);
    }
    audio_format_t format = formatFromString(formatLiteral);
    if (format == AUDIO_FORMAT_DEFAULT) {
        ALOGE("%s: Unrecognized format %s", __func__, formatLiteral.c_str());
        return Status::fromStatusT(BAD_VALUE);
    }
    Element pair = std::make_pair(format, Collection::mapped_type{});

    std::string subformatsLiteral = getXmlAttribute(cur, Attributes::subformats);
    if (subformatsLiteral.empty()) return pair;
    FormatVector subformats = formatsFromString(subformatsLiteral, " ");
    for (const auto& subformat : subformats) {
        auto result = pair.second.insert(subformat);
        if (!result.second) {
            ALOGE("%s: could not add subformat %x to collection", __func__, subformat);
            return Status::fromStatusT(BAD_VALUE);
        }
    }
    return pair;
}

status_t PolicySerializer::deserialize(const char *configFile, AudioPolicyConfig *config)
{
    auto doc = make_xmlUnique(xmlParseFile(configFile));
@@ -773,6 +854,9 @@ status_t PolicySerializer::deserialize(const char *configFile, AudioPolicyConfig
    // Global Configuration
    GlobalConfigTraits::deserialize(root, config);

    // Surround configuration
    SurroundSoundTraits::deserialize(root, config);

    return android::OK;
}

+22 −0
Original line number Diff line number Diff line
@@ -198,4 +198,26 @@

    <!-- End of Volume section -->

    <?disabledUntilHalV4_1
    <!-- Surround configuration -->

    <surroundSound>
      <!-- Each of the listed formats gets an entry in Surround Settings dialog.
           There must be a corresponding Java ENCODING_... contant defined in AudioFormat.java,
           and a display name defined in AudioFormat.toDisplayName. For the formats that don't
           need a dedicated Surrond Settings dialog entry, a subformats list should be used. -->
      <formats>
        <format name="AUDIO_FORMAT_AC3" />
        <format name="AUDIO_FORMAT_E_AC3" />
        <format name="AUDIO_FORMAT_E_AC3_JOC" />
        <format name="AUDIO_FORMAT_DOLBY_TRUEHD" />
        <format name="AUDIO_FORMAT_DTS" />
        <format name="AUDIO_FORMAT_DTS_HD" />
        <format name="AUDIO_FORMAT_AAC_LC" subformats="AUDIO_FORMAT_AAC_HE_V1 AUDIO_FORMAT_AAC_HE_V2 AUDIO_FORMAT_AAC_ELD AUDIO_FORMAT_AAC_XHE" />
      </formats>
    </surroundSound>

    <!-- End of Surround configuration -->
    ?>

</audioPolicyConfiguration>
+28 −59
Original line number Diff line number Diff line
@@ -62,26 +62,6 @@ namespace android {
// media / notification / system volume.
constexpr float IN_CALL_EARPIECE_HEADROOM_DB = 3.f;

#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
// Array of all surround formats.
static const audio_format_t SURROUND_FORMATS[] = {
    AUDIO_FORMAT_AC3,
    AUDIO_FORMAT_E_AC3,
    AUDIO_FORMAT_DTS,
    AUDIO_FORMAT_DTS_HD,
    AUDIO_FORMAT_AAC_LC,
    AUDIO_FORMAT_DOLBY_TRUEHD,
    AUDIO_FORMAT_E_AC3_JOC,
};
// Array of all AAC formats. When AAC is enabled by users, all AAC formats should be enabled.
static const audio_format_t AAC_FORMATS[] = {
    AUDIO_FORMAT_AAC_LC,
    AUDIO_FORMAT_AAC_HE_V1,
    AUDIO_FORMAT_AAC_HE_V2,
    AUDIO_FORMAT_AAC_ELD,
    AUDIO_FORMAT_AAC_XHE,
};

// Compressed formats for MSD module, ordered from most preferred to least preferred.
static const std::vector<audio_format_t> compressedFormatsOrder = {{
        AUDIO_FORMAT_MAT_2_1, AUDIO_FORMAT_MAT_2_0, AUDIO_FORMAT_E_AC3,
@@ -3606,35 +3586,38 @@ status_t AudioPolicyManager::getSurroundFormats(unsigned int *numSurroundFormats
             FormatVector supportedFormats =
                 hdmiOutputDevs[i]->getAudioPort()->getAudioProfiles().getSupportedFormats();
             for (size_t j = 0; j < supportedFormats.size(); j++) {
                 if (std::find(std::begin(SURROUND_FORMATS),
                                 std::end(SURROUND_FORMATS),
                                 supportedFormats[j]) != std::end(SURROUND_FORMATS)) {
                 if (mConfig.getSurroundFormats().count(supportedFormats[j]) != 0) {
                     formats.insert(supportedFormats[j]);
                 } else if (std::find(std::begin(AAC_FORMATS),
                                 std::end(AAC_FORMATS),
                                 supportedFormats[j]) != std::end(AAC_FORMATS)) {
                     // if any format in AAC_FORMATS is reported, insert AUDIO_FORMAT_AAC_LC as this
                     // is the only AAC format used in the TvSettings UI for all AAC formats.
                     formats.insert(AUDIO_FORMAT_AAC_LC);
                 } else {
                     for (const auto& pair : mConfig.getSurroundFormats()) {
                         if (pair.second.count(supportedFormats[j]) != 0) {
                             formats.insert(pair.first);
                             break;
                         }
                     }
                 }
             }
        }
    } else {
        for (size_t i = 0; i < ARRAY_SIZE(SURROUND_FORMATS); i++) {
            formats.insert(SURROUND_FORMATS[i]);
        for (const auto& pair : mConfig.getSurroundFormats()) {
            formats.insert(pair.first);
        }
    }
    for (const auto& format: formats) {
        if (formatsWritten < formatsMax) {
            surroundFormats[formatsWritten] = format;
            bool formatEnabled = false;
            if (format == AUDIO_FORMAT_AAC_LC) {
                for (size_t j = 0; j < ARRAY_SIZE(AAC_FORMATS) && !formatEnabled; j++) {
                    formatEnabled =
                            mSurroundFormats.find(AAC_FORMATS[j]) != mSurroundFormats.end();
            if (mConfig.getSurroundFormats().count(format) == 0) {
                // Check sub-formats
                for (const auto& pair : mConfig.getSurroundFormats()) {
                    for (const auto& subformat : pair.second) {
                        formatEnabled = mSurroundFormats.count(subformat) != 0;
                        if (formatEnabled) break;
                    }
                    if (formatEnabled) break;
                }
            } else {
                formatEnabled = mSurroundFormats.find(format) != mSurroundFormats.end();
                formatEnabled = mSurroundFormats.count(format) != 0;
            }
            surroundFormatsEnabled[formatsWritten++] = formatEnabled;
        }
@@ -3647,14 +3630,8 @@ status_t AudioPolicyManager::setSurroundFormatEnabled(audio_format_t audioFormat
{
    ALOGV("%s() format 0x%X enabled %d", __func__, audioFormat, enabled);
    // Check if audio format is a surround formats.
    bool isSurroundFormat = false;
    for (size_t i = 0; i < ARRAY_SIZE(SURROUND_FORMATS); i++) {
        if (audioFormat == SURROUND_FORMATS[i]) {
            isSurroundFormat = true;
            break;
        }
    }
    if (!isSurroundFormat) {
    const auto& formatIter = mConfig.getSurroundFormats().find(audioFormat);
    if (formatIter == mConfig.getSurroundFormats().end()) {
        ALOGW("%s() format 0x%X is not a known surround format", __func__, audioFormat);
        return BAD_VALUE;
    }
@@ -3667,8 +3644,7 @@ status_t AudioPolicyManager::setSurroundFormatEnabled(audio_format_t audioFormat
        return INVALID_OPERATION;
    }

    if ((mSurroundFormats.find(audioFormat) != mSurroundFormats.end() && enabled)
            || (mSurroundFormats.find(audioFormat) == mSurroundFormats.end() && !enabled)) {
    if ((mSurroundFormats.count(audioFormat) != 0) == enabled) {
        return NO_ERROR;
    }

@@ -3680,20 +3656,14 @@ status_t AudioPolicyManager::setSurroundFormatEnabled(audio_format_t audioFormat

    std::unordered_set<audio_format_t> surroundFormatsBackup(mSurroundFormats);
    if (enabled) {
        if (audioFormat == AUDIO_FORMAT_AAC_LC) {
            for (size_t i = 0; i < ARRAY_SIZE(AAC_FORMATS); i++) {
                mSurroundFormats.insert(AAC_FORMATS[i]);
            }
        } else {
        mSurroundFormats.insert(audioFormat);
        }
    } else {
        if (audioFormat == AUDIO_FORMAT_AAC_LC) {
            for (size_t i = 0; i < ARRAY_SIZE(AAC_FORMATS); i++) {
                mSurroundFormats.erase(AAC_FORMATS[i]);
        for (const auto& subFormat : formatIter->second) {
            mSurroundFormats.insert(subFormat);
        }
    } else {
        mSurroundFormats.erase(audioFormat);
        for (const auto& subFormat : formatIter->second) {
            mSurroundFormats.erase(subFormat);
        }
    }

@@ -3738,7 +3708,6 @@ status_t AudioPolicyManager::setSurroundFormatEnabled(audio_format_t audioFormat
        profileUpdated |= (status == NO_ERROR);
    }

    // Undo the surround formats change due to no audio profiles updated.
    if (!profileUpdated) {
        ALOGW("%s() no audio profiles updated, undoing surround formats change", __func__);
        mSurroundFormats = std::move(surroundFormatsBackup);