Merge changes I70ebe6bc,I9a6d6401,Icbde26fe,I40299d95,Ifd8eb281, ...

am: f21a5174bc

Change-Id: I55fc3e1d8020e1e788ac91f1f1f8b700c6fbcb36
gugelfrei
jiabin 5 years ago committed by android-build-merger
commit 2350fffd76

@ -10,11 +10,13 @@ cc_library_shared {
srcs: [
"AudioGain.cpp",
"AudioPortBase.cpp",
"AudioPort.cpp",
"AudioProfile.cpp",
"DeviceDescriptorBase.cpp",
],
shared_libs: [
"libaudioutils",
"libbase",
"libbinder",
"liblog",

@ -0,0 +1,191 @@
/*
* 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.
*/
#define LOG_TAG "AudioPort"
#include <algorithm>
#include <android-base/stringprintf.h>
#include <media/AudioPort.h>
#include <utils/Log.h>
namespace android {
void AudioPort::importAudioPort(const sp<AudioPort>& port, bool force __unused)
{
for (const auto& profileToImport : port->mProfiles) {
// Import only valid port, i.e. valid format, non empty rates and channels masks
if (!profileToImport->isValid()) {
continue;
}
if (std::find_if(mProfiles.begin(), mProfiles.end(),
[profileToImport](const auto &profile) {
return *profile == *profileToImport; }) == mProfiles.end()) {
addAudioProfile(profileToImport);
}
}
}
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", __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 AudioPort::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;
mProfiles.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);
}
}
}
}
void AudioPort::log(const char* indent) const
{
ALOGI("%s Port[nm:%s, type:%d, role:%d]", indent, mName.c_str(), mType, mRole);
}
// --- AudioPortConfig class implementation
status_t AudioPortConfig::applyAudioPortConfig(
const struct audio_port_config *config,
struct audio_port_config *backupConfig __unused)
{
if (config->config_mask & AUDIO_PORT_CONFIG_SAMPLE_RATE) {
mSamplingRate = config->sample_rate;
}
if (config->config_mask & AUDIO_PORT_CONFIG_CHANNEL_MASK) {
mChannelMask = config->channel_mask;
}
if (config->config_mask & AUDIO_PORT_CONFIG_FORMAT) {
mFormat = config->format;
}
if (config->config_mask & AUDIO_PORT_CONFIG_GAIN) {
mGain = config->gain;
}
return NO_ERROR;
}
namespace {
template<typename T>
void updateField(
const T& portConfigField, T audio_port_config::*port_config_field,
struct audio_port_config *dstConfig, const struct audio_port_config *srcConfig,
unsigned int configMask, T defaultValue)
{
if (dstConfig->config_mask & configMask) {
if ((srcConfig != nullptr) && (srcConfig->config_mask & configMask)) {
dstConfig->*port_config_field = srcConfig->*port_config_field;
} else {
dstConfig->*port_config_field = portConfigField;
}
} else {
dstConfig->*port_config_field = defaultValue;
}
}
} // namespace
void AudioPortConfig::toAudioPortConfig(
struct audio_port_config *dstConfig,
const struct audio_port_config *srcConfig) const
{
updateField(mSamplingRate, &audio_port_config::sample_rate,
dstConfig, srcConfig, AUDIO_PORT_CONFIG_SAMPLE_RATE, 0u);
updateField(mChannelMask, &audio_port_config::channel_mask,
dstConfig, srcConfig, AUDIO_PORT_CONFIG_CHANNEL_MASK,
(audio_channel_mask_t)AUDIO_CHANNEL_NONE);
updateField(mFormat, &audio_port_config::format,
dstConfig, srcConfig, AUDIO_PORT_CONFIG_FORMAT, AUDIO_FORMAT_INVALID);
dstConfig->id = mId;
sp<AudioPort> audioport = getAudioPort();
if ((dstConfig->config_mask & AUDIO_PORT_CONFIG_GAIN) && audioport != NULL) {
dstConfig->gain = mGain;
if ((srcConfig != NULL) && (srcConfig->config_mask & AUDIO_PORT_CONFIG_GAIN)
&& audioport->checkGain(&srcConfig->gain, srcConfig->gain.index) == OK) {
dstConfig->gain = srcConfig->gain;
}
} else {
dstConfig->gain.index = -1;
}
if (dstConfig->gain.index != -1) {
dstConfig->config_mask |= AUDIO_PORT_CONFIG_GAIN;
} else {
dstConfig->config_mask &= ~AUDIO_PORT_CONFIG_GAIN;
}
}
bool AudioPortConfig::hasGainController(bool canUseForVolume) const
{
sp<AudioPort> audioport = getAudioPort();
if (!audioport) {
return false;
}
return canUseForVolume ? audioport->getGains().canUseForVolume()
: audioport->getGains().size() > 0;
}
}

@ -1,87 +0,0 @@
/*
* 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 <algorithm>
#include <android-base/stringprintf.h>
#include <media/AudioPortBase.h>
#include <utils/Log.h>
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);
}
}
}
}
}

@ -1,5 +1,5 @@
/*
* Copyright (C) 2015 The Android Open Source Project
* 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.
@ -118,14 +118,14 @@ void AudioProfile::dump(std::string *dst, int spaces) const
}
}
ssize_t AudioProfileVectorBase::add(const sp<AudioProfile> &profile)
ssize_t AudioProfileVector::add(const sp<AudioProfile> &profile)
{
ssize_t index = size();
push_back(profile);
return index;
}
void AudioProfileVectorBase::clearProfiles()
void AudioProfileVector::clearProfiles()
{
for (auto it = begin(); it != end();) {
if ((*it)->isDynamicFormat() && (*it)->hasValidFormat()) {
@ -137,7 +137,7 @@ void AudioProfileVectorBase::clearProfiles()
}
}
sp<AudioProfile> AudioProfileVectorBase::getFirstValidProfile() const
sp<AudioProfile> AudioProfileVector::getFirstValidProfile() const
{
for (const auto &profile : *this) {
if (profile->isValid()) {
@ -147,7 +147,7 @@ sp<AudioProfile> AudioProfileVectorBase::getFirstValidProfile() const
return nullptr;
}
sp<AudioProfile> AudioProfileVectorBase::getFirstValidProfileFor(audio_format_t format) const
sp<AudioProfile> AudioProfileVector::getFirstValidProfileFor(audio_format_t format) const
{
for (const auto &profile : *this) {
if (profile->isValid() && profile->getFormat() == format) {
@ -157,7 +157,7 @@ sp<AudioProfile> AudioProfileVectorBase::getFirstValidProfileFor(audio_format_t
return nullptr;
}
FormatVector AudioProfileVectorBase::getSupportedFormats() const
FormatVector AudioProfileVector::getSupportedFormats() const
{
FormatVector supportedFormats;
for (const auto &profile : *this) {
@ -168,7 +168,7 @@ FormatVector AudioProfileVectorBase::getSupportedFormats() const
return supportedFormats;
}
bool AudioProfileVectorBase::hasDynamicChannelsFor(audio_format_t format) const
bool AudioProfileVector::hasDynamicChannelsFor(audio_format_t format) const
{
for (const auto &profile : *this) {
if (profile->getFormat() == format && profile->isDynamicChannels()) {
@ -178,7 +178,7 @@ bool AudioProfileVectorBase::hasDynamicChannelsFor(audio_format_t format) const
return false;
}
bool AudioProfileVectorBase::hasDynamicFormat() const
bool AudioProfileVector::hasDynamicFormat() const
{
for (const auto &profile : *this) {
if (profile->isDynamicFormat()) {
@ -188,7 +188,7 @@ bool AudioProfileVectorBase::hasDynamicFormat() const
return false;
}
bool AudioProfileVectorBase::hasDynamicProfile() const
bool AudioProfileVector::hasDynamicProfile() const
{
for (const auto &profile : *this) {
if (profile->isDynamic()) {
@ -198,7 +198,7 @@ bool AudioProfileVectorBase::hasDynamicProfile() const
return false;
}
bool AudioProfileVectorBase::hasDynamicRateFor(audio_format_t format) const
bool AudioProfileVector::hasDynamicRateFor(audio_format_t format) const
{
for (const auto &profile : *this) {
if (profile->getFormat() == format && profile->isDynamicRate()) {
@ -208,7 +208,7 @@ bool AudioProfileVectorBase::hasDynamicRateFor(audio_format_t format) const
return false;
}
void AudioProfileVectorBase::dump(std::string *dst, int spaces) const
void AudioProfileVector::dump(std::string *dst, int spaces) const
{
dst->append(base::StringPrintf("%*s- Profiles:\n", spaces, ""));
for (size_t i = 0; i < size(); i++) {

@ -0,0 +1,113 @@
/*
* 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.
*/
#define LOG_TAG "DeviceDescriptorBase"
//#define LOG_NDEBUG 0
#include <android-base/stringprintf.h>
#include <audio_utils/string.h>
#include <media/DeviceDescriptorBase.h>
#include <media/TypeConverter.h>
namespace android {
DeviceDescriptorBase::DeviceDescriptorBase(audio_devices_t type) :
AudioPort("", AUDIO_PORT_TYPE_DEVICE,
audio_is_output_device(type) ? AUDIO_PORT_ROLE_SINK :
AUDIO_PORT_ROLE_SOURCE),
mDeviceType(type)
{
if (audio_is_remote_submix_device(type)) {
mAddress = "0";
}
}
void DeviceDescriptorBase::toAudioPortConfig(struct audio_port_config *dstConfig,
const struct audio_port_config *srcConfig) const
{
dstConfig->config_mask = AUDIO_PORT_CONFIG_GAIN;
if (mSamplingRate != 0) {
dstConfig->config_mask |= AUDIO_PORT_CONFIG_SAMPLE_RATE;
}
if (mChannelMask != AUDIO_CHANNEL_NONE) {
dstConfig->config_mask |= AUDIO_PORT_CONFIG_CHANNEL_MASK;
}
if (mFormat != AUDIO_FORMAT_INVALID) {
dstConfig->config_mask |= AUDIO_PORT_CONFIG_FORMAT;
}
if (srcConfig != NULL) {
dstConfig->config_mask |= srcConfig->config_mask;
}
AudioPortConfig::toAudioPortConfig(dstConfig, srcConfig);
dstConfig->role = audio_is_output_device(mDeviceType) ?
AUDIO_PORT_ROLE_SINK : AUDIO_PORT_ROLE_SOURCE;
dstConfig->type = AUDIO_PORT_TYPE_DEVICE;
dstConfig->ext.device.type = mDeviceType;
(void)audio_utils_strlcpy_zerofill(dstConfig->ext.device.address, mAddress.c_str());
}
void DeviceDescriptorBase::toAudioPort(struct audio_port *port) const
{
ALOGV("DeviceDescriptorBase::toAudioPort() handle %d type %08x", mId, mDeviceType);
AudioPort::toAudioPort(port);
toAudioPortConfig(&port->active_config);
port->id = mId;
port->ext.device.type = mDeviceType;
(void)audio_utils_strlcpy_zerofill(port->ext.device.address, mAddress.c_str());
}
void DeviceDescriptorBase::dump(std::string *dst, int spaces, int index,
const char* extraInfo, bool verbose) const
{
dst->append(base::StringPrintf("%*sDevice %d:\n", spaces, "", index + 1));
if (mId != 0) {
dst->append(base::StringPrintf("%*s- id: %2d\n", spaces, "", mId));
}
if (extraInfo != nullptr) {
dst->append(extraInfo);
}
dst->append(base::StringPrintf("%*s- type: %-48s\n",
spaces, "", ::android::toString(mDeviceType).c_str()));
if (mAddress.size() != 0) {
dst->append(base::StringPrintf("%*s- address: %-32s\n", spaces, "", mAddress.c_str()));
}
AudioPort::dump(dst, spaces, verbose);
}
std::string DeviceDescriptorBase::toString() const
{
std::stringstream sstream;
sstream << "type:0x" << std::hex << type() << ",@:" << mAddress;
return sstream.str();
}
void DeviceDescriptorBase::log() const
{
ALOGI("Device id:%d type:0x%08X:%s, addr:%s", mId, mDeviceType,
::android::toString(mDeviceType).c_str(),
mAddress.c_str());
AudioPort::log(" ");
}
} // namespace android

