audiopolicy: Add support for hybrid mode on A2DP

Add support in AudioPolicyManager to select a module,
device or output based on device type and codec.
Implement hybrid mode with A2DP which enables runtime
switching between HALs for A2DP based on offload support
for specific A2DP codecs.
Optimize A2DP active device change and device config
change in AudioPolicyManager.

Bug: 111812273
Test: make
Change-Id: I246d71dd08bacbca6ed9b0012e7d7698bd8a0953
gugelfrei
Aniket Kumar Lata 6 years ago committed by Eric Laurent
parent fa66483acb
commit 4e4647077f

@ -784,7 +784,8 @@ const sp<IAudioPolicyService> AudioSystem::get_audio_policy_service()
status_t AudioSystem::setDeviceConnectionState(audio_devices_t device,
audio_policy_dev_state_t state,
const char *device_address,
const char *device_name)
const char *device_name,
audio_format_t encodedFormat)
{
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
const char *address = "";
@ -798,7 +799,7 @@ status_t AudioSystem::setDeviceConnectionState(audio_devices_t device,
if (device_name != NULL) {
name = device_name;
}
return aps->setDeviceConnectionState(device, state, address, name);
return aps->setDeviceConnectionState(device, state, address, name, encodedFormat);
}
audio_policy_dev_state_t AudioSystem::getDeviceConnectionState(audio_devices_t device,
@ -812,7 +813,8 @@ audio_policy_dev_state_t AudioSystem::getDeviceConnectionState(audio_devices_t d
status_t AudioSystem::handleDeviceConfigChange(audio_devices_t device,
const char *device_address,
const char *device_name)
const char *device_name,
audio_format_t encodedFormat)
{
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
const char *address = "";
@ -826,7 +828,7 @@ status_t AudioSystem::handleDeviceConfigChange(audio_devices_t device,
if (device_name != NULL) {
name = device_name;
}
return aps->handleDeviceConfigChange(device, address, name);
return aps->handleDeviceConfigChange(device, address, name, encodedFormat);
}
status_t AudioSystem::setPhoneState(audio_mode_t state)

@ -108,7 +108,8 @@ public:
audio_devices_t device,
audio_policy_dev_state_t state,
const char *device_address,
const char *device_name)
const char *device_name,
audio_format_t encodedFormat)
{
Parcel data, reply;
data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
@ -116,6 +117,7 @@ public:
data.writeInt32(static_cast <uint32_t>(state));
data.writeCString(device_address);
data.writeCString(device_name);
data.writeInt32(static_cast <uint32_t>(encodedFormat));
remote()->transact(SET_DEVICE_CONNECTION_STATE, data, &reply);
return static_cast <status_t> (reply.readInt32());
}
@ -134,13 +136,15 @@ public:
virtual status_t handleDeviceConfigChange(audio_devices_t device,
const char *device_address,
const char *device_name)
const char *device_name,
audio_format_t encodedFormat)
{
Parcel data, reply;
data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
data.writeInt32(static_cast <uint32_t>(device));
data.writeCString(device_address);
data.writeCString(device_name);
data.writeInt32(static_cast <uint32_t>(encodedFormat));
remote()->transact(HANDLE_DEVICE_CONFIG_CHANGE, data, &reply);
return static_cast <status_t> (reply.readInt32());
}
@ -1121,6 +1125,7 @@ status_t BnAudioPolicyService::onTransact(
static_cast <audio_policy_dev_state_t>(data.readInt32());
const char *device_address = data.readCString();
const char *device_name = data.readCString();
audio_format_t codecFormat = static_cast <audio_format_t>(data.readInt32());
if (device_address == nullptr || device_name == nullptr) {
ALOGE("Bad Binder transaction: SET_DEVICE_CONNECTION_STATE for device %u", device);
reply->writeInt32(static_cast<int32_t> (BAD_VALUE));
@ -1128,7 +1133,8 @@ status_t BnAudioPolicyService::onTransact(
reply->writeInt32(static_cast<uint32_t> (setDeviceConnectionState(device,
state,
device_address,
device_name)));
device_name,
codecFormat)));
}
return NO_ERROR;
} break;
@ -1154,13 +1160,16 @@ status_t BnAudioPolicyService::onTransact(
static_cast <audio_devices_t>(data.readInt32());
const char *device_address = data.readCString();
const char *device_name = data.readCString();
audio_format_t codecFormat =
static_cast <audio_format_t>(data.readInt32());
if (device_address == nullptr || device_name == nullptr) {
ALOGE("Bad Binder transaction: HANDLE_DEVICE_CONFIG_CHANGE for device %u", device);
reply->writeInt32(static_cast<int32_t> (BAD_VALUE));
} else {
reply->writeInt32(static_cast<uint32_t> (handleDeviceConfigChange(device,
device_address,
device_name)));
device_name,
codecFormat)));
}
return NO_ERROR;
} break;

@ -209,12 +209,14 @@ public:
// IAudioPolicyService interface (see AudioPolicyInterface for method descriptions)
//
static status_t setDeviceConnectionState(audio_devices_t device, audio_policy_dev_state_t state,
const char *device_address, const char *device_name);
const char *device_address, const char *device_name,
audio_format_t encodedFormat);
static audio_policy_dev_state_t getDeviceConnectionState(audio_devices_t device,
const char *device_address);
static status_t handleDeviceConfigChange(audio_devices_t device,
const char *device_address,
const char *device_name);
const char *device_name,
audio_format_t encodedFormat);
static status_t setPhoneState(audio_mode_t state);
static status_t setForceUse(audio_policy_force_use_t usage, audio_policy_forced_cfg_t config);
static audio_policy_forced_cfg_t getForceUse(audio_policy_force_use_t usage);

@ -44,12 +44,14 @@ public:
virtual status_t setDeviceConnectionState(audio_devices_t device,
audio_policy_dev_state_t state,
const char *device_address,
const char *device_name) = 0;
const char *device_name,
audio_format_t encodedFormat) = 0;
virtual audio_policy_dev_state_t getDeviceConnectionState(audio_devices_t device,
const char *device_address) = 0;
virtual status_t handleDeviceConfigChange(audio_devices_t device,
const char *device_address,
const char *device_name) = 0;
const char *device_name,
audio_format_t encodedFormat) = 0;
virtual status_t setPhoneState(audio_mode_t state) = 0;
virtual status_t setForceUse(audio_policy_force_use_t usage,
audio_policy_forced_cfg_t config) = 0;

