diff --git a/media/libaudiofoundation/Android.bp b/media/libaudiofoundation/Android.bp index 5045d8762f..c91b79e93b 100644 --- a/media/libaudiofoundation/Android.bp +++ b/media/libaudiofoundation/Android.bp @@ -10,17 +10,21 @@ cc_library_shared { srcs: [ "AudioGain.cpp", + "AudioPortBase.cpp", + "AudioProfile.cpp", ], shared_libs: [ "libbase", "libbinder", "liblog", + "libmedia_helper", "libutils", ], header_libs: [ "libaudio_system_headers", + "libaudioclient_headers", "libaudiofoundation_headers", ], diff --git a/media/libaudiofoundation/AudioPortBase.cpp b/media/libaudiofoundation/AudioPortBase.cpp new file mode 100644 index 0000000000..922a82cfd7 --- /dev/null +++ b/media/libaudiofoundation/AudioPortBase.cpp @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include +#include +#include + +namespace android { + +void AudioPortFoundation::toAudioPort(struct audio_port *port) const { + // TODO: update this function once audio_port structure reflects the new profile definition. + // For compatibility reason: flatening the AudioProfile into audio_port structure. + FormatSet flatenedFormats; + SampleRateSet flatenedRates; + ChannelMaskSet flatenedChannels; + for (const auto& profile : *getAudioProfileVectorBase()) { + if (profile->isValid()) { + audio_format_t formatToExport = profile->getFormat(); + const SampleRateSet &ratesToExport = profile->getSampleRates(); + const ChannelMaskSet &channelsToExport = profile->getChannels(); + + flatenedFormats.insert(formatToExport); + flatenedRates.insert(ratesToExport.begin(), ratesToExport.end()); + flatenedChannels.insert(channelsToExport.begin(), channelsToExport.end()); + + if (flatenedRates.size() > AUDIO_PORT_MAX_SAMPLING_RATES || + flatenedChannels.size() > AUDIO_PORT_MAX_CHANNEL_MASKS || + flatenedFormats.size() > AUDIO_PORT_MAX_FORMATS) { + ALOGE("%s: bailing out: cannot export profiles to port config", __func__); + return; + } + } + } + port->role = mRole; + port->type = mType; + strlcpy(port->name, mName.c_str(), AUDIO_PORT_MAX_NAME_LEN); + port->num_sample_rates = flatenedRates.size(); + port->num_channel_masks = flatenedChannels.size(); + port->num_formats = flatenedFormats.size(); + std::copy(flatenedRates.begin(), flatenedRates.end(), port->sample_rates); + std::copy(flatenedChannels.begin(), flatenedChannels.end(), port->channel_masks); + std::copy(flatenedFormats.begin(), flatenedFormats.end(), port->formats); + + ALOGV("AudioPort::toAudioPort() num gains %zu", mGains.size()); + + port->num_gains = std::min(mGains.size(), (size_t) AUDIO_PORT_MAX_GAINS); + for (size_t i = 0; i < port->num_gains; i++) { + port->gains[i] = mGains[i]->getGain(); + } +} + +void AudioPortFoundation::dump(std::string *dst, int spaces, bool verbose) const { + if (!mName.empty()) { + dst->append(base::StringPrintf("%*s- name: %s\n", spaces, "", mName.c_str())); + } + if (verbose) { + std::string profilesStr; + getAudioProfileVectorBase()->dump(&profilesStr, spaces); + dst->append(profilesStr); + + if (mGains.size() != 0) { + dst->append(base::StringPrintf("%*s- gains:\n", spaces, "")); + for (size_t i = 0; i < mGains.size(); i++) { + std::string gainStr; + mGains[i]->dump(&gainStr, spaces + 2, i); + dst->append(gainStr); + } + } + } +} + +} \ No newline at end of file diff --git a/media/libaudiofoundation/AudioProfile.cpp b/media/libaudiofoundation/AudioProfile.cpp new file mode 100644 index 0000000000..aaaa7d16cb --- /dev/null +++ b/media/libaudiofoundation/AudioProfile.cpp @@ -0,0 +1,222 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#define LOG_TAG "AudioProfile" +//#define LOG_NDEBUG 0 + +#include +#include +#include +#include +#include + +namespace android { + +bool operator == (const AudioProfile &left, const AudioProfile &right) +{ + return (left.getFormat() == right.getFormat()) && + (left.getChannels() == right.getChannels()) && + (left.getSampleRates() == right.getSampleRates()); +} + +// static +sp AudioProfile::createFullDynamic(audio_format_t dynamicFormat) +{ + AudioProfile* dynamicProfile = new AudioProfile(dynamicFormat, + ChannelMaskSet(), SampleRateSet()); + dynamicProfile->setDynamicFormat(true); + dynamicProfile->setDynamicChannels(true); + dynamicProfile->setDynamicRate(true); + return dynamicProfile; +} + +AudioProfile::AudioProfile(audio_format_t format, + audio_channel_mask_t channelMasks, + uint32_t samplingRate) : + mName(""), + mFormat(format) +{ + mChannelMasks.insert(channelMasks); + mSamplingRates.insert(samplingRate); +} + +AudioProfile::AudioProfile(audio_format_t format, + const ChannelMaskSet &channelMasks, + const SampleRateSet &samplingRateCollection) : + mName(""), + mFormat(format), + mChannelMasks(channelMasks), + mSamplingRates(samplingRateCollection) {} + +void AudioProfile::setChannels(const ChannelMaskSet &channelMasks) +{ + if (mIsDynamicChannels) { + mChannelMasks = channelMasks; + } +} + +void AudioProfile::setSampleRates(const SampleRateSet &sampleRates) +{ + if (mIsDynamicRate) { + mSamplingRates = sampleRates; + } +} + +void AudioProfile::clear() +{ + if (mIsDynamicChannels) { + mChannelMasks.clear(); + } + if (mIsDynamicRate) { + mSamplingRates.clear(); + } +} + +void AudioProfile::dump(std::string *dst, int spaces) const +{ + dst->append(base::StringPrintf("%s%s%s\n", mIsDynamicFormat ? "[dynamic format]" : "", + mIsDynamicChannels ? "[dynamic channels]" : "", + mIsDynamicRate ? "[dynamic rates]" : "")); + if (mName.length() != 0) { + dst->append(base::StringPrintf("%*s- name: %s\n", spaces, "", mName.c_str())); + } + std::string formatLiteral; + if (FormatConverter::toString(mFormat, formatLiteral)) { + dst->append(base::StringPrintf("%*s- format: %s\n", spaces, "", formatLiteral.c_str())); + } + if (!mSamplingRates.empty()) { + dst->append(base::StringPrintf("%*s- sampling rates:", spaces, "")); + for (auto it = mSamplingRates.begin(); it != mSamplingRates.end();) { + dst->append(base::StringPrintf("%d", *it)); + dst->append(++it == mSamplingRates.end() ? "" : ", "); + } + dst->append("\n"); + } + + if (!mChannelMasks.empty()) { + dst->append(base::StringPrintf("%*s- channel masks:", spaces, "")); + for (auto it = mChannelMasks.begin(); it != mChannelMasks.end();) { + dst->append(base::StringPrintf("0x%04x", *it)); + dst->append(++it == mChannelMasks.end() ? "" : ", "); + } + dst->append("\n"); + } +} + +ssize_t AudioProfileVectorBase::add(const sp &profile) +{ + ssize_t index = size(); + push_back(profile); + return index; +} + +void AudioProfileVectorBase::clearProfiles() +{ + for (auto it = begin(); it != end();) { + if ((*it)->isDynamicFormat() && (*it)->hasValidFormat()) { + it = erase(it); + } else { + (*it)->clear(); + ++it; + } + } +} + +sp AudioProfileVectorBase::getFirstValidProfile() const +{ + for (const auto &profile : *this) { + if (profile->isValid()) { + return profile; + } + } + return nullptr; +} + +sp AudioProfileVectorBase::getFirstValidProfileFor(audio_format_t format) const +{ + for (const auto &profile : *this) { + if (profile->isValid() && profile->getFormat() == format) { + return profile; + } + } + return nullptr; +} + +FormatVector AudioProfileVectorBase::getSupportedFormats() const +{ + FormatVector supportedFormats; + for (const auto &profile : *this) { + if (profile->hasValidFormat()) { + supportedFormats.push_back(profile->getFormat()); + } + } + return supportedFormats; +} + +bool AudioProfileVectorBase::hasDynamicChannelsFor(audio_format_t format) const +{ + for (const auto &profile : *this) { + if (profile->getFormat() == format && profile->isDynamicChannels()) { + return true; + } + } + return false; +} + +bool AudioProfileVectorBase::hasDynamicFormat() const +{ + for (const auto &profile : *this) { + if (profile->isDynamicFormat()) { + return true; + } + } + return false; +} + +bool AudioProfileVectorBase::hasDynamicProfile() const +{ + for (const auto &profile : *this) { + if (profile->isDynamic()) { + return true; + } + } + return false; +} + +bool AudioProfileVectorBase::hasDynamicRateFor(audio_format_t format) const +{ + for (const auto &profile : *this) { + if (profile->getFormat() == format && profile->isDynamicRate()) { + return true; + } + } + return false; +} + +void AudioProfileVectorBase::dump(std::string *dst, int spaces) const +{ + dst->append(base::StringPrintf("%*s- Profiles:\n", spaces, "")); + for (size_t i = 0; i < size(); i++) { + dst->append(base::StringPrintf("%*sProfile %zu:", spaces + 4, "", i)); + std::string profileStr; + at(i)->dump(&profileStr, spaces + 8); + dst->append(profileStr); + } +} + +} // namespace android diff --git a/media/libaudiofoundation/include/media/AudioPortBase.h b/media/libaudiofoundation/include/media/AudioPortBase.h new file mode 100644 index 0000000000..5812c2ca1a --- /dev/null +++ b/media/libaudiofoundation/include/media/AudioPortBase.h @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2019 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +#include +#include +#include +#include +#include +#include + +namespace android { + +class AudioPortFoundation : public virtual RefBase +{ +public: + AudioPortFoundation(const std::string& name, audio_port_type_t type, audio_port_role_t role) : + mName(name), mType(type), mRole(role) {} + + virtual ~AudioPortFoundation() = default; + + void setName(const std::string &name) { mName = name; } + const std::string &getName() const { return mName; } + + audio_port_type_t getType() const { return mType; } + audio_port_role_t getRole() const { return mRole; } + + virtual const std::string getTagName() const = 0; + + void setGains(const AudioGains &gains) { mGains = gains; } + const AudioGains &getGains() const { return mGains; } + + virtual void toAudioPort(struct audio_port *port) const; + + virtual AudioProfileVectorBase* getAudioProfileVectorBase() const = 0; + virtual void addAudioProfile(const sp &profile) { + getAudioProfileVectorBase()->add(profile); + } + virtual void clearAudioProfiles() { + getAudioProfileVectorBase()->clearProfiles(); + } + + bool hasValidAudioProfile() const { return getAudioProfileVectorBase()->hasValidProfile(); } + + status_t checkGain(const struct audio_gain_config *gainConfig, int index) const { + if (index < 0 || (size_t)index >= mGains.size()) { + return BAD_VALUE; + } + return mGains[index]->checkConfig(gainConfig); + } + + bool useInputChannelMask() const + { + return ((mType == AUDIO_PORT_TYPE_DEVICE) && (mRole == AUDIO_PORT_ROLE_SOURCE)) || + ((mType == AUDIO_PORT_TYPE_MIX) && (mRole == AUDIO_PORT_ROLE_SINK)); + } + + void dump(std::string *dst, int spaces, bool verbose = true) const; + + AudioGains mGains; // gain controllers +protected: + std::string mName; + audio_port_type_t mType; + audio_port_role_t mRole; +}; + +template ::value>::type> +class AudioPortBase : public AudioPortFoundation +{ +public: + AudioPortBase(const std::string& name, audio_port_type_t type, audio_port_role_t role) : + AudioPortFoundation(name, type, role) {} + + virtual ~AudioPortBase() {} + + AudioProfileVectorBase* getAudioProfileVectorBase() const override { + return static_cast(const_cast(&mProfiles)); + } + + void addAudioProfile(const sp &profile) override { mProfiles.add(profile); } + void clearAudioProfiles() override { return mProfiles.clearProfiles(); } + + void setAudioProfiles(const ProfileVector &profiles) { mProfiles = profiles; } + ProfileVector &getAudioProfiles() { return mProfiles; } + +protected: + ProfileVector mProfiles; // AudioProfiles supported by this port (format, Rates, Channels) +}; + + +class AudioPortConfigBase : public virtual RefBase +{ +public: + virtual ~AudioPortConfigBase() = default; + + virtual status_t applyAudioPortConfig(const struct audio_port_config *config, + struct audio_port_config *backupConfig = NULL) = 0; + virtual void toAudioPortConfig(struct audio_port_config *dstConfig, + const struct audio_port_config *srcConfig = NULL) const = 0; + + unsigned int getSamplingRate() const { return mSamplingRate; } + audio_format_t getFormat() const { return mFormat; } + audio_channel_mask_t getChannelMask() const { return mChannelMask; } + +protected: + unsigned int mSamplingRate = 0u; + audio_format_t mFormat = AUDIO_FORMAT_INVALID; + audio_channel_mask_t mChannelMask = AUDIO_CHANNEL_NONE; + struct audio_gain_config mGain = { .index = -1 }; +}; + +} // namespace android diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioProfile.h b/media/libaudiofoundation/include/media/AudioProfile.h similarity index 51% rename from services/audiopolicy/common/managerdefinitions/include/AudioProfile.h rename to media/libaudiofoundation/include/media/AudioProfile.h index ea56729827..20f35eb8a1 100644 --- a/services/audiopolicy/common/managerdefinitions/include/AudioProfile.h +++ b/media/libaudiofoundation/include/media/AudioProfile.h @@ -16,19 +16,19 @@ #pragma once +#include +#include + #include #include #include -#include - -#include "policy.h" namespace android { -class AudioProfile : public virtual RefBase +class AudioProfile final : public RefBase { public: - static sp createFullDynamic(); + static sp createFullDynamic(audio_format_t dynamicFormat = AUDIO_FORMAT_DEFAULT); AudioProfile(audio_format_t format, audio_channel_mask_t channelMasks, uint32_t samplingRate); AudioProfile(audio_format_t format, @@ -49,14 +49,6 @@ public: } bool supportsRate(uint32_t rate) const { return mSamplingRates.count(rate) != 0; } - status_t checkExact(uint32_t rate, audio_channel_mask_t channels, audio_format_t format) const; - status_t checkCompatibleChannelMask(audio_channel_mask_t channelMask, - audio_channel_mask_t &updatedChannelMask, - audio_port_type_t portType, - audio_port_role_t portRole) const; - status_t checkCompatibleSamplingRate(uint32_t samplingRate, - uint32_t &updatedSamplingRate) const; - bool hasValidFormat() const { return mFormat != AUDIO_FORMAT_DEFAULT; } bool hasValidRates() const { return !mSamplingRates.empty(); } bool hasValidChannels() const { return !mChannelMasks.empty(); } @@ -72,11 +64,11 @@ public: bool isDynamic() { return mIsDynamicFormat || mIsDynamicChannels || mIsDynamicRate; } - void dump(String8 *dst, int spaces) const; + void dump(std::string *dst, int spaces) const; private: - String8 mName; - audio_format_t mFormat; + std::string mName; + audio_format_t mFormat; // The format for an audio profile should only be set when initialized. ChannelMaskSet mChannelMasks; SampleRateSet mSamplingRates; @@ -85,35 +77,16 @@ private: bool mIsDynamicRate = false; }; - -class AudioProfileVector : public std::vector > +class AudioProfileVectorBase : public std::vector > { public: - ssize_t add(const sp &profile); - // This API is intended to be used by the policy manager once retrieving capabilities - // for a profile with dynamic format, rate and channels attributes - ssize_t addProfileFromHal(const sp &profileToAdd); - void appendProfiles(const AudioProfileVector& audioProfiles) { - insert(end(), audioProfiles.begin(), audioProfiles.end()); - } + virtual ~AudioProfileVectorBase() = default; - status_t checkExactProfile(uint32_t samplingRate, audio_channel_mask_t channelMask, - audio_format_t format) const; - status_t checkCompatibleProfile(uint32_t &samplingRate, audio_channel_mask_t &channelMask, - audio_format_t &format, - audio_port_type_t portType, - audio_port_role_t portRole) const; - void clearProfiles(); - // Assuming that this profile vector contains input profiles, - // find the best matching config from 'outputProfiles', according to - // the given preferences for audio formats and channel masks. - // Note: std::vectors are used because specialized containers for formats - // and channels can be sorted and use their own ordering. - status_t findBestMatchingOutputConfig(const AudioProfileVector& outputProfiles, - const std::vector& preferredFormats, // order: most pref -> least pref - const std::vector& preferredOutputChannels, - bool preferHigherSamplingRates, - audio_config_base *bestOutputConfig) const; + virtual ssize_t add(const sp &profile); + + // If the profile is dynamic format and has valid format, it will be removed when doing + // clearProfiles(). Otherwise, AudioProfile::clear() will be called. + virtual void clearProfiles(); sp getFirstValidProfile() const; sp getFirstValidProfileFor(audio_format_t format) const; @@ -121,19 +94,11 @@ public: FormatVector getSupportedFormats() const; bool hasDynamicChannelsFor(audio_format_t format) const; - bool hasDynamicFormat() const { return getProfileFor(gDynamicFormat) != 0; } + bool hasDynamicFormat() const; bool hasDynamicProfile() const; bool hasDynamicRateFor(audio_format_t format) const; - // One audio profile will be added for each format supported by Audio HAL - void setFormats(const FormatVector &formats); - - void dump(String8 *dst, int spaces) const; - -private: - sp getProfileFor(audio_format_t format) const; - void setSampleRatesFor(const SampleRateSet &sampleRates, audio_format_t format); - void setChannelsFor(const ChannelMaskSet &channelMasks, audio_format_t format); + virtual void dump(std::string *dst, int spaces) const; }; bool operator == (const AudioProfile &left, const AudioProfile &right); diff --git a/services/audiopolicy/common/managerdefinitions/Android.bp b/services/audiopolicy/common/managerdefinitions/Android.bp index ebfba832a8..71d5789d18 100644 --- a/services/audiopolicy/common/managerdefinitions/Android.bp +++ b/services/audiopolicy/common/managerdefinitions/Android.bp @@ -8,7 +8,7 @@ cc_library_static { "src/AudioPatch.cpp", "src/AudioPolicyMix.cpp", "src/AudioPort.cpp", - "src/AudioProfile.cpp", + "src/AudioProfileVector.cpp", "src/AudioRoute.cpp", "src/ClientDescriptor.cpp", "src/DeviceDescriptor.cpp", diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioCollections.h b/services/audiopolicy/common/managerdefinitions/include/AudioCollections.h index a948ea91a1..646ef31d2b 100644 --- a/services/audiopolicy/common/managerdefinitions/include/AudioCollections.h +++ b/services/audiopolicy/common/managerdefinitions/include/AudioCollections.h @@ -31,7 +31,7 @@ class AudioRoute; class AudioPortVector : public Vector > { public: - sp findByTagName(const String8 &tagName) const; + sp findByTagName(const std::string &tagName) const; }; diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioPolicyConfig.h b/services/audiopolicy/common/managerdefinitions/include/AudioPolicyConfig.h index 31c5041927..c17f308b95 100644 --- a/services/audiopolicy/common/managerdefinitions/include/AudioPolicyConfig.h +++ b/services/audiopolicy/common/managerdefinitions/include/AudioPolicyConfig.h @@ -29,6 +29,7 @@ #include #include #include +#include namespace android { @@ -118,9 +119,9 @@ public: mSource = "AudioPolicyConfig::setDefault"; mEngineLibraryNameSuffix = kDefaultEngineLibraryNameSuffix; mDefaultOutputDevice = new DeviceDescriptor(AUDIO_DEVICE_OUT_SPEAKER); - mDefaultOutputDevice->addAudioProfile(AudioProfile::createFullDynamic()); + mDefaultOutputDevice->addAudioProfile(AudioProfile::createFullDynamic(gDynamicFormat)); sp defaultInputDevice = new DeviceDescriptor(AUDIO_DEVICE_IN_BUILTIN_MIC); - defaultInputDevice->addAudioProfile(AudioProfile::createFullDynamic()); + defaultInputDevice->addAudioProfile(AudioProfile::createFullDynamic(gDynamicFormat)); sp micProfile = new AudioProfile( AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_MONO, 8000); defaultInputDevice->addAudioProfile(micProfile); @@ -132,14 +133,14 @@ public: mDefaultOutputDevice->attach(module); defaultInputDevice->attach(module); - sp outProfile = new OutputProfile(String8("primary")); + sp outProfile = new OutputProfile("primary"); outProfile->addAudioProfile( new AudioProfile(AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_OUT_STEREO, 44100)); outProfile->addSupportedDevice(mDefaultOutputDevice); outProfile->setFlags(AUDIO_OUTPUT_FLAG_PRIMARY); module->addOutputProfile(outProfile); - sp inProfile = new InputProfile(String8("primary")); + sp inProfile = new InputProfile("primary"); inProfile->addAudioProfile(micProfile); inProfile->addSupportedDevice(defaultInputDevice); module->addInputProfile(inProfile); diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioPort.h b/services/audiopolicy/common/managerdefinitions/include/AudioPort.h index 641cebfce4..c26bffc499 100644 --- a/services/audiopolicy/common/managerdefinitions/include/AudioPort.h +++ b/services/audiopolicy/common/managerdefinitions/include/AudioPort.h @@ -17,9 +17,10 @@ #pragma once #include "AudioCollections.h" -#include "AudioProfile.h" +#include "AudioProfileVector.h" #include "HandleGenerator.h" #include +#include #include #include #include @@ -32,25 +33,15 @@ namespace android { class HwModule; class AudioRoute; -class AudioPort : public virtual RefBase, private HandleGenerator +class AudioPort : public virtual RefBase, public AudioPortBase, + private HandleGenerator { public: - AudioPort(const String8& name, audio_port_type_t type, audio_port_role_t role) : - mName(name), mType(type), mRole(role), mFlags(AUDIO_OUTPUT_FLAG_NONE) {} + AudioPort(const std::string& name, audio_port_type_t type, audio_port_role_t role) : + AudioPortBase(name, type, role), mFlags(AUDIO_OUTPUT_FLAG_NONE) {} virtual ~AudioPort() {} - void setName(const String8 &name) { mName = name; } - const String8 &getName() const { return mName; } - - audio_port_type_t getType() const { return mType; } - audio_port_role_t getRole() const { return mRole; } - - virtual const String8 getTagName() const = 0; - - void setGains(const AudioGains &gains) { mGains = gains; } - const AudioGains &getGains() const { return mGains; } - virtual void setFlags(uint32_t flags) { //force direct flag if offload flag is set: offloading implies a direct output stream @@ -70,18 +61,9 @@ public: // Audio port IDs are in a different namespace than AudioFlinger unique IDs static audio_port_handle_t getNextUniqueId(); - virtual void toAudioPort(struct audio_port *port) const; - virtual void importAudioPort(const sp& port, bool force = false); - void addAudioProfile(const sp &profile) { mProfiles.add(profile); } - - void setAudioProfiles(const AudioProfileVector &profiles) { mProfiles = profiles; } - AudioProfileVector &getAudioProfiles() { return mProfiles; } - - bool hasValidAudioProfile() const { return mProfiles.hasValidProfile(); } - - bool hasDynamicAudioProfile() const { return mProfiles.hasDynamicProfile(); } + bool hasDynamicAudioProfile() const { return getAudioProfileVectorBase()->hasDynamicProfile(); } // searches for an exact match virtual status_t checkExactAudioProfile(const struct audio_port_config *config) const; @@ -95,10 +77,6 @@ public: return mProfiles.checkCompatibleProfile(samplingRate, channelMask, format, mType, mRole); } - void clearAudioProfiles() { return mProfiles.clearProfiles(); } - - status_t checkGain(const struct audio_gain_config *gainConfig, int index) const; - void pickAudioProfile(uint32_t &samplingRate, audio_channel_mask_t &channelMask, audio_format_t &format) const; @@ -121,12 +99,6 @@ public: const char *getModuleName() const; sp getModule() const { return mModule; } - bool useInputChannelMask() const - { - return ((mType == AUDIO_PORT_TYPE_DEVICE) && (mRole == AUDIO_PORT_ROLE_SOURCE)) || - ((mType == AUDIO_PORT_TYPE_MIX) && (mRole == AUDIO_PORT_ROLE_SINK)); - } - inline bool isDirectOutput() const { return (mType == AUDIO_PORT_TYPE_MIX) && (mRole == AUDIO_PORT_ROLE_SOURCE) && @@ -136,44 +108,36 @@ public: void addRoute(const sp &route) { mRoutes.add(route); } const AudioRouteVector &getRoutes() const { return mRoutes; } - void dump(String8 *dst, int spaces, bool verbose = true) const; - void log(const char* indent) const; - AudioGains mGains; // gain controllers - private: void pickChannelMask(audio_channel_mask_t &channelMask, const ChannelMaskSet &channelMasks) const; void pickSamplingRate(uint32_t &rate, const SampleRateSet &samplingRates) const; - sp mModule; // audio HW module exposing this I/O stream - String8 mName; - audio_port_type_t mType; - audio_port_role_t mRole; uint32_t mFlags; // attribute flags mask (e.g primary output, direct output...). - AudioProfileVector mProfiles; // AudioProfiles supported by this port (format, Rates, Channels) + sp mModule; // audio HW module exposing this I/O stream AudioRouteVector mRoutes; // Routes involving this port }; -class AudioPortConfig : public virtual RefBase +class AudioPortConfig : public AudioPortConfigBase { public: status_t applyAudioPortConfig(const struct audio_port_config *config, - struct audio_port_config *backupConfig = NULL); + struct audio_port_config *backupConfig = NULL) override; + virtual void toAudioPortConfig(struct audio_port_config *dstConfig, - const struct audio_port_config *srcConfig = NULL) const = 0; + const struct audio_port_config *srcConfig = NULL) const override; + virtual sp getAudioPort() const = 0; + virtual bool hasSameHwModuleAs(const sp& other) const { return (other != 0) && (other->getAudioPort() != 0) && (getAudioPort() != 0) && (other->getAudioPort()->getModuleHandle() == getAudioPort()->getModuleHandle()); } + bool hasGainController(bool canUseForVolume = false) const; - unsigned int mSamplingRate = 0u; - audio_format_t mFormat = AUDIO_FORMAT_INVALID; - audio_channel_mask_t mChannelMask = AUDIO_CHANNEL_NONE; - struct audio_gain_config mGain = { .index = -1 }; union audio_io_flags mFlags = { AUDIO_INPUT_FLAG_NONE }; }; diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioProfileVector.h b/services/audiopolicy/common/managerdefinitions/include/AudioProfileVector.h new file mode 100644 index 0000000000..2e7328d437 --- /dev/null +++ b/services/audiopolicy/common/managerdefinitions/include/AudioProfileVector.h @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include + +namespace android { + +class AudioProfileVector : public AudioProfileVectorBase { +public: + virtual ~AudioProfileVector() = default; + + ssize_t add(const sp &profile) override; + + // This API is intended to be used by the policy manager once retrieving capabilities + // for a profile with dynamic format, rate and channels attributes + ssize_t addProfileFromHal(const sp &profileToAdd); + void appendProfiles(const AudioProfileVectorBase& audioProfiles) { + insert(end(), audioProfiles.begin(), audioProfiles.end()); + } + + status_t checkExactProfile(const uint32_t samplingRate, + audio_channel_mask_t channelMask, + audio_format_t format) const; + + status_t checkCompatibleProfile(uint32_t &samplingRate, + audio_channel_mask_t &channelMask, + audio_format_t &format, + audio_port_type_t portType, + audio_port_role_t portRole) const; + + // Assuming that this profile vector contains input profiles, + // find the best matching config from 'outputProfiles', according to + // the given preferences for audio formats and channel masks. + // Note: std::vectors are used because specialized containers for formats + // and channels can be sorted and use their own ordering. + status_t findBestMatchingOutputConfig( + const AudioProfileVector &outputProfiles, + const std::vector &preferredFormats, // order: most pref -> least pref + const std::vector &preferredOutputChannels, + bool preferHigherSamplingRates, + audio_config_base *bestOutputConfig) const; + + // One audio profile will be added for each format supported by Audio HAL + void setFormats(const FormatVector &formats); + +private: + sp getProfileFor(audio_format_t format) const; + void setSampleRatesFor(const SampleRateSet &sampleRates, audio_format_t format); + void setChannelsFor(const ChannelMaskSet &channelMasks, audio_format_t format); +}; + +} // namespace android \ No newline at end of file diff --git a/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h index 33e506f1b7..c2f1d93953 100644 --- a/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h +++ b/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h @@ -30,13 +30,13 @@ class DeviceDescriptor : public AudioPort, public AudioPortConfig { public: // Note that empty name refers by convention to a generic device. - explicit DeviceDescriptor(audio_devices_t type, const String8 &tagName = String8("")); + explicit DeviceDescriptor(audio_devices_t type, const std::string &tagName = ""); DeviceDescriptor(audio_devices_t type, const FormatVector &encodedFormats, - const String8 &tagName = String8("")); + const std::string &tagName = ""); virtual ~DeviceDescriptor() {} - virtual const String8 getTagName() const { return mTagName; } + virtual const std::string getTagName() const { return mTagName; } audio_devices_t type() const { return mDeviceType; } String8 address() const { return mAddress; } @@ -75,7 +75,7 @@ public: private: String8 mAddress{""}; - String8 mTagName; // Unique human readable identifier for a device port found in conf file. + std::string mTagName; // Unique human readable identifier for a device port found in conf file. audio_devices_t mDeviceType; FormatVector mEncodedFormats; audio_port_handle_t mId = AUDIO_PORT_HANDLE_NONE; @@ -112,10 +112,17 @@ public: * equal to AUDIO_PORT_HANDLE_NONE, it also returns a nullptr. */ sp getDeviceFromId(audio_port_handle_t id) const; - sp getDeviceFromTagName(const String8 &tagName) const; + sp getDeviceFromTagName(const std::string &tagName) const; DeviceVector getDevicesFromHwModule(audio_module_handle_t moduleHandle) const; audio_devices_t getDeviceTypesFromHwModule(audio_module_handle_t moduleHandle) const; + DeviceVector getFirstDevicesFromTypes(std::vector orderedTypes) const; + sp getFirstExistingDevice(std::vector orderedTypes) const; + + // If there are devices with the given type and the devices to add is not empty, + // remove all the devices with the given type and add all the devices to add. + void replaceDevicesByType(audio_devices_t typeToRemove, const DeviceVector &devicesToAdd); + bool contains(const sp& item) const { return indexOf(item) >= 0; } /** diff --git a/services/audiopolicy/common/managerdefinitions/include/HwModule.h b/services/audiopolicy/common/managerdefinitions/include/HwModule.h index eb34da448a..65c886a560 100644 --- a/services/audiopolicy/common/managerdefinitions/include/HwModule.h +++ b/services/audiopolicy/common/managerdefinitions/include/HwModule.h @@ -82,17 +82,17 @@ public: status_t addInputProfile(const sp &profile); status_t addProfile(const sp &profile); - status_t addOutputProfile(const String8& name, const audio_config_t *config, + status_t addOutputProfile(const std::string& name, const audio_config_t *config, audio_devices_t device, const String8& address); - status_t removeOutputProfile(const String8& name); - status_t addInputProfile(const String8& name, const audio_config_t *config, + status_t removeOutputProfile(const std::string& name); + status_t addInputProfile(const std::string& name, const audio_config_t *config, audio_devices_t device, const String8& address); - status_t removeInputProfile(const String8& name); + status_t removeInputProfile(const std::string& name); audio_module_handle_t getHandle() const { return mHandle; } void setHandle(audio_module_handle_t handle); - sp findPortByTagName(const String8 &tagName) const + sp findPortByTagName(const std::string &tagName) const { return mPorts.findByTagName(tagName); } diff --git a/services/audiopolicy/common/managerdefinitions/include/IOProfile.h b/services/audiopolicy/common/managerdefinitions/include/IOProfile.h index e0b56d4793..419dd350fa 100644 --- a/services/audiopolicy/common/managerdefinitions/include/IOProfile.h +++ b/services/audiopolicy/common/managerdefinitions/include/IOProfile.h @@ -18,6 +18,7 @@ #include "AudioPort.h" #include "DeviceDescriptor.h" +#include "policy.h" #include #include @@ -33,7 +34,7 @@ class HwModule; class IOProfile : public AudioPort { public: - IOProfile(const String8 &name, audio_port_role_t role) + IOProfile(const std::string &name, audio_port_role_t role) : AudioPort(name, AUDIO_PORT_TYPE_MIX, role), maxOpenCount(1), curOpenCount(0), @@ -41,7 +42,7 @@ public: curActiveCount(0) {} // For a Profile aka MixPort, tag name and name are equivalent. - virtual const String8 getTagName() const { return getName(); } + virtual const std::string getTagName() const { return getName(); } // FIXME: this is needed because shared MMAP stream clients use the same audio session. // Once capture clients are tracked individually and not per session this can be removed @@ -183,13 +184,13 @@ private: class InputProfile : public IOProfile { public: - explicit InputProfile(const String8 &name) : IOProfile(name, AUDIO_PORT_ROLE_SINK) {} + explicit InputProfile(const std::string &name) : IOProfile(name, AUDIO_PORT_ROLE_SINK) {} }; class OutputProfile : public IOProfile { public: - explicit OutputProfile(const String8 &name) : IOProfile(name, AUDIO_PORT_ROLE_SOURCE) {} + explicit OutputProfile(const std::string &name) : IOProfile(name, AUDIO_PORT_ROLE_SOURCE) {} }; } // namespace android diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioCollections.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioCollections.cpp index e8cf485616..b391a09645 100644 --- a/services/audiopolicy/common/managerdefinitions/src/AudioCollections.cpp +++ b/services/audiopolicy/common/managerdefinitions/src/AudioCollections.cpp @@ -24,7 +24,7 @@ namespace android { -sp AudioPortVector::findByTagName(const String8 &tagName) const +sp AudioPortVector::findByTagName(const std::string &tagName) const { for (const auto& port : *this) { if (port->getTagName() == tagName) { diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp index a9b87e3f59..7cb2e10a2b 100644 --- a/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp +++ b/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp @@ -34,8 +34,8 @@ AudioInputDescriptor::AudioInputDescriptor(const sp& profile, { if (profile != NULL) { profile->pickAudioProfile(mSamplingRate, mChannelMask, mFormat); - if (profile->mGains.size() > 0) { - profile->mGains[0]->getDefaultConfig(&mGain); + if (profile->getGains().size() > 0) { + profile->getGains()[0]->getDefaultConfig(&mGain); } } } @@ -212,7 +212,7 @@ status_t AudioInputDescriptor::open(const audio_config_t *config, mDevice = device; ALOGV("opening input for device %s profile %p name %s", - mDevice->toString().c_str(), mProfile.get(), mProfile->getName().string()); + mDevice->toString().c_str(), mProfile.get(), mProfile->getName().c_str()); audio_devices_t deviceType = mDevice->type(); diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp index 49524b09fd..6f0c3f501b 100644 --- a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp +++ b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp @@ -40,8 +40,8 @@ AudioOutputDescriptor::AudioOutputDescriptor(const sp& port, { if (mPort.get() != nullptr) { mPort->pickAudioProfile(mSamplingRate, mChannelMask, mFormat); - if (mPort->mGains.size() > 0) { - mPort->mGains[0]->getDefaultConfig(&mGain); + if (mPort->getGains().size() > 0) { + mPort->getGains()[0]->getDefaultConfig(&mGain); } } } @@ -483,7 +483,7 @@ status_t SwAudioOutputDescriptor::open(const audio_config_t *config, mFlags = (audio_output_flags_t)(mFlags | flags); ALOGV("opening output for device %s profile %p name %s", - mDevices.toString().c_str(), mProfile.get(), mProfile->getName().string()); + mDevices.toString().c_str(), mProfile.get(), mProfile->getName().c_str()); status_t status = mClientInterface->openOutput(mProfile->getModuleHandle(), output, diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp index ff32284796..decfad1b7c 100644 --- a/services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp +++ b/services/audiopolicy/common/managerdefinitions/src/AudioPort.cpp @@ -30,7 +30,7 @@ namespace android { // --- AudioPort class implementation void AudioPort::attach(const sp& module) { - ALOGV("%s: attaching module %s to port %s", __FUNCTION__, getModuleName(), mName.string()); + ALOGV("%s: attaching module %s to port %s", __FUNCTION__, getModuleName(), mName.c_str()); mModule = module; } @@ -60,49 +60,6 @@ const char *AudioPort::getModuleName() const return mModule != 0 ? mModule->getName() : "invalid module"; } -void AudioPort::toAudioPort(struct audio_port *port) const -{ - // TODO: update this function once audio_port structure reflects the new profile definition. - // For compatibility reason: flatening the AudioProfile into audio_port structure. - FormatSet flatenedFormats; - SampleRateSet flatenedRates; - ChannelMaskSet flatenedChannels; - for (const auto& profile : mProfiles) { - if (profile->isValid()) { - audio_format_t formatToExport = profile->getFormat(); - const SampleRateSet &ratesToExport = profile->getSampleRates(); - const ChannelMaskSet &channelsToExport = profile->getChannels(); - - flatenedFormats.insert(formatToExport); - flatenedRates.insert(ratesToExport.begin(), ratesToExport.end()); - flatenedChannels.insert(channelsToExport.begin(), channelsToExport.end()); - - if (flatenedRates.size() > AUDIO_PORT_MAX_SAMPLING_RATES || - flatenedChannels.size() > AUDIO_PORT_MAX_CHANNEL_MASKS || - flatenedFormats.size() > AUDIO_PORT_MAX_FORMATS) { - ALOGE("%s: bailing out: cannot export profiles to port config", __FUNCTION__); - return; - } - } - } - port->role = mRole; - port->type = mType; - strlcpy(port->name, mName, AUDIO_PORT_MAX_NAME_LEN); - port->num_sample_rates = flatenedRates.size(); - port->num_channel_masks = flatenedChannels.size(); - port->num_formats = flatenedFormats.size(); - std::copy(flatenedRates.begin(), flatenedRates.end(), port->sample_rates); - std::copy(flatenedChannels.begin(), flatenedChannels.end(), port->channel_masks); - std::copy(flatenedFormats.begin(), flatenedFormats.end(), port->formats); - - ALOGV("AudioPort::toAudioPort() num gains %zu", mGains.size()); - - port->num_gains = std::min(mGains.size(), (size_t) AUDIO_PORT_MAX_GAINS); - for (size_t i = 0; i < port->num_gains; i++) { - port->gains[i] = mGains[i]->getGain(); - } -} - void AudioPort::importAudioPort(const sp& port, bool force __unused) { for (const auto& profileToImport : port->mProfiles) { @@ -324,40 +281,13 @@ void AudioPort::pickAudioProfile(uint32_t &samplingRate, } } } - ALOGV("%s Port[nm:%s] profile rate=%d, format=%d, channels=%d", __FUNCTION__, mName.string(), + ALOGV("%s Port[nm:%s] profile rate=%d, format=%d, channels=%d", __FUNCTION__, mName.c_str(), samplingRate, channelMask, format); } -status_t AudioPort::checkGain(const struct audio_gain_config *gainConfig, int index) const -{ - if (index < 0 || (size_t)index >= mGains.size()) { - return BAD_VALUE; - } - return mGains[index]->checkConfig(gainConfig); -} - -void AudioPort::dump(String8 *dst, int spaces, bool verbose) const -{ - if (!mName.isEmpty()) { - dst->appendFormat("%*s- name: %s\n", spaces, "", mName.string()); - } - if (verbose) { - mProfiles.dump(dst, spaces); - - if (mGains.size() != 0) { - dst->appendFormat("%*s- gains:\n", spaces, ""); - for (size_t i = 0; i < mGains.size(); i++) { - std::string gainStr; - mGains[i]->dump(&gainStr, spaces + 2, i); - dst->append(gainStr.c_str()); - } - } - } -} - void AudioPort::log(const char* indent) const { - ALOGI("%s Port[nm:%s, type:%d, role:%d]", indent, mName.string(), mType, mRole); + ALOGI("%s Port[nm:%s, type:%d, role:%d]", indent, mName.c_str(), mType, mRole); } // --- AudioPortConfig class implementation diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioProfile.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioProfileVector.cpp similarity index 70% rename from services/audiopolicy/common/managerdefinitions/src/AudioProfile.cpp rename to services/audiopolicy/common/managerdefinitions/src/AudioProfileVector.cpp index d1082e8a77..c17df37c0a 100644 --- a/services/audiopolicy/common/managerdefinitions/src/AudioProfile.cpp +++ b/services/audiopolicy/common/managerdefinitions/src/AudioProfileVector.cpp @@ -26,95 +26,31 @@ #include #include "AudioPort.h" -#include "AudioProfile.h" +#include "AudioProfileVector.h" #include "HwModule.h" -#include "TypeConverter.h" +#include "policy.h" namespace android { -bool operator == (const AudioProfile &left, const AudioProfile &compareTo) +status_t checkExact(const sp &audioProfile, uint32_t samplingRate, + audio_channel_mask_t channelMask, audio_format_t format) { - return (left.getFormat() == compareTo.getFormat()) && - (left.getChannels() == compareTo.getChannels()) && - (left.getSampleRates() == compareTo.getSampleRates()); -} - -static AudioProfile* createFullDynamicImpl() -{ - AudioProfile* dynamicProfile = new AudioProfile(gDynamicFormat, - ChannelMaskSet(), SampleRateSet()); - dynamicProfile->setDynamicFormat(true); - dynamicProfile->setDynamicChannels(true); - dynamicProfile->setDynamicRate(true); - return dynamicProfile; -} - -// static -sp AudioProfile::createFullDynamic() -{ - static sp dynamicProfile = createFullDynamicImpl(); - return dynamicProfile; -} - -AudioProfile::AudioProfile(audio_format_t format, - audio_channel_mask_t channelMasks, - uint32_t samplingRate) : - mName(String8("")), - mFormat(format) -{ - mChannelMasks.insert(channelMasks); - mSamplingRates.insert(samplingRate); -} - -AudioProfile::AudioProfile(audio_format_t format, - const ChannelMaskSet &channelMasks, - const SampleRateSet &samplingRateCollection) : - mName(String8("")), - mFormat(format), - mChannelMasks(channelMasks), - mSamplingRates(samplingRateCollection) {} - -void AudioProfile::setChannels(const ChannelMaskSet &channelMasks) -{ - if (mIsDynamicChannels) { - mChannelMasks = channelMasks; - } -} - -void AudioProfile::setSampleRates(const SampleRateSet &sampleRates) -{ - if (mIsDynamicRate) { - mSamplingRates = sampleRates; - } -} - -void AudioProfile::clear() -{ - if (mIsDynamicChannels) { - mChannelMasks.clear(); - } - if (mIsDynamicRate) { - mSamplingRates.clear(); - } -} - -status_t AudioProfile::checkExact(uint32_t samplingRate, audio_channel_mask_t channelMask, - audio_format_t format) const -{ - if (audio_formats_match(format, mFormat) && - supportsChannels(channelMask) && - supportsRate(samplingRate)) { + if (audio_formats_match(format, audioProfile->getFormat()) && + audioProfile->supportsChannels(channelMask) && + audioProfile->supportsRate(samplingRate)) { return NO_ERROR; } return BAD_VALUE; } -status_t AudioProfile::checkCompatibleSamplingRate(uint32_t samplingRate, - uint32_t &updatedSamplingRate) const +status_t checkCompatibleSamplingRate(const sp &audioProfile, + uint32_t samplingRate, + uint32_t &updatedSamplingRate) { ALOG_ASSERT(samplingRate > 0); - if (mSamplingRates.empty()) { + const SampleRateSet sampleRates = audioProfile->getSampleRates(); + if (sampleRates.empty()) { updatedSamplingRate = samplingRate; return NO_ERROR; } @@ -122,17 +58,17 @@ status_t AudioProfile::checkCompatibleSamplingRate(uint32_t samplingRate, // Search for the closest supported sampling rate that is above (preferred) // or below (acceptable) the desired sampling rate, within a permitted ratio. // The sampling rates are sorted in ascending order. - auto desiredRate = mSamplingRates.lower_bound(samplingRate); + auto desiredRate = sampleRates.lower_bound(samplingRate); // Prefer to down-sample from a higher sampling rate, as we get the desired frequency spectrum. - if (desiredRate != mSamplingRates.end()) { + if (desiredRate != sampleRates.end()) { if (*desiredRate / AUDIO_RESAMPLER_DOWN_RATIO_MAX <= samplingRate) { updatedSamplingRate = *desiredRate; return NO_ERROR; } } // But if we have to up-sample from a lower sampling rate, that's OK. - if (desiredRate != mSamplingRates.begin()) { + if (desiredRate != sampleRates.begin()) { uint32_t candidate = *(--desiredRate); if (candidate * AUDIO_RESAMPLER_UP_RATIO_MAX >= samplingRate) { updatedSamplingRate = candidate; @@ -143,12 +79,14 @@ status_t AudioProfile::checkCompatibleSamplingRate(uint32_t samplingRate, return BAD_VALUE; } -status_t AudioProfile::checkCompatibleChannelMask(audio_channel_mask_t channelMask, - audio_channel_mask_t &updatedChannelMask, - audio_port_type_t portType, - audio_port_role_t portRole) const +status_t checkCompatibleChannelMask(const sp &audioProfile, + audio_channel_mask_t channelMask, + audio_channel_mask_t &updatedChannelMask, + audio_port_type_t portType, + audio_port_role_t portRole) { - if (mChannelMasks.empty()) { + const ChannelMaskSet channelMasks = audioProfile->getChannels(); + if (channelMasks.empty()) { updatedChannelMask = channelMask; return NO_ERROR; } @@ -157,7 +95,7 @@ status_t AudioProfile::checkCompatibleChannelMask(audio_channel_mask_t channelMa == AUDIO_CHANNEL_REPRESENTATION_INDEX; const uint32_t channelCount = audio_channel_count_from_in_mask(channelMask); int bestMatch = 0; - for (const auto &supported : mChannelMasks) { + for (const auto &supported : channelMasks) { if (supported == channelMask) { // Exact matches always taken. updatedChannelMask = channelMask; @@ -235,37 +173,6 @@ status_t AudioProfile::checkCompatibleChannelMask(audio_channel_mask_t channelMa return bestMatch > 0 ? NO_ERROR : BAD_VALUE; } -void AudioProfile::dump(String8 *dst, int spaces) const -{ - dst->appendFormat("%s%s%s\n", mIsDynamicFormat ? "[dynamic format]" : "", - mIsDynamicChannels ? "[dynamic channels]" : "", - mIsDynamicRate ? "[dynamic rates]" : ""); - if (mName.length() != 0) { - dst->appendFormat("%*s- name: %s\n", spaces, "", mName.string()); - } - std::string formatLiteral; - if (FormatConverter::toString(mFormat, formatLiteral)) { - dst->appendFormat("%*s- format: %s\n", spaces, "", formatLiteral.c_str()); - } - if (!mSamplingRates.empty()) { - dst->appendFormat("%*s- sampling rates:", spaces, ""); - for (auto it = mSamplingRates.begin(); it != mSamplingRates.end();) { - dst->appendFormat("%d", *it); - dst->append(++it == mSamplingRates.end() ? "" : ", "); - } - dst->append("\n"); - } - - if (!mChannelMasks.empty()) { - dst->appendFormat("%*s- channel masks:", spaces, ""); - for (auto it = mChannelMasks.begin(); it != mChannelMasks.end();) { - dst->appendFormat("0x%04x", *it); - dst->append(++it == mChannelMasks.end() ? "" : ", "); - } - dst->append("\n"); - } -} - ssize_t AudioProfileVector::add(const sp &profile) { ssize_t index = size(); @@ -311,7 +218,7 @@ ssize_t AudioProfileVector::addProfileFromHal(const sp &profileToA return add(profileToAdd); } -status_t AudioProfileVector::checkExactProfile(uint32_t samplingRate, +status_t AudioProfileVector::checkExactProfile(const uint32_t samplingRate, audio_channel_mask_t channelMask, audio_format_t format) const { @@ -320,7 +227,7 @@ status_t AudioProfileVector::checkExactProfile(uint32_t samplingRate, } for (const auto& profile : *this) { - if (profile->checkExact(samplingRate, channelMask, format) == NO_ERROR) { + if (checkExact(profile, samplingRate, channelMask, format) == NO_ERROR) { return NO_ERROR; } } @@ -353,9 +260,9 @@ status_t AudioProfileVector::checkCompatibleProfile(uint32_t &samplingRate, // rate and channels as well audio_channel_mask_t updatedChannels; uint32_t updatedRate; - if (profile->checkCompatibleChannelMask(channelMask, updatedChannels, - portType, portRole) == NO_ERROR && - profile->checkCompatibleSamplingRate(samplingRate, updatedRate) == NO_ERROR) { + if (checkCompatibleChannelMask(profile, channelMask, updatedChannels, + portType, portRole) == NO_ERROR && + checkCompatibleSamplingRate(profile, samplingRate, updatedRate) == NO_ERROR) { // for inexact checks we take the first linear pcm format due to sorting. format = formatToCompare; channelMask = updatedChannels; @@ -367,18 +274,6 @@ status_t AudioProfileVector::checkCompatibleProfile(uint32_t &samplingRate, return BAD_VALUE; } -void AudioProfileVector::clearProfiles() -{ - for (auto it = begin(); it != end();) { - if ((*it)->isDynamicFormat() && (*it)->hasValidFormat()) { - it = erase(it); - } else { - (*it)->clear(); - ++it; - } - } -} - // Returns an intersection between two possibly unsorted vectors and the contents of 'order'. // The result is ordered according to 'order'. template @@ -449,67 +344,6 @@ status_t AudioProfileVector::findBestMatchingOutputConfig(const AudioProfileVect return BAD_VALUE; } -sp AudioProfileVector::getFirstValidProfile() const -{ - for (const auto &profile : *this) { - if (profile->isValid()) { - return profile; - } - } - return nullptr; -} - -sp AudioProfileVector::getFirstValidProfileFor(audio_format_t format) const -{ - for (const auto &profile : *this) { - if (profile->isValid() && profile->getFormat() == format) { - return profile; - } - } - return nullptr; -} - -FormatVector AudioProfileVector::getSupportedFormats() const -{ - FormatVector supportedFormats; - for (const auto &profile : *this) { - if (profile->hasValidFormat()) { - supportedFormats.push_back(profile->getFormat()); - } - } - return supportedFormats; -} - -bool AudioProfileVector::hasDynamicChannelsFor(audio_format_t format) const -{ - for (const auto &profile : *this) { - if (profile->getFormat() == format && profile->isDynamicChannels()) { - return true; - } - } - return false; -} - -bool AudioProfileVector::hasDynamicProfile() const -{ - for (const auto &profile : *this) { - if (profile->isDynamic()) { - return true; - } - } - return false; -} - -bool AudioProfileVector::hasDynamicRateFor(audio_format_t format) const -{ - for (const auto &profile : *this) { - if (profile->getFormat() == format && profile->isDynamicRate()) { - return true; - } - } - return false; -} - void AudioProfileVector::setFormats(const FormatVector &formats) { // Only allow to change the format of dynamic profile @@ -528,15 +362,6 @@ void AudioProfileVector::setFormats(const FormatVector &formats) } } -void AudioProfileVector::dump(String8 *dst, int spaces) const -{ - dst->appendFormat("%*s- Profiles:\n", spaces, ""); - for (size_t i = 0; i < size(); i++) { - dst->appendFormat("%*sProfile %zu:", spaces + 4, "", i); - at(i)->dump(dst, spaces + 8); - } -} - sp AudioProfileVector::getProfileFor(audio_format_t format) const { for (const auto &profile : *this) { diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioRoute.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioRoute.cpp index 92cbe4eb30..0f35ff8990 100644 --- a/services/audiopolicy/common/managerdefinitions/src/AudioRoute.cpp +++ b/services/audiopolicy/common/managerdefinitions/src/AudioRoute.cpp @@ -26,11 +26,11 @@ namespace android void AudioRoute::dump(String8 *dst, int spaces) const { dst->appendFormat("%*s- Type: %s\n", spaces, "", mType == AUDIO_ROUTE_MUX ? "Mux" : "Mix"); - dst->appendFormat("%*s- Sink: %s\n", spaces, "", mSink->getTagName().string()); + dst->appendFormat("%*s- Sink: %s\n", spaces, "", mSink->getTagName().c_str()); if (mSources.size() != 0) { dst->appendFormat("%*s- Sources: \n", spaces, ""); for (size_t i = 0; i < mSources.size(); i++) { - dst->appendFormat("%*s%s \n", spaces + 4, "", mSources[i]->getTagName().string()); + dst->appendFormat("%*s%s \n", spaces + 4, "", mSources[i]->getTagName().c_str()); } } dst->append("\n"); @@ -41,10 +41,10 @@ bool AudioRoute::supportsPatch(const sp &srcPort, const sp if (mSink == 0 || dstPort == 0 || dstPort != mSink) { return false; } - ALOGV("%s: sinks %s matching", __FUNCTION__, mSink->getTagName().string()); + ALOGV("%s: sinks %s matching", __FUNCTION__, mSink->getTagName().c_str()); for (const auto &sourcePort : mSources) { if (sourcePort == srcPort) { - ALOGV("%s: sources %s matching", __FUNCTION__, sourcePort->getTagName().string()); + ALOGV("%s: sources %s matching", __FUNCTION__, sourcePort->getTagName().c_str()); return true; } } diff --git a/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp index c996cbf4e3..018636dca1 100644 --- a/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp +++ b/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp @@ -26,14 +26,14 @@ namespace android { -DeviceDescriptor::DeviceDescriptor(audio_devices_t type, const String8 &tagName) : +DeviceDescriptor::DeviceDescriptor(audio_devices_t type, const std::string &tagName) : DeviceDescriptor(type, FormatVector{}, tagName) { } DeviceDescriptor::DeviceDescriptor(audio_devices_t type, const FormatVector &encodedFormats, - const String8 &tagName) : - AudioPort(String8(""), AUDIO_PORT_TYPE_DEVICE, + const std::string &tagName) : + AudioPort("", AUDIO_PORT_TYPE_DEVICE, audio_is_output_device(type) ? AUDIO_PORT_ROLE_SINK : AUDIO_PORT_ROLE_SOURCE), mTagName(tagName), mDeviceType(type), mEncodedFormats(encodedFormats) @@ -255,7 +255,6 @@ DeviceVector DeviceVector::getDevicesFromTypeMask(audio_devices_t type) const audio_devices_t curType = itemAt(i)->type() & ~AUDIO_DEVICE_BIT_IN; if ((isOutput == curIsOutput) && ((type & curType) != 0)) { devices.add(itemAt(i)); - type &= ~curType; ALOGV("DeviceVector::%s() for type %08x found %p", __func__, itemAt(i)->type(), itemAt(i).get()); } @@ -263,7 +262,7 @@ DeviceVector DeviceVector::getDevicesFromTypeMask(audio_devices_t type) const return devices; } -sp DeviceVector::getDeviceFromTagName(const String8 &tagName) const +sp DeviceVector::getDeviceFromTagName(const std::string &tagName) const { for (const auto& device : *this) { if (device->getTagName() == tagName) { @@ -273,6 +272,38 @@ sp DeviceVector::getDeviceFromTagName(const String8 &tagName) return nullptr; } +DeviceVector DeviceVector::getFirstDevicesFromTypes( + std::vector orderedTypes) const +{ + DeviceVector devices; + for (auto deviceType : orderedTypes) { + if (!(devices = getDevicesFromTypeMask(deviceType)).isEmpty()) { + break; + } + } + return devices; +} + +sp DeviceVector::getFirstExistingDevice( + std::vector orderedTypes) const { + sp device; + for (auto deviceType : orderedTypes) { + if ((device = getDevice(deviceType, String8(""), AUDIO_FORMAT_DEFAULT)) != nullptr) { + break; + } + } + return device; +} + +void DeviceVector::replaceDevicesByType( + audio_devices_t typeToRemove, const DeviceVector &devicesToAdd) { + DeviceVector devicesToRemove = getDevicesFromTypeMask(typeToRemove); + if (!devicesToRemove.isEmpty() && !devicesToAdd.isEmpty()) { + remove(devicesToRemove); + add(devicesToAdd); + } +} + void DeviceVector::dump(String8 *dst, const String8 &tag, int spaces, bool verbose) const { if (isEmpty()) { @@ -343,8 +374,8 @@ void DeviceDescriptor::dump(String8 *dst, int spaces, int index, bool verbose) c if (mId != 0) { dst->appendFormat("%*s- id: %2d\n", spaces, "", mId); } - if (!mTagName.isEmpty()) { - dst->appendFormat("%*s- tag name: %s\n", spaces, "", mTagName.string()); + if (!mTagName.empty()) { + dst->appendFormat("%*s- tag name: %s\n", spaces, "", mTagName.c_str()); } dst->appendFormat("%*s- type: %-48s\n", spaces, "", ::android::toString(mDeviceType).c_str()); @@ -352,7 +383,9 @@ void DeviceDescriptor::dump(String8 *dst, int spaces, int index, bool verbose) c if (mAddress.size() != 0) { dst->appendFormat("%*s- address: %-32s\n", spaces, "", mAddress.string()); } - AudioPort::dump(dst, spaces, verbose); + std::string portStr; + AudioPort::dump(&portStr, spaces, verbose); + dst->append(portStr.c_str()); } std::string DeviceDescriptor::toString() const diff --git a/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp b/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp index 99e282e872..c232775f12 100644 --- a/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp +++ b/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp @@ -41,7 +41,7 @@ HwModule::~HwModule() } } -status_t HwModule::addOutputProfile(const String8& name, const audio_config_t *config, +status_t HwModule::addOutputProfile(const std::string& name, const audio_config_t *config, audio_devices_t device, const String8& address) { sp profile = new OutputProfile(name); @@ -95,7 +95,7 @@ void HwModule::setProfiles(const IOProfileCollection &profiles) } } -status_t HwModule::removeOutputProfile(const String8& name) +status_t HwModule::removeOutputProfile(const std::string& name) { for (size_t i = 0; i < mOutputProfiles.size(); i++) { if (mOutputProfiles[i]->getName() == name) { @@ -110,7 +110,7 @@ status_t HwModule::removeOutputProfile(const String8& name) return NO_ERROR; } -status_t HwModule::addInputProfile(const String8& name, const audio_config_t *config, +status_t HwModule::addInputProfile(const std::string& name, const audio_config_t *config, audio_devices_t device, const String8& address) { sp profile = new InputProfile(name); @@ -125,12 +125,12 @@ status_t HwModule::addInputProfile(const String8& name, const audio_config_t *co profile->addSupportedDevice(devDesc); ALOGV("addInputProfile() name %s rate %d mask 0x%08x", - name.string(), config->sample_rate, config->channel_mask); + name.c_str(), config->sample_rate, config->channel_mask); return addInputProfile(profile); } -status_t HwModule::removeInputProfile(const String8& name) +status_t HwModule::removeInputProfile(const std::string& name) { for (size_t i = 0; i < mInputProfiles.size(); i++) { if (mInputProfiles[i]->getName() == name) { @@ -193,13 +193,13 @@ void HwModule::refreshSupportedDevices() } DeviceVector sourceDevicesForRoute = getRouteSourceDevices(route); if (sourceDevicesForRoute.isEmpty()) { - ALOGE("%s: invalid source devices for %s", __FUNCTION__, stream->getName().string()); + ALOGE("%s: invalid source devices for %s", __FUNCTION__, stream->getName().c_str()); continue; } sourceDevices.add(sourceDevicesForRoute); } if (sourceDevices.isEmpty()) { - ALOGE("%s: invalid source devices for %s", __FUNCTION__, stream->getName().string()); + ALOGE("%s: invalid source devices for %s", __FUNCTION__, stream->getName().c_str()); continue; } stream->setSupportedDevices(sourceDevices); @@ -214,7 +214,7 @@ void HwModule::refreshSupportedDevices() } sp sinkDevice = getRouteSinkDevice(route); if (sinkDevice == 0) { - ALOGE("%s: invalid sink device for %s", __FUNCTION__, stream->getName().string()); + ALOGE("%s: invalid sink device for %s", __FUNCTION__, stream->getName().c_str()); continue; } sinkDevices.add(sinkDevice); @@ -335,7 +335,7 @@ sp HwModuleCollection::getDeviceDescriptor(const audio_devices if (allowToCreate) { moduleDevice->attach(hwModule); moduleDevice->setAddress(devAddress); - moduleDevice->setName(String8(name)); + moduleDevice->setName(name); } return moduleDevice; } @@ -359,8 +359,8 @@ sp HwModuleCollection::createDevice(const audio_devices_t type address); return nullptr; } - sp device = new DeviceDescriptor(type, String8(name)); - device->setName(String8(name)); + sp device = new DeviceDescriptor(type, name); + device->setName(name); device->setAddress(String8(address)); device->setEncodedFormat(encodedFormat); diff --git a/services/audiopolicy/common/managerdefinitions/src/IOProfile.cpp b/services/audiopolicy/common/managerdefinitions/src/IOProfile.cpp index aefe557508..bf1a0f7182 100644 --- a/services/audiopolicy/common/managerdefinitions/src/IOProfile.cpp +++ b/services/audiopolicy/common/managerdefinitions/src/IOProfile.cpp @@ -107,7 +107,9 @@ bool IOProfile::isCompatibleProfile(const DeviceVector &devices, void IOProfile::dump(String8 *dst) const { - AudioPort::dump(dst, 4); + std::string portStr; + AudioPort::dump(&portStr, 4); + dst->append(portStr.c_str()); dst->appendFormat(" - flags: 0x%04x", getFlags()); std::string flagsLiteral; diff --git a/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp b/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp index c699aa733b..707169b10b 100644 --- a/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp +++ b/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp @@ -430,7 +430,7 @@ Return MixPortTraits::deserialize(const xmlNode *child, audio_port_role_t portRole = (role == Attributes::roleSource) ? AUDIO_PORT_ROLE_SOURCE : AUDIO_PORT_ROLE_SINK; - Element mixPort = new IOProfile(String8(name.c_str()), portRole); + Element mixPort = new IOProfile(name, portRole); AudioProfileTraits::Collection profiles; status_t status = deserializeCollection(child, &profiles, NULL); @@ -438,7 +438,7 @@ Return MixPortTraits::deserialize(const xmlNode *child, return Status::fromStatusT(status); } if (profiles.empty()) { - profiles.add(AudioProfile::createFullDynamic()); + profiles.add(AudioProfile::createFullDynamic(gDynamicFormat)); } mixPort->setAudioProfiles(profiles); @@ -508,7 +508,7 @@ Return DevicePortTraits::deserialize(const xmlNode *c if (!encodedFormatsLiteral.empty()) { encodedFormats = formatsFromString(encodedFormatsLiteral, " "); } - Element deviceDesc = new DeviceDescriptor(type, encodedFormats, String8(name.c_str())); + Element deviceDesc = new DeviceDescriptor(type, encodedFormats, name); std::string address = getXmlAttribute(cur, Attributes::address); if (!address.empty()) { @@ -522,7 +522,7 @@ Return DevicePortTraits::deserialize(const xmlNode *c return Status::fromStatusT(status); } if (profiles.empty()) { - profiles.add(AudioProfile::createFullDynamic()); + profiles.add(AudioProfile::createFullDynamic(gDynamicFormat)); } deviceDesc->setAudioProfiles(profiles); @@ -532,7 +532,7 @@ Return DevicePortTraits::deserialize(const xmlNode *c return Status::fromStatusT(status); } ALOGV("%s: adding device tag %s type %08x address %s", __func__, - deviceDesc->getName().string(), type, deviceDesc->address().string()); + deviceDesc->getName().c_str(), type, deviceDesc->address().string()); return deviceDesc; } @@ -555,7 +555,7 @@ Return RouteTraits::deserialize(const xmlNode *cur, PtrSer return Status::fromStatusT(BAD_VALUE); } // Convert Sink name to port pointer - sp sink = ctx->findPortByTagName(String8(sinkAttr.c_str())); + sp sink = ctx->findPortByTagName(sinkAttr); if (sink == NULL) { ALOGE("%s: no sink found with name=%s", __func__, sinkAttr.c_str()); return Status::fromStatusT(BAD_VALUE); @@ -574,7 +574,7 @@ Return RouteTraits::deserialize(const xmlNode *cur, PtrSer char *devTag = strtok(sourcesLiteral.get(), ","); while (devTag != NULL) { if (strlen(devTag) != 0) { - sp source = ctx->findPortByTagName(String8(devTag)); + sp source = ctx->findPortByTagName(devTag); if (source == NULL) { ALOGE("%s: no source found with name=%s", __func__, devTag); return Status::fromStatusT(BAD_VALUE); @@ -648,7 +648,7 @@ Return ModuleTraits::deserialize(const xmlNode *cur, PtrS ALOGV("%s: %s %s=%s", __func__, tag, childAttachedDeviceTag, reinterpret_cast(attachedDevice.get())); sp device = module->getDeclaredDevices(). - getDeviceFromTagName(String8(reinterpret_cast( + getDeviceFromTagName(std::string(reinterpret_cast( attachedDevice.get()))); ctx->addAvailableDevice(device); } @@ -663,7 +663,7 @@ Return ModuleTraits::deserialize(const xmlNode *cur, PtrS ALOGV("%s: %s %s=%s", __func__, tag, childDefaultOutputDeviceTag, reinterpret_cast(defaultOutputDevice.get())); sp device = module->getDeclaredDevices().getDeviceFromTagName( - String8(reinterpret_cast(defaultOutputDevice.get()))); + std::string(reinterpret_cast(defaultOutputDevice.get()))); if (device != 0 && ctx->getDefaultOutputDevice() == 0) { ctx->setDefaultOutputDevice(device); ALOGV("%s: default is %08x", diff --git a/services/audiopolicy/enginedefault/src/Engine.cpp b/services/audiopolicy/enginedefault/src/Engine.cpp index c602f3a19e..b895c2feec 100644 --- a/services/audiopolicy/enginedefault/src/Engine.cpp +++ b/services/audiopolicy/enginedefault/src/Engine.cpp @@ -136,27 +136,23 @@ status_t Engine::setForceUse(audio_policy_force_use_t usage, audio_policy_forced return EngineBase::setForceUse(usage, config); } -audio_devices_t Engine::getDeviceForStrategyInt(legacy_strategy strategy, - DeviceVector availableOutputDevices, - DeviceVector availableInputDevices, - const SwAudioOutputCollection &outputs, - uint32_t outputDeviceTypesToIgnore) const +DeviceVector Engine::getDevicesForStrategyInt(legacy_strategy strategy, + DeviceVector availableOutputDevices, + DeviceVector availableInputDevices, + const SwAudioOutputCollection &outputs) const { - uint32_t device = AUDIO_DEVICE_NONE; - uint32_t availableOutputDevicesType = - availableOutputDevices.types() & ~outputDeviceTypesToIgnore; + DeviceVector devices; switch (strategy) { case STRATEGY_TRANSMITTED_THROUGH_SPEAKER: - device = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER; + devices = availableOutputDevices.getDevicesFromTypeMask(AUDIO_DEVICE_OUT_SPEAKER); break; case STRATEGY_SONIFICATION_RESPECTFUL: if (isInCall() || outputs.isActiveLocally(toVolumeSource(AUDIO_STREAM_VOICE_CALL))) { - device = getDeviceForStrategyInt( - STRATEGY_SONIFICATION, availableOutputDevices, availableInputDevices, outputs, - outputDeviceTypesToIgnore); + devices = getDevicesForStrategyInt( + STRATEGY_SONIFICATION, availableOutputDevices, availableInputDevices, outputs); } else { bool media_active_locally = outputs.isActiveLocally(toVolumeSource(AUDIO_STREAM_MUSIC), @@ -165,17 +161,18 @@ audio_devices_t Engine::getDeviceForStrategyInt(legacy_strategy strategy, toVolumeSource(AUDIO_STREAM_ACCESSIBILITY), SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY); // routing is same as media without the "remote" device - device = getDeviceForStrategyInt(STRATEGY_MEDIA, + availableOutputDevices.remove(availableOutputDevices.getDevicesFromTypeMask( + AUDIO_DEVICE_OUT_REMOTE_SUBMIX)); + devices = getDevicesForStrategyInt(STRATEGY_MEDIA, availableOutputDevices, - availableInputDevices, outputs, - AUDIO_DEVICE_OUT_REMOTE_SUBMIX | outputDeviceTypesToIgnore); + availableInputDevices, outputs); // if no media is playing on the device, check for mandatory use of "safe" speaker // when media would have played on speaker, and the safe speaker path is available - if (!media_active_locally - && (device & AUDIO_DEVICE_OUT_SPEAKER) - && (availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER_SAFE)) { - device |= AUDIO_DEVICE_OUT_SPEAKER_SAFE; - device &= ~AUDIO_DEVICE_OUT_SPEAKER; + if (!media_active_locally) { + devices.replaceDevicesByType( + AUDIO_DEVICE_OUT_SPEAKER, + availableOutputDevices.getDevicesFromTypeMask( + AUDIO_DEVICE_OUT_SPEAKER_SAFE)); } } break; @@ -183,9 +180,8 @@ audio_devices_t Engine::getDeviceForStrategyInt(legacy_strategy strategy, case STRATEGY_DTMF: if (!isInCall()) { // when off call, DTMF strategy follows the same rules as MEDIA strategy - device = getDeviceForStrategyInt( - STRATEGY_MEDIA, availableOutputDevices, availableInputDevices, outputs, - outputDeviceTypesToIgnore); + devices = getDevicesForStrategyInt( + STRATEGY_MEDIA, availableOutputDevices, availableInputDevices, outputs); break; } // when in call, DTMF and PHONE strategies follow the same rules @@ -197,24 +193,27 @@ audio_devices_t Engine::getDeviceForStrategyInt(legacy_strategy strategy, // - cannot route from voice call RX OR // - audio HAL version is < 3.0 and TX device is on the primary HW module if (getPhoneState() == AUDIO_MODE_IN_CALL) { - audio_devices_t txDevice = getDeviceForInputSource(AUDIO_SOURCE_VOICE_COMMUNICATION); + audio_devices_t txDevice = getDeviceForInputSource( + AUDIO_SOURCE_VOICE_COMMUNICATION)->type(); sp primaryOutput = outputs.getPrimaryOutput(); - audio_devices_t availPrimaryInputDevices = - availableInputDevices.getDeviceTypesFromHwModule(primaryOutput->getModuleHandle()); + DeviceVector availPrimaryInputDevices = + availableInputDevices.getDevicesFromHwModule(primaryOutput->getModuleHandle()); // TODO: getPrimaryOutput return only devices from first module in // audio_policy_configuration.xml, hearing aid is not there, but it's // a primary device // FIXME: this is not the right way of solving this problem - audio_devices_t availPrimaryOutputDevices = - (primaryOutput->supportedDevices().types() | AUDIO_DEVICE_OUT_HEARING_AID) & - availableOutputDevices.types(); - - if (((availableInputDevices.types() & - AUDIO_DEVICE_IN_TELEPHONY_RX & ~AUDIO_DEVICE_BIT_IN) == 0) || - (((txDevice & availPrimaryInputDevices & ~AUDIO_DEVICE_BIT_IN) != 0) && - (primaryOutput->getAudioPort()->getModuleVersionMajor() < 3))) { - availableOutputDevicesType = availPrimaryOutputDevices; + DeviceVector availPrimaryOutputDevices = availableOutputDevices.getDevicesFromTypeMask( + primaryOutput->supportedDevices().types()); + availPrimaryOutputDevices.add( + availableOutputDevices.getDevicesFromTypeMask(AUDIO_DEVICE_OUT_HEARING_AID)); + + if ((availableInputDevices.getDevice(AUDIO_DEVICE_IN_TELEPHONY_RX, + String8(""), AUDIO_FORMAT_DEFAULT) == nullptr) || + ((availPrimaryInputDevices.getDevice( + txDevice, String8(""), AUDIO_FORMAT_DEFAULT) != nullptr) && + (primaryOutput->getAudioPort()->getModuleVersionMajor() < 3))) { + availableOutputDevices = availPrimaryOutputDevices; } } // for phone strategy, we first consider the forced use and then the available devices by @@ -222,49 +221,40 @@ audio_devices_t Engine::getDeviceForStrategyInt(legacy_strategy strategy, switch (getForceUse(AUDIO_POLICY_FORCE_FOR_COMMUNICATION)) { case AUDIO_POLICY_FORCE_BT_SCO: if (!isInCall() || strategy != STRATEGY_DTMF) { - device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT; - if (device) break; + devices = availableOutputDevices.getDevicesFromTypeMask( + AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT); + if (!devices.isEmpty()) break; } - device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET; - if (device) break; - device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_SCO; - if (device) break; + devices = availableOutputDevices.getFirstDevicesFromTypes({ + AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET, AUDIO_DEVICE_OUT_BLUETOOTH_SCO}); + if (!devices.isEmpty()) break; // if SCO device is requested but no SCO device is available, fall back to default case FALLTHROUGH_INTENDED; default: // FORCE_NONE - device = availableOutputDevicesType & AUDIO_DEVICE_OUT_HEARING_AID; - if (device) break; + devices = availableOutputDevices.getDevicesFromTypeMask(AUDIO_DEVICE_OUT_HEARING_AID); + if (!devices.isEmpty()) break; // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to A2DP if (!isInCall() && (getForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA) != AUDIO_POLICY_FORCE_NO_BT_A2DP) && outputs.isA2dpSupported()) { - device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP; - if (device) break; - device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES; - if (device) break; + devices = availableOutputDevices.getFirstDevicesFromTypes({ + AUDIO_DEVICE_OUT_BLUETOOTH_A2DP, + AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES}); + if (!devices.isEmpty()) break; } - device = availableOutputDevicesType & AUDIO_DEVICE_OUT_WIRED_HEADPHONE; - if (device) break; - device = availableOutputDevicesType & AUDIO_DEVICE_OUT_WIRED_HEADSET; - if (device) break; - device = availableOutputDevicesType & AUDIO_DEVICE_OUT_LINE; - if (device) break; - device = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_HEADSET; - if (device) break; - device = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_DEVICE; - if (device) break; + devices = availableOutputDevices.getFirstDevicesFromTypes({ + AUDIO_DEVICE_OUT_WIRED_HEADPHONE, AUDIO_DEVICE_OUT_WIRED_HEADSET, + AUDIO_DEVICE_OUT_LINE, AUDIO_DEVICE_OUT_USB_HEADSET, + AUDIO_DEVICE_OUT_USB_DEVICE}); + if (!devices.isEmpty()) break; if (!isInCall()) { - device = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_ACCESSORY; - if (device) break; - device = availableOutputDevicesType & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET; - if (device) break; - device = availableOutputDevicesType & AUDIO_DEVICE_OUT_AUX_DIGITAL; - if (device) break; - device = availableOutputDevicesType & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET; - if (device) break; + devices = availableOutputDevices.getFirstDevicesFromTypes({ + AUDIO_DEVICE_OUT_USB_ACCESSORY, AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET, + AUDIO_DEVICE_OUT_AUX_DIGITAL, AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET}); + if (!devices.isEmpty()) break; } - device = availableOutputDevicesType & AUDIO_DEVICE_OUT_EARPIECE; + devices = availableOutputDevices.getDevicesFromTypeMask(AUDIO_DEVICE_OUT_EARPIECE); break; case AUDIO_POLICY_FORCE_SPEAKER: @@ -273,22 +263,18 @@ audio_devices_t Engine::getDeviceForStrategyInt(legacy_strategy strategy, if (!isInCall() && (getForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA) != AUDIO_POLICY_FORCE_NO_BT_A2DP) && outputs.isA2dpSupported()) { - device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER; - if (device) break; + devices = availableOutputDevices.getDevicesFromTypeMask( + AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER); + if (!devices.isEmpty()) break; } if (!isInCall()) { - device = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_ACCESSORY; - if (device) break; - device = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_DEVICE; - if (device) break; - device = availableOutputDevicesType & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET; - if (device) break; - device = availableOutputDevicesType & AUDIO_DEVICE_OUT_AUX_DIGITAL; - if (device) break; - device = availableOutputDevicesType & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET; - if (device) break; + devices = availableOutputDevices.getFirstDevicesFromTypes({ + AUDIO_DEVICE_OUT_USB_ACCESSORY, AUDIO_DEVICE_OUT_USB_DEVICE, + AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET, AUDIO_DEVICE_OUT_AUX_DIGITAL, + AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET}); + if (!devices.isEmpty()) break; } - device = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER; + devices = availableOutputDevices.getDevicesFromTypeMask(AUDIO_DEVICE_OUT_SPEAKER); break; } break; @@ -298,9 +284,8 @@ audio_devices_t Engine::getDeviceForStrategyInt(legacy_strategy strategy, // If incall, just select the STRATEGY_PHONE device if (isInCall() || outputs.isActiveLocally(toVolumeSource(AUDIO_STREAM_VOICE_CALL))) { - device = getDeviceForStrategyInt( - STRATEGY_PHONE, availableOutputDevices, availableInputDevices, outputs, - outputDeviceTypesToIgnore); + devices = getDevicesForStrategyInt( + STRATEGY_PHONE, availableOutputDevices, availableInputDevices, outputs); break; } FALLTHROUGH_INTENDED; @@ -313,41 +298,37 @@ audio_devices_t Engine::getDeviceForStrategyInt(legacy_strategy strategy, if ((strategy == STRATEGY_SONIFICATION) || (getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED)) { - device = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER; + devices = availableOutputDevices.getDevicesFromTypeMask(AUDIO_DEVICE_OUT_SPEAKER); } // if SCO headset is connected and we are told to use it, play ringtone over // speaker and BT SCO - if ((availableOutputDevicesType & AUDIO_DEVICE_OUT_ALL_SCO) != 0) { - uint32_t device2 = AUDIO_DEVICE_NONE; - device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT; - if (device2 == AUDIO_DEVICE_NONE) { - device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET; - } - if (device2 == AUDIO_DEVICE_NONE) { - device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_SCO; - } + if (!availableOutputDevices.getDevicesFromTypeMask(AUDIO_DEVICE_OUT_ALL_SCO).isEmpty()) { + DeviceVector devices2; + devices2 = availableOutputDevices.getFirstDevicesFromTypes({ + AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT, AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET, + AUDIO_DEVICE_OUT_BLUETOOTH_SCO}); // Use ONLY Bluetooth SCO output when ringing in vibration mode if (!((getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED) && (strategy == STRATEGY_ENFORCED_AUDIBLE))) { if (getForceUse(AUDIO_POLICY_FORCE_FOR_VIBRATE_RINGING) == AUDIO_POLICY_FORCE_BT_SCO) { - if (device2 != AUDIO_DEVICE_NONE) { - device = device2; + if (!devices2.isEmpty()) { + devices = devices2; break; } } } // Use both Bluetooth SCO and phone default output when ringing in normal mode if (getForceUse(AUDIO_POLICY_FORCE_FOR_COMMUNICATION) == AUDIO_POLICY_FORCE_BT_SCO) { - if ((strategy == STRATEGY_SONIFICATION) && - (device & AUDIO_DEVICE_OUT_SPEAKER) && - (availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER_SAFE)) { - device |= AUDIO_DEVICE_OUT_SPEAKER_SAFE; - device &= ~AUDIO_DEVICE_OUT_SPEAKER; + if (strategy == STRATEGY_SONIFICATION) { + devices.replaceDevicesByType( + AUDIO_DEVICE_OUT_SPEAKER, + availableOutputDevices.getDevicesFromTypeMask( + AUDIO_DEVICE_OUT_SPEAKER_SAFE)); } - if (device2 != AUDIO_DEVICE_NONE) { - device |= device2; + if (!devices2.isEmpty()) { + devices.add(devices2); break; } } @@ -361,25 +342,20 @@ audio_devices_t Engine::getDeviceForStrategyInt(legacy_strategy strategy, // compressed format as they would likely not be mixed and dropped. for (size_t i = 0; i < outputs.size(); i++) { sp desc = outputs.valueAt(i); - audio_devices_t devices = desc->devices().types() & - (AUDIO_DEVICE_OUT_HDMI | AUDIO_DEVICE_OUT_SPDIF | AUDIO_DEVICE_OUT_HDMI_ARC); - if (desc->isActive() && !audio_is_linear_pcm(desc->mFormat) && - devices != AUDIO_DEVICE_NONE) { - availableOutputDevicesType = availableOutputDevices.types() & ~devices; + if (desc->isActive() && !audio_is_linear_pcm(desc->getFormat())) { + availableOutputDevices.remove(desc->devices().getDevicesFromTypeMask( + AUDIO_DEVICE_OUT_HDMI | AUDIO_DEVICE_OUT_SPDIF + | AUDIO_DEVICE_OUT_HDMI_ARC)); } } - availableOutputDevices = - availableOutputDevices.getDevicesFromTypeMask(availableOutputDevicesType); if (outputs.isActive(toVolumeSource(AUDIO_STREAM_RING)) || outputs.isActive(toVolumeSource(AUDIO_STREAM_ALARM))) { - return getDeviceForStrategyInt( - STRATEGY_SONIFICATION, availableOutputDevices, availableInputDevices, outputs, - outputDeviceTypesToIgnore); + return getDevicesForStrategyInt( + STRATEGY_SONIFICATION, availableOutputDevices, availableInputDevices, outputs); } if (isInCall()) { - return getDeviceForStrategyInt( - STRATEGY_PHONE, availableOutputDevices, availableInputDevices, outputs, - outputDeviceTypesToIgnore); + return getDevicesForStrategyInt( + STRATEGY_PHONE, availableOutputDevices, availableInputDevices, outputs); } } // For other cases, STRATEGY_ACCESSIBILITY behaves like STRATEGY_MEDIA @@ -388,128 +364,116 @@ audio_devices_t Engine::getDeviceForStrategyInt(legacy_strategy strategy, // FIXME: STRATEGY_REROUTING follow STRATEGY_MEDIA for now case STRATEGY_REROUTING: case STRATEGY_MEDIA: { - uint32_t device2 = AUDIO_DEVICE_NONE; + DeviceVector devices2; if (strategy != STRATEGY_SONIFICATION) { // no sonification on remote submix (e.g. WFD) - if (availableOutputDevices.getDevice(AUDIO_DEVICE_OUT_REMOTE_SUBMIX, - String8("0"), AUDIO_FORMAT_DEFAULT) != 0) { - device2 = availableOutputDevices.types() & AUDIO_DEVICE_OUT_REMOTE_SUBMIX; + sp remoteSubmix; + if ((remoteSubmix = availableOutputDevices.getDevice( + AUDIO_DEVICE_OUT_REMOTE_SUBMIX, String8("0"), + AUDIO_FORMAT_DEFAULT)) != nullptr) { + devices2.add(remoteSubmix); } } if (isInCall() && (strategy == STRATEGY_MEDIA)) { - device = getDeviceForStrategyInt( - STRATEGY_PHONE, availableOutputDevices, availableInputDevices, outputs, - outputDeviceTypesToIgnore); + devices = getDevicesForStrategyInt( + STRATEGY_PHONE, availableOutputDevices, availableInputDevices, outputs); break; } // FIXME: Find a better solution to prevent routing to BT hearing aid(b/122931261). - if ((device2 == AUDIO_DEVICE_NONE) && + if ((devices2.isEmpty()) && (getForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA) != AUDIO_POLICY_FORCE_NO_BT_A2DP)) { - device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_HEARING_AID; + devices2 = availableOutputDevices.getDevicesFromTypeMask(AUDIO_DEVICE_OUT_HEARING_AID); } - if ((device2 == AUDIO_DEVICE_NONE) && + if ((devices2.isEmpty()) && (getForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA) != AUDIO_POLICY_FORCE_NO_BT_A2DP) && outputs.isA2dpSupported()) { - device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP; - if (device2 == AUDIO_DEVICE_NONE) { - device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES; - } - if (device2 == AUDIO_DEVICE_NONE) { - device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER; - } + devices2 = availableOutputDevices.getFirstDevicesFromTypes({ + AUDIO_DEVICE_OUT_BLUETOOTH_A2DP, AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES, + AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER}); } - if ((device2 == AUDIO_DEVICE_NONE) && + if ((devices2.isEmpty()) && (getForceUse(AUDIO_POLICY_FORCE_FOR_MEDIA) == AUDIO_POLICY_FORCE_SPEAKER)) { - device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER; - } - if (device2 == AUDIO_DEVICE_NONE) { - device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_WIRED_HEADPHONE; - } - if (device2 == AUDIO_DEVICE_NONE) { - device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_LINE; - } - if (device2 == AUDIO_DEVICE_NONE) { - device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_WIRED_HEADSET; - } - if (device2 == AUDIO_DEVICE_NONE) { - device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_HEADSET; + devices2 = availableOutputDevices.getDevicesFromTypeMask(AUDIO_DEVICE_OUT_SPEAKER); } - if (device2 == AUDIO_DEVICE_NONE) { - device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_ACCESSORY; + if (devices2.isEmpty()) { + devices2 = availableOutputDevices.getFirstDevicesFromTypes({ + AUDIO_DEVICE_OUT_WIRED_HEADPHONE, AUDIO_DEVICE_OUT_LINE, + AUDIO_DEVICE_OUT_WIRED_HEADSET, AUDIO_DEVICE_OUT_USB_HEADSET, + AUDIO_DEVICE_OUT_USB_ACCESSORY, AUDIO_DEVICE_OUT_USB_DEVICE, + AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET}); } - if (device2 == AUDIO_DEVICE_NONE) { - device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_DEVICE; - } - if (device2 == AUDIO_DEVICE_NONE) { - device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET; - } - if ((device2 == AUDIO_DEVICE_NONE) && (strategy != STRATEGY_SONIFICATION)) { + if ((devices2.isEmpty()) && (strategy != STRATEGY_SONIFICATION)) { // no sonification on aux digital (e.g. HDMI) - device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_AUX_DIGITAL; + devices2 = availableOutputDevices.getDevicesFromTypeMask(AUDIO_DEVICE_OUT_AUX_DIGITAL); } - if ((device2 == AUDIO_DEVICE_NONE) && + if ((devices2.isEmpty()) && (getForceUse(AUDIO_POLICY_FORCE_FOR_DOCK) == AUDIO_POLICY_FORCE_ANALOG_DOCK)) { - device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET; + devices2 = availableOutputDevices.getDevicesFromTypeMask( + AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET); } - if (device2 == AUDIO_DEVICE_NONE) { - device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER; + if (devices2.isEmpty()) { + devices2 = availableOutputDevices.getDevicesFromTypeMask(AUDIO_DEVICE_OUT_SPEAKER); } - int device3 = AUDIO_DEVICE_NONE; + DeviceVector devices3; if (strategy == STRATEGY_MEDIA) { // ARC, SPDIF and AUX_LINE can co-exist with others. - device3 = availableOutputDevicesType & AUDIO_DEVICE_OUT_HDMI_ARC; - device3 |= (availableOutputDevicesType & AUDIO_DEVICE_OUT_SPDIF); - device3 |= (availableOutputDevicesType & AUDIO_DEVICE_OUT_AUX_LINE); + devices3 = availableOutputDevices.getDevicesFromTypeMask( + AUDIO_DEVICE_OUT_HDMI_ARC | AUDIO_DEVICE_OUT_SPDIF | AUDIO_DEVICE_OUT_AUX_LINE); } - device2 |= device3; + devices2.add(devices3); // device is DEVICE_OUT_SPEAKER if we come from case STRATEGY_SONIFICATION or // STRATEGY_ENFORCED_AUDIBLE, AUDIO_DEVICE_NONE otherwise - device |= device2; + devices.add(devices2); // If hdmi system audio mode is on, remove speaker out of output list. if ((strategy == STRATEGY_MEDIA) && (getForceUse(AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO) == AUDIO_POLICY_FORCE_HDMI_SYSTEM_AUDIO_ENFORCED)) { - device &= ~AUDIO_DEVICE_OUT_SPEAKER; + devices.remove(devices.getDevicesFromTypeMask(AUDIO_DEVICE_OUT_SPEAKER)); } // for STRATEGY_SONIFICATION: // if SPEAKER was selected, and SPEAKER_SAFE is available, use SPEAKER_SAFE instead - if ((strategy == STRATEGY_SONIFICATION) && - (device & AUDIO_DEVICE_OUT_SPEAKER) && - (availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER_SAFE)) { - device |= AUDIO_DEVICE_OUT_SPEAKER_SAFE; - device &= ~AUDIO_DEVICE_OUT_SPEAKER; + if (strategy == STRATEGY_SONIFICATION) { + devices.replaceDevicesByType( + AUDIO_DEVICE_OUT_SPEAKER, + availableOutputDevices.getDevicesFromTypeMask( + AUDIO_DEVICE_OUT_SPEAKER_SAFE)); } } break; default: - ALOGW("getDeviceForStrategy() unknown strategy: %d", strategy); + ALOGW("getDevicesForStrategy() unknown strategy: %d", strategy); break; } - if (device == AUDIO_DEVICE_NONE) { - ALOGV("getDeviceForStrategy() no device found for strategy %d", strategy); - device = getApmObserver()->getDefaultOutputDevice()->type(); - ALOGE_IF(device == AUDIO_DEVICE_NONE, - "getDeviceForStrategy() no default device defined"); + if (devices.isEmpty()) { + ALOGV("getDevicesForStrategy() no device found for strategy %d", strategy); + sp defaultOutputDevice = getApmObserver()->getDefaultOutputDevice(); + if (defaultOutputDevice != nullptr) { + devices.add(defaultOutputDevice); + } + ALOGE_IF(devices.isEmpty(), + "getDevicesForStrategy() no default device defined"); } - ALOGVV("getDeviceForStrategy() strategy %d, device %x", strategy, device); - return device; + + ALOGVV("getDevices" + "ForStrategy() strategy %d, device %x", strategy, devices.types()); + return devices; } -audio_devices_t Engine::getDeviceForInputSource(audio_source_t inputSource) const +sp Engine::getDeviceForInputSource(audio_source_t inputSource) const { const DeviceVector availableOutputDevices = getApmObserver()->getAvailableOutputDevices(); const DeviceVector availableInputDevices = getApmObserver()->getAvailableInputDevices(); const SwAudioOutputCollection &outputs = getApmObserver()->getOutputs(); - audio_devices_t availableDeviceTypes = availableInputDevices.types() & ~AUDIO_DEVICE_BIT_IN; + DeviceVector availableDevices = availableInputDevices; sp primaryOutput = outputs.getPrimaryOutput(); - audio_devices_t availablePrimaryDeviceTypes = availableInputDevices.getDeviceTypesFromHwModule( - primaryOutput->getModuleHandle()) & ~AUDIO_DEVICE_BIT_IN; - uint32_t device = AUDIO_DEVICE_NONE; + DeviceVector availablePrimaryDevices = availableInputDevices.getDevicesFromHwModule( + primaryOutput->getModuleHandle()); + sp device; // when a call is active, force device selection to match source VOICE_COMMUNICATION // for most other input sources to avoid rerouting call TX audio @@ -532,57 +496,47 @@ audio_devices_t Engine::getDeviceForInputSource(audio_source_t inputSource) cons switch (inputSource) { case AUDIO_SOURCE_DEFAULT: case AUDIO_SOURCE_MIC: - if (availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_A2DP) { - device = AUDIO_DEVICE_IN_BLUETOOTH_A2DP; - } else if ((getForceUse(AUDIO_POLICY_FORCE_FOR_RECORD) == AUDIO_POLICY_FORCE_BT_SCO) && - (availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET)) { - device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET; - } else if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) { - device = AUDIO_DEVICE_IN_WIRED_HEADSET; - } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_HEADSET) { - device = AUDIO_DEVICE_IN_USB_HEADSET; - } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) { - device = AUDIO_DEVICE_IN_USB_DEVICE; - } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) { - device = AUDIO_DEVICE_IN_BUILTIN_MIC; - } - break; + device = availableDevices.getDevice( + AUDIO_DEVICE_IN_BLUETOOTH_A2DP, String8(""), AUDIO_FORMAT_DEFAULT); + if (device != nullptr) break; + if (getForceUse(AUDIO_POLICY_FORCE_FOR_RECORD) == AUDIO_POLICY_FORCE_BT_SCO) { + device = availableDevices.getDevice( + AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET, String8(""), AUDIO_FORMAT_DEFAULT); + if (device != nullptr) break; + } + device = availableDevices.getFirstExistingDevice({ + AUDIO_DEVICE_IN_WIRED_HEADSET, AUDIO_DEVICE_IN_USB_HEADSET, + AUDIO_DEVICE_IN_USB_DEVICE, AUDIO_DEVICE_IN_BUILTIN_MIC}); + break; case AUDIO_SOURCE_VOICE_COMMUNICATION: // Allow only use of devices on primary input if in call and HAL does not support routing // to voice call path. if ((getPhoneState() == AUDIO_MODE_IN_CALL) && - (availableOutputDevices.types() & AUDIO_DEVICE_OUT_TELEPHONY_TX) == 0) { - availableDeviceTypes = availablePrimaryDeviceTypes; + (availableOutputDevices.getDevice(AUDIO_DEVICE_OUT_TELEPHONY_TX, + String8(""), AUDIO_FORMAT_DEFAULT)) == nullptr) { + availableDevices = availablePrimaryDevices; } switch (getForceUse(AUDIO_POLICY_FORCE_FOR_COMMUNICATION)) { case AUDIO_POLICY_FORCE_BT_SCO: // if SCO device is requested but no SCO device is available, fall back to default case - if (availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) { - device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET; + device = availableDevices.getDevice( + AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET, String8(""), AUDIO_FORMAT_DEFAULT); + if (device != nullptr) { break; } FALLTHROUGH_INTENDED; default: // FORCE_NONE - if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) { - device = AUDIO_DEVICE_IN_WIRED_HEADSET; - } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_HEADSET) { - device = AUDIO_DEVICE_IN_USB_HEADSET; - } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) { - device = AUDIO_DEVICE_IN_USB_DEVICE; - } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) { - device = AUDIO_DEVICE_IN_BUILTIN_MIC; - } + device = availableDevices.getFirstExistingDevice({ + AUDIO_DEVICE_IN_WIRED_HEADSET, AUDIO_DEVICE_IN_USB_HEADSET, + AUDIO_DEVICE_IN_USB_DEVICE, AUDIO_DEVICE_IN_BUILTIN_MIC}); break; case AUDIO_POLICY_FORCE_SPEAKER: - if (availableDeviceTypes & AUDIO_DEVICE_IN_BACK_MIC) { - device = AUDIO_DEVICE_IN_BACK_MIC; - } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) { - device = AUDIO_DEVICE_IN_BUILTIN_MIC; - } + device = availableDevices.getFirstExistingDevice({ + AUDIO_DEVICE_IN_BACK_MIC, AUDIO_DEVICE_IN_BUILTIN_MIC}); break; } break; @@ -591,77 +545,60 @@ audio_devices_t Engine::getDeviceForInputSource(audio_source_t inputSource) cons case AUDIO_SOURCE_UNPROCESSED: case AUDIO_SOURCE_HOTWORD: if (inputSource == AUDIO_SOURCE_HOTWORD) { - availableDeviceTypes = availablePrimaryDeviceTypes; - } - if (getForceUse(AUDIO_POLICY_FORCE_FOR_RECORD) == AUDIO_POLICY_FORCE_BT_SCO && - availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) { - device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET; - } else if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) { - device = AUDIO_DEVICE_IN_WIRED_HEADSET; - } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_HEADSET) { - device = AUDIO_DEVICE_IN_USB_HEADSET; - } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) { - device = AUDIO_DEVICE_IN_USB_DEVICE; - } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) { - device = AUDIO_DEVICE_IN_BUILTIN_MIC; + availableDevices = availablePrimaryDevices; + } + if (getForceUse(AUDIO_POLICY_FORCE_FOR_RECORD) == AUDIO_POLICY_FORCE_BT_SCO) { + device = availableDevices.getDevice( + AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET, String8(""), AUDIO_FORMAT_DEFAULT); + if (device != nullptr) break; } + device = availableDevices.getFirstExistingDevice({ + AUDIO_DEVICE_IN_WIRED_HEADSET, AUDIO_DEVICE_IN_USB_HEADSET, + AUDIO_DEVICE_IN_USB_DEVICE, AUDIO_DEVICE_IN_BUILTIN_MIC}); break; case AUDIO_SOURCE_CAMCORDER: - if (availableDeviceTypes & AUDIO_DEVICE_IN_BACK_MIC) { - device = AUDIO_DEVICE_IN_BACK_MIC; - } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) { - device = AUDIO_DEVICE_IN_BUILTIN_MIC; - } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) { - // This is specifically for a device without built-in mic - device = AUDIO_DEVICE_IN_USB_DEVICE; - } + // For a device without built-in mic, adding usb device + device = availableDevices.getFirstExistingDevice({ + AUDIO_DEVICE_IN_BACK_MIC, AUDIO_DEVICE_IN_BUILTIN_MIC, + AUDIO_DEVICE_IN_USB_DEVICE}); break; case AUDIO_SOURCE_VOICE_DOWNLINK: case AUDIO_SOURCE_VOICE_CALL: case AUDIO_SOURCE_VOICE_UPLINK: - if (availableDeviceTypes & AUDIO_DEVICE_IN_VOICE_CALL) { - device = AUDIO_DEVICE_IN_VOICE_CALL; - } + device = availableDevices.getDevice( + AUDIO_DEVICE_IN_VOICE_CALL, String8(""), AUDIO_FORMAT_DEFAULT); break; case AUDIO_SOURCE_VOICE_PERFORMANCE: - if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) { - device = AUDIO_DEVICE_IN_WIRED_HEADSET; - } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_HEADSET) { - device = AUDIO_DEVICE_IN_USB_HEADSET; - } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) { - device = AUDIO_DEVICE_IN_USB_DEVICE; - } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) { - device = AUDIO_DEVICE_IN_BUILTIN_MIC; - } + device = availableDevices.getFirstExistingDevice({ + AUDIO_DEVICE_IN_WIRED_HEADSET, AUDIO_DEVICE_IN_USB_HEADSET, + AUDIO_DEVICE_IN_USB_DEVICE, AUDIO_DEVICE_IN_BUILTIN_MIC}); break; case AUDIO_SOURCE_REMOTE_SUBMIX: - if (availableDeviceTypes & AUDIO_DEVICE_IN_REMOTE_SUBMIX) { - device = AUDIO_DEVICE_IN_REMOTE_SUBMIX; - } + device = availableDevices.getDevice( + AUDIO_DEVICE_IN_REMOTE_SUBMIX, String8(""), AUDIO_FORMAT_DEFAULT); break; case AUDIO_SOURCE_FM_TUNER: - if (availableDeviceTypes & AUDIO_DEVICE_IN_FM_TUNER) { - device = AUDIO_DEVICE_IN_FM_TUNER; - } + device = availableDevices.getDevice( + AUDIO_DEVICE_IN_FM_TUNER, String8(""), AUDIO_FORMAT_DEFAULT); break; case AUDIO_SOURCE_ECHO_REFERENCE: - if (availableDeviceTypes & AUDIO_DEVICE_IN_ECHO_REFERENCE) { - device = AUDIO_DEVICE_IN_ECHO_REFERENCE; - } + device = availableDevices.getDevice( + AUDIO_DEVICE_IN_ECHO_REFERENCE, String8(""), AUDIO_FORMAT_DEFAULT); break; default: ALOGW("getDeviceForInputSource() invalid input source %d", inputSource); break; } - if (device == AUDIO_DEVICE_NONE) { + if (device == nullptr) { ALOGV("getDeviceForInputSource() no device found for source %d", inputSource); - if (availableDeviceTypes & AUDIO_DEVICE_IN_STUB) { - device = AUDIO_DEVICE_IN_STUB; - } - ALOGE_IF(device == AUDIO_DEVICE_NONE, + device = availableDevices.getDevice( + AUDIO_DEVICE_IN_STUB, String8(""), AUDIO_FORMAT_DEFAULT); + ALOGE_IF(device == nullptr, "getDeviceForInputSource() no default device defined"); } - ALOGV("getDeviceForInputSource()input source %d, device %08x", inputSource, device); + ALOGV_IF(device != nullptr, + "getDeviceForInputSource()input source %d, device %08x", + inputSource, device->type()); return device; } @@ -684,11 +621,9 @@ DeviceVector Engine::getDevicesForProductStrategy(product_strategy_t strategy) c auto legacyStrategy = mLegacyStrategyMap.find(strategy) != end(mLegacyStrategyMap) ? mLegacyStrategyMap.at(strategy) : STRATEGY_NONE; - audio_devices_t devices = getDeviceForStrategyInt(legacyStrategy, - availableOutputDevices, - availableInputDevices, outputs, - (uint32_t)AUDIO_DEVICE_NONE); - return availableOutputDevices.getDevicesFromTypeMask(devices); + return getDevicesForStrategyInt(legacyStrategy, + availableOutputDevices, + availableInputDevices, outputs); } DeviceVector Engine::getOutputDevicesForAttributes(const audio_attributes_t &attributes, @@ -747,17 +682,21 @@ sp Engine::getInputDeviceForAttributes(const audio_attributes_ if (device != nullptr) { return device; } - audio_devices_t deviceType = getDeviceForInputSource(attr.source); - if (audio_is_remote_submix_device(deviceType)) { - address = "0"; - std::size_t pos; - std::string tags { attr.tags }; - if ((pos = tags.find("addr=")) != std::string::npos) { - address = tags.substr(pos + std::strlen("addr=")); - } + device = getDeviceForInputSource(attr.source); + if (device == nullptr || !audio_is_remote_submix_device(device->type())) { + // Return immediately if the device is null or it is not a remote submix device. + return device; + } + + // For remote submix device, try to find the device by address. + address = "0"; + std::size_t pos; + std::string tags { attr.tags }; + if ((pos = tags.find("addr=")) != std::string::npos) { + address = tags.substr(pos + std::strlen("addr=")); } - return availableInputDevices.getDevice(deviceType, + return availableInputDevices.getDevice(device->type(), String8(address.c_str()), AUDIO_FORMAT_DEFAULT); } diff --git a/services/audiopolicy/enginedefault/src/Engine.h b/services/audiopolicy/enginedefault/src/Engine.h index dd1b680c63..4360c6fe66 100644 --- a/services/audiopolicy/enginedefault/src/Engine.h +++ b/services/audiopolicy/enginedefault/src/Engine.h @@ -73,15 +73,14 @@ private: status_t setDefaultDevice(audio_devices_t device); - audio_devices_t getDeviceForStrategyInt(legacy_strategy strategy, - DeviceVector availableOutputDevices, - DeviceVector availableInputDevices, - const SwAudioOutputCollection &outputs, - uint32_t outputDeviceTypesToIgnore) const; + DeviceVector getDevicesForStrategyInt(legacy_strategy strategy, + DeviceVector availableOutputDevices, + DeviceVector availableInputDevices, + const SwAudioOutputCollection &outputs) const; DeviceVector getDevicesForProductStrategy(product_strategy_t strategy) const; - audio_devices_t getDeviceForInputSource(audio_source_t inputSource) const; + sp getDeviceForInputSource(audio_source_t inputSource) const; DeviceStrategyMap mDevicesForStrategies; diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp index 630091e569..28eb2635e1 100644 --- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp +++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp @@ -1206,9 +1206,9 @@ audio_io_handle_t AudioPolicyManager::getOutputForDevices( if (!desc->isDuplicated() && (profile == desc->mProfile)) { // reuse direct output if currently open by the same client // and configured with same parameters - if ((config->sample_rate == desc->mSamplingRate) && - (config->format == desc->mFormat) && - (channelMask == desc->mChannelMask) && + if ((config->sample_rate == desc->getSamplingRate()) && + (config->format == desc->getFormat()) && + (channelMask == desc->getChannelMask()) && (session == desc->mDirectClientSession)) { desc->mDirectOpenCount++; ALOGI("%s reusing direct output %d for session %d", __func__, @@ -1248,13 +1248,13 @@ audio_io_handle_t AudioPolicyManager::getOutputForDevices( // only accept an output with the requested parameters if (status != NO_ERROR || - (config->sample_rate != 0 && config->sample_rate != outputDesc->mSamplingRate) || - (config->format != AUDIO_FORMAT_DEFAULT && config->format != outputDesc->mFormat) || - (channelMask != 0 && channelMask != outputDesc->mChannelMask)) { + (config->sample_rate != 0 && config->sample_rate != outputDesc->getSamplingRate()) || + (config->format != AUDIO_FORMAT_DEFAULT && config->format != outputDesc->getFormat()) || + (channelMask != 0 && channelMask != outputDesc->getChannelMask())) { ALOGV("%s failed opening direct output: output %d sample rate %d %d," "format %d %d, channel mask %04x %04x", __func__, output, config->sample_rate, - outputDesc->mSamplingRate, config->format, outputDesc->mFormat, - channelMask, outputDesc->mChannelMask); + outputDesc->getSamplingRate(), config->format, outputDesc->getFormat(), + channelMask, outputDesc->getChannelMask()); if (output != AUDIO_IO_HANDLE_NONE) { outputDesc->close(); } @@ -1525,13 +1525,13 @@ audio_io_handle_t AudioPolicyManager::selectOutput(const SortedVectormChannelMask & AUDIO_CHANNEL_HAPTIC_ALL); + outputDesc->getChannelMask() & AUDIO_CHANNEL_HAPTIC_ALL); if ((hapticChannelCount == 0) != (outputHapticChannelCount == 0)) { continue; } if (outputHapticChannelCount >= hapticChannelCount - && format == outputDesc->mFormat - && samplingRate == outputDesc->mSamplingRate) { + && format == outputDesc->getFormat() + && samplingRate == outputDesc->getSamplingRate()) { currentMatchCriteria[0] = outputHapticChannelCount; } @@ -1539,12 +1539,13 @@ audio_io_handle_t AudioPolicyManager::selectOutput(const SortedVectormFlags & functionalFlags); // channel mask and channel count match - uint32_t outputChannelCount = audio_channel_count_from_out_mask(outputDesc->mChannelMask); + uint32_t outputChannelCount = audio_channel_count_from_out_mask( + outputDesc->getChannelMask()); if (channelMask != AUDIO_CHANNEL_NONE && channelCount > 2 && channelCount <= outputChannelCount) { if ((audio_channel_mask_get_representation(channelMask) == - audio_channel_mask_get_representation(outputDesc->mChannelMask)) && - ((channelMask & outputDesc->mChannelMask) == channelMask)) { + audio_channel_mask_get_representation(outputDesc->getChannelMask())) && + ((channelMask & outputDesc->getChannelMask()) == channelMask)) { currentMatchCriteria[2] = outputChannelCount; } currentMatchCriteria[3] = outputChannelCount; @@ -1552,8 +1553,8 @@ audio_io_handle_t AudioPolicyManager::selectOutput(const SortedVector SAMPLE_RATE_HZ_DEFAULT && - samplingRate <= outputDesc->mSamplingRate) { - currentMatchCriteria[4] = outputDesc->mSamplingRate; + samplingRate <= outputDesc->getSamplingRate()) { + currentMatchCriteria[4] = outputDesc->getSamplingRate(); } // performance flags match @@ -1563,7 +1564,7 @@ audio_io_handle_t AudioPolicyManager::selectOutput(const SortedVectormFormat); + AudioPort::formatDistance(format, outputDesc->getFormat()); } // primary output match @@ -2922,9 +2923,9 @@ status_t AudioPolicyManager::registerPolicyMixes(const Vector& mixes) // stereo and let audio flinger do the channel conversion if needed. outputConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO; inputConfig.channel_mask = AUDIO_CHANNEL_IN_STEREO; - rSubmixModule->addOutputProfile(address, &outputConfig, + rSubmixModule->addOutputProfile(address.c_str(), &outputConfig, AUDIO_DEVICE_OUT_REMOTE_SUBMIX, address); - rSubmixModule->addInputProfile(address, &inputConfig, + rSubmixModule->addInputProfile(address.c_str(), &inputConfig, AUDIO_DEVICE_IN_REMOTE_SUBMIX, address); if ((res = setDeviceConnectionStateInt(deviceTypeToMakeAvailable, @@ -3020,8 +3021,8 @@ status_t AudioPolicyManager::unregisterPolicyMixes(Vector mixes) } } } - rSubmixModule->removeOutputProfile(address); - rSubmixModule->removeInputProfile(address); + rSubmixModule->removeOutputProfile(address.c_str()); + rSubmixModule->removeInputProfile(address.c_str()); } else if ((mix.mRouteFlags & MIX_ROUTE_FLAG_RENDER) == MIX_ROUTE_FLAG_RENDER) { if (mPolicyMixes.unregisterMix(mix) != NO_ERROR) { @@ -3233,7 +3234,7 @@ bool AudioPolicyManager::isDirectOutputSupported(const audio_config_base_t& conf ALOGV("%s() profile %sfound with name: %s, " "sample rate: %u, format: 0x%x, channel_mask: 0x%x, output flags: 0x%x", __FUNCTION__, profile != 0 ? "" : "NOT ", - (profile != 0 ? profile->getTagName().string() : "null"), + (profile != 0 ? profile->getTagName().c_str() : "null"), config.sample_rate, config.format, config.channel_mask, output_flags); return (profile != 0); } @@ -3897,7 +3898,7 @@ status_t AudioPolicyManager::connectAudioSource(const sp if (srcDevice->hasSameHwModuleAs(sinkDevice) && srcDevice->getModuleVersionMajor() >= 3 && sinkDevice->getModule()->supportsPatch(srcDevice, sinkDevice) && - srcDevice->getAudioPort()->mGains.size() > 0) { + srcDevice->getAudioPort()->getGains().size() > 0) { ALOGV("%s Device to Device route supported by >=3.0 HAL", __FUNCTION__); // TODO: may explicitly specify whether we should use HW or SW patch // create patch between src device and output device @@ -4137,7 +4138,7 @@ status_t AudioPolicyManager::setSurroundFormatEnabled(audio_format_t audioFormat for (size_t i = 0; i < hdmiOutputDevices.size(); i++) { // Simulate reconnection to update enabled surround sound formats. String8 address = hdmiOutputDevices[i]->address(); - String8 name = hdmiOutputDevices[i]->getName(); + std::string name = hdmiOutputDevices[i]->getName(); status_t status = setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_HDMI, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE, address.c_str(), @@ -4159,7 +4160,7 @@ status_t AudioPolicyManager::setSurroundFormatEnabled(audio_format_t audioFormat for (size_t i = 0; i < hdmiInputDevices.size(); i++) { // Simulate reconnection to update enabled surround sound formats. String8 address = hdmiInputDevices[i]->address(); - String8 name = hdmiInputDevices[i]->getName(); + std::string name = hdmiInputDevices[i]->getName(); status_t status = setDeviceConnectionStateInt(AUDIO_DEVICE_IN_HDMI, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE, address.c_str(), @@ -4642,7 +4643,7 @@ status_t AudioPolicyManager::checkOutputsForDevice(const sp& d } ALOGV("opening output for device %08x with params %s profile %p name %s", - deviceType, address.string(), profile.get(), profile->getName().string()); + deviceType, address.string(), profile.get(), profile->getName().c_str()); desc = new SwAudioOutputDescriptor(profile, mpClientInterface); audio_io_handle_t output = AUDIO_IO_HANDLE_NONE; status_t status = desc->open(nullptr, DeviceVector(device), diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h index 02c6171593..4270aa87be 100644 --- a/services/audiopolicy/managerdefault/AudioPolicyManager.h +++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h @@ -38,7 +38,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/services/audiopolicy/tests/audiopolicymanager_tests.cpp b/services/audiopolicy/tests/audiopolicymanager_tests.cpp index 8c30466759..48d707a629 100644 --- a/services/audiopolicy/tests/audiopolicymanager_tests.cpp +++ b/services/audiopolicy/tests/audiopolicymanager_tests.cpp @@ -396,12 +396,11 @@ void AudioPolicyManagerTestMsd::SetUpConfig(AudioPolicyConfig *config) { mMsdOutputDevice->attach(msdModule); mMsdInputDevice->attach(msdModule); - sp msdOutputProfile = new OutputProfile(String8("msd input")); + sp msdOutputProfile = new OutputProfile("msd input"); msdOutputProfile->addAudioProfile(pcmOutputProfile); msdOutputProfile->addSupportedDevice(mMsdOutputDevice); msdModule->addOutputProfile(msdOutputProfile); - sp msdCompressedOutputProfile = - new OutputProfile(String8("msd compressed input")); + sp msdCompressedOutputProfile = new OutputProfile("msd compressed input"); msdCompressedOutputProfile->addAudioProfile(ac3OutputProfile); msdCompressedOutputProfile->setFlags( AUDIO_OUTPUT_FLAG_DIRECT | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD | @@ -409,7 +408,7 @@ void AudioPolicyManagerTestMsd::SetUpConfig(AudioPolicyConfig *config) { msdCompressedOutputProfile->addSupportedDevice(mMsdOutputDevice); msdModule->addOutputProfile(msdCompressedOutputProfile); - sp msdInputProfile = new InputProfile(String8("msd output")); + sp msdInputProfile = new InputProfile("msd output"); msdInputProfile->addAudioProfile(pcmInputProfile); msdInputProfile->addSupportedDevice(mMsdInputDevice); msdModule->addInputProfile(msdInputProfile); @@ -419,7 +418,7 @@ void AudioPolicyManagerTestMsd::SetUpConfig(AudioPolicyConfig *config) { sp dtsOutputProfile = new AudioProfile( AUDIO_FORMAT_DTS, AUDIO_CHANNEL_OUT_5POINT1, 48000); config->getDefaultOutputDevice()->addAudioProfile(dtsOutputProfile); - sp primaryEncodedOutputProfile = new OutputProfile(String8("encoded")); + sp primaryEncodedOutputProfile = new OutputProfile("encoded"); primaryEncodedOutputProfile->addAudioProfile(dtsOutputProfile); primaryEncodedOutputProfile->setFlags(AUDIO_OUTPUT_FLAG_DIRECT); primaryEncodedOutputProfile->addSupportedDevice(config->getDefaultOutputDevice());