@ -27,13 +27,13 @@
namespace android {
class AudioPortFoundation : public virtual RefBase
class AudioPort : public virtual RefBase
{
public:
AudioPortFoundation(const std::string& name, audio_port_type_t type, audio_port_role_t role) :
AudioPort(const std::string& name, audio_port_type_t type, audio_port_role_t role) :
mName(name), mType(type), mRole(role) {}
virtual ~AudioPortFoundation() = default;
virtual ~AudioPort() = default;
void setName(const std::string &name) { mName = name; }
const std::string &getName() const { return mName; }
@ -41,22 +41,26 @@ public:
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<AudioProfile> &profile) {
getAudioProfileVectorBase()->add(profile);
mProfiles.add(profile);
}
virtual void clearAudioProfiles() {
getAudioProfileVectorBase()->clearProfiles();
mProfiles.clearProfiles();
}
bool hasValidAudioProfile() const { return getAudioProfileVectorBase()->hasValidProfile(); }
bool hasValidAudioProfile() const { return mProfiles.hasValidProfile(); }
bool hasDynamicAudioProfile() const { return mProfiles.hasDynamicProfile(); }
void setAudioProfiles(const AudioProfileVector &profiles) { mProfiles = profiles; }
AudioProfileVector &getAudioProfiles() { return mProfiles; }
virtual void importAudioPort(const sp<AudioPort>& port, bool force = false);
status_t checkGain(const struct audio_gain_config *gainConfig, int index) const {
if (index < 0 || (size_t)index >= mGains.size()) {
@ -73,57 +77,42 @@ public:
void dump(std::string *dst, int spaces, bool verbose = true) const;
void log(const char* indent) const;
AudioGains mGains; // gain controllers
protected:
std::string mName;
audio_port_type_t mType;
audio_port_role_t mRole;
AudioProfileVector mProfiles; // AudioProfiles supported by this port (format, Rates, Channels)
};
template <typename ProfileVector,
typename = typename std::enable_if<std::is_base_of<
AudioProfileVectorBase, ProfileVector>::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<AudioProfileVectorBase*>(const_cast<ProfileVector*>(&mProfiles));
}
void addAudioProfile(const sp<AudioProfile> &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
class AudioPortConfig : public virtual RefBase
{
public:
virtual ~AudioPortConfigBase() = default;
virtual ~AudioPortConfig() = default;
virtual sp<AudioPort> getAudioPort() const = 0;
virtual status_t applyAudioPortConfig(const struct audio_port_config *config,
struct audio_port_config *backupConfig = NULL) = 0;
struct audio_port_config *backupConfig = NULL);
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;
unsigned int getSamplingRate() const { return mSamplingRate; }
audio_format_t getFormat() const { return mFormat; }
audio_channel_mask_t getChannelMask() const { return mChannelMask; }
audio_port_handle_t getId() const { return mId; }
bool hasGainController(bool canUseForVolume = false) const;
protected:
unsigned int mSamplingRate = 0u;
audio_format_t mFormat = AUDIO_FORMAT_INVALID;
audio_channel_mask_t mChannelMask = AUDIO_CHANNEL_NONE;
audio_port_handle_t mId = AUDIO_PORT_HANDLE_NONE;
struct audio_gain_config mGain = { .index = -1 };
};

@ -77,10 +77,10 @@ private:
bool mIsDynamicRate = false;
};
class AudioProfileVectorBase : public std::vector<sp<AudioProfile> >
class AudioProfileVector : public std::vector<sp<AudioProfile>>
{
public:
virtual ~AudioProfileVectorBase() = default;
virtual ~AudioProfileVector() = default;
virtual ssize_t add(const sp<AudioProfile> &profile);

@ -0,0 +1,59 @@
/*
* 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 <media/AudioPort.h>
#include <utils/Errors.h>
#include <cutils/config_utils.h>
#include <system/audio.h>
#include <system/audio_policy.h>
namespace android {
class DeviceDescriptorBase : public AudioPort, public AudioPortConfig
{
public:
// Note that empty name refers by convention to a generic device.
explicit DeviceDescriptorBase(audio_devices_t type);
virtual ~DeviceDescriptorBase() {}
audio_devices_t type() const { return mDeviceType; }
std::string address() const { return mAddress; }
void setAddress(const std::string &address) { mAddress = address; }
// AudioPortConfig
virtual sp<AudioPort> getAudioPort() const {
return static_cast<AudioPort*>(const_cast<DeviceDescriptorBase*>(this));
}
virtual void toAudioPortConfig(struct audio_port_config *dstConfig,
const struct audio_port_config *srcConfig = NULL) const;
// AudioPort
virtual void toAudioPort(struct audio_port *port) const;
void dump(std::string *dst, int spaces, int index,
const char* extraInfo = nullptr, bool verbose = true) const;
void log() const;
std::string toString() const;
protected:
std::string mAddress{""};
audio_devices_t mDeviceType;
};
} // namespace android

@ -7,14 +7,14 @@ cc_library_static {
"src/AudioOutputDescriptor.cpp",
"src/AudioPatch.cpp",
"src/AudioPolicyMix.cpp",
"src/AudioPort.cpp",
"src/AudioProfileVector.cpp",
"src/AudioProfileVectorHelper.cpp",
"src/AudioRoute.cpp",
"src/ClientDescriptor.cpp",
"src/DeviceDescriptor.cpp",
"src/EffectDescriptor.cpp",
"src/HwModule.cpp",
"src/IOProfile.cpp",
"src/PolicyAudioPort.cpp",
"src/Serializer.cpp",
"src/SoundTriggerSession.cpp",
"src/TypeConverter.cpp",

@ -25,20 +25,15 @@
namespace android {
class AudioPort;
class PolicyAudioPort;
class AudioRoute;
class AudioPortVector : public Vector<sp<AudioPort> >
{
public:
sp<AudioPort> findByTagName(const std::string &tagName) const;
};
using PolicyAudioPortVector = Vector<sp<PolicyAudioPort>>;
using AudioRouteVector = Vector<sp<AudioRoute>>;
sp<PolicyAudioPort> findByTagName(const PolicyAudioPortVector& policyAudioPortVector,
const std::string &tagName);
class AudioRouteVector : public Vector<sp<AudioRoute> >
{
public:
void dump(String8 *dst, int spaces) const;
};
void dumpAudioRouteVector(const AudioRouteVector& audioRouteVector, String8 *dst, int spaces);
} // namespace android

@ -21,11 +21,11 @@
#include <utils/SortedVector.h>
#include <utils/KeyedVector.h>
#include "AudioIODescriptorInterface.h"
#include "AudioPort.h"
#include "ClientDescriptor.h"
#include "DeviceDescriptor.h"
#include "EffectDescriptor.h"
#include "IOProfile.h"
#include "PolicyAudioPort.h"
namespace android {
@ -34,13 +34,17 @@ class AudioPolicyClientInterface;
// descriptor for audio inputs. Used to maintain current configuration of each opened audio input
// and keep track of the usage of this input.
class AudioInputDescriptor: public AudioPortConfig, public AudioIODescriptorInterface
, public ClientMapHandler<RecordClientDescriptor>
class AudioInputDescriptor: public AudioPortConfig,
public PolicyAudioPortConfig,
public AudioIODescriptorInterface,
public ClientMapHandler<RecordClientDescriptor>
{
public:
explicit AudioInputDescriptor(const sp<IOProfile>& profile,
AudioPolicyClientInterface *clientInterface);
audio_port_handle_t getId() const;
AudioInputDescriptor(const sp<IOProfile>& profile,
AudioPolicyClientInterface *clientInterface);
virtual ~AudioInputDescriptor() = default;
audio_module_handle_t getModuleHandle() const;
audio_devices_t getDeviceType() const { return (mDevice != nullptr) ?
@ -56,9 +60,18 @@ public:
wp<AudioPolicyMix> mPolicyMix; // non NULL when used by a dynamic policy
const sp<IOProfile> mProfile; // I/O profile this output derives from
// PolicyAudioPortConfig
virtual sp<PolicyAudioPort> getPolicyAudioPort() const {
return mProfile;
}
// AudioPortConfig
virtual status_t applyAudioPortConfig(const struct audio_port_config *config,
struct audio_port_config *backupConfig = NULL);
virtual void toAudioPortConfig(struct audio_port_config *dstConfig,
const struct audio_port_config *srcConfig = NULL) const;
virtual sp<AudioPort> getAudioPort() const { return mProfile; }
void toAudioPort(struct audio_port *port) const;
void setPreemptedSessions(const SortedVector<audio_session_t>& sessions);
SortedVector<audio_session_t> getPreemptedSessions() const;
@ -111,7 +124,6 @@ public:
void updateClientRecordingConfiguration(int event, const sp<RecordClientDescriptor>& client);
audio_patch_handle_t mPatchHandle = AUDIO_PATCH_HANDLE_NONE;
audio_port_handle_t mId = AUDIO_PORT_HANDLE_NONE;
sp<DeviceDescriptor> mDevice = nullptr; /**< current device this input is routed to */
// Because a preemptible capture session can preempt another one, we end up in an endless loop

@ -26,9 +26,9 @@
#include <utils/KeyedVector.h>
#include <system/audio.h>
#include "AudioIODescriptorInterface.h"
#include "AudioPort.h"
#include "ClientDescriptor.h"
#include "DeviceDescriptor.h"
#include "PolicyAudioPort.h"
#include <vector>
namespace android {
@ -138,18 +138,19 @@ using RoutingActivities = std::map<product_strategy_t, RoutingActivity>;
// descriptor for audio outputs. Used to maintain current configuration of each opened audio output
// and keep track of the usage of this output by each audio stream type.
class AudioOutputDescriptor: public AudioPortConfig, public AudioIODescriptorInterface
, public ClientMapHandler<TrackClientDescriptor>
class AudioOutputDescriptor: public AudioPortConfig,
public PolicyAudioPortConfig,
public AudioIODescriptorInterface,
public ClientMapHandler<TrackClientDescriptor>
{
public:
AudioOutputDescriptor(const sp<AudioPort>& port,
AudioOutputDescriptor(const sp<PolicyAudioPort>& policyAudioPort,
AudioPolicyClientInterface *clientInterface);
virtual ~AudioOutputDescriptor() {}
void dump(String8 *dst) const override;
void log(const char* indent);
audio_port_handle_t getId() const;
virtual DeviceVector devices() const { return mDevices; }
bool sharesHwModuleWith(const sp<AudioOutputDescriptor>& outputDesc);
virtual DeviceVector supportedDevices() const { return mDevices; }
@ -245,9 +246,19 @@ public:
mRoutingActivities[ps].setMutedByDevice(isMuted);
}
// PolicyAudioPortConfig
virtual sp<PolicyAudioPort> getPolicyAudioPort() const
{
return mPolicyAudioPort;
}
// AudioPortConfig
virtual status_t applyAudioPortConfig(const struct audio_port_config *config,
struct audio_port_config *backupConfig = NULL);
virtual void toAudioPortConfig(struct audio_port_config *dstConfig,
const struct audio_port_config *srcConfig = NULL) const;
virtual sp<AudioPort> getAudioPort() const { return mPort; }
virtual sp<AudioPort> getAudioPort() const { return mPolicyAudioPort->asAudioPort(); }
virtual void toAudioPort(struct audio_port *port) const;
audio_module_handle_t getModuleHandle() const;
@ -289,11 +300,10 @@ public:
wp<AudioPolicyMix> mPolicyMix; // non NULL when used by a dynamic policy
protected:
const sp<AudioPort> mPort;
const sp<PolicyAudioPort> mPolicyAudioPort;
AudioPolicyClientInterface * const mClientInterface;
uint32_t mGlobalActiveCount = 0; // non-client-specific active count
audio_patch_handle_t mPatchHandle = AUDIO_PATCH_HANDLE_NONE;
audio_port_handle_t mId = AUDIO_PORT_HANDLE_NONE;
// The ActiveClients shows the clients that contribute to the @VolumeSource counts
// and may include upstream clients from a duplicating thread.

@ -19,11 +19,11 @@
#include <unordered_map>
#include <unordered_set>
#include <AudioPort.h>
#include <AudioPatch.h>
#include <DeviceDescriptor.h>
#include <IOProfile.h>
#include <HwModule.h>
#include <PolicyAudioPort.h>
#include <AudioInputDescriptor.h>
#include <AudioOutputDescriptor.h>
#include <AudioPolicyMix.h>

@ -1,68 +0,0 @@
/*
* 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 <media/AudioProfile.h>
#include <system/audio.h>
namespace android {
class AudioProfileVector : public AudioProfileVectorBase {
public:
virtual ~AudioProfileVector() = default;
ssize_t add(const sp<AudioProfile> &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<AudioProfile> &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<audio_format_t> &preferredFormats, // order: most pref -> least pref
const std::vector<audio_channel_mask_t> &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<AudioProfile> 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

@ -0,0 +1,67 @@
/*
* 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 <media/AudioProfile.h>
#include <system/audio.h>
namespace android {
void sortAudioProfiles(AudioProfileVector &audioProfileVector);
ssize_t addAudioProfileAndSort(AudioProfileVector &audioProfileVector,
const sp<AudioProfile> &profile);
// One audio profile will be added for each format supported by Audio HAL
void addProfilesForFormats(AudioProfileVector &audioProfileVector,
const FormatVector &formatVector);
// This API is intended to be used by the policy manager once retrieving capabilities
// for a profile with dynamic format, rate and channels attributes
void addDynamicAudioProfileAndSort(AudioProfileVector &audioProfileVector,
const sp<AudioProfile> &profileToAdd);
void appendAudioProfiles(AudioProfileVector &audioProfileVector,
const AudioProfileVector &audioProfileVectorToAppend);
status_t checkExactProfile(const AudioProfileVector &audioProfileVector,
const uint32_t samplingRate,
audio_channel_mask_t channelMask,
audio_format_t format);
status_t checkCompatibleProfile(const AudioProfileVector &audioProfileVector,
uint32_t &samplingRate,
audio_channel_mask_t &channelMask,
audio_format_t &format,
audio_port_type_t portType,
audio_port_role_t portRole);
// 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 &audioProfileVector,
const AudioProfileVector &outputProfileVector,
const std::vector<audio_format_t> &preferredFormatVector, // order: most pref -> least pref
const std::vector<audio_channel_mask_t> &preferredOutputChannelVector,
bool preferHigherSamplingRates,
audio_config_base &bestOutputConfig);
} // namespace android

@ -25,7 +25,7 @@
namespace android
{
class AudioPort;
class PolicyAudioPort;
class DeviceDescriptor;
typedef enum {
@ -38,11 +38,11 @@ class AudioRoute : public virtual RefBase
public:
explicit AudioRoute(audio_route_type_t type) : mType(type) {}
void setSources(const AudioPortVector &sources) { mSources = sources; }
const AudioPortVector &getSources() const { return mSources; }
void setSources(const PolicyAudioPortVector &sources) { mSources = sources; }
const PolicyAudioPortVector &getSources() const { return mSources; }
void setSink(const sp<AudioPort> &sink) { mSink = sink; }
const sp<AudioPort> &getSink() const { return mSink; }
void setSink(const sp<PolicyAudioPort> &sink) { mSink = sink; }
const sp<PolicyAudioPort> &getSink() const { return mSink; }
audio_route_type_t getType() const { return mType; }
@ -57,13 +57,14 @@ public:
* @return true if the audio route supports the connection between the sink and the source,
* false otherwise
*/
bool supportsPatch(const sp<AudioPort> &srcPort, const sp<AudioPort> &dstPort) const;
bool supportsPatch(const sp<PolicyAudioPort> &srcPort,
const sp<PolicyAudioPort> &dstPort) const;
void dump(String8 *dst, int spaces) const;
private:
AudioPortVector mSources;
sp<AudioPort> mSink;
PolicyAudioPortVector mSources;
sp<PolicyAudioPort> mSink;
audio_route_type_t mType;
};

@ -16,7 +16,8 @@
#pragma once
#include "AudioPort.h"
#include "PolicyAudioPort.h"
#include <media/DeviceDescriptorBase.h>
#include <utils/Errors.h>
#include <utils/String8.h>
#include <utils/SortedVector.h>
@ -26,7 +27,8 @@
namespace android {
class DeviceDescriptor : public AudioPort, public AudioPortConfig
class DeviceDescriptor : public DeviceDescriptorBase,
public PolicyAudioPort, public PolicyAudioPortConfig
{
public:
// Note that empty name refers by convention to a generic device.
@ -36,11 +38,11 @@ public:
virtual ~DeviceDescriptor() {}
virtual const std::string getTagName() const { return mTagName; }
virtual void addAudioProfile(const sp<AudioProfile> &profile) {
addAudioProfileAndSort(mProfiles, profile);
}
audio_devices_t type() const { return mDeviceType; }
String8 address() const { return mAddress; }
void setAddress(const String8 &address) { mAddress = address; }
virtual const std::string getTagName() const { return mTagName; }
const FormatVector& encodedFormats() const { return mEncodedFormats; }
@ -56,29 +58,35 @@ public:
bool supportsFormat(audio_format_t format);
// PolicyAudioPortConfig
virtual sp<PolicyAudioPort> getPolicyAudioPort() const {
return static_cast<PolicyAudioPort*>(const_cast<DeviceDescriptor*>(this));
}
// AudioPortConfig
virtual sp<AudioPort> getAudioPort() const { return (AudioPort*) this; }
virtual status_t applyAudioPortConfig(const struct audio_port_config *config,
struct audio_port_config *backupConfig = NULL);
virtual void toAudioPortConfig(struct audio_port_config *dstConfig,
const struct audio_port_config *srcConfig = NULL) const;
// AudioPort
// PolicyAudioPort
virtual sp<AudioPort> asAudioPort() const {
return static_cast<AudioPort*>(const_cast<DeviceDescriptor*>(this));
}
virtual void attach(const sp<HwModule>& module);
virtual void detach();
// AudioPort
virtual void toAudioPort(struct audio_port *port) const;
virtual void importAudioPort(const sp<AudioPort>& port, bool force = false);
audio_port_handle_t getId() const;
void importAudioPortAndPickAudioProfile(const sp<PolicyAudioPort>& policyPort,
bool force = false);
void dump(String8 *dst, int spaces, int index, bool verbose = true) const;
void log() const;
std::string toString() const;
private:
String8 mAddress{""};
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;
audio_format_t mCurrentEncodedFormat;
};
@ -203,7 +211,7 @@ public:
{
for (const auto &device : *this) {
if (device->address() != "") {
return device->address();
return String8(device->address().c_str());
}
}
return String8("");

@ -92,9 +92,9 @@ public:
audio_module_handle_t getHandle() const { return mHandle; }
void setHandle(audio_module_handle_t handle);
sp<AudioPort> findPortByTagName(const std::string &tagName) const
sp<PolicyAudioPort> findPortByTagName(const std::string &tagName) const
{
return mPorts.findByTagName(tagName);
return findByTagName(mPorts, tagName);
}
/**
@ -106,7 +106,8 @@ public:
* @return true if the HwModule supports the connection between the sink and the source,
* false otherwise
*/
bool supportsPatch(const sp<AudioPort> &srcPort, const sp<AudioPort> &dstPort) const;
bool supportsPatch(const sp<PolicyAudioPort> &srcPort,
const sp<PolicyAudioPort> &dstPort) const;
// TODO remove from here (split serialization)
void dump(String8 *dst) const;
@ -122,7 +123,7 @@ private:
DeviceVector mDeclaredDevices; // devices declared in audio_policy configuration file.
DeviceVector mDynamicDevices; /**< devices that can be added/removed at runtime (e.g. rsbumix)*/
AudioRouteVector mRoutes;
AudioPortVector mPorts;
PolicyAudioPortVector mPorts;
};
class HwModuleCollection : public Vector<sp<HwModule> >

@ -16,8 +16,8 @@
#pragma once
#include "AudioPort.h"
#include "DeviceDescriptor.h"
#include "PolicyAudioPort.h"
#include "policy.h"
#include <utils/String8.h>
#include <system/audio.h>
@ -31,7 +31,7 @@ class HwModule;
// It is used by the policy manager to determine if an output or input is suitable for
// a given use case, open/close it accordingly and connect/disconnect audio tracks
// to/from it.
class IOProfile : public AudioPort
class IOProfile : public AudioPort, public PolicyAudioPort
{
public:
IOProfile(const std::string &name, audio_port_role_t role)
@ -41,9 +41,19 @@ public:
maxActiveCount(1),
curActiveCount(0) {}
virtual ~IOProfile() = default;
// For a Profile aka MixPort, tag name and name are equivalent.
virtual const std::string getTagName() const { return getName(); }
virtual void addAudioProfile(const sp<AudioProfile> &profile) {
addAudioProfileAndSort(mProfiles, profile);
}
virtual sp<AudioPort> asAudioPort() const {
return static_cast<AudioPort*>(const_cast<IOProfile*>(this));
}
// 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
// MMAP no IRQ input streams do not have the default limitation of one active client
@ -52,7 +62,7 @@ public:
// flags are parsed before maxActiveCount by the serializer.
void setFlags(uint32_t flags) override
{
AudioPort::setFlags(flags);
PolicyAudioPort::setFlags(flags);
if (getRole() == AUDIO_PORT_ROLE_SINK && (flags & AUDIO_INPUT_FLAG_MMAP_NOIRQ) != 0) {
maxActiveCount = 0;
}

@ -17,10 +17,10 @@
#pragma once
#include "AudioCollections.h"
#include "AudioProfileVector.h"
#include "AudioProfileVectorHelper.h"
#include "HandleGenerator.h"
#include <media/AudioGain.h>
#include <media/AudioPortBase.h>
#include <media/AudioPort.h>
#include <utils/String8.h>
#include <utils/Vector.h>
#include <utils/RefBase.h>
@ -33,21 +33,24 @@ namespace android {
class HwModule;
class AudioRoute;
class AudioPort : public virtual RefBase, public AudioPortBase<AudioProfileVector>,
private HandleGenerator<audio_port_handle_t>
class PolicyAudioPort : public virtual RefBase, private HandleGenerator<audio_port_handle_t>
{
public:
AudioPort(const std::string& name, audio_port_type_t type, audio_port_role_t role) :
AudioPortBase(name, type, role), mFlags(AUDIO_OUTPUT_FLAG_NONE) {}
PolicyAudioPort() : mFlags(AUDIO_OUTPUT_FLAG_NONE) {}
virtual ~AudioPort() {}
virtual ~PolicyAudioPort() = default;
virtual const std::string getTagName() const = 0;
virtual sp<AudioPort> asAudioPort() const = 0;
virtual void setFlags(uint32_t flags)
{
//force direct flag if offload flag is set: offloading implies a direct output stream
// and all common behaviors are driven by checking only the direct flag
// this should normally be set appropriately in the policy configuration file
if (mRole == AUDIO_PORT_ROLE_SOURCE && (flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) {
if (asAudioPort()->getRole() == AUDIO_PORT_ROLE_SOURCE &&
(flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) {
flags |= AUDIO_OUTPUT_FLAG_DIRECT;
}
mFlags = flags;
@ -61,10 +64,6 @@ public:
// Audio port IDs are in a different namespace than AudioFlinger unique IDs
static audio_port_handle_t getNextUniqueId();
virtual void importAudioPort(const sp<AudioPort>& port, bool force = false);
bool hasDynamicAudioProfile() const { return getAudioProfileVectorBase()->hasDynamicProfile(); }
// searches for an exact match
virtual status_t checkExactAudioProfile(const struct audio_port_config *config) const;
@ -74,7 +73,9 @@ public:
audio_channel_mask_t &channelMask,
audio_format_t &format) const
{
return mProfiles.checkCompatibleProfile(samplingRate, channelMask, format, mType, mRole);
return checkCompatibleProfile(
asAudioPort()->getAudioProfiles(), samplingRate, channelMask, format,
asAudioPort()->getType(), asAudioPort()->getRole());
}
void pickAudioProfile(uint32_t &samplingRate,
@ -101,15 +102,14 @@ public:
inline bool isDirectOutput() const
{
return (mType == AUDIO_PORT_TYPE_MIX) && (mRole == AUDIO_PORT_ROLE_SOURCE) &&
return (asAudioPort()->getType() == AUDIO_PORT_TYPE_MIX) &&
(asAudioPort()->getRole() == AUDIO_PORT_ROLE_SOURCE) &&
(mFlags & (AUDIO_OUTPUT_FLAG_DIRECT | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD));
}
void addRoute(const sp<AudioRoute> &route) { mRoutes.add(route); }
const AudioRouteVector &getRoutes() const { return mRoutes; }
void log(const char* indent) const;
private:
void pickChannelMask(audio_channel_mask_t &channelMask,
const ChannelMaskSet &channelMasks) const;
@ -120,23 +120,32 @@ private:
AudioRouteVector mRoutes; // Routes involving this port
};
class AudioPortConfig : public AudioPortConfigBase
class PolicyAudioPortConfig : public virtual RefBase
{
public:
status_t applyAudioPortConfig(const struct audio_port_config *config,
struct audio_port_config *backupConfig = NULL) override;
virtual ~PolicyAudioPortConfig() = default;
virtual void toAudioPortConfig(struct audio_port_config *dstConfig,
const struct audio_port_config *srcConfig = NULL) const override;
virtual sp<PolicyAudioPort> getPolicyAudioPort() const = 0;
virtual sp<AudioPort> getAudioPort() const = 0;
status_t validationBeforeApplyConfig(const struct audio_port_config *config) const;
virtual bool hasSameHwModuleAs(const sp<AudioPortConfig>& other) const {
return (other != 0) && (other->getAudioPort() != 0) && (getAudioPort() != 0) &&
(other->getAudioPort()->getModuleHandle() == getAudioPort()->getModuleHandle());
void applyPolicyAudioPortConfig(const struct audio_port_config *config) {
if (config->config_mask & AUDIO_PORT_CONFIG_FLAGS) {
mFlags = config->flags;
}
}
bool hasGainController(bool canUseForVolume = false) const;
void toPolicyAudioPortConfig(
struct audio_port_config *dstConfig,
const struct audio_port_config *srcConfig = NULL) const;
virtual bool hasSameHwModuleAs(const sp<PolicyAudioPortConfig>& other) const {
return (other.get() != nullptr) && (other->getPolicyAudioPort().get() != nullptr) &&
(getPolicyAudioPort().get() != nullptr) &&
(other->getPolicyAudioPort()->getModuleHandle() ==
getPolicyAudioPort()->getModuleHandle());
}
union audio_io_flags mFlags = { AUDIO_INPUT_FLAG_NONE };
};

@ -18,15 +18,16 @@
//#define LOG_NDEBUG 0
#include "AudioCollections.h"
#include "AudioPort.h"
#include "AudioRoute.h"
#include "HwModule.h"
#include "PolicyAudioPort.h"
namespace android {
sp<AudioPort> AudioPortVector::findByTagName(const std::string &tagName) const
sp<PolicyAudioPort> findByTagName(const PolicyAudioPortVector& policyAudioPortVector,
const std::string &tagName)
{
for (const auto& port : *this) {
for (const auto& port : policyAudioPortVector) {
if (port->getTagName() == tagName) {
return port;
}
@ -34,15 +35,15 @@ sp<AudioPort> AudioPortVector::findByTagName(const std::string &tagName) const
return nullptr;
}
void AudioRouteVector::dump(String8 *dst, int spaces) const
void dumpAudioRouteVector(const AudioRouteVector& audioRouteVector, String8 *dst, int spaces)
{
if (isEmpty()) {
if (audioRouteVector.isEmpty()) {
return;
}
dst->appendFormat("\n%*sAudio Routes (%zu):\n", spaces, "", size());
for (size_t i = 0; i < size(); i++) {
dst->appendFormat("\n%*sAudio Routes (%zu):\n", spaces, "", audioRouteVector.size());
for (size_t i = 0; i < audioRouteVector.size(); i++) {
dst->appendFormat("%*s- Route %zu:\n", spaces, "", i + 1);
itemAt(i)->dump(dst, 4);
audioRouteVector.itemAt(i)->dump(dst, 4);
}
}

@ -48,14 +48,27 @@ audio_module_handle_t AudioInputDescriptor::getModuleHandle() const
return mProfile->getModuleHandle();
}
audio_port_handle_t AudioInputDescriptor::getId() const
audio_source_t AudioInputDescriptor::source() const
{
return mId;
return getHighestPriorityAttributes().source;
}
audio_source_t AudioInputDescriptor::source() const
status_t AudioInputDescriptor::applyAudioPortConfig(const struct audio_port_config *config,
audio_port_config *backupConfig)
{
return getHighestPriorityAttributes().source;
struct audio_port_config localBackupConfig = { .config_mask = config->config_mask };
status_t status = NO_ERROR;
toAudioPortConfig(&localBackupConfig);
if ((status = validationBeforeApplyConfig(config)) == NO_ERROR) {
AudioPortConfig::applyAudioPortConfig(config, backupConfig);
applyPolicyAudioPortConfig(config);
}
if (backupConfig != NULL) {
*backupConfig = localBackupConfig;
}
return status;
}
void AudioInputDescriptor::toAudioPortConfig(struct audio_port_config *dstConfig,
@ -70,8 +83,8 @@ void AudioInputDescriptor::toAudioPortConfig(struct audio_port_config *dstConfig
}
AudioPortConfig::toAudioPortConfig(dstConfig, srcConfig);
toPolicyAudioPortConfig(dstConfig, srcConfig);
dstConfig->id = mId;
dstConfig->role = AUDIO_PORT_ROLE_SINK;
dstConfig->type = AUDIO_PORT_TYPE_MIX;
dstConfig->ext.mix.hw_module = getModuleHandle();
@ -220,7 +233,7 @@ status_t AudioInputDescriptor::open(const audio_config_t *config,
input,
&lConfig,
&deviceType,
mDevice->address(),
String8(mDevice->address().c_str()),
source,
flags);
LOG_ALWAYS_FATAL_IF(mDevice->type() != deviceType,
@ -234,7 +247,7 @@ status_t AudioInputDescriptor::open(const audio_config_t *config,
mSamplingRate = lConfig.sample_rate;
mChannelMask = lConfig.channel_mask;
mFormat = lConfig.format;
mId = AudioPort::getNextUniqueId();
mId = PolicyAudioPort::getNextUniqueId();
mIoHandle = *input;
mProfile->curOpenCount++;
}

@ -34,14 +34,14 @@
namespace android {
AudioOutputDescriptor::AudioOutputDescriptor(const sp<AudioPort>& port,
AudioOutputDescriptor::AudioOutputDescriptor(const sp<PolicyAudioPort>& policyAudioPort,
AudioPolicyClientInterface *clientInterface)
: mPort(port), mClientInterface(clientInterface)
: mPolicyAudioPort(policyAudioPort), mClientInterface(clientInterface)
{
if (mPort.get() != nullptr) {
mPort->pickAudioProfile(mSamplingRate, mChannelMask, mFormat);
if (mPort->getGains().size() > 0) {
mPort->getGains()[0]->getDefaultConfig(&mGain);
if (mPolicyAudioPort.get() != nullptr) {
mPolicyAudioPort->pickAudioProfile(mSamplingRate, mChannelMask, mFormat);
if (mPolicyAudioPort->asAudioPort()->getGains().size() > 0) {
mPolicyAudioPort->asAudioPort()->getGains()[0]->getDefaultConfig(&mGain);
}
}
}
@ -55,7 +55,8 @@ audio_config_base_t AudioOutputDescriptor::getConfig() const
audio_module_handle_t AudioOutputDescriptor::getModuleHandle() const
{
return mPort.get() != nullptr ? mPort->getModuleHandle() : AUDIO_MODULE_HANDLE_NONE;
return mPolicyAudioPort.get() != nullptr ?
mPolicyAudioPort->getModuleHandle() : AUDIO_MODULE_HANDLE_NONE;
}
audio_patch_handle_t AudioOutputDescriptor::getPatchHandle() const
@ -68,11 +69,6 @@ void AudioOutputDescriptor::setPatchHandle(audio_patch_handle_t handle)
mPatchHandle = handle;
}
audio_port_handle_t AudioOutputDescriptor::getId() const
{
return mId;
}
bool AudioOutputDescriptor::sharesHwModuleWith(
const sp<AudioOutputDescriptor>& outputDesc)
{
@ -167,9 +163,27 @@ bool AudioOutputDescriptor::setVolume(float volumeDb,
return false;
}
void AudioOutputDescriptor::toAudioPortConfig(
struct audio_port_config *dstConfig,
const struct audio_port_config *srcConfig) const
status_t AudioOutputDescriptor::applyAudioPortConfig(const struct audio_port_config *config,
audio_port_config *backupConfig)
{
struct audio_port_config localBackupConfig = { .config_mask = config->config_mask };
status_t status = NO_ERROR;
toAudioPortConfig(&localBackupConfig);
if ((status = validationBeforeApplyConfig(config)) == NO_ERROR) {
AudioPortConfig::applyAudioPortConfig(config, backupConfig);
applyPolicyAudioPortConfig(config);
}
if (backupConfig != NULL) {
*backupConfig = localBackupConfig;
}
return status;
}
void AudioOutputDescriptor::toAudioPortConfig(struct audio_port_config *dstConfig,
const struct audio_port_config *srcConfig) const
{
dstConfig->config_mask = AUDIO_PORT_CONFIG_SAMPLE_RATE|AUDIO_PORT_CONFIG_CHANNEL_MASK|
AUDIO_PORT_CONFIG_FORMAT|AUDIO_PORT_CONFIG_GAIN;
@ -177,8 +191,8 @@ void AudioOutputDescriptor::toAudioPortConfig(
dstConfig->config_mask |= srcConfig->config_mask;
}
AudioPortConfig::toAudioPortConfig(dstConfig, srcConfig);
toPolicyAudioPortConfig(dstConfig, srcConfig);
dstConfig->id = mId;
dstConfig->role = AUDIO_PORT_ROLE_SOURCE;
dstConfig->type = AUDIO_PORT_TYPE_MIX;
dstConfig->ext.mix.hw_module = getModuleHandle();
@ -188,7 +202,7 @@ void AudioOutputDescriptor::toAudioPortConfig(
void AudioOutputDescriptor::toAudioPort(struct audio_port *port) const
{
// Should not be called for duplicated ports, see SwAudioOutputDescriptor::toAudioPortConfig.
mPort->toAudioPort(port);
mPolicyAudioPort->asAudioPort()->toAudioPort(port);
port->id = mId;
port->ext.mix.hw_module = getModuleHandle();
}
@ -503,7 +517,7 @@ status_t SwAudioOutputDescriptor::open(const audio_config_t *config,
mSamplingRate = lConfig.sample_rate;
mChannelMask = lConfig.channel_mask;
mFormat = lConfig.format;
mId = AudioPort::getNextUniqueId();
mId = PolicyAudioPort::getNextUniqueId();
mIoHandle = *output;
mProfile->curOpenCount++;
}
@ -589,7 +603,7 @@ status_t SwAudioOutputDescriptor::openDuplicating(const sp<SwAudioOutputDescript
return INVALID_OPERATION;
}
mId = AudioPort::getNextUniqueId();
mId = PolicyAudioPort::getNextUniqueId();
mIoHandle = *ioHandle;
mOutput1 = output1;
mOutput2 = output2;

@ -20,7 +20,7 @@
#include "AudioPolicyMix.h"
#include "TypeConverter.h"
#include "HwModule.h"
#include "AudioPort.h"
#include "PolicyAudioPort.h"
#include "IOProfile.h"
#include <AudioOutputDescriptor.h>

@ -18,22 +18,155 @@
#include <set>
#include <string>
#define LOG_TAG "APM::AudioProfile"
#define LOG_TAG "APM::AudioProfileVectorHelper"
//#define LOG_NDEBUG 0
#include <media/AudioContainers.h>
#include <media/AudioResamplerPublic.h>
#include <utils/Errors.h>
#include "AudioPort.h"
#include "AudioProfileVector.h"
#include "AudioProfileVectorHelper.h"
#include "HwModule.h"
#include "PolicyAudioPort.h"
#include "policy.h"
namespace android {
status_t checkExact(const sp<AudioProfile> &audioProfile, uint32_t samplingRate,
audio_channel_mask_t channelMask, audio_format_t format)
void sortAudioProfiles(AudioProfileVector &audioProfileVector) {
std::sort(audioProfileVector.begin(), audioProfileVector.end(),
[](const sp<AudioProfile> & a, const sp<AudioProfile> & b)
{
return PolicyAudioPort::compareFormats(a->getFormat(), b->getFormat()) < 0;
});
}
ssize_t addAudioProfileAndSort(AudioProfileVector &audioProfileVector,
const sp<AudioProfile> &profile)
{
ssize_t ret = audioProfileVector.add(profile);
// we sort from worst to best, so that AUDIO_FORMAT_DEFAULT is always the first entry.
sortAudioProfiles(audioProfileVector);
return ret;
}
sp<AudioProfile> getAudioProfileForFormat(const AudioProfileVector &audioProfileVector,
audio_format_t format)
{
for (const auto &profile : audioProfileVector) {
if (profile->getFormat() == format) {
return profile;
}
}
return nullptr;
}
void setSampleRatesForAudioProfiles(AudioProfileVector &audioProfileVector,
const SampleRateSet &sampleRateSet,
audio_format_t format)
{
for (const auto &profile : audioProfileVector) {
if (profile->getFormat() == format && profile->isDynamicRate()) {
if (profile->hasValidRates()) {
// Need to create a new profile with same format
sp<AudioProfile> profileToAdd = new AudioProfile(
format, profile->getChannels(), sampleRateSet);
profileToAdd->setDynamicFormat(true); // need to set to allow cleaning
addAudioProfileAndSort(audioProfileVector, profileToAdd);
} else {
profile->setSampleRates(sampleRateSet);
}
return;
}
}
}
void setChannelsForAudioProfiles(AudioProfileVector &audioProfileVector,
const ChannelMaskSet &channelMaskSet,
audio_format_t format)
{
for (const auto &profile : audioProfileVector) {
if (profile->getFormat() == format && profile->isDynamicChannels()) {
if (profile->hasValidChannels()) {
// Need to create a new profile with same format
sp<AudioProfile> profileToAdd = new AudioProfile(format, channelMaskSet,
profile->getSampleRates());
profileToAdd->setDynamicFormat(true); // need to set to allow cleaning
addAudioProfileAndSort(audioProfileVector, profileToAdd);
} else {
profile->setChannels(channelMaskSet);
}
return;
}
}
}
void addProfilesForFormats(AudioProfileVector &audioProfileVector, const FormatVector &formatVector)
{
// Only allow to change the format of dynamic profile
sp<AudioProfile> dynamicFormatProfile = getAudioProfileForFormat(
audioProfileVector, gDynamicFormat);
if (!dynamicFormatProfile) {
return;
}
for (const auto &format : formatVector) {
sp<AudioProfile> profile = new AudioProfile(format,
dynamicFormatProfile->getChannels(),
dynamicFormatProfile->getSampleRates());
profile->setDynamicFormat(true);
profile->setDynamicChannels(dynamicFormatProfile->isDynamicChannels());
profile->setDynamicRate(dynamicFormatProfile->isDynamicRate());
addAudioProfileAndSort(audioProfileVector, profile);
}
}
void addDynamicAudioProfileAndSort(AudioProfileVector &audioProfileVector,
const sp<AudioProfile> &profileToAdd)
{
// Check valid profile to add:
if (!profileToAdd->hasValidFormat()) {
ALOGW("Adding dynamic audio profile without valid format");
return;
}
if (!profileToAdd->hasValidChannels() && !profileToAdd->hasValidRates()) {
FormatVector formats;
formats.push_back(profileToAdd->getFormat());
addProfilesForFormats(audioProfileVector, FormatVector(formats));
return;
}
if (!profileToAdd->hasValidChannels() && profileToAdd->hasValidRates()) {
setSampleRatesForAudioProfiles(
audioProfileVector, profileToAdd->getSampleRates(), profileToAdd->getFormat());
return;
}
if (profileToAdd->hasValidChannels() && !profileToAdd->hasValidRates()) {
setChannelsForAudioProfiles(
audioProfileVector, profileToAdd->getChannels(), profileToAdd->getFormat());
return;
}
// Go through the list of profile to avoid duplicates
for (size_t profileIndex = 0; profileIndex < audioProfileVector.size(); profileIndex++) {
const sp<AudioProfile> &profile = audioProfileVector.at(profileIndex);
if (profile->isValid() && profile == profileToAdd) {
// Nothing to do
return;
}
}
profileToAdd->setDynamicFormat(true); // set the format as dynamic to allow removal
addAudioProfileAndSort(audioProfileVector, profileToAdd);
}
void appendAudioProfiles(AudioProfileVector &audioProfileVector,
const AudioProfileVector &audioProfileVectorToAppend)
{
audioProfileVector.insert(audioProfileVector.end(),
audioProfileVectorToAppend.begin(),
audioProfileVectorToAppend.end());
}
status_t checkExact(const sp<AudioProfile> &audioProfile,
uint32_t samplingRate,
audio_channel_mask_t channelMask,
audio_format_t format)
{
if (audio_formats_match(format, audioProfile->getFormat()) &&
audioProfile->supportsChannels(channelMask) &&
@ -173,60 +306,16 @@ status_t checkCompatibleChannelMask(const sp<AudioProfile> &audioProfile,
return bestMatch > 0 ? NO_ERROR : BAD_VALUE;
}
ssize_t AudioProfileVector::add(const sp<AudioProfile> &profile)
{
ssize_t index = size();
push_back(profile);
// we sort from worst to best, so that AUDIO_FORMAT_DEFAULT is always the first entry.
std::sort(begin(), end(),
[](const sp<AudioProfile> & a, const sp<AudioProfile> & b)
{
return AudioPort::compareFormats(a->getFormat(), b->getFormat()) < 0;
});
return index;
}
ssize_t AudioProfileVector::addProfileFromHal(const sp<AudioProfile> &profileToAdd)
status_t checkExactProfile(const AudioProfileVector& audioProfileVector,
const uint32_t samplingRate,
audio_channel_mask_t channelMask,
audio_format_t format)
{
// Check valid profile to add:
if (!profileToAdd->hasValidFormat()) {
return -1;
}
if (!profileToAdd->hasValidChannels() && !profileToAdd->hasValidRates()) {
FormatVector formats;
formats.push_back(profileToAdd->getFormat());
setFormats(FormatVector(formats));
return 0;
}
if (!profileToAdd->hasValidChannels() && profileToAdd->hasValidRates()) {
setSampleRatesFor(profileToAdd->getSampleRates(), profileToAdd->getFormat());
return 0;
}
if (profileToAdd->hasValidChannels() && !profileToAdd->hasValidRates()) {
setChannelsFor(profileToAdd->getChannels(), profileToAdd->getFormat());
return 0;
}
// Go through the list of profile to avoid duplicates
for (size_t profileIndex = 0; profileIndex < size(); profileIndex++) {
const sp<AudioProfile> &profile = at(profileIndex);
if (profile->isValid() && profile == profileToAdd) {
// Nothing to do
return profileIndex;
}
}
profileToAdd->setDynamicFormat(true); // set the format as dynamic to allow removal
return add(profileToAdd);
}
status_t AudioProfileVector::checkExactProfile(const uint32_t samplingRate,
audio_channel_mask_t channelMask,
audio_format_t format) const
{
if (empty()) {
if (audioProfileVector.empty()) {
return NO_ERROR;
}
for (const auto& profile : *this) {
for (const auto& profile : audioProfileVector) {
if (checkExact(profile, samplingRate, channelMask, format) == NO_ERROR) {
return NO_ERROR;
}
@ -234,13 +323,14 @@ status_t AudioProfileVector::checkExactProfile(const uint32_t samplingRate,
return BAD_VALUE;
}
status_t AudioProfileVector::checkCompatibleProfile(uint32_t &samplingRate,
audio_channel_mask_t &channelMask,
audio_format_t &format,
audio_port_type_t portType,
audio_port_role_t portRole) const
status_t checkCompatibleProfile(const AudioProfileVector &audioProfileVector,
uint32_t &samplingRate,
audio_channel_mask_t &channelMask,
audio_format_t &format,
audio_port_type_t portType,
audio_port_role_t portRole)
{
if (empty()) {
if (audioProfileVector.empty()) {
return NO_ERROR;
}
@ -249,8 +339,8 @@ status_t AudioProfileVector::checkCompatibleProfile(uint32_t &samplingRate,
&& audio_is_linear_pcm(format);
// iterate from best format to worst format (reverse order)
for (ssize_t i = size() - 1; i >= 0 ; --i) {
const sp<AudioProfile> profile = at(i);
for (ssize_t i = audioProfileVector.size() - 1; i >= 0 ; --i) {
const sp<AudioProfile> profile = audioProfileVector.at(i);
audio_format_t formatToCompare = profile->getFormat();
if (formatToCompare == format ||
(checkInexact
@ -306,23 +396,25 @@ std::vector<typename T::value_type> intersectAndOrder(
return result;
}
status_t AudioProfileVector::findBestMatchingOutputConfig(const AudioProfileVector& outputProfiles,
const std::vector<audio_format_t>& preferredFormats,
const std::vector<audio_channel_mask_t>& preferredOutputChannels,
bool preferHigherSamplingRates,
audio_config_base *bestOutputConfig) const
status_t findBestMatchingOutputConfig(
const AudioProfileVector &audioProfileVector,
const AudioProfileVector &outputProfileVector,
const std::vector<audio_format_t> &preferredFormatVector, // order: most pref -> least pref
const std::vector<audio_channel_mask_t> &preferredOutputChannelVector,
bool preferHigherSamplingRates,
audio_config_base &bestOutputConfig)
{
auto formats = intersectFilterAndOrder(getSupportedFormats(),
outputProfiles.getSupportedFormats(), preferredFormats);
auto formats = intersectFilterAndOrder(audioProfileVector.getSupportedFormats(),
outputProfileVector.getSupportedFormats(), preferredFormatVector);
// Pick the best compatible profile.
for (const auto& f : formats) {
sp<AudioProfile> inputProfile = getFirstValidProfileFor(f);
sp<AudioProfile> outputProfile = outputProfiles.getFirstValidProfileFor(f);
sp<AudioProfile> inputProfile = audioProfileVector.getFirstValidProfileFor(f);
sp<AudioProfile> outputProfile = outputProfileVector.getFirstValidProfileFor(f);
if (inputProfile == nullptr || outputProfile == nullptr) {
continue;
}
auto channels = intersectFilterAndOrder(asOutMask(inputProfile->getChannels()),
outputProfile->getChannels(), preferredOutputChannels);
outputProfile->getChannels(), preferredOutputChannelVector);
if (channels.empty()) {
continue;
}
@ -336,77 +428,12 @@ status_t AudioProfileVector::findBestMatchingOutputConfig(const AudioProfileVect
}
ALOGD("%s() found channel mask %#x and sample rate %d for format %#x.",
__func__, *channels.begin(), *sampleRates.begin(), f);
bestOutputConfig->format = f;
bestOutputConfig->sample_rate = *sampleRates.begin();
bestOutputConfig->channel_mask = *channels.begin();
bestOutputConfig.format = f;
bestOutputConfig.sample_rate = *sampleRates.begin();
bestOutputConfig.channel_mask = *channels.begin();
return NO_ERROR;
}
return BAD_VALUE;
}
void AudioProfileVector::setFormats(const FormatVector &formats)
{
// Only allow to change the format of dynamic profile
sp<AudioProfile> dynamicFormatProfile = getProfileFor(gDynamicFormat);
if (dynamicFormatProfile == 0) {
return;
}
for (const auto &format : formats) {
sp<AudioProfile> profile = new AudioProfile(format,
dynamicFormatProfile->getChannels(),
dynamicFormatProfile->getSampleRates());
profile->setDynamicFormat(true);
profile->setDynamicChannels(dynamicFormatProfile->isDynamicChannels());
profile->setDynamicRate(dynamicFormatProfile->isDynamicRate());
add(profile);
}
}
sp<AudioProfile> AudioProfileVector::getProfileFor(audio_format_t format) const
{
for (const auto &profile : *this) {
if (profile->getFormat() == format) {
return profile;
}
}
return nullptr;
}
void AudioProfileVector::setSampleRatesFor(
const SampleRateSet &sampleRates, audio_format_t format)
{
for (const auto &profile : *this) {
if (profile->getFormat() == format && profile->isDynamicRate()) {
if (profile->hasValidRates()) {
// Need to create a new profile with same format
sp<AudioProfile> profileToAdd = new AudioProfile(format, profile->getChannels(),
sampleRates);
profileToAdd->setDynamicFormat(true); // need to set to allow cleaning
add(profileToAdd);
} else {
profile->setSampleRates(sampleRates);
}
return;
}
}
}
void AudioProfileVector::setChannelsFor(const ChannelMaskSet &channelMasks, audio_format_t format)
{
for (const auto &profile : *this) {
if (profile->getFormat() == format && profile->isDynamicChannels()) {
if (profile->hasValidChannels()) {
// Need to create a new profile with same format
sp<AudioProfile> profileToAdd = new AudioProfile(format, channelMasks,
profile->getSampleRates());
profileToAdd->setDynamicFormat(true); // need to set to allow cleaning
add(profileToAdd);
} else {
profile->setChannels(channelMasks);
}
return;
}
}
}
} // namespace android

@ -36,7 +36,8 @@ void AudioRoute::dump(String8 *dst, int spaces) const
dst->append("\n");
}
bool AudioRoute::supportsPatch(const sp<AudioPort> &srcPort, const sp<AudioPort> &dstPort) const
bool AudioRoute::supportsPatch(const sp<PolicyAudioPort> &srcPort,
const sp<PolicyAudioPort> &dstPort) const
{
if (mSink == 0 || dstPort == 0 || dstPort != mSink) {
return false;

@ -33,15 +33,9 @@ DeviceDescriptor::DeviceDescriptor(audio_devices_t type, const std::string &tagN
DeviceDescriptor::DeviceDescriptor(audio_devices_t type, const FormatVector &encodedFormats,
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)
DeviceDescriptorBase(type), mTagName(tagName), mEncodedFormats(encodedFormats)
{
mCurrentEncodedFormat = AUDIO_FORMAT_DEFAULT;
if (audio_is_remote_submix_device(type)) {
mAddress = String8("0");
}
/* If framework runs against a pre 5.0 Audio HAL, encoded formats are absent from the config.
* FIXME: APM should know the version of the HAL and don't add the formats for V5.0.
* For now, the workaround to remove AC3 and IEC61937 support on HDMI is to declare
@ -53,20 +47,15 @@ DeviceDescriptor::DeviceDescriptor(audio_devices_t type, const FormatVector &enc
}
}
audio_port_handle_t DeviceDescriptor::getId() const
{
return mId;
}
void DeviceDescriptor::attach(const sp<HwModule>& module)
{
AudioPort::attach(module);
PolicyAudioPort::attach(module);
mId = getNextUniqueId();
}
void DeviceDescriptor::detach() {
mId = AUDIO_PORT_HANDLE_NONE;
AudioPort::detach();
PolicyAudioPort::detach();
}
template<typename T>
@ -117,6 +106,62 @@ bool DeviceDescriptor::supportsFormat(audio_format_t format)
return false;
}
status_t DeviceDescriptor::applyAudioPortConfig(const struct audio_port_config *config,
audio_port_config *backupConfig)
{
struct audio_port_config localBackupConfig = { .config_mask = config->config_mask };
status_t status = NO_ERROR;
toAudioPortConfig(&localBackupConfig);
if ((status = validationBeforeApplyConfig(config)) == NO_ERROR) {
AudioPortConfig::applyAudioPortConfig(config, backupConfig);
applyPolicyAudioPortConfig(config);
}
if (backupConfig != NULL) {
*backupConfig = localBackupConfig;
}
return status;
}
void DeviceDescriptor::toAudioPortConfig(struct audio_port_config *dstConfig,
const struct audio_port_config *srcConfig) const
{
DeviceDescriptorBase::toAudioPortConfig(dstConfig, srcConfig);
toPolicyAudioPortConfig(dstConfig, srcConfig);
dstConfig->ext.device.hw_module = getModuleHandle();
}
void DeviceDescriptor::toAudioPort(struct audio_port *port) const
{
ALOGV("DeviceDescriptor::toAudioPort() handle %d type %08x", mId, mDeviceType);
DeviceDescriptorBase::toAudioPort(port);
port->ext.device.hw_module = getModuleHandle();
}
void DeviceDescriptor::importAudioPortAndPickAudioProfile(
const sp<PolicyAudioPort>& policyPort, bool force) {
if (!force && !policyPort->asAudioPort()->hasDynamicAudioProfile()) {
return;
}
AudioPort::importAudioPort(policyPort->asAudioPort());
policyPort->pickAudioProfile(mSamplingRate, mChannelMask, mFormat);
}
void DeviceDescriptor::dump(String8 *dst, int spaces, int index, bool verbose) const
{
String8 extraInfo;
if (!mTagName.empty()) {
extraInfo.appendFormat("%*s- tag name: %s\n", spaces, "", mTagName.c_str());
}
std::string descBaseDumpStr;
DeviceDescriptorBase::dump(&descBaseDumpStr, spaces, index, extraInfo.string(), verbose);
dst->append(descBaseDumpStr.c_str());
}
void DeviceVector::refreshTypes()
{
mDeviceTypes = AUDIO_DEVICE_NONE;
@ -218,11 +263,11 @@ sp<DeviceDescriptor> DeviceVector::getDevice(audio_devices_t type, const String8
// If format is specified, match it and ignore address
// Otherwise if address is specified match it
// Otherwise always match
if (((address == "" || itemAt(i)->address() == address) &&
if (((address == "" || (itemAt(i)->address().compare(address.c_str()) == 0)) &&
format == AUDIO_FORMAT_DEFAULT) ||
(itemAt(i)->supportsFormat(format) && format != AUDIO_FORMAT_DEFAULT)) {
device = itemAt(i);
if (itemAt(i)->address() == address) {
if (itemAt(i)->address().compare(address.c_str()) == 0) {
break;
}
}
@ -315,86 +360,6 @@ void DeviceVector::dump(String8 *dst, const String8 &tag, int spaces, bool verbo
}
}
void DeviceDescriptor::toAudioPortConfig(struct audio_port_config *dstConfig,
const struct audio_port_config *srcConfig) const
{
dstConfig->config_mask = AUDIO_PORT_CONFIG_GAIN;
if (mSamplingRate != 0) {
dstConfig->config_mask |= AUDIO_PORT_CONFIG_SAMPLE_RATE;
}
if (mChannelMask != AUDIO_CHANNEL_NONE) {
dstConfig->config_mask |= AUDIO_PORT_CONFIG_CHANNEL_MASK;
}
if (mFormat != AUDIO_FORMAT_INVALID) {
dstConfig->config_mask |= AUDIO_PORT_CONFIG_FORMAT;
}
if (srcConfig != NULL) {
dstConfig->config_mask |= srcConfig->config_mask;
}
AudioPortConfig::toAudioPortConfig(dstConfig, srcConfig);
dstConfig->id = mId;
dstConfig->role = audio_is_output_device(mDeviceType) ?
AUDIO_PORT_ROLE_SINK : AUDIO_PORT_ROLE_SOURCE;
dstConfig->type = AUDIO_PORT_TYPE_DEVICE;
dstConfig->ext.device.type = mDeviceType;
//TODO Understand why this test is necessary. i.e. why at boot time does it crash
// without the test?
// This has been demonstrated to NOT be true (at start up)
// ALOG_ASSERT(mModule != NULL);
dstConfig->ext.device.hw_module = getModuleHandle();
(void)audio_utils_strlcpy_zerofill(dstConfig->ext.device.address, mAddress.string());
}
void DeviceDescriptor::toAudioPort(struct audio_port *port) const
{
ALOGV("DeviceDescriptor::toAudioPort() handle %d type %08x", mId, mDeviceType);
AudioPort::toAudioPort(port);
port->id = mId;
toAudioPortConfig(&port->active_config);
port->ext.device.type = mDeviceType;
port->ext.device.hw_module = getModuleHandle();
(void)audio_utils_strlcpy_zerofill(port->ext.device.address, mAddress.string());
}
void DeviceDescriptor::importAudioPort(const sp<AudioPort>& port, bool force) {
if (!force && !port->hasDynamicAudioProfile()) {
return;
}
AudioPort::importAudioPort(port);
port->pickAudioProfile(mSamplingRate, mChannelMask, mFormat);
}
void DeviceDescriptor::dump(String8 *dst, int spaces, int index, bool verbose) const
{
dst->appendFormat("%*sDevice %d:\n", spaces, "", index + 1);
if (mId != 0) {
dst->appendFormat("%*s- id: %2d\n", spaces, "", mId);
}
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());
if (mAddress.size() != 0) {
dst->appendFormat("%*s- address: %-32s\n", spaces, "", mAddress.string());
}
std::string portStr;
AudioPort::dump(&portStr, spaces, verbose);
dst->append(portStr.c_str());
}
std::string DeviceDescriptor::toString() const
{
std::stringstream sstream;
sstream << "type:0x" << std::hex << type() << ",@:" << mAddress;
return sstream.str();
}
std::string DeviceVector::toString() const
{
if (isEmpty()) {
@ -443,13 +408,4 @@ DeviceVector DeviceVector::filterForEngine() const
return filteredDevices;
}
void DeviceDescriptor::log() const
{
ALOGI("Device id:%d type:0x%08X:%s, addr:%s", mId, mDeviceType,
::android::toString(mDeviceType).c_str(),
mAddress.string());
AudioPort::log(" ");
}
} // namespace android

@ -50,7 +50,7 @@ status_t HwModule::addOutputProfile(const std::string& name, const audio_config_
config->sample_rate));
sp<DeviceDescriptor> devDesc = new DeviceDescriptor(device);
devDesc->setAddress(address);
devDesc->setAddress(address.string());
addDynamicDevice(devDesc);
// Reciprocally attach the device to the module
devDesc->attach(this);
@ -118,7 +118,7 @@ status_t HwModule::addInputProfile(const std::string& name, const audio_config_t
config->sample_rate));
sp<DeviceDescriptor> devDesc = new DeviceDescriptor(device);
devDesc->setAddress(address);
devDesc->setAddress(address.string());
addDynamicDevice(devDesc);
// Reciprocally attach the device to the module
devDesc->attach(this);
@ -156,7 +156,7 @@ void HwModule::setDeclaredDevices(const DeviceVector &devices)
sp<DeviceDescriptor> HwModule::getRouteSinkDevice(const sp<AudioRoute> &route) const
{
sp<DeviceDescriptor> sinkDevice = 0;
if (route->getSink()->getType() == AUDIO_PORT_TYPE_DEVICE) {
if (route->getSink()->asAudioPort()->getType() == AUDIO_PORT_TYPE_DEVICE) {
sinkDevice = mDeclaredDevices.getDeviceFromTagName(route->getSink()->getTagName());
}
return sinkDevice;
@ -166,7 +166,7 @@ DeviceVector HwModule::getRouteSourceDevices(const sp<AudioRoute> &route) const
{
DeviceVector sourceDevices;
for (const auto& source : route->getSources()) {
if (source->getType() == AUDIO_PORT_TYPE_DEVICE) {
if (source->asAudioPort()->getType() == AUDIO_PORT_TYPE_DEVICE) {
sourceDevices.add(mDeclaredDevices.getDeviceFromTagName(source->getTagName()));
}
}
@ -186,7 +186,7 @@ void HwModule::refreshSupportedDevices()
for (const auto& stream : mInputProfiles) {
DeviceVector sourceDevices;
for (const auto& route : stream->getRoutes()) {
sp<AudioPort> sink = route->getSink();
sp<PolicyAudioPort> sink = route->getSink();
if (sink == 0 || stream != sink) {
ALOGE("%s: Invalid route attached to input stream", __FUNCTION__);
continue;
@ -207,7 +207,7 @@ void HwModule::refreshSupportedDevices()
for (const auto& stream : mOutputProfiles) {
DeviceVector sinkDevices;
for (const auto& route : stream->getRoutes()) {
sp<AudioPort> source = route->getSources().findByTagName(stream->getTagName());
sp<PolicyAudioPort> source = findByTagName(route->getSources(), stream->getTagName());
if (source == 0 || stream != source) {
ALOGE("%s: Invalid route attached to output stream", __FUNCTION__);
continue;
@ -229,7 +229,8 @@ void HwModule::setHandle(audio_module_handle_t handle) {
mHandle = handle;
}
bool HwModule::supportsPatch(const sp<AudioPort> &srcPort, const sp<AudioPort> &dstPort) const {
bool HwModule::supportsPatch(const sp<PolicyAudioPort> &srcPort,
const sp<PolicyAudioPort> &dstPort) const {
for (const auto &route : mRoutes) {
if (route->supportsPatch(srcPort, dstPort)) {
return true;
@ -259,7 +260,7 @@ void HwModule::dump(String8 *dst) const
}
mDeclaredDevices.dump(dst, String8("Declared"), 2, true);
mDynamicDevices.dump(dst, String8("Dynamic"), 2, true);
mRoutes.dump(dst, 2);
dumpAudioRouteVector(mRoutes, dst, 2);
}
sp <HwModule> HwModuleCollection::getModuleFromName(const char *name) const
@ -334,7 +335,7 @@ sp<DeviceDescriptor> HwModuleCollection::getDeviceDescriptor(const audio_devices
}
if (allowToCreate) {
moduleDevice->attach(hwModule);
moduleDevice->setAddress(devAddress);
moduleDevice->setAddress(devAddress.string());
moduleDevice->setName(name);
}
return moduleDevice;
@ -361,7 +362,7 @@ sp<DeviceDescriptor> HwModuleCollection::createDevice(const audio_devices_t type
}
sp<DeviceDescriptor> device = new DeviceDescriptor(type, name);
device->setName(name);
device->setAddress(String8(address));
device->setAddress(address);
device->setEncodedFormat(encodedFormat);
// Add the device to the list of dynamic devices
@ -381,7 +382,7 @@ sp<DeviceDescriptor> HwModuleCollection::createDevice(const audio_devices_t type
// @todo quid of audio profile? import the profile from device of the same type?
const auto &isoTypeDeviceForProfile =
profile->getSupportedDevices().getDevice(type, String8(), AUDIO_FORMAT_DEFAULT);
device->importAudioPort(isoTypeDeviceForProfile, true /* force */);
device->importAudioPortAndPickAudioProfile(isoTypeDeviceForProfile, true /* force */);
ALOGV("%s: adding device %s to profile %s", __FUNCTION__,
device->toString().c_str(), profile->getTagName().c_str());

@ -14,10 +14,10 @@
* limitations under the License.
*/
#define LOG_TAG "APM::AudioPort"
#define LOG_TAG "APM::PolicyAudioPort"
//#define LOG_NDEBUG 0
#include "TypeConverter.h"
#include "AudioPort.h"
#include "PolicyAudioPort.h"
#include "HwModule.h"
#include <policy.h>
@ -27,81 +27,61 @@
namespace android {
// --- AudioPort class implementation
void AudioPort::attach(const sp<HwModule>& module)
// --- PolicyAudioPort class implementation
void PolicyAudioPort::attach(const sp<HwModule>& module)
{
ALOGV("%s: attaching module %s to port %s", __FUNCTION__, getModuleName(), mName.c_str());
ALOGV("%s: attaching module %s to port %s",
__FUNCTION__, getModuleName(), asAudioPort()->getName().c_str());
mModule = module;
}
void AudioPort::detach()
void PolicyAudioPort::detach()
{
mModule = nullptr;
}
// Note that is a different namespace than AudioFlinger unique IDs
audio_port_handle_t AudioPort::getNextUniqueId()
audio_port_handle_t PolicyAudioPort::getNextUniqueId()
{
return getNextHandle();
}
audio_module_handle_t AudioPort::getModuleHandle() const
audio_module_handle_t PolicyAudioPort::getModuleHandle() const
{
return mModule != 0 ? mModule->getHandle() : AUDIO_MODULE_HANDLE_NONE;
}
uint32_t AudioPort::getModuleVersionMajor() const
uint32_t PolicyAudioPort::getModuleVersionMajor() const
{
return mModule != 0 ? mModule->getHalVersionMajor() : 0;
}
const char *AudioPort::getModuleName() const
const char *PolicyAudioPort::getModuleName() const
{
return mModule != 0 ? mModule->getName() : "invalid module";
}
void AudioPort::importAudioPort(const sp<AudioPort>& port, bool force __unused)
{
for (const auto& profileToImport : port->mProfiles) {
if (profileToImport->isValid()) {
// Import only valid port, i.e. valid format, non empty rates and channels masks
bool hasSameProfile = false;
for (const auto& profile : mProfiles) {
if (*profile == *profileToImport) {
// never import a profile twice
hasSameProfile = true;
break;
}
}
if (hasSameProfile) { // never import a same profile twice
continue;
}
addAudioProfile(profileToImport);
}
}
}
status_t AudioPort::checkExactAudioProfile(const struct audio_port_config *config) const
status_t PolicyAudioPort::checkExactAudioProfile(const struct audio_port_config *config) const
{
status_t status = NO_ERROR;
auto config_mask = config->config_mask;
if (config_mask & AUDIO_PORT_CONFIG_GAIN) {
config_mask &= ~AUDIO_PORT_CONFIG_GAIN;
status = checkGain(&config->gain, config->gain.index);
status = asAudioPort()->checkGain(&config->gain, config->gain.index);
if (status != NO_ERROR) {
return status;
}
}
if (config_mask != 0) {
// TODO should we check sample_rate / channel_mask / format separately?
status = mProfiles.checkExactProfile(config->sample_rate,
config->channel_mask,
config->format);
status = checkExactProfile(asAudioPort()->getAudioProfiles(), config->sample_rate,
config->channel_mask, config->format);
}
return status;
}
void AudioPort::pickSamplingRate(uint32_t &pickedRate,const SampleRateSet &samplingRates) const
void PolicyAudioPort::pickSamplingRate(uint32_t &pickedRate,
const SampleRateSet &samplingRates) const
{
pickedRate = 0;
// For direct outputs, pick minimum sampling rate: this helps ensuring that the
@ -121,7 +101,7 @@ void AudioPort::pickSamplingRate(uint32_t &pickedRate,const SampleRateSet &sampl
// For mixed output and inputs, use max mixer sampling rates. Do not
// limit sampling rate otherwise
// For inputs, also see checkCompatibleSamplingRate().
if (mType != AUDIO_PORT_TYPE_MIX) {
if (asAudioPort()->getType() == AUDIO_PORT_TYPE_MIX) {
maxRate = UINT_MAX;
}
// TODO: should mSamplingRates[] be ordered in terms of our preference
@ -135,8 +115,8 @@ void AudioPort::pickSamplingRate(uint32_t &pickedRate,const SampleRateSet &sampl
}
}
void AudioPort::pickChannelMask(audio_channel_mask_t &pickedChannelMask,
const ChannelMaskSet &channelMasks) const
void PolicyAudioPort::pickChannelMask(audio_channel_mask_t &pickedChannelMask,
const ChannelMaskSet &channelMasks) const
{
pickedChannelMask = AUDIO_CHANNEL_NONE;
// For direct outputs, pick minimum channel count: this helps ensuring that the
@ -146,7 +126,7 @@ void AudioPort::pickChannelMask(audio_channel_mask_t &pickedChannelMask,
uint32_t channelCount = UINT_MAX;
for (const auto channelMask : channelMasks) {
uint32_t cnlCount;
if (useInputChannelMask()) {
if (asAudioPort()->useInputChannelMask()) {
cnlCount = audio_channel_count_from_in_mask(channelMask);
} else {
cnlCount = audio_channel_count_from_out_mask(channelMask);
@ -162,12 +142,12 @@ void AudioPort::pickChannelMask(audio_channel_mask_t &pickedChannelMask,
// For mixed output and inputs, use max mixer channel count. Do not
// limit channel count otherwise
if (mType != AUDIO_PORT_TYPE_MIX) {
if (asAudioPort()->getType() != AUDIO_PORT_TYPE_MIX) {
maxCount = UINT_MAX;
}
for (const auto channelMask : channelMasks) {
uint32_t cnlCount;
if (useInputChannelMask()) {
if (asAudioPort()->useInputChannelMask()) {
cnlCount = audio_channel_count_from_in_mask(channelMask);
} else {
cnlCount = audio_channel_count_from_out_mask(channelMask);
@ -181,7 +161,7 @@ void AudioPort::pickChannelMask(audio_channel_mask_t &pickedChannelMask,
}
/* format in order of increasing preference */
const audio_format_t AudioPort::sPcmFormatCompareTable[] = {
const audio_format_t PolicyAudioPort::sPcmFormatCompareTable[] = {
AUDIO_FORMAT_DEFAULT,
AUDIO_FORMAT_PCM_16_BIT,
AUDIO_FORMAT_PCM_8_24_BIT,
@ -190,7 +170,7 @@ const audio_format_t AudioPort::sPcmFormatCompareTable[] = {
AUDIO_FORMAT_PCM_FLOAT,
};
int AudioPort::compareFormats(audio_format_t format1, audio_format_t format2)
int PolicyAudioPort::compareFormats(audio_format_t format1, audio_format_t format2)
{
// NOTE: AUDIO_FORMAT_INVALID is also considered not PCM and will be compared equal to any
// compressed format and better than any PCM format. This is by design of pickFormat()
@ -220,7 +200,7 @@ int AudioPort::compareFormats(audio_format_t format1, audio_format_t format2)
return index1 - index2;
}
uint32_t AudioPort::formatDistance(audio_format_t format1, audio_format_t format2)
uint32_t PolicyAudioPort::formatDistance(audio_format_t format1, audio_format_t format2)
{
if (format1 == format2) {
return 0;
@ -234,43 +214,44 @@ uint32_t AudioPort::formatDistance(audio_format_t format1, audio_format_t format
return abs(diffBytes);
}
bool AudioPort::isBetterFormatMatch(audio_format_t newFormat,
audio_format_t currentFormat,
audio_format_t targetFormat)
bool PolicyAudioPort::isBetterFormatMatch(audio_format_t newFormat,
audio_format_t currentFormat,
audio_format_t targetFormat)
{
return formatDistance(newFormat, targetFormat) < formatDistance(currentFormat, targetFormat);
}
void AudioPort::pickAudioProfile(uint32_t &samplingRate,
audio_channel_mask_t &channelMask,
audio_format_t &format) const
void PolicyAudioPort::pickAudioProfile(uint32_t &samplingRate,
audio_channel_mask_t &channelMask,
audio_format_t &format) const
{
format = AUDIO_FORMAT_DEFAULT;
samplingRate = 0;
channelMask = AUDIO_CHANNEL_NONE;
// special case for uninitialized dynamic profile
if (!mProfiles.hasValidProfile()) {
if (!asAudioPort()->hasValidAudioProfile()) {
return;
}
audio_format_t bestFormat = sPcmFormatCompareTable[ARRAY_SIZE(sPcmFormatCompareTable) - 1];
// For mixed output and inputs, use best mixer output format.
// Do not limit format otherwise
if ((mType != AUDIO_PORT_TYPE_MIX) || isDirectOutput()) {
if ((asAudioPort()->getType() != AUDIO_PORT_TYPE_MIX) || isDirectOutput()) {
bestFormat = AUDIO_FORMAT_INVALID;
}
for (size_t i = 0; i < mProfiles.size(); i ++) {
if (!mProfiles[i]->isValid()) {
const AudioProfileVector& audioProfiles = asAudioPort()->getAudioProfiles();
for (size_t i = 0; i < audioProfiles.size(); i ++) {
if (!audioProfiles[i]->isValid()) {
continue;
}
audio_format_t formatToCompare = mProfiles[i]->getFormat();
audio_format_t formatToCompare = audioProfiles[i]->getFormat();
if ((compareFormats(formatToCompare, format) > 0) &&
(compareFormats(formatToCompare, bestFormat) <= 0)) {
uint32_t pickedSamplingRate = 0;
audio_channel_mask_t pickedChannelMask = AUDIO_CHANNEL_NONE;
pickChannelMask(pickedChannelMask, mProfiles[i]->getChannels());
pickSamplingRate(pickedSamplingRate, mProfiles[i]->getSampleRates());
pickChannelMask(pickedChannelMask, audioProfiles[i]->getChannels());
pickSamplingRate(pickedSamplingRate, audioProfiles[i]->getSampleRates());
if (formatToCompare != AUDIO_FORMAT_DEFAULT && pickedChannelMask != AUDIO_CHANNEL_NONE
&& pickedSamplingRate != 0) {
@ -281,120 +262,33 @@ void AudioPort::pickAudioProfile(uint32_t &samplingRate,
}
}
}
ALOGV("%s Port[nm:%s] profile rate=%d, format=%d, channels=%d", __FUNCTION__, mName.c_str(),
samplingRate, channelMask, format);
}
void AudioPort::log(const char* indent) const
{
ALOGI("%s Port[nm:%s, type:%d, role:%d]", indent, mName.c_str(), mType, mRole);
ALOGV("%s Port[nm:%s] profile rate=%d, format=%d, channels=%d", __FUNCTION__,
asAudioPort()->getName().c_str(), samplingRate, channelMask, format);
}
// --- AudioPortConfig class implementation
// --- PolicyAudioPortConfig class implementation
status_t AudioPortConfig::applyAudioPortConfig(const struct audio_port_config *config,
struct audio_port_config *backupConfig)
status_t PolicyAudioPortConfig::validationBeforeApplyConfig(
const struct audio_port_config *config) const
{
struct audio_port_config localBackupConfig = { .config_mask = config->config_mask };
status_t status = NO_ERROR;
toAudioPortConfig(&localBackupConfig);
sp<AudioPort> audioport = getAudioPort();
if (audioport == 0) {
status = NO_INIT;
goto exit;
}
status = audioport->checkExactAudioProfile(config);
if (status != NO_ERROR) {
goto exit;
}
if (config->config_mask & AUDIO_PORT_CONFIG_SAMPLE_RATE) {
mSamplingRate = config->sample_rate;
}
if (config->config_mask & AUDIO_PORT_CONFIG_CHANNEL_MASK) {
mChannelMask = config->channel_mask;
}
if (config->config_mask & AUDIO_PORT_CONFIG_FORMAT) {
mFormat = config->format;
}
if (config->config_mask & AUDIO_PORT_CONFIG_GAIN) {
mGain = config->gain;
}
if (config->config_mask & AUDIO_PORT_CONFIG_FLAGS) {
mFlags = config->flags;
}
exit:
if (status != NO_ERROR) {
applyAudioPortConfig(&localBackupConfig);
}
if (backupConfig != NULL) {
*backupConfig = localBackupConfig;
}
return status;
sp<PolicyAudioPort> policyAudioPort = getPolicyAudioPort();
return policyAudioPort ? policyAudioPort->checkExactAudioProfile(config) : NO_INIT;
}
namespace {
template<typename T>
void updateField(
const T& portConfigField, T audio_port_config::*port_config_field,
struct audio_port_config *dstConfig, const struct audio_port_config *srcConfig,
unsigned int configMask, T defaultValue)
void PolicyAudioPortConfig::toPolicyAudioPortConfig(struct audio_port_config *dstConfig,
const struct audio_port_config *srcConfig) const
{
if (dstConfig->config_mask & configMask) {
if ((srcConfig != nullptr) && (srcConfig->config_mask & configMask)) {
dstConfig->*port_config_field = srcConfig->*port_config_field;
if (dstConfig->config_mask & AUDIO_PORT_CONFIG_FLAGS) {
if ((srcConfig != nullptr) && (srcConfig->config_mask & AUDIO_PORT_CONFIG_FLAGS)) {
dstConfig->flags = srcConfig->flags;
} else {
dstConfig->*port_config_field = portConfigField;
dstConfig->flags = mFlags;
}
} else {
dstConfig->*port_config_field = defaultValue;
dstConfig->flags = { AUDIO_INPUT_FLAG_NONE };
}
}
} // namespace
void AudioPortConfig::toAudioPortConfig(struct audio_port_config *dstConfig,
const struct audio_port_config *srcConfig) const
{
updateField(mSamplingRate, &audio_port_config::sample_rate,
dstConfig, srcConfig, AUDIO_PORT_CONFIG_SAMPLE_RATE, 0u);
updateField(mChannelMask, &audio_port_config::channel_mask,
dstConfig, srcConfig, AUDIO_PORT_CONFIG_CHANNEL_MASK,
(audio_channel_mask_t)AUDIO_CHANNEL_NONE);
updateField(mFormat, &audio_port_config::format,
dstConfig, srcConfig, AUDIO_PORT_CONFIG_FORMAT, AUDIO_FORMAT_INVALID);
sp<AudioPort> audioport = getAudioPort();
if ((dstConfig->config_mask & AUDIO_PORT_CONFIG_GAIN) && audioport != NULL) {
dstConfig->gain = mGain;
if ((srcConfig != NULL) && (srcConfig->config_mask & AUDIO_PORT_CONFIG_GAIN)
&& audioport->checkGain(&srcConfig->gain, srcConfig->gain.index) == OK) {
dstConfig->gain = srcConfig->gain;
}
} else {
dstConfig->gain.index = -1;
}
if (dstConfig->gain.index != -1) {
dstConfig->config_mask |= AUDIO_PORT_CONFIG_GAIN;
} else {
dstConfig->config_mask &= ~AUDIO_PORT_CONFIG_GAIN;
}
updateField(mFlags, &audio_port_config::flags,
dstConfig, srcConfig, AUDIO_PORT_CONFIG_FLAGS, { AUDIO_INPUT_FLAG_NONE });
}
bool AudioPortConfig::hasGainController(bool canUseForVolume) const
{
sp<AudioPort> audioport = getAudioPort();
if (audioport == nullptr) {
return false;
}
return canUseForVolume ? audioport->getGains().canUseForVolume()
: audioport->getGains().size() > 0;
}
} // namespace android

@ -440,6 +440,9 @@ Return<MixPortTraits::Element> MixPortTraits::deserialize(const xmlNode *child,
if (profiles.empty()) {
profiles.add(AudioProfile::createFullDynamic(gDynamicFormat));
}
// The audio profiles are in order of listed in audio policy configuration file.
// Sort audio profiles accroding to the format.
sortAudioProfiles(profiles);
mixPort->setAudioProfiles(profiles);
std::string flags = getXmlAttribute(child, Attributes::flags);
@ -513,7 +516,7 @@ Return<DevicePortTraits::Element> DevicePortTraits::deserialize(const xmlNode *c
std::string address = getXmlAttribute(cur, Attributes::address);
if (!address.empty()) {
ALOGV("%s: address=%s for %s", __func__, address.c_str(), name.c_str());
deviceDesc->setAddress(String8(address.c_str()));
deviceDesc->setAddress(address);
}
AudioProfileTraits::Collection profiles;
@ -524,6 +527,9 @@ Return<DevicePortTraits::Element> DevicePortTraits::deserialize(const xmlNode *c
if (profiles.empty()) {
profiles.add(AudioProfile::createFullDynamic(gDynamicFormat));
}
// The audio profiles are in order of listed in audio policy configuration file.
// Sort audio profiles accroding to the format.
sortAudioProfiles(profiles);
deviceDesc->setAudioProfiles(profiles);
// Deserialize AudioGain children
@ -532,7 +538,7 @@ Return<DevicePortTraits::Element> DevicePortTraits::deserialize(const xmlNode *c
return Status::fromStatusT(status);
}
ALOGV("%s: adding device tag %s type %08x address %s", __func__,
deviceDesc->getName().c_str(), type, deviceDesc->address().string());
deviceDesc->getName().c_str(), type, deviceDesc->address().c_str());
return deviceDesc;
}
@ -555,7 +561,7 @@ Return<RouteTraits::Element> RouteTraits::deserialize(const xmlNode *cur, PtrSer
return Status::fromStatusT(BAD_VALUE);
}
// Convert Sink name to port pointer
sp<AudioPort> sink = ctx->findPortByTagName(sinkAttr);
sp<PolicyAudioPort> sink = ctx->findPortByTagName(sinkAttr);
if (sink == NULL) {
ALOGE("%s: no sink found with name=%s", __func__, sinkAttr.c_str());
return Status::fromStatusT(BAD_VALUE);
@ -568,13 +574,13 @@ Return<RouteTraits::Element> RouteTraits::deserialize(const xmlNode *cur, PtrSer
return Status::fromStatusT(BAD_VALUE);
}
// Tokenize and Convert Sources name to port pointer
AudioPortVector sources;
PolicyAudioPortVector sources;
std::unique_ptr<char[]> sourcesLiteral{strndup(
sourcesAttr.c_str(), strlen(sourcesAttr.c_str()))};
char *devTag = strtok(sourcesLiteral.get(), ",");
while (devTag != NULL) {
if (strlen(devTag) != 0) {
sp<AudioPort> source = ctx->findPortByTagName(devTag);
sp<PolicyAudioPort> source = ctx->findPortByTagName(devTag);
if (source == NULL) {
ALOGE("%s: no source found with name=%s", __func__, devTag);
return Status::fromStatusT(BAD_VALUE);
@ -586,7 +592,7 @@ Return<RouteTraits::Element> RouteTraits::deserialize(const xmlNode *cur, PtrSer
sink->addRoute(route);
for (size_t i = 0; i < sources.size(); i++) {
sp<AudioPort> source = sources.itemAt(i);
sp<PolicyAudioPort> source = sources.itemAt(i);
source->addRoute(route);
}
route->setSources(sources);

@ -16,7 +16,7 @@
#pragma once
#include <AudioPort.h>
#include <PolicyAudioPort.h>
#include <AudioPatch.h>
#include <IOProfile.h>
#include <DeviceDescriptor.h>

@ -259,7 +259,7 @@ status_t ParameterManagerWrapper::setDeviceConnectionState(const sp<DeviceDescri
std::string criterionName = audio_is_output_device(devDesc->type()) ?
gOutputDeviceAddressCriterionName : gInputDeviceAddressCriterionName;
ALOGV("%s: device with address %s %s", __FUNCTION__, devDesc->address().string(),
ALOGV("%s: device with address %s %s", __FUNCTION__, devDesc->address().c_str(),
state != AUDIO_POLICY_DEVICE_STATE_AVAILABLE? "disconnected" : "connected");
ISelectionCriterionInterface *criterion =
getElement<ISelectionCriterionInterface>(criterionName, mPolicyCriteria);
@ -271,7 +271,7 @@ status_t ParameterManagerWrapper::setDeviceConnectionState(const sp<DeviceDescri
auto criterionType = criterion->getCriterionType();
int deviceAddressId;
if (not criterionType->getNumericalValue(devDesc->address().string(), deviceAddressId)) {
if (not criterionType->getNumericalValue(devDesc->address().c_str(), deviceAddressId)) {
ALOGW("%s: unknown device address reported (%s)", __FUNCTION__, devDesc->address().c_str());
return BAD_TYPE;
}

@ -16,7 +16,7 @@
#pragma once
#include <AudioPort.h>
#include <PolicyAudioPort.h>
#include <HwModule.h>
#include <DeviceDescriptor.h>
#include <system/audio.h>

@ -27,7 +27,7 @@
#include "Engine.h"
#include <android-base/macros.h>
#include <AudioPolicyManagerObserver.h>
#include <AudioPort.h>
#include <PolicyAudioPort.h>
#include <IOProfile.h>
#include <AudioIODescriptorInterface.h>
#include <policy.h>
@ -212,7 +212,7 @@ DeviceVector Engine::getDevicesForStrategyInt(legacy_strategy strategy,
String8(""), AUDIO_FORMAT_DEFAULT) == nullptr) ||
((availPrimaryInputDevices.getDevice(
txDevice, String8(""), AUDIO_FORMAT_DEFAULT) != nullptr) &&
(primaryOutput->getAudioPort()->getModuleVersionMajor() < 3))) {
(primaryOutput->getPolicyAudioPort()->getModuleVersionMajor() < 3))) {
availableOutputDevices = availPrimaryOutputDevices;
}
}

@ -112,7 +112,7 @@ status_t AudioPolicyManager::setDeviceConnectionState(audio_devices_t device,
void AudioPolicyManager::broadcastDeviceConnectionState(const sp<DeviceDescriptor> &device,
audio_policy_dev_state_t state)
{
AudioParameter param(device->address());
AudioParameter param(String8(device->address().c_str()));
const String8 key(state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE ?
AudioParameter::keyDeviceConnect : AudioParameter::keyDeviceDisconnect);
param.addInt(key, device->type());
@ -1109,7 +1109,7 @@ status_t AudioPolicyManager::getOutputForAttr(const audio_attributes_t *attr,
.channel_mask = config->channel_mask,
.format = config->format,
};
*portId = AudioPort::getNextUniqueId();
*portId = PolicyAudioPort::getNextUniqueId();
sp<TrackClientDescriptor> clientDesc =
new TrackClientDescriptor(*portId, uid, session, resultAttr, clientConfig,
@ -1360,19 +1360,19 @@ status_t AudioPolicyManager::getBestMsdAudioProfileFor(const sp<DeviceDescriptor
// Each IOProfile represents a MixPort from audio_policy_configuration.xml
for (const auto &inProfile : inputProfiles) {
if (hwAvSync == ((inProfile->getFlags() & AUDIO_INPUT_FLAG_HW_AV_SYNC) != 0)) {
msdProfiles.appendProfiles(inProfile->getAudioProfiles());
appendAudioProfiles(msdProfiles, inProfile->getAudioProfiles());
}
}
AudioProfileVector deviceProfiles;
for (const auto &outProfile : outputProfiles) {
if (hwAvSync == ((outProfile->getFlags() & AUDIO_OUTPUT_FLAG_HW_AV_SYNC) != 0)) {
deviceProfiles.appendProfiles(outProfile->getAudioProfiles());
appendAudioProfiles(deviceProfiles, outProfile->getAudioProfiles());
}
}
struct audio_config_base bestSinkConfig;
status_t result = msdProfiles.findBestMatchingOutputConfig(deviceProfiles,
status_t result = findBestMatchingOutputConfig(msdProfiles, deviceProfiles,
compressedFormatsOrder, surroundChannelMasksOrder, true /*preferHigherSamplingRates*/,
&bestSinkConfig);
bestSinkConfig);
if (result != NO_ERROR) {
ALOGD("%s() no matching profiles found for device: %s, hwAvSync: %d",
__func__, outputDevice->toString().c_str(), hwAvSync);
@ -1563,8 +1563,8 @@ audio_io_handle_t AudioPolicyManager::selectOutput(const SortedVector<audio_io_h
// format match
if (format != AUDIO_FORMAT_INVALID) {
currentMatchCriteria[6] =
AudioPort::kFormatDistanceMax -
AudioPort::formatDistance(format, outputDesc->getFormat());
PolicyAudioPort::kFormatDistanceMax -
PolicyAudioPort::formatDistance(format, outputDesc->getFormat());
}
// primary output match
@ -2088,7 +2088,7 @@ exit:
isSoundTrigger = attributes.source == AUDIO_SOURCE_HOTWORD &&
mSoundTriggerSessions.indexOfKey(session) >= 0;
*portId = AudioPort::getNextUniqueId();
*portId = PolicyAudioPort::getNextUniqueId();
clientDesc = new RecordClientDescriptor(*portId, riid, uid, session, attributes, *config,
requestedDeviceId, attributes.source, flags,
@ -2431,7 +2431,8 @@ void AudioPolicyManager::checkCloseInputs() {
const sp<AudioInputDescriptor> input = mInputs.valueAt(i);
if (input->clientsList().size() == 0
|| !mAvailableInputDevices.containsAtLeastOne(input->supportedDevices())
|| (input->getAudioPort()->getFlags() & AUDIO_INPUT_FLAG_MMAP_NOIRQ) != 0) {
|| (input->getPolicyAudioPort()->getFlags()
& AUDIO_INPUT_FLAG_MMAP_NOIRQ) != 0) {
inputsToClose.push_back(mInputs.keyAt(i));
} else {
bool close = false;
@ -3857,7 +3858,7 @@ status_t AudioPolicyManager::startAudioSource(const struct audio_port_config *so
return BAD_VALUE;
}
*portId = AudioPort::getNextUniqueId();
*portId = PolicyAudioPort::getNextUniqueId();
struct audio_patch dummyPatch = {};
sp<AudioPatch> patchDesc = new AudioPatch(&dummyPatch, uid);
@ -4137,7 +4138,7 @@ status_t AudioPolicyManager::setSurroundFormatEnabled(audio_format_t audioFormat
AUDIO_DEVICE_OUT_HDMI);
for (size_t i = 0; i < hdmiOutputDevices.size(); i++) {
// Simulate reconnection to update enabled surround sound formats.
String8 address = hdmiOutputDevices[i]->address();
String8 address = String8(hdmiOutputDevices[i]->address().c_str());
std::string name = hdmiOutputDevices[i]->getName();
status_t status = setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_HDMI,
AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
@ -4159,7 +4160,7 @@ status_t AudioPolicyManager::setSurroundFormatEnabled(audio_format_t audioFormat
AUDIO_DEVICE_IN_HDMI);
for (size_t i = 0; i < hdmiInputDevices.size(); i++) {
// Simulate reconnection to update enabled surround sound formats.
String8 address = hdmiInputDevices[i]->address();
String8 address = String8(hdmiInputDevices[i]->address().c_str());
std::string name = hdmiInputDevices[i]->getName();
status_t status = setDeviceConnectionStateInt(AUDIO_DEVICE_IN_HDMI,
AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
@ -4471,7 +4472,7 @@ status_t AudioPolicyManager::initialize() {
// give a valid ID to an attached device once confirmed it is reachable
if (!device->isAttached()) {
device->attach(hwModule);
device->importAudioPort(inProfile, true);
device->importAudioPortAndPickAudioProfile(inProfile, true);
}
}
inputDesc->close();
@ -4502,11 +4503,11 @@ status_t AudioPolicyManager::initialize() {
}
// If microphones address is empty, set it according to device type
for (size_t i = 0; i < mAvailableInputDevices.size(); i++) {
if (mAvailableInputDevices[i]->address().isEmpty()) {
if (mAvailableInputDevices[i]->address().empty()) {
if (mAvailableInputDevices[i]->type() == AUDIO_DEVICE_IN_BUILTIN_MIC) {
mAvailableInputDevices[i]->setAddress(String8(AUDIO_BOTTOM_MICROPHONE_ADDRESS));
mAvailableInputDevices[i]->setAddress(AUDIO_BOTTOM_MICROPHONE_ADDRESS);
} else if (mAvailableInputDevices[i]->type() == AUDIO_DEVICE_IN_BACK_MIC) {
mAvailableInputDevices[i]->setAddress(String8(AUDIO_BACK_MICROPHONE_ADDRESS));
mAvailableInputDevices[i]->setAddress(AUDIO_BACK_MICROPHONE_ADDRESS);
}
}
}
@ -4575,7 +4576,7 @@ status_t AudioPolicyManager::checkOutputsForDevice(const sp<DeviceDescriptor>& d
SortedVector<audio_io_handle_t>& outputs)
{
audio_devices_t deviceType = device->type();
const String8 &address = device->address();
const String8 &address = String8(device->address().c_str());
sp<SwAudioOutputDescriptor> desc;
if (audio_device_is_digital(deviceType)) {
@ -4627,7 +4628,7 @@ status_t AudioPolicyManager::checkOutputsForDevice(const sp<DeviceDescriptor>& d
// matching profile: save the sample rates, format and channel masks supported
// by the profile in our device descriptor
if (audio_device_is_digital(deviceType)) {
device->importAudioPort(profile);
device->importAudioPortAndPickAudioProfile(profile);
}
break;
}
@ -4729,7 +4730,7 @@ status_t AudioPolicyManager::checkOutputsForDevice(const sp<DeviceDescriptor>& d
outputs.add(output);
// Load digital format info only for digital devices
if (audio_device_is_digital(deviceType)) {
device->importAudioPort(profile);
device->importAudioPortAndPickAudioProfile(profile);
}
if (device_distinguishes_on_address(deviceType)) {
@ -4823,7 +4824,7 @@ status_t AudioPolicyManager::checkInputsForDevice(const sp<DeviceDescriptor>& de
desc = mInputs.valueAt(input_index);
if (desc->mProfile == profile) {
if (audio_device_is_digital(device->type())) {
device->importAudioPort(profile);
device->importAudioPortAndPickAudioProfile(profile);
}
break;
}
@ -4847,7 +4848,7 @@ status_t AudioPolicyManager::checkInputsForDevice(const sp<DeviceDescriptor>& de
&input);
if (status == NO_ERROR) {
const String8& address = device->address();
const String8& address = String8(device->address().c_str());
if (!address.isEmpty()) {
char *param = audio_device_address_to_parameter(device->type(), address);
mpClientInterface->setParameters(input, String8(param));
@ -4872,7 +4873,7 @@ status_t AudioPolicyManager::checkInputsForDevice(const sp<DeviceDescriptor>& de
profile_index--;
} else {
if (audio_device_is_digital(device->type())) {
device->importAudioPort(profile);
device->importAudioPortAndPickAudioProfile(profile);
}
ALOGV("checkInputsForDevice(): adding input %d", input);
}
@ -6168,7 +6169,7 @@ void AudioPolicyManager::updateAudioProfiles(const sp<DeviceDescriptor>& devDesc
|| isDeviceOfModule(devDesc, AUDIO_HARDWARE_MODULE_ID_MSD)) {
modifySurroundFormats(devDesc, &formats);
}
profiles.setFormats(formats);
addProfilesForFormats(profiles, formats);
}
for (audio_format_t format : profiles.getSupportedFormats()) {
@ -6204,7 +6205,8 @@ void AudioPolicyManager::updateAudioProfiles(const sp<DeviceDescriptor>& devDesc
}
}
}
profiles.addProfileFromHal(new AudioProfile(format, channelMasks, samplingRates));
addDynamicAudioProfileAndSort(
profiles, new AudioProfile(format, channelMasks, samplingRates));
}
}

@ -31,14 +31,14 @@
#include <utils/SortedVector.h>
#include <media/AudioParameter.h>
#include <media/AudioPolicy.h>
#include <media/AudioProfile.h>
#include <media/PatchBuilder.h>
#include "AudioPolicyInterface.h"
#include <AudioPolicyManagerObserver.h>
#include <AudioPolicyConfig.h>
#include <AudioPort.h>
#include <PolicyAudioPort.h>
#include <AudioPatch.h>
#include <AudioProfileVector.h>
#include <DeviceDescriptor.h>
#include <IOProfile.h>
#include <HwModule.h>
@ -646,7 +646,8 @@ protected:
}
String8 getFirstDeviceAddress(const DeviceVector &devices) const
{
return (devices.size() > 0) ? devices.itemAt(0)->address() : String8("");
return (devices.size() > 0) ?
String8(devices.itemAt(0)->address().c_str()) : String8("");
}
uint32_t updateCallRouting(const DeviceVector &rxDevices, uint32_t delayMs = 0);

Loading…
Cancel
Save