Loading services/audiopolicy/common/include/policy.h +4 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,10 @@ #include <system/audio.h> static const uint32_t gDynamicRate = 0; static const audio_format_t gDynamicFormat = AUDIO_FORMAT_DEFAULT; static const audio_channel_mask_t gDynamicChannelMask = AUDIO_CHANNEL_NONE; // For mixed output and inputs, the policy will use max mixer sampling rates. // Do not limit sampling rate otherwise #define MAX_MIXER_SAMPLING_RATE 192000 Loading services/audiopolicy/common/managerdefinitions/include/TypeConverter.h +145 −50 Original line number Diff line number Diff line Loading @@ -16,123 +16,218 @@ #pragma once #include "policy.h" #include <Volume.h> #include <system/audio.h> #include <convert/convert.h> #include <utils/Log.h> #include <string> #include <utils/Vector.h> #include <utils/SortedVector.h> namespace android { /** * As far as we do not have real type (only typedef on uint32_t for some types, we * will need this trick to handle template specialization. */ class Devices; class InputFlags; class OutputFlags; class Formats; class OutputChannel; class InputChannel; class ChannelIndex; class GainMode; #define DYNAMIC_VALUE_TAG "dynamic" // special value for "channel_masks", "sampling_rates" and // "formats" in outputs descriptors indicating that supported // values should be queried after opening the output. struct SampleRateTraits { typedef uint32_t Type; typedef Vector<Type> Collection; }; struct DeviceTraits { typedef audio_devices_t Type; typedef Vector<Type> Collection; }; struct OutputFlagTraits { typedef audio_output_flags_t Type; typedef Vector<Type> Collection; }; struct InputFlagTraits { typedef audio_input_flags_t Type; typedef Vector<Type> Collection; }; struct FormatTraits { typedef audio_format_t Type; typedef Vector<Type> Collection; }; struct ChannelTraits { typedef audio_channel_mask_t Type; typedef Vector<Type> Collection; }; struct OutputChannelTraits : public ChannelTraits {}; struct InputChannelTraits : public ChannelTraits {}; struct ChannelIndexTraits : public ChannelTraits {}; struct GainModeTraits { typedef audio_gain_mode_t Type; typedef Vector<Type> Collection; }; struct StreamTraits { typedef audio_stream_type_t Type; typedef Vector<Type> Collection; }; struct DeviceCategoryTraits { typedef device_category Type; typedef Vector<Type> Collection; }; template <typename T> static void collectionFromString(const std::string &str, Vector<T> &collection) struct DefaultTraits { typedef T Type; typedef Vector<Type> Collection; }; template <class Traits> static void collectionFromString(const std::string &str, typename Traits::Collection &collection, const char *del = "|") { char *literal = strdup(str.c_str()); for (const char *cstr = strtok(literal, "|"); cstr != NULL; cstr = strtok(NULL, "|")) { T value; if (utilities::convertTo<std::string, T>(cstr, value)) { for (const char *cstr = strtok(literal, del); cstr != NULL; cstr = strtok(NULL, del)) { typename Traits::Type value; if (utilities::convertTo<std::string, typename Traits::Type >(cstr, value)) { collection.add(value); } } free(literal); } template <typename T, typename SupportedType> template <class Traits> class TypeConverter { public: static bool toString(const T &value, std::string &str); static bool toString(const typename Traits::Type &value, std::string &str); static bool fromString(const std::string &str, T &result); static bool fromString(const std::string &str, typename Traits::Type &result); static void collectionFromString(const std::string &str, Vector<T> &collection); static void collectionFromString(const std::string &str, typename Traits::Collection &collection, const char *del = "|"); static uint32_t maskFromString(const std::string &str); static uint32_t maskFromString(const std::string &str, const char *del = "|"); protected: struct Table { const char *literal; T value; typename Traits::Type value; }; static const Table mTable[]; static const size_t mSize; }; typedef TypeConverter<audio_devices_t, Devices> DeviceConverter; typedef TypeConverter<audio_output_flags_t, OutputFlags> OutputFlagConverter; typedef TypeConverter<audio_input_flags_t, InputFlags> InputFlagConverter; typedef TypeConverter<audio_format_t, Formats> FormatConverter; typedef TypeConverter<audio_channel_mask_t, OutputChannel> OutputChannelConverter; typedef TypeConverter<audio_channel_mask_t, InputChannel> InputChannelConverter; typedef TypeConverter<audio_channel_mask_t, ChannelIndex> ChannelIndexConverter; typedef TypeConverter<audio_gain_mode_t, GainMode> GainModeConverter; static Vector<uint32_t> samplingRatesFromString(const std::string &samplingRates) typedef TypeConverter<DeviceTraits> DeviceConverter; typedef TypeConverter<OutputFlagTraits> OutputFlagConverter; typedef TypeConverter<InputFlagTraits> InputFlagConverter; typedef TypeConverter<FormatTraits> FormatConverter; typedef TypeConverter<OutputChannelTraits> OutputChannelConverter; typedef TypeConverter<InputChannelTraits> InputChannelConverter; typedef TypeConverter<ChannelIndexTraits> ChannelIndexConverter; typedef TypeConverter<GainModeTraits> GainModeConverter; typedef TypeConverter<StreamTraits> StreamTypeConverter; typedef TypeConverter<DeviceCategoryTraits> DeviceCategoryConverter; static SampleRateTraits::Collection samplingRatesFromString(const std::string &samplingRates, const char *del = "|") { Vector<uint32_t> samplingRateCollection; SampleRateTraits::Collection samplingRateCollection; // by convention, "0' in the first entry in mSamplingRates indicates the supported sampling // rates should be read from the output stream after it is opened for the first time if (samplingRates == DYNAMIC_VALUE_TAG) { samplingRateCollection.add(0); samplingRateCollection.add(gDynamicRate); } else { collectionFromString<uint32_t>(samplingRates, samplingRateCollection); collectionFromString<SampleRateTraits>(samplingRates, samplingRateCollection, del); } return samplingRateCollection; } static Vector<audio_format_t> formatsFromString(const std::string &formats) static FormatTraits::Collection formatsFromString(const std::string &formats, const char *del = "|") { Vector<audio_format_t> formatCollection; FormatTraits::Collection formatCollection; // by convention, "0' in the first entry in mFormats indicates the supported formats // should be read from the output stream after it is opened for the first time if (formats == DYNAMIC_VALUE_TAG) { formatCollection.add(AUDIO_FORMAT_DEFAULT); formatCollection.add(gDynamicFormat); } else { FormatConverter::collectionFromString(formats, formatCollection); FormatConverter::collectionFromString(formats, formatCollection, del); } return formatCollection; } static Vector<audio_channel_mask_t> inputChannelMasksFromString(const std::string &inChannels) static audio_format_t formatFromString(const std::string &literalFormat) { audio_format_t format; // by convention, "0' in the first entry in literalFormat indicates the supported formats // should be read from the output stream after it is opened for the first time if (literalFormat == DYNAMIC_VALUE_TAG) { return gDynamicFormat; } else { FormatConverter::fromString(literalFormat, format); } return format; } static audio_channel_mask_t channelMaskFromString(const std::string &literalChannels) { audio_channel_mask_t channels; // by convention, "0' in the first entry in literalChannels indicates the supported channels // should be read from the output stream after it is opened for the first time if (literalChannels == DYNAMIC_VALUE_TAG) { return gDynamicChannelMask; } if (!OutputChannelConverter::fromString(literalChannels, channels) || !InputChannelConverter::fromString(literalChannels, channels)) { return AUDIO_CHANNEL_INVALID; } return channels; } static ChannelTraits::Collection channelMasksFromString(const std::string &channels, const char *del = "|") { ChannelTraits::Collection channelMaskCollection; if (channels == DYNAMIC_VALUE_TAG) { channelMaskCollection.add(gDynamicChannelMask); } else { OutputChannelConverter::collectionFromString(channels, channelMaskCollection, del); InputChannelConverter::collectionFromString(channels, channelMaskCollection, del); ChannelIndexConverter::collectionFromString(channels, channelMaskCollection, del); } return channelMaskCollection; } static InputChannelTraits::Collection inputChannelMasksFromString(const std::string &inChannels, const char *del = "|") { Vector <audio_channel_mask_t> inputChannelMaskCollection; InputChannelTraits::Collection inputChannelMaskCollection; if (inChannels == DYNAMIC_VALUE_TAG) { inputChannelMaskCollection.add(0); inputChannelMaskCollection.add(gDynamicChannelMask); } else { InputChannelConverter::collectionFromString(inChannels, inputChannelMaskCollection); ChannelIndexConverter::collectionFromString(inChannels, inputChannelMaskCollection); InputChannelConverter::collectionFromString(inChannels, inputChannelMaskCollection, del); ChannelIndexConverter::collectionFromString(inChannels, inputChannelMaskCollection, del); } return inputChannelMaskCollection; } static Vector<audio_channel_mask_t> outputChannelMasksFromString(const std::string &outChannels) static OutputChannelTraits::Collection outputChannelMasksFromString(const std::string &outChannels, const char *del = "|") { Vector <audio_channel_mask_t> outputChannelMaskCollection; OutputChannelTraits::Collection outputChannelMaskCollection; // by convention, "0' in the first entry in mChannelMasks indicates the supported channel // masks should be read from the output stream after it is opened for the first time if (outChannels == DYNAMIC_VALUE_TAG) { outputChannelMaskCollection.add(0); outputChannelMaskCollection.add(gDynamicChannelMask); } else { OutputChannelConverter::collectionFromString(outChannels, outputChannelMaskCollection); ChannelIndexConverter::collectionFromString(outChannels, outputChannelMaskCollection); OutputChannelConverter::collectionFromString(outChannels, outputChannelMaskCollection, del); ChannelIndexConverter::collectionFromString(outChannels, outputChannelMaskCollection, del); } return outputChannelMaskCollection; } Loading services/audiopolicy/common/managerdefinitions/src/TypeConverter.cpp +56 −22 Original line number Diff line number Diff line Loading @@ -166,7 +166,6 @@ template<> const size_t InputChannelConverter::mSize = sizeof(InputChannelConverter::mTable) / sizeof(InputChannelConverter::mTable[0]); template <> const ChannelIndexConverter::Table ChannelIndexConverter::mTable[] = { "AUDIO_CHANNEL_INDEX_MASK_1", static_cast<audio_channel_mask_t>(AUDIO_CHANNEL_INDEX_MASK_1), Loading Loading @@ -194,9 +193,41 @@ template<> const size_t GainModeConverter::mSize = sizeof(GainModeConverter::mTable) / sizeof(GainModeConverter::mTable[0]); template <> const DeviceCategoryConverter::Table DeviceCategoryConverter::mTable[] = { MAKE_STRING_FROM_ENUM(DEVICE_CATEGORY_HEADSET), MAKE_STRING_FROM_ENUM(DEVICE_CATEGORY_SPEAKER), MAKE_STRING_FROM_ENUM(DEVICE_CATEGORY_EARPIECE), MAKE_STRING_FROM_ENUM(DEVICE_CATEGORY_EXT_MEDIA) }; template<> const size_t DeviceCategoryConverter::mSize = sizeof(DeviceCategoryConverter::mTable) / sizeof(DeviceCategoryConverter::mTable[0]); template <> const StreamTypeConverter::Table StreamTypeConverter::mTable[] = { MAKE_STRING_FROM_ENUM(AUDIO_STREAM_VOICE_CALL), MAKE_STRING_FROM_ENUM(AUDIO_STREAM_SYSTEM), MAKE_STRING_FROM_ENUM(AUDIO_STREAM_RING), MAKE_STRING_FROM_ENUM(AUDIO_STREAM_MUSIC), MAKE_STRING_FROM_ENUM(AUDIO_STREAM_ALARM), MAKE_STRING_FROM_ENUM(AUDIO_STREAM_NOTIFICATION), MAKE_STRING_FROM_ENUM(AUDIO_STREAM_BLUETOOTH_SCO ), MAKE_STRING_FROM_ENUM(AUDIO_STREAM_ENFORCED_AUDIBLE), MAKE_STRING_FROM_ENUM(AUDIO_STREAM_DTMF), MAKE_STRING_FROM_ENUM(AUDIO_STREAM_TTS), MAKE_STRING_FROM_ENUM(AUDIO_STREAM_ACCESSIBILITY), MAKE_STRING_FROM_ENUM(AUDIO_STREAM_REROUTING), MAKE_STRING_FROM_ENUM(AUDIO_STREAM_PATCH) }; template<> const size_t StreamTypeConverter::mSize = sizeof(StreamTypeConverter::mTable) / sizeof(StreamTypeConverter::mTable[0]); template <typename T, typename SupportedType> bool TypeConverter<T, SupportedType>::toString(const T &value, std::string &str) template <class Traits> bool TypeConverter<Traits>::toString(const typename Traits::Type &value, std::string &str) { for (size_t i = 0; i < mSize; i++) { if (mTable[i].value == value) { Loading @@ -207,8 +238,8 @@ bool TypeConverter<T, SupportedType>::toString(const T &value, std::string &str) return false; } template <typename T, typename SupportedType> bool TypeConverter<T, SupportedType>::fromString(const std::string &str, T &result) template <class Traits> bool TypeConverter<Traits>::fromString(const std::string &str, typename Traits::Type &result) { for (size_t i = 0; i < mSize; i++) { if (strcmp(mTable[i].literal, str.c_str()) == 0) { Loading @@ -220,14 +251,15 @@ bool TypeConverter<T, SupportedType>::fromString(const std::string &str, T &resu return false; } template <typename T, typename SupportedType> void TypeConverter<T, SupportedType>::collectionFromString(const std::string &str, Vector<T> &collection) template <class Traits> void TypeConverter<Traits>::collectionFromString(const std::string &str, typename Traits::Collection &collection, const char *del) { char *literal = strdup(str.c_str()); for (const char *cstr = strtok(literal, "|"); cstr != NULL; cstr = strtok(NULL, "|")) { T value; for (const char *cstr = strtok(literal, del); cstr != NULL; cstr = strtok(NULL, del)) { typename Traits::Type value; if (fromString(cstr, value)) { collection.add(value); } Loading @@ -235,13 +267,13 @@ void TypeConverter<T, SupportedType>::collectionFromString(const std::string &st free(literal); } template <typename T, typename SupportedType> uint32_t TypeConverter<T, SupportedType>::maskFromString(const std::string &str) template <class Traits> uint32_t TypeConverter<Traits>::maskFromString(const std::string &str, const char *del) { char *literal = strdup(str.c_str()); uint32_t value = 0; for (const char *cstr = strtok(literal, "|"); cstr != NULL; cstr = strtok(NULL, "|")) { T type; for (const char *cstr = strtok(literal, del); cstr != NULL; cstr = strtok(NULL, del)) { typename Traits::Type type; if (fromString(cstr, type)) { value |= static_cast<uint32_t>(type); } Loading @@ -250,14 +282,16 @@ uint32_t TypeConverter<T, SupportedType>::maskFromString(const std::string &str) return value; } template class TypeConverter<audio_devices_t, Devices>; template class TypeConverter<audio_output_flags_t, OutputFlags>; template class TypeConverter<audio_input_flags_t, InputFlags>; template class TypeConverter<audio_format_t, Formats>; template class TypeConverter<audio_channel_mask_t, OutputChannel>; template class TypeConverter<audio_channel_mask_t, InputChannel>; template class TypeConverter<audio_channel_mask_t, ChannelIndex>; template class TypeConverter<audio_gain_mode_t, GainMode>; template class TypeConverter<DeviceTraits>; template class TypeConverter<OutputFlagTraits>; template class TypeConverter<InputFlagTraits>; template class TypeConverter<FormatTraits>; template class TypeConverter<OutputChannelTraits>; template class TypeConverter<InputChannelTraits>; template class TypeConverter<ChannelIndexTraits>; template class TypeConverter<GainModeTraits>; template class TypeConverter<StreamTraits>; template class TypeConverter<DeviceCategoryTraits>; }; // namespace android Loading
services/audiopolicy/common/include/policy.h +4 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,10 @@ #include <system/audio.h> static const uint32_t gDynamicRate = 0; static const audio_format_t gDynamicFormat = AUDIO_FORMAT_DEFAULT; static const audio_channel_mask_t gDynamicChannelMask = AUDIO_CHANNEL_NONE; // For mixed output and inputs, the policy will use max mixer sampling rates. // Do not limit sampling rate otherwise #define MAX_MIXER_SAMPLING_RATE 192000 Loading
services/audiopolicy/common/managerdefinitions/include/TypeConverter.h +145 −50 Original line number Diff line number Diff line Loading @@ -16,123 +16,218 @@ #pragma once #include "policy.h" #include <Volume.h> #include <system/audio.h> #include <convert/convert.h> #include <utils/Log.h> #include <string> #include <utils/Vector.h> #include <utils/SortedVector.h> namespace android { /** * As far as we do not have real type (only typedef on uint32_t for some types, we * will need this trick to handle template specialization. */ class Devices; class InputFlags; class OutputFlags; class Formats; class OutputChannel; class InputChannel; class ChannelIndex; class GainMode; #define DYNAMIC_VALUE_TAG "dynamic" // special value for "channel_masks", "sampling_rates" and // "formats" in outputs descriptors indicating that supported // values should be queried after opening the output. struct SampleRateTraits { typedef uint32_t Type; typedef Vector<Type> Collection; }; struct DeviceTraits { typedef audio_devices_t Type; typedef Vector<Type> Collection; }; struct OutputFlagTraits { typedef audio_output_flags_t Type; typedef Vector<Type> Collection; }; struct InputFlagTraits { typedef audio_input_flags_t Type; typedef Vector<Type> Collection; }; struct FormatTraits { typedef audio_format_t Type; typedef Vector<Type> Collection; }; struct ChannelTraits { typedef audio_channel_mask_t Type; typedef Vector<Type> Collection; }; struct OutputChannelTraits : public ChannelTraits {}; struct InputChannelTraits : public ChannelTraits {}; struct ChannelIndexTraits : public ChannelTraits {}; struct GainModeTraits { typedef audio_gain_mode_t Type; typedef Vector<Type> Collection; }; struct StreamTraits { typedef audio_stream_type_t Type; typedef Vector<Type> Collection; }; struct DeviceCategoryTraits { typedef device_category Type; typedef Vector<Type> Collection; }; template <typename T> static void collectionFromString(const std::string &str, Vector<T> &collection) struct DefaultTraits { typedef T Type; typedef Vector<Type> Collection; }; template <class Traits> static void collectionFromString(const std::string &str, typename Traits::Collection &collection, const char *del = "|") { char *literal = strdup(str.c_str()); for (const char *cstr = strtok(literal, "|"); cstr != NULL; cstr = strtok(NULL, "|")) { T value; if (utilities::convertTo<std::string, T>(cstr, value)) { for (const char *cstr = strtok(literal, del); cstr != NULL; cstr = strtok(NULL, del)) { typename Traits::Type value; if (utilities::convertTo<std::string, typename Traits::Type >(cstr, value)) { collection.add(value); } } free(literal); } template <typename T, typename SupportedType> template <class Traits> class TypeConverter { public: static bool toString(const T &value, std::string &str); static bool toString(const typename Traits::Type &value, std::string &str); static bool fromString(const std::string &str, T &result); static bool fromString(const std::string &str, typename Traits::Type &result); static void collectionFromString(const std::string &str, Vector<T> &collection); static void collectionFromString(const std::string &str, typename Traits::Collection &collection, const char *del = "|"); static uint32_t maskFromString(const std::string &str); static uint32_t maskFromString(const std::string &str, const char *del = "|"); protected: struct Table { const char *literal; T value; typename Traits::Type value; }; static const Table mTable[]; static const size_t mSize; }; typedef TypeConverter<audio_devices_t, Devices> DeviceConverter; typedef TypeConverter<audio_output_flags_t, OutputFlags> OutputFlagConverter; typedef TypeConverter<audio_input_flags_t, InputFlags> InputFlagConverter; typedef TypeConverter<audio_format_t, Formats> FormatConverter; typedef TypeConverter<audio_channel_mask_t, OutputChannel> OutputChannelConverter; typedef TypeConverter<audio_channel_mask_t, InputChannel> InputChannelConverter; typedef TypeConverter<audio_channel_mask_t, ChannelIndex> ChannelIndexConverter; typedef TypeConverter<audio_gain_mode_t, GainMode> GainModeConverter; static Vector<uint32_t> samplingRatesFromString(const std::string &samplingRates) typedef TypeConverter<DeviceTraits> DeviceConverter; typedef TypeConverter<OutputFlagTraits> OutputFlagConverter; typedef TypeConverter<InputFlagTraits> InputFlagConverter; typedef TypeConverter<FormatTraits> FormatConverter; typedef TypeConverter<OutputChannelTraits> OutputChannelConverter; typedef TypeConverter<InputChannelTraits> InputChannelConverter; typedef TypeConverter<ChannelIndexTraits> ChannelIndexConverter; typedef TypeConverter<GainModeTraits> GainModeConverter; typedef TypeConverter<StreamTraits> StreamTypeConverter; typedef TypeConverter<DeviceCategoryTraits> DeviceCategoryConverter; static SampleRateTraits::Collection samplingRatesFromString(const std::string &samplingRates, const char *del = "|") { Vector<uint32_t> samplingRateCollection; SampleRateTraits::Collection samplingRateCollection; // by convention, "0' in the first entry in mSamplingRates indicates the supported sampling // rates should be read from the output stream after it is opened for the first time if (samplingRates == DYNAMIC_VALUE_TAG) { samplingRateCollection.add(0); samplingRateCollection.add(gDynamicRate); } else { collectionFromString<uint32_t>(samplingRates, samplingRateCollection); collectionFromString<SampleRateTraits>(samplingRates, samplingRateCollection, del); } return samplingRateCollection; } static Vector<audio_format_t> formatsFromString(const std::string &formats) static FormatTraits::Collection formatsFromString(const std::string &formats, const char *del = "|") { Vector<audio_format_t> formatCollection; FormatTraits::Collection formatCollection; // by convention, "0' in the first entry in mFormats indicates the supported formats // should be read from the output stream after it is opened for the first time if (formats == DYNAMIC_VALUE_TAG) { formatCollection.add(AUDIO_FORMAT_DEFAULT); formatCollection.add(gDynamicFormat); } else { FormatConverter::collectionFromString(formats, formatCollection); FormatConverter::collectionFromString(formats, formatCollection, del); } return formatCollection; } static Vector<audio_channel_mask_t> inputChannelMasksFromString(const std::string &inChannels) static audio_format_t formatFromString(const std::string &literalFormat) { audio_format_t format; // by convention, "0' in the first entry in literalFormat indicates the supported formats // should be read from the output stream after it is opened for the first time if (literalFormat == DYNAMIC_VALUE_TAG) { return gDynamicFormat; } else { FormatConverter::fromString(literalFormat, format); } return format; } static audio_channel_mask_t channelMaskFromString(const std::string &literalChannels) { audio_channel_mask_t channels; // by convention, "0' in the first entry in literalChannels indicates the supported channels // should be read from the output stream after it is opened for the first time if (literalChannels == DYNAMIC_VALUE_TAG) { return gDynamicChannelMask; } if (!OutputChannelConverter::fromString(literalChannels, channels) || !InputChannelConverter::fromString(literalChannels, channels)) { return AUDIO_CHANNEL_INVALID; } return channels; } static ChannelTraits::Collection channelMasksFromString(const std::string &channels, const char *del = "|") { ChannelTraits::Collection channelMaskCollection; if (channels == DYNAMIC_VALUE_TAG) { channelMaskCollection.add(gDynamicChannelMask); } else { OutputChannelConverter::collectionFromString(channels, channelMaskCollection, del); InputChannelConverter::collectionFromString(channels, channelMaskCollection, del); ChannelIndexConverter::collectionFromString(channels, channelMaskCollection, del); } return channelMaskCollection; } static InputChannelTraits::Collection inputChannelMasksFromString(const std::string &inChannels, const char *del = "|") { Vector <audio_channel_mask_t> inputChannelMaskCollection; InputChannelTraits::Collection inputChannelMaskCollection; if (inChannels == DYNAMIC_VALUE_TAG) { inputChannelMaskCollection.add(0); inputChannelMaskCollection.add(gDynamicChannelMask); } else { InputChannelConverter::collectionFromString(inChannels, inputChannelMaskCollection); ChannelIndexConverter::collectionFromString(inChannels, inputChannelMaskCollection); InputChannelConverter::collectionFromString(inChannels, inputChannelMaskCollection, del); ChannelIndexConverter::collectionFromString(inChannels, inputChannelMaskCollection, del); } return inputChannelMaskCollection; } static Vector<audio_channel_mask_t> outputChannelMasksFromString(const std::string &outChannels) static OutputChannelTraits::Collection outputChannelMasksFromString(const std::string &outChannels, const char *del = "|") { Vector <audio_channel_mask_t> outputChannelMaskCollection; OutputChannelTraits::Collection outputChannelMaskCollection; // by convention, "0' in the first entry in mChannelMasks indicates the supported channel // masks should be read from the output stream after it is opened for the first time if (outChannels == DYNAMIC_VALUE_TAG) { outputChannelMaskCollection.add(0); outputChannelMaskCollection.add(gDynamicChannelMask); } else { OutputChannelConverter::collectionFromString(outChannels, outputChannelMaskCollection); ChannelIndexConverter::collectionFromString(outChannels, outputChannelMaskCollection); OutputChannelConverter::collectionFromString(outChannels, outputChannelMaskCollection, del); ChannelIndexConverter::collectionFromString(outChannels, outputChannelMaskCollection, del); } return outputChannelMaskCollection; } Loading
services/audiopolicy/common/managerdefinitions/src/TypeConverter.cpp +56 −22 Original line number Diff line number Diff line Loading @@ -166,7 +166,6 @@ template<> const size_t InputChannelConverter::mSize = sizeof(InputChannelConverter::mTable) / sizeof(InputChannelConverter::mTable[0]); template <> const ChannelIndexConverter::Table ChannelIndexConverter::mTable[] = { "AUDIO_CHANNEL_INDEX_MASK_1", static_cast<audio_channel_mask_t>(AUDIO_CHANNEL_INDEX_MASK_1), Loading Loading @@ -194,9 +193,41 @@ template<> const size_t GainModeConverter::mSize = sizeof(GainModeConverter::mTable) / sizeof(GainModeConverter::mTable[0]); template <> const DeviceCategoryConverter::Table DeviceCategoryConverter::mTable[] = { MAKE_STRING_FROM_ENUM(DEVICE_CATEGORY_HEADSET), MAKE_STRING_FROM_ENUM(DEVICE_CATEGORY_SPEAKER), MAKE_STRING_FROM_ENUM(DEVICE_CATEGORY_EARPIECE), MAKE_STRING_FROM_ENUM(DEVICE_CATEGORY_EXT_MEDIA) }; template<> const size_t DeviceCategoryConverter::mSize = sizeof(DeviceCategoryConverter::mTable) / sizeof(DeviceCategoryConverter::mTable[0]); template <> const StreamTypeConverter::Table StreamTypeConverter::mTable[] = { MAKE_STRING_FROM_ENUM(AUDIO_STREAM_VOICE_CALL), MAKE_STRING_FROM_ENUM(AUDIO_STREAM_SYSTEM), MAKE_STRING_FROM_ENUM(AUDIO_STREAM_RING), MAKE_STRING_FROM_ENUM(AUDIO_STREAM_MUSIC), MAKE_STRING_FROM_ENUM(AUDIO_STREAM_ALARM), MAKE_STRING_FROM_ENUM(AUDIO_STREAM_NOTIFICATION), MAKE_STRING_FROM_ENUM(AUDIO_STREAM_BLUETOOTH_SCO ), MAKE_STRING_FROM_ENUM(AUDIO_STREAM_ENFORCED_AUDIBLE), MAKE_STRING_FROM_ENUM(AUDIO_STREAM_DTMF), MAKE_STRING_FROM_ENUM(AUDIO_STREAM_TTS), MAKE_STRING_FROM_ENUM(AUDIO_STREAM_ACCESSIBILITY), MAKE_STRING_FROM_ENUM(AUDIO_STREAM_REROUTING), MAKE_STRING_FROM_ENUM(AUDIO_STREAM_PATCH) }; template<> const size_t StreamTypeConverter::mSize = sizeof(StreamTypeConverter::mTable) / sizeof(StreamTypeConverter::mTable[0]); template <typename T, typename SupportedType> bool TypeConverter<T, SupportedType>::toString(const T &value, std::string &str) template <class Traits> bool TypeConverter<Traits>::toString(const typename Traits::Type &value, std::string &str) { for (size_t i = 0; i < mSize; i++) { if (mTable[i].value == value) { Loading @@ -207,8 +238,8 @@ bool TypeConverter<T, SupportedType>::toString(const T &value, std::string &str) return false; } template <typename T, typename SupportedType> bool TypeConverter<T, SupportedType>::fromString(const std::string &str, T &result) template <class Traits> bool TypeConverter<Traits>::fromString(const std::string &str, typename Traits::Type &result) { for (size_t i = 0; i < mSize; i++) { if (strcmp(mTable[i].literal, str.c_str()) == 0) { Loading @@ -220,14 +251,15 @@ bool TypeConverter<T, SupportedType>::fromString(const std::string &str, T &resu return false; } template <typename T, typename SupportedType> void TypeConverter<T, SupportedType>::collectionFromString(const std::string &str, Vector<T> &collection) template <class Traits> void TypeConverter<Traits>::collectionFromString(const std::string &str, typename Traits::Collection &collection, const char *del) { char *literal = strdup(str.c_str()); for (const char *cstr = strtok(literal, "|"); cstr != NULL; cstr = strtok(NULL, "|")) { T value; for (const char *cstr = strtok(literal, del); cstr != NULL; cstr = strtok(NULL, del)) { typename Traits::Type value; if (fromString(cstr, value)) { collection.add(value); } Loading @@ -235,13 +267,13 @@ void TypeConverter<T, SupportedType>::collectionFromString(const std::string &st free(literal); } template <typename T, typename SupportedType> uint32_t TypeConverter<T, SupportedType>::maskFromString(const std::string &str) template <class Traits> uint32_t TypeConverter<Traits>::maskFromString(const std::string &str, const char *del) { char *literal = strdup(str.c_str()); uint32_t value = 0; for (const char *cstr = strtok(literal, "|"); cstr != NULL; cstr = strtok(NULL, "|")) { T type; for (const char *cstr = strtok(literal, del); cstr != NULL; cstr = strtok(NULL, del)) { typename Traits::Type type; if (fromString(cstr, type)) { value |= static_cast<uint32_t>(type); } Loading @@ -250,14 +282,16 @@ uint32_t TypeConverter<T, SupportedType>::maskFromString(const std::string &str) return value; } template class TypeConverter<audio_devices_t, Devices>; template class TypeConverter<audio_output_flags_t, OutputFlags>; template class TypeConverter<audio_input_flags_t, InputFlags>; template class TypeConverter<audio_format_t, Formats>; template class TypeConverter<audio_channel_mask_t, OutputChannel>; template class TypeConverter<audio_channel_mask_t, InputChannel>; template class TypeConverter<audio_channel_mask_t, ChannelIndex>; template class TypeConverter<audio_gain_mode_t, GainMode>; template class TypeConverter<DeviceTraits>; template class TypeConverter<OutputFlagTraits>; template class TypeConverter<InputFlagTraits>; template class TypeConverter<FormatTraits>; template class TypeConverter<OutputChannelTraits>; template class TypeConverter<InputChannelTraits>; template class TypeConverter<ChannelIndexTraits>; template class TypeConverter<GainModeTraits>; template class TypeConverter<StreamTraits>; template class TypeConverter<DeviceCategoryTraits>; }; // namespace android