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

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

@ -209,12 +209,14 @@ public:
// IAudioPolicyService interface (see AudioPolicyInterface for method descriptions) // IAudioPolicyService interface (see AudioPolicyInterface for method descriptions)
// //
static status_t setDeviceConnectionState(audio_devices_t device, audio_policy_dev_state_t state, 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, static audio_policy_dev_state_t getDeviceConnectionState(audio_devices_t device,
const char *device_address); const char *device_address);
static status_t handleDeviceConfigChange(audio_devices_t device, static status_t handleDeviceConfigChange(audio_devices_t device,
const char *device_address, 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 setPhoneState(audio_mode_t state);
static status_t setForceUse(audio_policy_force_use_t usage, audio_policy_forced_cfg_t config); 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); 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, virtual status_t setDeviceConnectionState(audio_devices_t device,
audio_policy_dev_state_t state, audio_policy_dev_state_t state,
const char *device_address, 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, virtual audio_policy_dev_state_t getDeviceConnectionState(audio_devices_t device,
const char *device_address) = 0; const char *device_address) = 0;
virtual status_t handleDeviceConfigChange(audio_devices_t device, virtual status_t handleDeviceConfigChange(audio_devices_t device,
const char *device_address, 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 setPhoneState(audio_mode_t state) = 0;
virtual status_t setForceUse(audio_policy_force_use_t usage, virtual status_t setForceUse(audio_policy_force_use_t usage,
audio_policy_forced_cfg_t config) = 0; audio_policy_forced_cfg_t config) = 0;

@ -75,14 +75,16 @@ public:
virtual status_t setDeviceConnectionState(audio_devices_t device, virtual status_t setDeviceConnectionState(audio_devices_t device,
audio_policy_dev_state_t state, audio_policy_dev_state_t state,
const char *device_address, const char *device_address,
const char *device_name) = 0; const char *device_name,
audio_format_t encodedFormat) = 0;
// retrieve a device connection status // retrieve a device connection status
virtual audio_policy_dev_state_t getDeviceConnectionState(audio_devices_t device, virtual audio_policy_dev_state_t getDeviceConnectionState(audio_devices_t device,
const char *device_address) = 0; const char *device_address) = 0;
// indicate a change in device configuration // indicate a change in device configuration
virtual status_t handleDeviceConfigChange(audio_devices_t device, virtual status_t handleDeviceConfigChange(audio_devices_t device,
const char *device_address, 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 // indicate a change in phone state. Valid phones states are defined by audio_mode_t
virtual void setPhoneState(audio_mode_t state) = 0; virtual void setPhoneState(audio_mode_t state) = 0;
// force using a specific device category for the specified usage // 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)); ((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 * 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 * 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; } void setDevices(const DeviceVector &devices) { mDevices = devices; }
bool sharesHwModuleWith(const sp<SwAudioOutputDescriptor>& outputDesc); bool sharesHwModuleWith(const sp<SwAudioOutputDescriptor>& outputDesc);
virtual DeviceVector supportedDevices() const; virtual DeviceVector supportedDevices() const;
virtual bool deviceSupportsEncodedFormats(audio_devices_t device);
virtual uint32_t latency(); virtual uint32_t latency();
virtual bool isDuplicated() const { return (mOutput1 != NULL && mOutput2 != NULL); } virtual bool isDuplicated() const { return (mOutput1 != NULL && mOutput2 != NULL); }
virtual bool isFixedVolume(audio_devices_t device); virtual bool isFixedVolume(audio_devices_t device);

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

@ -130,9 +130,11 @@ class HwModuleCollection : public Vector<sp<HwModule> >
public: public:
sp<HwModule> getModuleFromName(const char *name) const; 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, DeviceVector getAvailableDevicesFromModuleName(const char *name,
const DeviceVector &availableDevices) const; const DeviceVector &availableDevices) const;
@ -149,6 +151,7 @@ public:
* @param type of the device requested * @param type of the device requested
* @param address of the device requested * @param address of the device requested
* @param name of the device that 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 matchAddress true if a strong match is required
* @param allowToCreate true if allowed to create dynamic device (e.g. hdmi, usb...) * @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) * @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, sp<DeviceDescriptor> getDeviceDescriptor(const audio_devices_t type,
const char *address, const char *address,
const char *name, const char *name,
audio_format_t encodedFormat,
bool allowToCreate = false, bool allowToCreate = false,
bool matchAddress = true) const; bool matchAddress = true) const;
@ -171,7 +175,8 @@ public:
*/ */
sp<DeviceDescriptor> createDevice(const audio_devices_t type, sp<DeviceDescriptor> createDevice(const audio_devices_t type,
const char *address, 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 * @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 bool supportsDeviceTypes(audio_devices_t device) const
{ {
if (audio_is_output_devices(device)) { 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); return mSupportedDevices.types() & (device & ~AUDIO_DEVICE_BIT_IN);
} }
@ -116,6 +119,16 @@ public:
return mSupportedDevices.contains(device); 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 clearSupportedDevices() { mSupportedDevices.clear(); }
void addSupportedDevice(const sp<DeviceDescriptor> &device) void addSupportedDevice(const sp<DeviceDescriptor> &device)
{ {

@ -364,6 +364,16 @@ DeviceVector SwAudioOutputDescriptor::filterSupportedDevices(const DeviceVector
return filteredDevices.filter(devices); 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() uint32_t SwAudioOutputDescriptor::latency()
{ {
if (isDuplicated()) { if (isDuplicated()) {
@ -687,7 +697,9 @@ audio_io_handle_t SwAudioOutputCollection::getA2dpOutput() const
for (size_t i = 0; i < size(); i++) { for (size_t i = 0; i < size(); i++) {
sp<SwAudioOutputDescriptor> outputDesc = valueAt(i); sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
if (!outputDesc->isDuplicated() && 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); return this->keyAt(i);
} }
} }

@ -296,7 +296,8 @@ sp<DeviceDescriptor> AudioPolicyMixCollection::getDeviceAndMixForInputSource(
// assuming PolicyMix only for remote submix for input // assuming PolicyMix only for remote submix for input
// so mix->mDeviceType can only be AUDIO_DEVICE_OUT_REMOTE_SUBMIX // so mix->mDeviceType can only be AUDIO_DEVICE_OUT_REMOTE_SUBMIX
audio_devices_t device = AUDIO_DEVICE_IN_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 (mixDevice != nullptr) {
if (policyMix != NULL) { if (policyMix != NULL) {
*policyMix = mix; *policyMix = mix;

@ -18,6 +18,7 @@
//#define LOG_NDEBUG 0 //#define LOG_NDEBUG 0
#include <audio_utils/string.h> #include <audio_utils/string.h>
#include <set>
#include "DeviceDescriptor.h" #include "DeviceDescriptor.h"
#include "TypeConverter.h" #include "TypeConverter.h"
#include "AudioGain.h" #include "AudioGain.h"
@ -37,6 +38,7 @@ DeviceDescriptor::DeviceDescriptor(audio_devices_t type, const FormatVector &enc
AUDIO_PORT_ROLE_SOURCE), AUDIO_PORT_ROLE_SOURCE),
mTagName(tagName), mDeviceType(type), mEncodedFormats(encodedFormats) mTagName(tagName), mDeviceType(type), mEncodedFormats(encodedFormats)
{ {
mCurrentEncodedFormat = AUDIO_FORMAT_DEFAULT;
if (type == AUDIO_DEVICE_IN_REMOTE_SUBMIX || type == AUDIO_DEVICE_OUT_REMOTE_SUBMIX ) { if (type == AUDIO_DEVICE_IN_REMOTE_SUBMIX || type == AUDIO_DEVICE_OUT_REMOTE_SUBMIX ) {
mAddress = String8("0"); 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_AC3);
mEncodedFormats.add(AUDIO_FORMAT_IEC61937); 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 audio_port_handle_t DeviceDescriptor::getId() const
@ -58,21 +66,49 @@ void DeviceDescriptor::attach(const sp<HwModule>& module)
mId = getNextUniqueId(); mId = getNextUniqueId();
} }
void DeviceDescriptor::detach() void DeviceDescriptor::detach() {
{
mId = AUDIO_PORT_HANDLE_NONE; mId = AUDIO_PORT_HANDLE_NONE;
AudioPort::detach(); 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 bool DeviceDescriptor::equals(const sp<DeviceDescriptor>& other) const
{ {
// Devices are considered equal if they: // Devices are considered equal if they:
// - are of the same type (a device type cannot be AUDIO_DEVICE_NONE) // - are of the same type (a device type cannot be AUDIO_DEVICE_NONE)
// - have the same address // - have the same address
// - have the same encodingFormats (if device supports encoding)
if (other == 0) { if (other == 0) {
return false; 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() void DeviceVector::refreshTypes()
@ -167,12 +203,17 @@ audio_devices_t DeviceVector::getDeviceTypesFromHwModule(audio_module_handle_t m
return deviceTypes; 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; sp<DeviceDescriptor> device;
for (size_t i = 0; i < size(); i++) { for (size_t i = 0; i < size(); i++) {
if (itemAt(i)->type() == type) { 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); device = itemAt(i);
if (itemAt(i)->address() == address) { if (itemAt(i)->address() == address) {
break; 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", ALOGV("DeviceVector::%s() for type %08x address \"%s\" found %p format %08x",
__func__, type, address.string(), device.get()); __func__, type, address.string(), device.get(), format);
return device; return device;
} }

@ -273,32 +273,34 @@ sp <HwModule> HwModuleCollection::getModuleFromName(const char *name) const
return nullptr; 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) { 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(); module->getOutputProfiles() : module->getInputProfiles();
for (const auto& profile : profiles) { for (const auto& profile : profiles) {
if (profile->supportsDeviceTypes(device)) { if (profile->supportsDeviceTypes(type)) {
return module; 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; 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) { return getModuleForDeviceTypes(device->type(), encodedFormat);
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;
} }
DeviceVector HwModuleCollection::getAvailableDevicesFromModuleName( DeviceVector HwModuleCollection::getAvailableDevicesFromModuleName(
@ -314,6 +316,7 @@ DeviceVector HwModuleCollection::getAvailableDevicesFromModuleName(
sp<DeviceDescriptor> HwModuleCollection::getDeviceDescriptor(const audio_devices_t deviceType, sp<DeviceDescriptor> HwModuleCollection::getDeviceDescriptor(const audio_devices_t deviceType,
const char *address, const char *address,
const char *name, const char *name,
const audio_format_t encodedFormat,
bool allowToCreate, bool allowToCreate,
bool matchAddress) const bool matchAddress) const
{ {
@ -325,8 +328,14 @@ sp<DeviceDescriptor> HwModuleCollection::getDeviceDescriptor(const audio_devices
for (const auto& hwModule : *this) { for (const auto& hwModule : *this) {
DeviceVector moduleDevices = hwModule->getAllDevices(); DeviceVector moduleDevices = hwModule->getAllDevices();
auto moduleDevice = moduleDevices.getDevice(deviceType, devAddress); auto moduleDevice = moduleDevices.getDevice(deviceType, devAddress, encodedFormat);
if (moduleDevice) { if (moduleDevice) {
if (encodedFormat != AUDIO_FORMAT_DEFAULT) {
moduleDevice->setEncodedFormat(encodedFormat);
if (moduleDevice->address() != devAddress) {
moduleDevice->setAddress(devAddress);
}
}
if (allowToCreate) { if (allowToCreate) {
moduleDevice->attach(hwModule); moduleDevice->attach(hwModule);
} }
@ -338,14 +347,15 @@ sp<DeviceDescriptor> HwModuleCollection::getDeviceDescriptor(const audio_devices
name, deviceType, address); name, deviceType, address);
return nullptr; return nullptr;
} }
return createDevice(deviceType, address, name); return createDevice(deviceType, address, name, encodedFormat);
} }
sp<DeviceDescriptor> HwModuleCollection::createDevice(const audio_devices_t type, sp<DeviceDescriptor> HwModuleCollection::createDevice(const audio_devices_t type,
const char *address, 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) { if (hwModule == 0) {
ALOGE("%s: could not find HW module for device %04x address %s", __FUNCTION__, type, ALOGE("%s: could not find HW module for device %04x address %s", __FUNCTION__, type,
address); address);
@ -354,8 +364,9 @@ sp<DeviceDescriptor> HwModuleCollection::createDevice(const audio_devices_t type
sp<DeviceDescriptor> device = new DeviceDescriptor(type, String8(name)); sp<DeviceDescriptor> device = new DeviceDescriptor(type, String8(name));
device->setName(String8(name)); device->setName(String8(name));
device->setAddress(String8(address)); 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); hwModule->addDynamicDevice(device);
// Reciprocally attach the device to the module // Reciprocally attach the device to the module
device->attach(hwModule); device->attach(hwModule);
@ -370,7 +381,8 @@ sp<DeviceDescriptor> HwModuleCollection::createDevice(const audio_devices_t type
if (profile->supportsDevice(device, false /*matchAdress*/)) { if (profile->supportsDevice(device, false /*matchAdress*/)) {
// @todo quid of audio profile? import the profile from device of the same type? // @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 */); device->importAudioPort(isoTypeDeviceForProfile, true /* force */);
ALOGV("%s: adding device %s to profile %s", __FUNCTION__, 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>. */ static constexpr const char *roleSource = "source"; /**< <attribute role source value>. */
/** optional: device address, char string less than 64. */ /** optional: device address, char string less than 64. */
static constexpr const char *address = "address"; 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); 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); ALOGW("%s: bad type %08x", __func__, type);
return Status::fromStatusT(BAD_VALUE); 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); std::string address = getXmlAttribute(cur, Attributes::address);
if (!address.empty()) { if (!address.empty()) {

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

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

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

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

Loading…
Cancel
Save