Support query encapsualtion modes and metadata types.
When a new device is attached to hardware module, query the HAL to get
the supported encapsulation modes and metadata types.
Test: atest EnumDevicesTest, manually
Test: atest audiofoundation_parcelable_test
Bug: 155799506
Change-Id: I903e46e35a44416c9f2d206c128face8a6c61dcb
diff --git a/media/libaudiofoundation/DeviceDescriptorBase.cpp b/media/libaudiofoundation/DeviceDescriptorBase.cpp
index ef7576e..3dbe37d 100644
--- a/media/libaudiofoundation/DeviceDescriptorBase.cpp
+++ b/media/libaudiofoundation/DeviceDescriptorBase.cpp
@@ -80,9 +80,28 @@
toAudioPortConfig(&port->active_config);
port->id = mId;
port->ext.device.type = mDeviceTypeAddr.mType;
+ port->ext.device.encapsulation_modes = mEncapsulationModes;
+ port->ext.device.encapsulation_metadata_types = mEncapsulationMetadataTypes;
(void)audio_utils_strlcpy_zerofill(port->ext.device.address, mDeviceTypeAddr.getAddress());
}
+status_t DeviceDescriptorBase::setEncapsulationModes(uint32_t encapsulationModes) {
+ if ((encapsulationModes & ~AUDIO_ENCAPSULATION_MODE_ALL_POSITION_BITS) != 0) {
+ return BAD_VALUE;
+ }
+ mEncapsulationModes = encapsulationModes & ~(1 << AUDIO_ENCAPSULATION_MODE_NONE);
+ return NO_ERROR;
+}
+
+status_t DeviceDescriptorBase::setEncapsulationMetadataTypes(uint32_t encapsulationMetadataTypes) {
+ if ((encapsulationMetadataTypes & ~AUDIO_ENCAPSULATION_METADATA_TYPE_ALL_POSITION_BITS) != 0) {
+ return BAD_VALUE;
+ }
+ mEncapsulationMetadataTypes =
+ encapsulationMetadataTypes & ~(1 << AUDIO_ENCAPSULATION_METADATA_TYPE_NONE);
+ return NO_ERROR;
+}
+
void DeviceDescriptorBase::dump(std::string *dst, int spaces, int index,
const char* extraInfo, bool verbose) const
{
@@ -98,6 +117,12 @@
dst->append(base::StringPrintf("%*s- type: %-48s\n",
spaces, "", ::android::toString(mDeviceTypeAddr.mType).c_str()));
+ dst->append(base::StringPrintf(
+ "%*s- supported encapsulation modes: %u", spaces, "", mEncapsulationModes));
+ dst->append(base::StringPrintf(
+ "%*s- supported encapsulation metadata types: %u",
+ spaces, "", mEncapsulationMetadataTypes));
+
if (mDeviceTypeAddr.mAddress.size() != 0) {
dst->append(base::StringPrintf(
"%*s- address: %-32s\n", spaces, "", mDeviceTypeAddr.getAddress()));
@@ -135,6 +160,8 @@
if ((status = AudioPort::writeToParcel(parcel)) != NO_ERROR) return status;
if ((status = AudioPortConfig::writeToParcel(parcel)) != NO_ERROR) return status;
if ((status = parcel->writeParcelable(mDeviceTypeAddr)) != NO_ERROR) return status;
+ if ((status = parcel->writeUint32(mEncapsulationModes)) != NO_ERROR) return status;
+ if ((status = parcel->writeUint32(mEncapsulationMetadataTypes)) != NO_ERROR) return status;
return status;
}
@@ -144,6 +171,8 @@
if ((status = AudioPort::readFromParcel(parcel)) != NO_ERROR) return status;
if ((status = AudioPortConfig::readFromParcel(parcel)) != NO_ERROR) return status;
if ((status = parcel->readParcelable(&mDeviceTypeAddr)) != NO_ERROR) return status;
+ if ((status = parcel->readUint32(&mEncapsulationModes)) != NO_ERROR) return status;
+ if ((status = parcel->readUint32(&mEncapsulationMetadataTypes)) != NO_ERROR) return status;
return status;
}
diff --git a/media/libaudiofoundation/include/media/DeviceDescriptorBase.h b/media/libaudiofoundation/include/media/DeviceDescriptorBase.h
index 4c03667..af04721 100644
--- a/media/libaudiofoundation/include/media/DeviceDescriptorBase.h
+++ b/media/libaudiofoundation/include/media/DeviceDescriptorBase.h
@@ -55,6 +55,9 @@
// AudioPort
virtual void toAudioPort(struct audio_port *port) const;
+ status_t setEncapsulationModes(uint32_t encapsulationModes);
+ status_t setEncapsulationMetadataTypes(uint32_t encapsulationMetadataTypes);
+
void dump(std::string *dst, int spaces, int index,
const char* extraInfo = nullptr, bool verbose = true) const;
void log() const;
@@ -67,6 +70,8 @@
protected:
AudioDeviceTypeAddr mDeviceTypeAddr;
+ uint32_t mEncapsulationModes = 0;
+ uint32_t mEncapsulationMetadataTypes = 0;
};
using DeviceDescriptorBaseVector = std::vector<sp<DeviceDescriptorBase>>;
diff --git a/media/libaudiofoundation/tests/audiofoundation_parcelable_test.cpp b/media/libaudiofoundation/tests/audiofoundation_parcelable_test.cpp
index 5baa072..068b5d8 100644
--- a/media/libaudiofoundation/tests/audiofoundation_parcelable_test.cpp
+++ b/media/libaudiofoundation/tests/audiofoundation_parcelable_test.cpp
@@ -131,6 +131,9 @@
desc->setAudioProfiles(getAudioProfileVectorForTest());
desc->applyAudioPortConfig(&TEST_AUDIO_PORT_CONFIG);
desc->setAddress("DeviceDescriptorBaseTestAddress");
+ ASSERT_EQ(desc->setEncapsulationModes(1 << AUDIO_ENCAPSULATION_MODE_HANDLE), NO_ERROR);
+ ASSERT_EQ(desc->setEncapsulationMetadataTypes(
+ AUDIO_ENCAPSULATION_METADATA_TYPE_ALL_POSITION_BITS), NO_ERROR);
ASSERT_EQ(data.writeParcelable(*desc), NO_ERROR);
data.setDataPosition(0);
diff --git a/media/libaudiohal/impl/ConversionHelperHidl.cpp b/media/libaudiohal/impl/ConversionHelperHidl.cpp
index f29b0f3..ebed5fd 100644
--- a/media/libaudiohal/impl/ConversionHelperHidl.cpp
+++ b/media/libaudiohal/impl/ConversionHelperHidl.cpp
@@ -41,16 +41,25 @@
bool keepFormatValue = halKeys.size() == 2 &&
(halKeys.get(String8(AudioParameter::keyStreamSupportedChannels), value) == NO_ERROR ||
halKeys.get(String8(AudioParameter::keyStreamSupportedSamplingRates), value) == NO_ERROR);
+ // When querying encapsulation capabilities, "keyRouting=<value>" pair is used to identify
+ // the device. We need to transform it into a single key string so that it is carried over to
+ // the legacy HAL via HIDL.
+ bool keepRoutingValue =
+ halKeys.get(String8(AUDIO_PARAMETER_DEVICE_SUP_ENCAPSULATION_MODES),
+ value) == NO_ERROR ||
+ halKeys.get(String8(AUDIO_PARAMETER_DEVICE_SUP_ENCAPSULATION_METADATA_TYPES),
+ value) == NO_ERROR;
for (size_t i = 0; i < halKeys.size(); ++i) {
String8 key;
status_t status = halKeys.getAt(i, key);
if (status != OK) return status;
- if (keepFormatValue && key == AudioParameter::keyFormat) {
- AudioParameter formatParam;
+ if ((keepFormatValue && key == AudioParameter::keyFormat) ||
+ (keepRoutingValue && key == AudioParameter::keyRouting)) {
+ AudioParameter keepValueParam;
halKeys.getAt(i, key, value);
- formatParam.add(key, value);
- key = formatParam.toString();
+ keepValueParam.add(key, value);
+ key = keepValueParam.toString();
}
(*hidlKeys)[i] = key.string();
}
diff --git a/media/libmediahelper/AudioParameter.cpp b/media/libmediahelper/AudioParameter.cpp
index 9f34035..fc8306c 100644
--- a/media/libmediahelper/AudioParameter.cpp
+++ b/media/libmediahelper/AudioParameter.cpp
@@ -53,6 +53,10 @@
const char * const AudioParameter::valueListSeparator = AUDIO_PARAMETER_VALUE_LIST_SEPARATOR;
const char * const AudioParameter::keyReconfigA2dp = AUDIO_PARAMETER_RECONFIG_A2DP;
const char * const AudioParameter::keyReconfigA2dpSupported = AUDIO_PARAMETER_A2DP_RECONFIG_SUPPORTED;
+// const char * const AudioParameter::keyDeviceSupportedEncapsulationModes =
+// AUDIO_PARAMETER_DEVICE_SUP_ENCAPSULATION_MODES;
+// const char * const AudioParameter::keyDeviceSupportedEncapsulationMetadataTypes =
+// AUDIO_PARAMETER_DEVICE_SUP_ENCAPSULATION_METADATA_TYPES;
AudioParameter::AudioParameter(const String8& keyValuePairs)
{
diff --git a/media/libmediahelper/include/media/AudioParameter.h b/media/libmediahelper/include/media/AudioParameter.h
index 3c190f2..66d8dfb 100644
--- a/media/libmediahelper/include/media/AudioParameter.h
+++ b/media/libmediahelper/include/media/AudioParameter.h
@@ -92,6 +92,18 @@
static const char * const keyReconfigA2dp;
static const char * const keyReconfigA2dpSupported;
+ // For querying device supported encapsulation capabilities. All returned values are integer,
+ // which are bit fields composed from using encapsulation capability values as position bits.
+ // Encapsulation capability values are defined in audio_encapsulation_mode_t and
+ // audio_encapsulation_metadata_type_t. For instance, if the supported encapsulation mode is
+ // AUDIO_ENCAPSULATION_MODE_ELEMENTARY_STREAM, the returned value is
+ // "supEncapsulationModes=1 << AUDIO_ENCAPSULATION_MODE_HANDLE".
+ // When querying device supported encapsulation capabilities, the key should use with device
+ // type and address so that it is able to identify the device. The device will be a key. The
+ // device type will be the value of key AUDIO_PARAMETER_STREAM_ROUTING.
+ // static const char * const keyDeviceSupportedEncapsulationModes;
+ // static const char * const keyDeviceSupportedEncapsulationMetadataTypes;
+
String8 toString() const { return toStringImpl(true); }
String8 keysToString() const { return toStringImpl(false); }
diff --git a/services/audiopolicy/common/managerdefinitions/Android.bp b/services/audiopolicy/common/managerdefinitions/Android.bp
index fad3c5b..57f0b5b 100644
--- a/services/audiopolicy/common/managerdefinitions/Android.bp
+++ b/services/audiopolicy/common/managerdefinitions/Android.bp
@@ -25,12 +25,14 @@
"libhidlbase",
"liblog",
"libmedia",
+ "libmedia_helper",
"libutils",
"libxml2",
],
export_shared_lib_headers: [
"libaudiofoundation",
"libmedia",
+ "libmedia_helper",
],
static_libs: [
"libaudioutils",
diff --git a/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h
index a6562d7..dd1499c 100644
--- a/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h
@@ -28,6 +28,8 @@
namespace android {
+class AudioPolicyClientInterface;
+
class DeviceDescriptor : public DeviceDescriptorBase,
public PolicyAudioPort, public PolicyAudioPortConfig
{
@@ -87,6 +89,8 @@
void importAudioPortAndPickAudioProfile(const sp<PolicyAudioPort>& policyPort,
bool force = false);
+ void setEncapsulationInfoFromHal(AudioPolicyClientInterface *clientInterface);
+
void dump(String8 *dst, int spaces, int index, bool verbose = true) const;
private:
diff --git a/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
index 86dbba8..a29e60e 100644
--- a/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
@@ -17,9 +17,12 @@
#define LOG_TAG "APM::Devices"
//#define LOG_NDEBUG 0
-#include <audio_utils/string.h>
-#include <media/TypeConverter.h>
#include <set>
+
+#include <AudioPolicyInterface.h>
+#include <audio_utils/string.h>
+#include <media/AudioParameter.h>
+#include <media/TypeConverter.h>
#include "DeviceDescriptor.h"
#include "TypeConverter.h"
#include "HwModule.h"
@@ -165,6 +168,29 @@
policyPort->pickAudioProfile(mSamplingRate, mChannelMask, mFormat);
}
+void DeviceDescriptor::setEncapsulationInfoFromHal(
+ AudioPolicyClientInterface *clientInterface) {
+ AudioParameter param(String8(mDeviceTypeAddr.getAddress()));
+ param.addInt(String8(AudioParameter::keyRouting), mDeviceTypeAddr.mType);
+ param.addKey(String8(AUDIO_PARAMETER_DEVICE_SUP_ENCAPSULATION_MODES));
+ param.addKey(String8(AUDIO_PARAMETER_DEVICE_SUP_ENCAPSULATION_METADATA_TYPES));
+ String8 reply = clientInterface->getParameters(AUDIO_IO_HANDLE_NONE, param.toString());
+ AudioParameter repliedParameters(reply);
+ int value;
+ if (repliedParameters.getInt(
+ String8(AUDIO_PARAMETER_DEVICE_SUP_ENCAPSULATION_MODES), value) == NO_ERROR) {
+ if (setEncapsulationModes(value) != NO_ERROR) {
+ ALOGE("Failed to set encapsulation mode(%d)", value);
+ }
+ }
+ if (repliedParameters.getInt(
+ String8(AUDIO_PARAMETER_DEVICE_SUP_ENCAPSULATION_METADATA_TYPES), value) == NO_ERROR) {
+ if (setEncapsulationMetadataTypes(value) != NO_ERROR) {
+ ALOGE("Failed to set encapsulation metadata types(%d)", value);
+ }
+ }
+}
+
void DeviceDescriptor::dump(String8 *dst, int spaces, int index, bool verbose) const
{
String8 extraInfo;
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index bcf6f38..2a9a4c4 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -178,6 +178,9 @@
return INVALID_OPERATION;
}
+ // Populate encapsulation information when a output device is connected.
+ device->setEncapsulationInfoFromHal(mpClientInterface);
+
// outputs should never be empty here
ALOG_ASSERT(outputs.size() != 0, "setDeviceConnectionState():"
"checkOutputsForDevice() returned no outputs but status OK");
@@ -4635,6 +4638,7 @@
if (!device->isAttached()) {
device->attach(hwModule);
mAvailableOutputDevices.add(device);
+ device->setEncapsulationInfoFromHal(mpClientInterface);
if (newDevices) newDevices->add(device);
setEngineDeviceConnectionState(device, AUDIO_POLICY_DEVICE_STATE_AVAILABLE);
}