@ -75,14 +75,16 @@ public:
virtual status_t setDeviceConnectionState(audio_devices_t device,
audio_policy_dev_state_t state,
const char *device_address,
const char *device_name) = 0;
const char *device_name,
audio_format_t encodedFormat) = 0;
// retrieve a device connection status
virtual audio_policy_dev_state_t getDeviceConnectionState(audio_devices_t device,
const char *device_address) = 0;
// indicate a change in device configuration
virtual status_t handleDeviceConfigChange(audio_devices_t device,
const char *device_address,
const char *device_name) = 0;
const char *device_name,
audio_format_t encodedFormat) = 0;
// indicate a change in phone state. Valid phones states are defined by audio_mode_t
virtual void setPhoneState(audio_mode_t state) = 0;
// force using a specific device category for the specified usage

@ -75,6 +75,21 @@ static inline bool device_distinguishes_on_address(audio_devices_t device)
((device & APM_AUDIO_DEVICE_OUT_MATCH_ADDRESS_ALL) != 0));
}
/**
* Check whether audio device has encoding capability.
*
* @param[in] device to consider
*
* @return true if device has encoding capability, false otherwise..
*/
static inline bool device_has_encoding_capability(audio_devices_t device)
{
if (device & AUDIO_DEVICE_OUT_ALL_A2DP) {
return true;
}
return false;
}
/**
* Returns the priority of a given audio source for capture. The priority is used when more than one
* capture session is active on a given input stream to determine which session drives routing and

@ -154,6 +154,7 @@ public:
void setDevices(const DeviceVector &devices) { mDevices = devices; }
bool sharesHwModuleWith(const sp<SwAudioOutputDescriptor>& outputDesc);
virtual DeviceVector supportedDevices() const;
virtual bool deviceSupportsEncodedFormats(audio_devices_t device);
virtual uint32_t latency();
virtual bool isDuplicated() const { return (mOutput1 != NULL && mOutput2 != NULL); }
virtual bool isFixedVolume(audio_devices_t device);

@ -44,8 +44,18 @@ public:
const FormatVector& encodedFormats() const { return mEncodedFormats; }
audio_format_t getEncodedFormat() { return mCurrentEncodedFormat; }
void setEncodedFormat(audio_format_t format) {
mCurrentEncodedFormat = format;
}
bool equals(const sp<DeviceDescriptor>& other) const;
bool hasCurrentEncodedFormat() const;
bool supportsFormat(audio_format_t format);
// AudioPortConfig
virtual sp<AudioPort> getAudioPort() const { return (AudioPort*) this; }
virtual void toAudioPortConfig(struct audio_port_config *dstConfig,
@ -69,6 +79,7 @@ private:
audio_devices_t mDeviceType;
FormatVector mEncodedFormats;
audio_port_handle_t mId = AUDIO_PORT_HANDLE_NONE;
audio_format_t mCurrentEncodedFormat;
};
class DeviceVector : public SortedVector<sp<DeviceDescriptor> >
@ -88,9 +99,10 @@ public:
audio_devices_t types() const { return mDeviceTypes; }
// If 'address' is empty, a device with a non-empty address may be returned
// if there is no device with the specified 'type' and empty address.
sp<DeviceDescriptor> getDevice(audio_devices_t type, const String8 &address = {}) const;
// If 'address' is empty and 'codec' is AUDIO_FORMAT_DEFAULT, a device with a non-empty
// address may be returned if there is no device with the specified 'type' and empty address.
sp<DeviceDescriptor> getDevice(audio_devices_t type, const String8 &address,
audio_format_t codec) const;
DeviceVector getDevicesFromTypeMask(audio_devices_t types) const;
/**

@ -130,9 +130,11 @@ class HwModuleCollection : public Vector<sp<HwModule> >
public:
sp<HwModule> getModuleFromName(const char *name) const;
sp<HwModule> getModuleForDeviceTypes(audio_devices_t device) const;
sp<HwModule> getModuleForDeviceTypes(audio_devices_t device,
audio_format_t encodedFormat) const;
sp<HwModule> getModuleForDevice(const sp<DeviceDescriptor> &device) const;
sp<HwModule> getModuleForDevice(const sp<DeviceDescriptor> &device,
audio_format_t encodedFormat) const;
DeviceVector getAvailableDevicesFromModuleName(const char *name,
const DeviceVector &availableDevices) const;
@ -149,6 +151,7 @@ public:
* @param type of the device requested
* @param address of the device requested
* @param name of the device that requested
* @param encodedFormat if not AUDIO_FORMAT_DEFAULT, must match one supported format
* @param matchAddress true if a strong match is required
* @param allowToCreate true if allowed to create dynamic device (e.g. hdmi, usb...)
* @return device descriptor associated to the type (and address if matchAddress is true)
@ -156,6 +159,7 @@ public:
sp<DeviceDescriptor> getDeviceDescriptor(const audio_devices_t type,
const char *address,
const char *name,
audio_format_t encodedFormat,
bool allowToCreate = false,
bool matchAddress = true) const;
@ -171,7 +175,8 @@ public:
*/
sp<DeviceDescriptor> createDevice(const audio_devices_t type,
const char *address,
const char *name) const;
const char *name,
const audio_format_t encodedFormat) const;
/**
* @brief cleanUpForDevice: loop on all profiles of all modules to remove device from

@ -94,7 +94,10 @@ public:
bool supportsDeviceTypes(audio_devices_t device) const
{
if (audio_is_output_devices(device)) {
return mSupportedDevices.types() & device;
if (deviceSupportsEncodedFormats(device)) {
return mSupportedDevices.types() & device;
}
return false;
}
return mSupportedDevices.types() & (device & ~AUDIO_DEVICE_BIT_IN);
}
@ -116,6 +119,16 @@ public:
return mSupportedDevices.contains(device);
}
bool deviceSupportsEncodedFormats(audio_devices_t device) const
{
DeviceVector deviceList =
mSupportedDevices.getDevicesFromTypeMask(device);
if (!deviceList.empty()) {
return deviceList.itemAt(0)->hasCurrentEncodedFormat();
}
return false;
}
void clearSupportedDevices() { mSupportedDevices.clear(); }
void addSupportedDevice(const sp<DeviceDescriptor> &device)
{

@ -364,6 +364,16 @@ DeviceVector SwAudioOutputDescriptor::filterSupportedDevices(const DeviceVector
return filteredDevices.filter(devices);
}
bool SwAudioOutputDescriptor::deviceSupportsEncodedFormats(audio_devices_t device)
{
if (isDuplicated()) {
return (mOutput1->deviceSupportsEncodedFormats(device)
|| mOutput2->deviceSupportsEncodedFormats(device));
} else {
return mProfile->deviceSupportsEncodedFormats(device);
}
}
uint32_t SwAudioOutputDescriptor::latency()
{
if (isDuplicated()) {
@ -687,7 +697,9 @@ audio_io_handle_t SwAudioOutputCollection::getA2dpOutput() const
for (size_t i = 0; i < size(); i++) {
sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
if (!outputDesc->isDuplicated() &&
outputDesc->devices().types() & AUDIO_DEVICE_OUT_ALL_A2DP) {
outputDesc->devices().types() & AUDIO_DEVICE_OUT_ALL_A2DP &&
outputDesc->deviceSupportsEncodedFormats(
AUDIO_DEVICE_OUT_BLUETOOTH_A2DP)) {
return this->keyAt(i);
}
}

@ -296,7 +296,8 @@ sp<DeviceDescriptor> AudioPolicyMixCollection::getDeviceAndMixForInputSource(
// assuming PolicyMix only for remote submix for input
// so mix->mDeviceType can only be AUDIO_DEVICE_OUT_REMOTE_SUBMIX
audio_devices_t device = AUDIO_DEVICE_IN_REMOTE_SUBMIX;
auto mixDevice = availDevices.getDevice(device, mix->mDeviceAddress);
auto mixDevice =
availDevices.getDevice(device, mix->mDeviceAddress, AUDIO_FORMAT_DEFAULT);
if (mixDevice != nullptr) {
if (policyMix != NULL) {
*policyMix = mix;

@ -18,6 +18,7 @@
//#define LOG_NDEBUG 0
#include <audio_utils/string.h>
#include <set>
#include "DeviceDescriptor.h"
#include "TypeConverter.h"
#include "AudioGain.h"
@ -37,6 +38,7 @@ DeviceDescriptor::DeviceDescriptor(audio_devices_t type, const FormatVector &enc
AUDIO_PORT_ROLE_SOURCE),
mTagName(tagName), mDeviceType(type), mEncodedFormats(encodedFormats)
{
mCurrentEncodedFormat = AUDIO_FORMAT_DEFAULT;
if (type == AUDIO_DEVICE_IN_REMOTE_SUBMIX || type == AUDIO_DEVICE_OUT_REMOTE_SUBMIX ) {
mAddress = String8("0");
}
@ -45,6 +47,12 @@ DeviceDescriptor::DeviceDescriptor(audio_devices_t type, const FormatVector &enc
mEncodedFormats.add(AUDIO_FORMAT_AC3);
mEncodedFormats.add(AUDIO_FORMAT_IEC61937);
}
// For backward compatibility always indicate support for SBC and AAC if no
// supported format is listed in the configuration file
if ((type & AUDIO_DEVICE_OUT_ALL_A2DP) != 0 && mEncodedFormats.isEmpty()) {
mEncodedFormats.add(AUDIO_FORMAT_SBC);
mEncodedFormats.add(AUDIO_FORMAT_AAC);
}
}
audio_port_handle_t DeviceDescriptor::getId() const
@ -58,21 +66,49 @@ void DeviceDescriptor::attach(const sp<HwModule>& module)
mId = getNextUniqueId();
}
void DeviceDescriptor::detach()
{
void DeviceDescriptor::detach() {
mId = AUDIO_PORT_HANDLE_NONE;
AudioPort::detach();
}
template<typename T>
bool checkEqual(const T& f1, const T& f2)
{
std::set<typename T::value_type> s1(f1.begin(), f1.end());
std::set<typename T::value_type> s2(f2.begin(), f2.end());
return s1 == s2;
}
bool DeviceDescriptor::equals(const sp<DeviceDescriptor>& other) const
{
// Devices are considered equal if they:
// - are of the same type (a device type cannot be AUDIO_DEVICE_NONE)
// - have the same address
// - have the same encodingFormats (if device supports encoding)
if (other == 0) {
return false;
}
return (mDeviceType == other->mDeviceType) && (mAddress == other->mAddress);
return (mDeviceType == other->mDeviceType) && (mAddress == other->mAddress) &&
checkEqual(mEncodedFormats, other->mEncodedFormats);
}
bool DeviceDescriptor::hasCurrentEncodedFormat() const
{
if (!device_has_encoding_capability(type())) {
return true;
}
return (mCurrentEncodedFormat != AUDIO_FORMAT_DEFAULT);
}
bool DeviceDescriptor::supportsFormat(audio_format_t format)
{
for (const auto& devFormat : mEncodedFormats) {
if (devFormat == format) {
return true;
}
}
return false;
}
void DeviceVector::refreshTypes()
@ -167,12 +203,17 @@ audio_devices_t DeviceVector::getDeviceTypesFromHwModule(audio_module_handle_t m
return deviceTypes;
}
sp<DeviceDescriptor> DeviceVector::getDevice(audio_devices_t type, const String8& address) const
sp<DeviceDescriptor> DeviceVector::getDevice(audio_devices_t type, const String8& address,
audio_format_t format) const
{
sp<DeviceDescriptor> device;
for (size_t i = 0; i < size(); i++) {
if (itemAt(i)->type() == type) {
if (address == "" || itemAt(i)->address() == address) {
// Assign device if address is empty or matches and
// format is default or matches
if (((address == "" || itemAt(i)->address() == address) &&
format == AUDIO_FORMAT_DEFAULT) ||
itemAt(i)->supportsFormat(format)) {
device = itemAt(i);
if (itemAt(i)->address() == address) {
break;
@ -180,8 +221,8 @@ sp<DeviceDescriptor> DeviceVector::getDevice(audio_devices_t type, const String8
}
}
}
ALOGV("DeviceVector::%s() for type %08x address \"%s\" found %p",
__func__, type, address.string(), device.get());
ALOGV("DeviceVector::%s() for type %08x address \"%s\" found %p format %08x",
__func__, type, address.string(), device.get(), format);
return device;
}

@ -273,32 +273,34 @@ sp <HwModule> HwModuleCollection::getModuleFromName(const char *name) const
return nullptr;
}
sp <HwModule> HwModuleCollection::getModuleForDeviceTypes(audio_devices_t device) const
sp <HwModule> HwModuleCollection::getModuleForDeviceTypes(audio_devices_t type,
audio_format_t encodedFormat) const
{
for (const auto& module : *this) {
const auto& profiles = audio_is_output_device(device) ?
const auto& profiles = audio_is_output_device(type) ?
module->getOutputProfiles() : module->getInputProfiles();
for (const auto& profile : profiles) {
if (profile->supportsDeviceTypes(device)) {
return module;
if (profile->supportsDeviceTypes(type)) {
if (encodedFormat != AUDIO_FORMAT_DEFAULT) {
DeviceVector declaredDevices = module->getDeclaredDevices();
sp <DeviceDescriptor> deviceDesc =
declaredDevices.getDevice(type, String8(), encodedFormat);
if (deviceDesc) {
return module;
}
} else {
return module;
}
}
}
}
return nullptr;
}
sp <HwModule> HwModuleCollection::getModuleForDevice(const sp<DeviceDescriptor> &device) const
sp<HwModule> HwModuleCollection::getModuleForDevice(const sp<DeviceDescriptor> &device,
audio_format_t encodedFormat) const
{
for (const auto& module : *this) {
const auto& profiles = audio_is_output_device(device->type()) ?
module->getOutputProfiles() : module->getInputProfiles();
for (const auto& profile : profiles) {
if (profile->supportsDevice(device)) {
return module;
}
}
}
return nullptr;
return getModuleForDeviceTypes(device->type(), encodedFormat);
}
DeviceVector HwModuleCollection::getAvailableDevicesFromModuleName(
@ -314,6 +316,7 @@ DeviceVector HwModuleCollection::getAvailableDevicesFromModuleName(
sp<DeviceDescriptor> HwModuleCollection::getDeviceDescriptor(const audio_devices_t deviceType,
const char *address,
const char *name,
const audio_format_t encodedFormat,
bool allowToCreate,
bool matchAddress) const
{
@ -325,8 +328,14 @@ sp<DeviceDescriptor> HwModuleCollection::getDeviceDescriptor(const audio_devices
for (const auto& hwModule : *this) {
DeviceVector moduleDevices = hwModule->getAllDevices();
auto moduleDevice = moduleDevices.getDevice(deviceType, devAddress);
auto moduleDevice = moduleDevices.getDevice(deviceType, devAddress, encodedFormat);
if (moduleDevice) {
if (encodedFormat != AUDIO_FORMAT_DEFAULT) {
moduleDevice->setEncodedFormat(encodedFormat);
if (moduleDevice->address() != devAddress) {
moduleDevice->setAddress(devAddress);
}
}
if (allowToCreate) {
moduleDevice->attach(hwModule);
}
@ -338,14 +347,15 @@ sp<DeviceDescriptor> HwModuleCollection::getDeviceDescriptor(const audio_devices
name, deviceType, address);
return nullptr;
}
return createDevice(deviceType, address, name);
return createDevice(deviceType, address, name, encodedFormat);
}
sp<DeviceDescriptor> HwModuleCollection::createDevice(const audio_devices_t type,
const char *address,
const char *name) const
const char *name,
const audio_format_t encodedFormat) const
{
sp<HwModule> hwModule = getModuleForDeviceTypes(type);
sp<HwModule> hwModule = getModuleForDeviceTypes(type, encodedFormat);
if (hwModule == 0) {
ALOGE("%s: could not find HW module for device %04x address %s", __FUNCTION__, type,
address);
@ -354,8 +364,9 @@ sp<DeviceDescriptor> HwModuleCollection::createDevice(const audio_devices_t type
sp<DeviceDescriptor> device = new DeviceDescriptor(type, String8(name));
device->setName(String8(name));
device->setAddress(String8(address));
device->setEncodedFormat(encodedFormat);
// Add the device to the list of dynamic devices
// Add the device to the list of dynamic devices
hwModule->addDynamicDevice(device);
// Reciprocally attach the device to the module
device->attach(hwModule);
@ -370,7 +381,8 @@ sp<DeviceDescriptor> HwModuleCollection::createDevice(const audio_devices_t type
if (profile->supportsDevice(device, false /*matchAdress*/)) {
// @todo quid of audio profile? import the profile from device of the same type?
const auto &isoTypeDeviceForProfile = profile->getSupportedDevices().getDevice(type);
const auto &isoTypeDeviceForProfile =
profile->getSupportedDevices().getDevice(type, String8(), AUDIO_FORMAT_DEFAULT);
device->importAudioPort(isoTypeDeviceForProfile, true /* force */);
ALOGV("%s: adding device %s to profile %s", __FUNCTION__,

@ -140,6 +140,8 @@ struct DevicePortTraits : public AndroidCollectionTraits<DeviceDescriptor, Devic
static constexpr const char *roleSource = "source"; /**< <attribute role source value>. */
/** optional: device address, char string less than 64. */
static constexpr const char *address = "address";
/** optional: the list of encoded audio formats that are known to be supported. */
static constexpr const char *encodedFormats = "encodedFormats";
};
static Return<Element> deserialize(const xmlNode *cur, PtrSerializingCtx serializingContext);
@ -511,7 +513,13 @@ Return<DevicePortTraits::Element> DevicePortTraits::deserialize(const xmlNode *c
ALOGW("%s: bad type %08x", __func__, type);
return Status::fromStatusT(BAD_VALUE);
}
Element deviceDesc = new DeviceDescriptor(type, String8(name.c_str()));
std::string encodedFormatsLiteral = getXmlAttribute(cur, Attributes::encodedFormats);
ALOGV("%s: %s %s=%s", __func__, tag, Attributes::encodedFormats, encodedFormatsLiteral.c_str());
FormatVector encodedFormats;
if (!encodedFormatsLiteral.empty()) {
encodedFormats = formatsFromString(encodedFormatsLiteral, " ");
}
Element deviceDesc = new DeviceDescriptor(type, encodedFormats, String8(name.c_str()));
std::string address = getXmlAttribute(cur, Attributes::address);
if (!address.empty()) {

@ -506,7 +506,7 @@ audio_devices_t Engine::getDeviceForStrategyInt(routing_strategy strategy,
if (strategy != STRATEGY_SONIFICATION) {
// no sonification on remote submix (e.g. WFD)
if (availableOutputDevices.getDevice(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
String8("0")) != 0) {
String8("0"), AUDIO_FORMAT_DEFAULT) != 0) {
device2 = availableOutputDevices.types() & AUDIO_DEVICE_OUT_REMOTE_SUBMIX;
}
}

@ -81,9 +81,11 @@ static const std::vector<audio_channel_mask_t> surroundChannelMasksOrder = {{
status_t AudioPolicyManager::setDeviceConnectionState(audio_devices_t device,
audio_policy_dev_state_t state,
const char *device_address,
const char *device_name)
const char *device_name,
audio_format_t encodedFormat)
{
status_t status = setDeviceConnectionStateInt(device, state, device_address, device_name);
status_t status = setDeviceConnectionStateInt(device, state, device_address,
device_name, encodedFormat);
nextAudioPortGeneration();
return status;
}
@ -101,16 +103,17 @@ void AudioPolicyManager::broadcastDeviceConnectionState(const sp<DeviceDescripto
status_t AudioPolicyManager::setDeviceConnectionStateInt(audio_devices_t deviceType,
audio_policy_dev_state_t state,
const char *device_address,
const char *device_name)
const char *device_name,
audio_format_t encodedFormat)
{
ALOGV("setDeviceConnectionStateInt() device: 0x%X, state %d, address %s name %s",
deviceType, state, device_address, device_name);
ALOGV("setDeviceConnectionStateInt() device: 0x%X, state %d, address %s name %s format 0x%X",
deviceType, state, device_address, device_name, encodedFormat);
// connect/disconnect only 1 device at a time
if (!audio_is_output_device(deviceType) && !audio_is_input_device(deviceType)) return BAD_VALUE;
sp<DeviceDescriptor> device =
mHwModules.getDeviceDescriptor(deviceType, device_address, device_name,
mHwModules.getDeviceDescriptor(deviceType, device_address, device_name, encodedFormat,
state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE);
if (device == 0) {
return INVALID_OPERATION;
@ -133,10 +136,22 @@ status_t AudioPolicyManager::setDeviceConnectionStateInt(audio_devices_t deviceT
ALOGW("%s() device already connected: %s", __func__, device->toString().c_str());
return INVALID_OPERATION;
}
ALOGV("%s() connecting device %s", __func__, device->toString().c_str());
ALOGV("%s() connecting device %s format %x",
__func__, device->toString().c_str(), encodedFormat);
// register new device as available
if (mAvailableOutputDevices.add(device) < 0) {
index = mAvailableOutputDevices.add(device);
if (index >= 0) {
sp<HwModule> module = mHwModules.getModuleForDevice(device, encodedFormat);
if (module == 0) {
ALOGD("setDeviceConnectionState() could not find HW module for device %s",
device->toString().c_str());
mAvailableOutputDevices.remove(device);
return INVALID_OPERATION;
}
ALOGV("setDeviceConnectionState() module name=%s", module->getName());
mAvailableOutputDevices[index]->attach(module);
} else {
return NO_MEMORY;
}
@ -178,6 +193,9 @@ status_t AudioPolicyManager::setDeviceConnectionStateInt(audio_devices_t deviceT
checkOutputsForDevice(device, state, outputs);
// Reset active device codec
device->setEncodedFormat(AUDIO_FORMAT_DEFAULT);
// Propagate device availability to Engine
mEngine->setDeviceConnectionState(device, state);
} break;
@ -248,6 +266,13 @@ status_t AudioPolicyManager::setDeviceConnectionStateInt(audio_devices_t deviceT
ALOGW("%s() device already connected: %s", __func__, device->toString().c_str());
return INVALID_OPERATION;
}
sp<HwModule> module = mHwModules.getModuleForDevice(device, AUDIO_FORMAT_DEFAULT);
if (module == NULL) {
ALOGW("setDeviceConnectionState(): could not find HW module for device %s",
device->toString().c_str());
return INVALID_OPERATION;
}
// Before checking intputs, broadcast connect event to allow HAL to retrieve dynamic
// parameters on newly connected devices (instead of opening the inputs...)
broadcastDeviceConnectionState(device, state);
@ -318,7 +343,8 @@ audio_policy_dev_state_t AudioPolicyManager::getDeviceConnectionState(audio_devi
const char *device_address)
{
sp<DeviceDescriptor> devDesc =
mHwModules.getDeviceDescriptor(device, device_address, "", false /* allowToCreate */,
mHwModules.getDeviceDescriptor(device, device_address, "", AUDIO_FORMAT_DEFAULT,
false /* allowToCreate */,
(strlen(device_address) != 0)/*matchAddress*/);
if (devDesc == 0) {
@ -338,50 +364,61 @@ audio_policy_dev_state_t AudioPolicyManager::getDeviceConnectionState(audio_devi
return AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE;
}
return (deviceVector->getDevice(device, String8(device_address)) != 0) ?
return (deviceVector->getDevice(
device, String8(device_address), AUDIO_FORMAT_DEFAULT) != 0) ?
AUDIO_POLICY_DEVICE_STATE_AVAILABLE : AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE;
}
status_t AudioPolicyManager::handleDeviceConfigChange(audio_devices_t device,
const char *device_address,
const char *device_name)
const char *device_name,
audio_format_t encodedFormat)
{
status_t status;
String8 reply;
AudioParameter param;
int isReconfigA2dpSupported = 0;
ALOGV("handleDeviceConfigChange(() device: 0x%X, address %s name %s",
device, device_address, device_name);
ALOGV("handleDeviceConfigChange(() device: 0x%X, address %s name %s encodedFormat: 0x%X",
device, device_address, device_name, encodedFormat);
// connect/disconnect only 1 device at a time
if (!audio_is_output_device(device) && !audio_is_input_device(device)) return BAD_VALUE;
// Check if the device is currently connected
sp<DeviceDescriptor> devDesc =
mHwModules.getDeviceDescriptor(device, device_address, device_name);
if (devDesc == 0 || mAvailableOutputDevices.indexOf(devDesc) < 0) {
DeviceVector availableDevices = getAvailableOutputDevices();
DeviceVector deviceList = availableDevices.getDevicesFromTypeMask(device);
if (deviceList.empty()) {
// Nothing to do: device is not connected
return NO_ERROR;
}
sp<DeviceDescriptor> devDesc = deviceList.itemAt(0);
// For offloaded A2DP, Hw modules may have the capability to
// configure codecs. Check if any of the loaded hw modules
// supports this.
// If supported, send a set parameter to configure A2DP codecs
// and return. No need to toggle device state.
// configure codecs.
// Handle two specific cases by sending a set parameter to
// configure A2DP codecs. No need to toggle device state.
// Case 1: A2DP active device switches from primary to primary
// module
// Case 2: A2DP device config changes on primary module.
if (device & AUDIO_DEVICE_OUT_ALL_A2DP) {
reply = mpClientInterface->getParameters(
AUDIO_IO_HANDLE_NONE,
String8(AudioParameter::keyReconfigA2dpSupported));
AudioParameter repliedParameters(reply);
repliedParameters.getInt(
String8(AudioParameter::keyReconfigA2dpSupported), isReconfigA2dpSupported);
if (isReconfigA2dpSupported) {
const String8 key(AudioParameter::keyReconfigA2dp);
param.add(key, String8("true"));
mpClientInterface->setParameters(AUDIO_IO_HANDLE_NONE, param.toString());
return NO_ERROR;
sp<HwModule> module = mHwModules.getModuleForDeviceTypes(device, encodedFormat);
audio_module_handle_t primaryHandle = mPrimaryOutput->getModuleHandle();
if (availablePrimaryOutputDevices().contains(devDesc) &&
(module != 0 && module->getHandle() == primaryHandle)) {
reply = mpClientInterface->getParameters(
AUDIO_IO_HANDLE_NONE,
String8(AudioParameter::keyReconfigA2dpSupported));
AudioParameter repliedParameters(reply);
repliedParameters.getInt(
String8(AudioParameter::keyReconfigA2dpSupported), isReconfigA2dpSupported);
if (isReconfigA2dpSupported) {
const String8 key(AudioParameter::keyReconfigA2dp);
param.add(key, String8("true"));
mpClientInterface->setParameters(AUDIO_IO_HANDLE_NONE, param.toString());
devDesc->setEncodedFormat(encodedFormat);
return NO_ERROR;
}
}
}
@ -389,7 +426,8 @@ status_t AudioPolicyManager::handleDeviceConfigChange(audio_devices_t device,
// This will force reading again the device configuration
status = setDeviceConnectionState(device,
AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
device_address, device_name);
device_address, device_name,
devDesc->getEncodedFormat());
if (status != NO_ERROR) {
ALOGW("handleDeviceConfigChange() error disabling connection state: %d",
status);
@ -398,7 +436,7 @@ status_t AudioPolicyManager::handleDeviceConfigChange(audio_devices_t device,
status = setDeviceConnectionState(device,
AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
device_address, device_name);
device_address, device_name, encodedFormat);
if (status != NO_ERROR) {
ALOGW("handleDeviceConfigChange() error enabling connection state: %d",
status);
@ -464,15 +502,18 @@ sp<AudioPatch> AudioPolicyManager::createTelephonyPatch(
}
if (isRx) {
patchBuilder.addSink(device).
addSource(mAvailableInputDevices.getDevice(AUDIO_DEVICE_IN_TELEPHONY_RX));
addSource(mAvailableInputDevices.getDevice(
AUDIO_DEVICE_IN_TELEPHONY_RX, String8(), AUDIO_FORMAT_DEFAULT));
} else {
patchBuilder.addSource(device).
addSink(mAvailableOutputDevices.getDevice(AUDIO_DEVICE_OUT_TELEPHONY_TX));
addSink(mAvailableOutputDevices.getDevice(
AUDIO_DEVICE_OUT_TELEPHONY_TX, String8(), AUDIO_FORMAT_DEFAULT));
}
// @TODO: still ignoring the address, or not dealing platform with mutliple telephonydevices
const sp<DeviceDescriptor> outputDevice = isRx ?
device : mAvailableOutputDevices.getDevice(AUDIO_DEVICE_OUT_TELEPHONY_TX);
device : mAvailableOutputDevices.getDevice(
AUDIO_DEVICE_OUT_TELEPHONY_TX, String8(), AUDIO_FORMAT_DEFAULT);
SortedVector<audio_io_handle_t> outputs =
getOutputsForDevices(DeviceVector(outputDevice), mOutputs);
audio_io_handle_t output = selectOutput(outputs, AUDIO_OUTPUT_FLAG_NONE, AUDIO_FORMAT_INVALID);
@ -736,6 +777,10 @@ sp<IOProfile> AudioPolicyManager::getProfileForOutput(
if (!mAvailableOutputDevices.containsAtLeastOne(curProfile->getSupportedDevices())) {
continue;
}
// reject profiles if connected device does not support codec
if (!curProfile->deviceSupportsEncodedFormats(devices.types())) {
continue;
}
if (!directOnly) return curProfile;
// when searching for direct outputs, if several profiles are compatible, give priority
// to one with offload capability
@ -840,7 +885,8 @@ status_t AudioPolicyManager::getOutputForAttrInt(audio_attributes_t *resultAttr,
*output = desc->mIoHandle;
AudioMix *mix = desc->mPolicyMix;
sp<DeviceDescriptor> deviceDesc =
mAvailableOutputDevices.getDevice(mix->mDeviceType, mix->mDeviceAddress);
mAvailableOutputDevices.getDevice(
mix->mDeviceType, mix->mDeviceAddress, AUDIO_FORMAT_DEFAULT);
*selectedDeviceId = deviceDesc != 0 ? deviceDesc->getId() : AUDIO_PORT_HANDLE_NONE;
ALOGV("%s returns output %d", __func__, *output);
return NO_ERROR;
@ -883,7 +929,8 @@ status_t AudioPolicyManager::getOutputForAttrInt(audio_attributes_t *resultAttr,
*output = AUDIO_IO_HANDLE_NONE;
if (!msdDevices.isEmpty()) {
*output = getOutputForDevices(msdDevices, session, *stream, config, flags);
sp<DeviceDescriptor> deviceDesc = mAvailableOutputDevices.getDevice(deviceType);
sp<DeviceDescriptor> deviceDesc =
mAvailableOutputDevices.getDevice(deviceType, String8(), AUDIO_FORMAT_DEFAULT);
if (*output != AUDIO_IO_HANDLE_NONE && setMsdPatch(deviceDesc) == NO_ERROR) {
ALOGV("%s() Using MSD devices %s instead of device %s",
__func__, msdDevices.toString().c_str(), deviceDesc->toString().c_str());
@ -1158,7 +1205,7 @@ status_t AudioPolicyManager::getBestMsdAudioProfileFor(const sp<DeviceDescriptor
ALOGE("%s() unable to get MSD module", __func__);
return NO_INIT;
}
sp<HwModule> deviceModule = mHwModules.getModuleForDevice(outputDevice);
sp<HwModule> deviceModule = mHwModules.getModuleForDevice(outputDevice, AUDIO_FORMAT_DEFAULT);
if (deviceModule == nullptr) {
ALOGE("%s() unable to get module for %s", __func__, outputDevice->toString().c_str());
return NO_INIT;
@ -1456,7 +1503,8 @@ status_t AudioPolicyManager::startSource(const sp<SwAudioOutputDescriptor>& outp
} else {
newDeviceType = AUDIO_DEVICE_OUT_REMOTE_SUBMIX;
}
devices.add(mAvailableOutputDevices.getDevice(newDeviceType, String8(address)));
devices.add(mAvailableOutputDevices.getDevice(newDeviceType,
String8(address), AUDIO_FORMAT_DEFAULT));
}
// requiresMuteCheck is false when we can bypass mute strategy.
@ -1574,7 +1622,8 @@ status_t AudioPolicyManager::startSource(const sp<SwAudioOutputDescriptor>& outp
setDeviceConnectionStateInt(AUDIO_DEVICE_IN_REMOTE_SUBMIX,
AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
address,
"remote-submix");
"remote-submix",
AUDIO_FORMAT_DEFAULT);
}
return NO_ERROR;
@ -1620,7 +1669,7 @@ status_t AudioPolicyManager::stopSource(const sp<SwAudioOutputDescriptor>& outpu
setDeviceConnectionStateInt(AUDIO_DEVICE_IN_REMOTE_SUBMIX,
AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
outputDesc->mPolicyMix->mDeviceAddress,
"remote-submix");
"remote-submix", AUDIO_FORMAT_DEFAULT);
}
}
bool forceDeviceUpdate = false;
@ -1812,7 +1861,8 @@ status_t AudioPolicyManager::getInputForAttr(const audio_attributes_t *attr,
}
*inputType = API_INPUT_MIX_EXT_POLICY_REROUTE;
device = mAvailableInputDevices.getDevice(AUDIO_DEVICE_IN_REMOTE_SUBMIX,
String8(attr->tags + strlen("addr=")));
String8(attr->tags + strlen("addr=")),
AUDIO_FORMAT_DEFAULT);
} else {
if (explicitRoutingDevice != nullptr) {
device = explicitRoutingDevice;
@ -1831,7 +1881,8 @@ status_t AudioPolicyManager::getInputForAttr(const audio_attributes_t *attr,
// know about it and is therefore considered "legacy"
*inputType = API_INPUT_LEGACY;
} else if (audio_is_remote_submix_device(device->type())) {
device = mAvailableInputDevices.getDevice(AUDIO_DEVICE_IN_REMOTE_SUBMIX, String8("0"));
device = mAvailableInputDevices.getDevice(AUDIO_DEVICE_IN_REMOTE_SUBMIX, String8("0"),
AUDIO_FORMAT_DEFAULT);
*inputType = API_INPUT_MIX_CAPTURE;
} else if (device->type() == AUDIO_DEVICE_IN_TELEPHONY_RX) {
*inputType = API_INPUT_TELEPHONY_RX;
@ -2065,7 +2116,7 @@ status_t AudioPolicyManager::startInput(audio_port_handle_t portId)
if (address != "") {
setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
address, "remote-submix");
address, "remote-submix", AUDIO_FORMAT_DEFAULT);
}
}
}
@ -2116,7 +2167,7 @@ status_t AudioPolicyManager::stopInput(audio_port_handle_t portId)
if (address != "") {
setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
address, "remote-submix");
address, "remote-submix", AUDIO_FORMAT_DEFAULT);
}
}
resetInputDevice(input);
@ -2536,11 +2587,11 @@ status_t AudioPolicyManager::registerPolicyMixes(const Vector<AudioMix>& mixes)
if (mix.mMixType == MIX_TYPE_PLAYERS) {
setDeviceConnectionStateInt(AUDIO_DEVICE_IN_REMOTE_SUBMIX,
AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
address.string(), "remote-submix");
address.string(), "remote-submix", AUDIO_FORMAT_DEFAULT);
} else {
setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
address.string(), "remote-submix");
address.string(), "remote-submix", AUDIO_FORMAT_DEFAULT);
}
} else if ((mix.mRouteFlags & MIX_ROUTE_FLAG_RENDER) == MIX_ROUTE_FLAG_RENDER) {
String8 address = mix.mDeviceAddress;
@ -2614,13 +2665,13 @@ status_t AudioPolicyManager::unregisterPolicyMixes(Vector<AudioMix> mixes)
AUDIO_POLICY_DEVICE_STATE_AVAILABLE) {
setDeviceConnectionStateInt(AUDIO_DEVICE_IN_REMOTE_SUBMIX,
AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
address.string(), "remote-submix");
address.string(), "remote-submix", AUDIO_FORMAT_DEFAULT);
}
if (getDeviceConnectionState(AUDIO_DEVICE_OUT_REMOTE_SUBMIX, address.string()) ==
AUDIO_POLICY_DEVICE_STATE_AVAILABLE) {
setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
address.string(), "remote-submix");
address.string(), "remote-submix", AUDIO_FORMAT_DEFAULT);
}
rSubmixModule->removeOutputProfile(address);
rSubmixModule->removeInputProfile(address);
@ -2664,7 +2715,8 @@ status_t AudioPolicyManager::setUidDeviceAffinities(uid_t uid,
// reevaluate outputs for all given devices
for (size_t i = 0; i < devices.size(); i++) {
sp<DeviceDescriptor> devDesc = mHwModules.getDeviceDescriptor(
devices[i].mType, devices[i].mAddress, String8());
devices[i].mType, devices[i].mAddress, String8(),
AUDIO_FORMAT_DEFAULT);
SortedVector<audio_io_handle_t> outputs;
if (checkOutputsForDevice(devDesc, AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
outputs) != NO_ERROR) {
@ -2685,7 +2737,8 @@ status_t AudioPolicyManager::removeUidDeviceAffinities(uid_t uid) {
// reevaluate outputs for all found devices
for (size_t i = 0; i < devices.size(); i++) {
sp<DeviceDescriptor> devDesc = mHwModules.getDeviceDescriptor(
devices[i].mType, devices[i].mAddress, String8());
devices[i].mType, devices[i].mAddress, String8(),
AUDIO_FORMAT_DEFAULT);
SortedVector<audio_io_handle_t> outputs;
if (checkOutputsForDevice(devDesc, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
outputs) != NO_ERROR) {
@ -3442,7 +3495,8 @@ status_t AudioPolicyManager::startAudioSource(const struct audio_port_config *so
sp<DeviceDescriptor> srcDevice =
mAvailableInputDevices.getDevice(source->ext.device.type,
String8(source->ext.device.address));
String8(source->ext.device.address),
AUDIO_FORMAT_DEFAULT);
if (srcDevice == 0) {
ALOGW("%s source->ext.device.type %08x not found", __FUNCTION__, source->ext.device.type);
return BAD_VALUE;
@ -3726,14 +3780,16 @@ status_t AudioPolicyManager::setSurroundFormatEnabled(audio_format_t audioFormat
status_t status = setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_HDMI,
AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
address.c_str(),
name.c_str());
name.c_str(),
AUDIO_FORMAT_DEFAULT);
if (status != NO_ERROR) {
continue;
}
status = setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_HDMI,
AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
address.c_str(),
name.c_str());
name.c_str(),
AUDIO_FORMAT_DEFAULT);
profileUpdated |= (status == NO_ERROR);
}
// FIXME: Why doing this for input HDMI devices if we don't augment their reported formats?
@ -3746,14 +3802,16 @@ status_t AudioPolicyManager::setSurroundFormatEnabled(audio_format_t audioFormat
status_t status = setDeviceConnectionStateInt(AUDIO_DEVICE_IN_HDMI,
AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
address.c_str(),
name.c_str());
name.c_str(),
AUDIO_FORMAT_DEFAULT);
if (status != NO_ERROR) {
continue;
}
status = setDeviceConnectionStateInt(AUDIO_DEVICE_IN_HDMI,
AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
address.c_str(),
name.c_str());
name.c_str(),
AUDIO_FORMAT_DEFAULT);
profileUpdated |= (status == NO_ERROR);
}
@ -4178,7 +4236,8 @@ status_t AudioPolicyManager::checkOutputsForDevice(const sp<DeviceDescriptor>& d
// first list already open outputs that can be routed to this device
for (size_t i = 0; i < mOutputs.size(); i++) {
desc = mOutputs.valueAt(i);
if (!desc->isDuplicated() && desc->supportsDevice(device)) {
if (!desc->isDuplicated() && desc->supportsDevice(device)
&& desc->deviceSupportsEncodedFormats(deviceType)) {
ALOGV("checkOutputsForDevice(): adding opened output %d on device %s",
mOutputs.keyAt(i), device->toString().c_str());
outputs.add(mOutputs.keyAt(i));
@ -4341,7 +4400,8 @@ status_t AudioPolicyManager::checkOutputsForDevice(const sp<DeviceDescriptor>& d
desc = mOutputs.valueAt(i);
if (!desc->isDuplicated()) {
// exact match on device
if (device_distinguishes_on_address(deviceType) && desc->supportsDevice(device)) {
if (device_distinguishes_on_address(deviceType) && desc->supportsDevice(device)
&& desc->deviceSupportsEncodedFormats(deviceType)) {
outputs.add(mOutputs.keyAt(i));
} else if (!mAvailableOutputDevices.containsAtLeastOne(desc->supportedDevices())) {
ALOGV("checkOutputsForDevice(): disconnecting adding output %d",
@ -4628,7 +4688,8 @@ SortedVector<audio_io_handle_t> AudioPolicyManager::getOutputsForDevices(
ALOGVV("output %zu isDuplicated=%d device=%s",
i, openOutputs.valueAt(i)->isDuplicated(),
openOutputs.valueAt(i)->supportedDevices().toString().c_str());
if (openOutputs.valueAt(i)->supportsAllDevices(devices)) {
if (openOutputs.valueAt(i)->supportsAllDevices(devices)
&& openOutputs.valueAt(i)->deviceSupportsEncodedFormats(devices.types())) {
ALOGVV("%s() found output %d", __func__, openOutputs.keyAt(i));
outputs.add(openOutputs.keyAt(i));
}
@ -4684,9 +4745,10 @@ void AudioPolicyManager::checkOutputForStrategy(routing_strategy strategy)
maxLatency = desc->latency();
}
}
ALOGV("%s: strategy %d, moving from output %s to output %s", __func__, strategy,
(srcOutputs.isEmpty()? "none" : std::to_string(srcOutputs[0]).c_str()),
(dstOutputs.isEmpty()? "none" : std::to_string(dstOutputs[0]).c_str()));
ALOGV_IF(!(srcOutputs.isEmpty() || dstOutputs.isEmpty()),
"%s: strategy %d, moving from output %s to output %s", __func__, strategy,
std::to_string(srcOutputs[0]).c_str(),
std::to_string(dstOutputs[0]).c_str());
// mute strategy while moving tracks from one output to another
for (audio_io_handle_t srcOut : srcOutputs) {
sp<SwAudioOutputDescriptor> desc = mPreviousOutputs.valueFor(srcOut);
@ -5404,9 +5466,10 @@ sp<DeviceDescriptor> AudioPolicyManager::getDeviceForAttributes(const audio_attr
if (attributes.source == AUDIO_SOURCE_REMOTE_SUBMIX &&
strncmp(attributes.tags, "addr=", strlen("addr=")) == 0) {
return mAvailableInputDevices.getDevice(AUDIO_DEVICE_IN_REMOTE_SUBMIX,
String8(attributes.tags + strlen("addr=")));
String8(attributes.tags + strlen("addr=")),
AUDIO_FORMAT_DEFAULT);
}
return mAvailableInputDevices.getDevice(device);
return mAvailableInputDevices.getDevice(device, String8(), AUDIO_FORMAT_DEFAULT);
}
float AudioPolicyManager::computeVolume(audio_stream_type_t stream,

@ -97,12 +97,14 @@ public:
virtual status_t setDeviceConnectionState(audio_devices_t device,
audio_policy_dev_state_t state,
const char *device_address,
const char *device_name);
const char *device_name,
audio_format_t encodedFormat);
virtual audio_policy_dev_state_t getDeviceConnectionState(audio_devices_t device,
const char *device_address);
virtual status_t handleDeviceConfigChange(audio_devices_t device,
const char *device_address,
const char *device_name);
const char *device_name,
audio_format_t encodedFormat);
virtual void setPhoneState(audio_mode_t state);
virtual void setForceUse(audio_policy_force_use_t usage,
audio_policy_forced_cfg_t config);
@ -731,7 +733,8 @@ private:
status_t setDeviceConnectionStateInt(audio_devices_t deviceType,
audio_policy_dev_state_t state,
const char *device_address,
const char *device_name);
const char *device_name,
audio_format_t encodedFormat);
void updateMono(audio_io_handle_t output) {
AudioParameter param;
param.addInt(String8(AudioParameter::keyMonoOutput), (int)mMasterMono);

@ -32,7 +32,8 @@ namespace android {
status_t AudioPolicyService::setDeviceConnectionState(audio_devices_t device,
audio_policy_dev_state_t state,
const char *device_address,
const char *device_name)
const char *device_name,
audio_format_t encodedFormat)
{
if (mAudioPolicyManager == NULL) {
return NO_INIT;
@ -49,7 +50,7 @@ status_t AudioPolicyService::setDeviceConnectionState(audio_devices_t device,
Mutex::Autolock _l(mLock);
AutoCallerClear acc;
return mAudioPolicyManager->setDeviceConnectionState(device, state,
device_address, device_name);
device_address, device_name, encodedFormat);
}
audio_policy_dev_state_t AudioPolicyService::getDeviceConnectionState(
@ -66,7 +67,8 @@ audio_policy_dev_state_t AudioPolicyService::getDeviceConnectionState(
status_t AudioPolicyService::handleDeviceConfigChange(audio_devices_t device,
const char *device_address,
const char *device_name)
const char *device_name,
audio_format_t encodedFormat)
{
if (mAudioPolicyManager == NULL) {
return NO_INIT;
@ -79,7 +81,7 @@ status_t AudioPolicyService::handleDeviceConfigChange(audio_devices_t device,
Mutex::Autolock _l(mLock);
AutoCallerClear acc;
return mAudioPolicyManager->handleDeviceConfigChange(device, device_address,
device_name);
device_name, encodedFormat);
}
status_t AudioPolicyService::setPhoneState(audio_mode_t state)

@ -61,13 +61,15 @@ public:
virtual status_t setDeviceConnectionState(audio_devices_t device,
audio_policy_dev_state_t state,
const char *device_address,
const char *device_name);
const char *device_name,
audio_format_t encodedFormat);
virtual audio_policy_dev_state_t getDeviceConnectionState(
audio_devices_t device,
const char *device_address);
virtual status_t handleDeviceConfigChange(audio_devices_t device,
const char *device_address,
const char *device_name);
const char *device_name,
audio_format_t encodedFormat);
virtual status_t setPhoneState(audio_mode_t state);
virtual status_t setForceUse(audio_policy_force_use_t usage, audio_policy_forced_cfg_t config);
virtual audio_policy_forced_cfg_t getForceUse(audio_policy_force_use_t usage);

Loading…
Cancel
Save