Merge "Add libmedia2_jni to media apex."
diff --git a/media/libaudioclient/AudioSystem.cpp b/media/libaudioclient/AudioSystem.cpp
index baeae8b..4c762ed 100644
--- a/media/libaudioclient/AudioSystem.cpp
+++ b/media/libaudioclient/AudioSystem.cpp
@@ -784,7 +784,8 @@
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 @@
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 @@
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 @@
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)
@@ -1335,6 +1337,13 @@
return aps->isHapticPlaybackSupported();
}
+status_t AudioSystem::getHwOffloadEncodingFormatsSupportedForA2DP(
+ std::vector<audio_format_t> *formats)
+{
+ const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+ if (aps == 0) return PERMISSION_DENIED;
+ return aps->getHwOffloadEncodingFormatsSupportedForA2DP(formats);
+}
// ---------------------------------------------------------------------------
diff --git a/media/libaudioclient/IAudioPolicyService.cpp b/media/libaudioclient/IAudioPolicyService.cpp
index 272415c..8c7fac5 100644
--- a/media/libaudioclient/IAudioPolicyService.cpp
+++ b/media/libaudioclient/IAudioPolicyService.cpp
@@ -92,6 +92,7 @@
IS_HAPTIC_PLAYBACK_SUPPORTED,
SET_UID_DEVICE_AFFINITY,
REMOVE_UID_DEVICE_AFFINITY,
+ GET_OFFLOAD_FORMATS_A2DP
};
#define MAX_ITEMS_PER_LIST 1024
@@ -108,7 +109,8 @@
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 +118,7 @@
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 +137,15 @@
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());
}
@@ -884,7 +889,30 @@
return reply.readInt32();
}
- virtual status_t addStreamDefaultEffect(const effect_uuid_t *type,
+ virtual status_t getHwOffloadEncodingFormatsSupportedForA2DP(
+ std::vector<audio_format_t> *formats)
+ {
+ if (formats == NULL) {
+ return BAD_VALUE;
+ }
+
+ Parcel data, reply;
+ data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
+ status_t status = remote()->transact(GET_OFFLOAD_FORMATS_A2DP, data, &reply);
+ if (status != NO_ERROR || (status = (status_t)reply.readInt32()) != NO_ERROR) {
+ return status;
+ }
+
+ size_t list_size = reply.readUint32();
+
+ for (size_t i = 0; i < list_size; i++) {
+ formats->push_back(static_cast<audio_format_t>(reply.readInt32()));
+ }
+ return NO_ERROR;
+ }
+
+
+ virtual status_t addStreamDefaultEffect(const effect_uuid_t *type,
const String16& opPackageName,
const effect_uuid_t *uuid,
int32_t priority,
@@ -1096,7 +1124,8 @@
case SET_ASSISTANT_UID:
case SET_A11Y_SERVICES_UIDS:
case SET_UID_DEVICE_AFFINITY:
- case REMOVE_UID_DEVICE_AFFINITY: {
+ case REMOVE_UID_DEVICE_AFFINITY:
+ case GET_OFFLOAD_FORMATS_A2DP: {
if (!isServiceUid(IPCThreadState::self()->getCallingUid())) {
ALOGW("%s: transaction %d received from PID %d unauthorized UID %d",
__func__, code, IPCThreadState::self()->getCallingPid(),
@@ -1121,6 +1150,7 @@
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 +1158,8 @@
reply->writeInt32(static_cast<uint32_t> (setDeviceConnectionState(device,
state,
device_address,
- device_name)));
+ device_name,
+ codecFormat)));
}
return NO_ERROR;
} break;
@@ -1154,13 +1185,16 @@
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;
@@ -1745,6 +1779,21 @@
return NO_ERROR;
}
+ case GET_OFFLOAD_FORMATS_A2DP: {
+ CHECK_INTERFACE(IAudioPolicyService, data, reply);
+ std::vector<audio_format_t> encodingFormats;
+ status_t status = getHwOffloadEncodingFormatsSupportedForA2DP(&encodingFormats);
+ reply->writeInt32(status);
+ if (status != NO_ERROR) {
+ return NO_ERROR;
+ }
+ reply->writeUint32(static_cast<uint32_t>(encodingFormats.size()));
+ for (size_t i = 0; i < encodingFormats.size(); i++)
+ reply->writeInt32(static_cast<int32_t>(encodingFormats[i]));
+ return NO_ERROR;
+ }
+
+
case ADD_STREAM_DEFAULT_EFFECT: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
effect_uuid_t type;
diff --git a/media/libaudioclient/include/media/AudioSystem.h b/media/libaudioclient/include/media/AudioSystem.h
index 781e9df..a208602 100644
--- a/media/libaudioclient/include/media/AudioSystem.h
+++ b/media/libaudioclient/include/media/AudioSystem.h
@@ -209,12 +209,14 @@
// 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);
@@ -342,6 +344,9 @@
static status_t getMicrophones(std::vector<media::MicrophoneInfo> *microphones);
+ static status_t getHwOffloadEncodingFormatsSupportedForA2DP(
+ std::vector<audio_format_t> *formats);
+
// numSurroundFormats holds the maximum number of formats and bool value allowed in the array.
// When numSurroundFormats is 0, surroundFormats and surroundFormatsEnabled will not be
// populated. The actual number of surround formats should be returned at numSurroundFormats.
diff --git a/media/libaudioclient/include/media/IAudioPolicyService.h b/media/libaudioclient/include/media/IAudioPolicyService.h
index fb4fe93..177adc2 100644
--- a/media/libaudioclient/include/media/IAudioPolicyService.h
+++ b/media/libaudioclient/include/media/IAudioPolicyService.h
@@ -44,12 +44,14 @@
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;
@@ -186,6 +188,8 @@
audio_format_t *surroundFormats,
bool *surroundFormatsEnabled,
bool reported) = 0;
+ virtual status_t getHwOffloadEncodingFormatsSupportedForA2DP(
+ std::vector<audio_format_t> *formats) = 0;
virtual status_t setSurroundFormatEnabled(audio_format_t audioFormat, bool enabled) = 0;
virtual status_t setAssistantUid(uid_t uid) = 0;
diff --git a/services/audiopolicy/AudioPolicyInterface.h b/services/audiopolicy/AudioPolicyInterface.h
index 1c2b9d7..cf2ce99 100644
--- a/services/audiopolicy/AudioPolicyInterface.h
+++ b/services/audiopolicy/AudioPolicyInterface.h
@@ -75,14 +75,16 @@
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
@@ -234,6 +236,9 @@
virtual bool isHapticPlaybackSupported() = 0;
+ virtual status_t getHwOffloadEncodingFormatsSupportedForA2DP(
+ std::vector<audio_format_t> *formats) = 0;
+
virtual void setAppState(uid_t uid, app_state_t state);
};
diff --git a/services/audiopolicy/common/include/policy.h b/services/audiopolicy/common/include/policy.h
index 46a2a40..837ca47 100644
--- a/services/audiopolicy/common/include/policy.h
+++ b/services/audiopolicy/common/include/policy.h
@@ -76,6 +76,21 @@
}
/**
+ * 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
* effect configuration.
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h
index 14b995b..e1ecc61 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h
@@ -154,6 +154,7 @@
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);
diff --git a/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h
index b581665..cc43fe6 100644
--- a/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h
@@ -44,8 +44,18 @@
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 @@
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 @@
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;
/**
diff --git a/services/audiopolicy/common/managerdefinitions/include/HwModule.h b/services/audiopolicy/common/managerdefinitions/include/HwModule.h
index d7dc4b0..eb34da4 100644
--- a/services/audiopolicy/common/managerdefinitions/include/HwModule.h
+++ b/services/audiopolicy/common/managerdefinitions/include/HwModule.h
@@ -130,9 +130,11 @@
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 @@
* @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 @@
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 @@
*/
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
diff --git a/services/audiopolicy/common/managerdefinitions/include/IOProfile.h b/services/audiopolicy/common/managerdefinitions/include/IOProfile.h
index d0c05a5..dc409a7 100644
--- a/services/audiopolicy/common/managerdefinitions/include/IOProfile.h
+++ b/services/audiopolicy/common/managerdefinitions/include/IOProfile.h
@@ -94,7 +94,10 @@
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 @@
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)
{
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
index 643cbd1..57328f0 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
@@ -364,6 +364,16 @@
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 @@
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);
}
}
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
index d18091c..799950c 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
@@ -296,7 +296,8 @@
// 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;
diff --git a/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
index 01111c5..2ed8455 100644
--- a/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
@@ -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 @@
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 @@
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 @@
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 @@
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 @@
}
}
}
- 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;
}
diff --git a/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp b/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp
index 7d2d094..85d9bce 100644
--- a/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp
@@ -273,32 +273,34 @@
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 @@
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 @@
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 @@
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> 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 @@
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__,
diff --git a/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp b/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp
index 1154654..98d375c 100644
--- a/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp
@@ -140,6 +140,8 @@
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 @@
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()) {
diff --git a/services/audiopolicy/enginedefault/src/Engine.cpp b/services/audiopolicy/enginedefault/src/Engine.cpp
index 3d68cd8..cc5a025 100644
--- a/services/audiopolicy/enginedefault/src/Engine.cpp
+++ b/services/audiopolicy/enginedefault/src/Engine.cpp
@@ -506,7 +506,7 @@
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;
}
}
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 5c8a799..cc151e7 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -81,9 +81,11 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
// 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 = 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);
@@ -408,6 +446,43 @@
return NO_ERROR;
}
+status_t AudioPolicyManager::getHwOffloadEncodingFormatsSupportedForA2DP(
+ std::vector<audio_format_t> *formats)
+{
+ ALOGV("getHwOffloadEncodingFormatsSupportedForA2DP()");
+ char *tok = NULL, *saveptr;
+ status_t status = NO_ERROR;
+ char encoding_formats_list[PROPERTY_VALUE_MAX];
+ audio_format_t format = AUDIO_FORMAT_DEFAULT;
+ // FIXME This list should not come from a property but the supported encoded
+ // formats of declared A2DP devices in primary module
+ property_get("persist.bluetooth.a2dp_offload.cap", encoding_formats_list, "");
+ tok = strtok_r(encoding_formats_list, "-", &saveptr);
+ for (;tok != NULL; tok = strtok_r(NULL, "-", &saveptr)) {
+ if (strcmp(tok, "sbc") == 0) {
+ ALOGV("%s: SBC offload supported\n",__func__);
+ format = AUDIO_FORMAT_SBC;
+ } else if (strcmp(tok, "aptx") == 0) {
+ ALOGV("%s: APTX offload supported\n",__func__);
+ format = AUDIO_FORMAT_APTX;
+ } else if (strcmp(tok, "aptxhd") == 0) {
+ ALOGV("%s: APTX HD offload supported\n",__func__);
+ format = AUDIO_FORMAT_APTX_HD;
+ } else if (strcmp(tok, "ldac") == 0) {
+ ALOGV("%s: LDAC offload supported\n",__func__);
+ format = AUDIO_FORMAT_LDAC;
+ } else if (strcmp(tok, "aac") == 0) {
+ ALOGV("%s: AAC offload supported\n",__func__);
+ format = AUDIO_FORMAT_AAC;
+ } else {
+ ALOGE("%s: undefined token - %s\n",__func__, tok);
+ continue;
+ }
+ formats->push_back(format);
+ }
+ return status;
+}
+
uint32_t AudioPolicyManager::updateCallRouting(const DeviceVector &rxDevices, uint32_t delayMs)
{
bool createTxPatch = false;
@@ -464,15 +539,18 @@
}
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 +814,10 @@
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 +922,8 @@
*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 +966,8 @@
*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 +1242,7 @@
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 +1540,8 @@
} 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 +1659,8 @@
setDeviceConnectionStateInt(AUDIO_DEVICE_IN_REMOTE_SUBMIX,
AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
address,
- "remote-submix");
+ "remote-submix",
+ AUDIO_FORMAT_DEFAULT);
}
return NO_ERROR;
@@ -1620,7 +1706,7 @@
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 +1898,8 @@
}
*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 +1918,8 @@
// 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 +2153,7 @@
if (address != "") {
setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
- address, "remote-submix");
+ address, "remote-submix", AUDIO_FORMAT_DEFAULT);
}
}
}
@@ -2116,7 +2204,7 @@
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 +2624,11 @@
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 +2702,13 @@
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 +2752,8 @@
// 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 +2774,8 @@
// 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 +3532,8 @@
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 +3817,16 @@
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 +3839,16 @@
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 +4273,8 @@
// 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 +4437,8 @@
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 +4725,8 @@
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 +4782,10 @@
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 +5503,10 @@
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,
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index e99de16..fb1f7cb 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -97,12 +97,14 @@
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);
@@ -239,6 +241,9 @@
bool reported);
virtual status_t setSurroundFormatEnabled(audio_format_t audioFormat, bool enabled);
+ virtual status_t getHwOffloadEncodingFormatsSupportedForA2DP(
+ std::vector<audio_format_t> *formats);
+
// return the strategy corresponding to a given stream type
routing_strategy getStrategy(audio_stream_type_t stream) const;
@@ -731,7 +736,8 @@
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);
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index 2c904d9..49c541c 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -32,7 +32,8 @@
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 @@
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 @@
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 @@
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)
@@ -1138,6 +1140,17 @@
surroundFormatsEnabled, reported);
}
+status_t AudioPolicyService::getHwOffloadEncodingFormatsSupportedForA2DP(
+ std::vector<audio_format_t> *formats)
+{
+ if (mAudioPolicyManager == NULL) {
+ return NO_INIT;
+ }
+ Mutex::Autolock _l(mLock);
+ AutoCallerClear acc;
+ return mAudioPolicyManager->getHwOffloadEncodingFormatsSupportedForA2DP(formats);
+}
+
status_t AudioPolicyService::setSurroundFormatEnabled(audio_format_t audioFormat, bool enabled)
{
if (mAudioPolicyManager == NULL) {
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index 959e757..c073b7c 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -61,13 +61,15 @@
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);
@@ -218,6 +220,8 @@
audio_format_t *surroundFormats,
bool *surroundFormatsEnabled,
bool reported);
+ virtual status_t getHwOffloadEncodingFormatsSupportedForA2DP(
+ std::vector<audio_format_t> *formats);
virtual status_t setSurroundFormatEnabled(audio_format_t audioFormat, bool enabled);
virtual status_t setAssistantUid(uid_t uid);