Loading services/audiopolicy/common/managerdefinitions/include/AudioPolicyConfig.h +33 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,9 @@ #pragma once #include <unordered_map> #include <unordered_set> #include <AudioGain.h> #include <VolumeCurve.h> #include <AudioPort.h> Loading Loading @@ -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: Loading @@ -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 services/audiopolicy/common/managerdefinitions/src/ConfigParsingUtils.cpp +2 −0 Original line number Diff line number Diff line Loading @@ -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); Loading services/audiopolicy/common/managerdefinitions/src/Serializer.cpp +93 −9 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ #include <memory> #include <string> #include <utility> #include <hidl/Status.h> #include <libxml/parser.h> Loading @@ -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; Loading @@ -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"; Loading Loading @@ -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"; Loading @@ -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"; Loading @@ -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"; Loading @@ -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"; Loading @@ -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"; Loading Loading @@ -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"; Loading @@ -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: Loading @@ -224,7 +259,7 @@ private: const std::string mVersion; // Children: ModulesTraits, VolumeTraits // Children: ModulesTraits, VolumeTraits, SurroundSoundTraits (optional) }; template <class T> Loading Loading @@ -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)); Loading Loading @@ -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; } Loading services/audiopolicy/config/audio_policy_configuration.xml +22 −0 Original line number Diff line number Diff line Loading @@ -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> services/audiopolicy/managerdefault/AudioPolicyManager.cpp +28 −59 Original line number Diff line number Diff line Loading @@ -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, Loading Loading @@ -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; } Loading @@ -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; } Loading @@ -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; } Loading @@ -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); } } Loading Loading @@ -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); Loading Loading
services/audiopolicy/common/managerdefinitions/include/AudioPolicyConfig.h +33 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,9 @@ #pragma once #include <unordered_map> #include <unordered_set> #include <AudioGain.h> #include <VolumeCurve.h> #include <AudioPort.h> Loading Loading @@ -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: Loading @@ -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
services/audiopolicy/common/managerdefinitions/src/ConfigParsingUtils.cpp +2 −0 Original line number Diff line number Diff line Loading @@ -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); Loading
services/audiopolicy/common/managerdefinitions/src/Serializer.cpp +93 −9 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ #include <memory> #include <string> #include <utility> #include <hidl/Status.h> #include <libxml/parser.h> Loading @@ -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; Loading @@ -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"; Loading Loading @@ -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"; Loading @@ -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"; Loading @@ -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"; Loading @@ -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"; Loading @@ -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"; Loading Loading @@ -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"; Loading @@ -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: Loading @@ -224,7 +259,7 @@ private: const std::string mVersion; // Children: ModulesTraits, VolumeTraits // Children: ModulesTraits, VolumeTraits, SurroundSoundTraits (optional) }; template <class T> Loading Loading @@ -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)); Loading Loading @@ -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; } Loading
services/audiopolicy/config/audio_policy_configuration.xml +22 −0 Original line number Diff line number Diff line Loading @@ -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>
services/audiopolicy/managerdefault/AudioPolicyManager.cpp +28 −59 Original line number Diff line number Diff line Loading @@ -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, Loading Loading @@ -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; } Loading @@ -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; } Loading @@ -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; } Loading @@ -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); } } Loading Loading @@ -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); Loading