Call getAudioPort to get supported attributes for audio devices.
GetAudioPort API will return the supported attributes for the devices.
Call getAudioPort to get the supported attributes for the audio
devices so that it is no needed to get supported attributes via
getParameters API.
Bug: 160352965
Test: make
Test: atest audiopolicy_tests AudioPlaybackCaptureTest
Change-Id: Icdfe76e15066bbff10308d6dfd1cf742da33fec9
diff --git a/media/libaudioclient/IAudioFlinger.cpp b/media/libaudioclient/IAudioFlinger.cpp
index 57142b0..adb16d4 100644
--- a/media/libaudioclient/IAudioFlinger.cpp
+++ b/media/libaudioclient/IAudioFlinger.cpp
@@ -946,14 +946,14 @@
reply.read(ports, *num_ports * sizeof(struct audio_port));
return status;
}
- virtual status_t getAudioPort(struct audio_port *port)
+ virtual status_t getAudioPort(struct audio_port_v7 *port)
{
- if (port == NULL) {
+ if (port == nullptr) {
return BAD_VALUE;
}
Parcel data, reply;
data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
- data.write(port, sizeof(struct audio_port));
+ data.write(port, sizeof(struct audio_port_v7));
status_t status = remote()->transact(GET_AUDIO_PORT, data, &reply);
if (status != NO_ERROR ||
(status = (status_t)reply.readInt32()) != NO_ERROR) {
@@ -1645,7 +1645,7 @@
} break;
case GET_AUDIO_PORT: {
CHECK_INTERFACE(IAudioFlinger, data, reply);
- struct audio_port port = {};
+ struct audio_port_v7 port = {};
status_t status = data.read(&port, sizeof(struct audio_port));
if (status != NO_ERROR) {
ALOGE("b/23905951");
@@ -1657,7 +1657,7 @@
}
reply->writeInt32(status);
if (status == NO_ERROR) {
- reply->write(&port, sizeof(struct audio_port));
+ reply->write(&port, sizeof(struct audio_port_v7));
}
return NO_ERROR;
} break;
diff --git a/media/libaudioclient/include/media/IAudioFlinger.h b/media/libaudioclient/include/media/IAudioFlinger.h
index 3491fda..db7e4f6 100644
--- a/media/libaudioclient/include/media/IAudioFlinger.h
+++ b/media/libaudioclient/include/media/IAudioFlinger.h
@@ -317,7 +317,7 @@
struct audio_port *ports) = 0;
/* Get attributes for a given audio port */
- virtual status_t getAudioPort(struct audio_port *port) = 0;
+ virtual status_t getAudioPort(struct audio_port_v7 *port) = 0;
/* Create an audio patch between several source and sink ports */
virtual status_t createAudioPatch(const struct audio_patch *patch,
diff --git a/media/libaudiofoundation/AudioPort.cpp b/media/libaudiofoundation/AudioPort.cpp
index 1846a6b..d650c67 100644
--- a/media/libaudiofoundation/AudioPort.cpp
+++ b/media/libaudiofoundation/AudioPort.cpp
@@ -38,6 +38,21 @@
}
}
+void AudioPort::importAudioPort(const audio_port_v7 &port) {
+ for (size_t i = 0; i < port.num_audio_profiles; ++i) {
+ sp<AudioProfile> profile = new AudioProfile(port.audio_profiles[i].format,
+ ChannelMaskSet(port.audio_profiles[i].channel_masks,
+ port.audio_profiles[i].channel_masks +
+ port.audio_profiles->num_channel_masks),
+ SampleRateSet(port.audio_profiles[i].sample_rates,
+ port.audio_profiles[i].sample_rates +
+ port.audio_profiles[i].num_sample_rates));
+ if (!mProfiles.contains(profile)) {
+ addAudioProfile(profile);
+ }
+ }
+}
+
void AudioPort::toAudioPort(struct audio_port *port) const {
// TODO: update this function once audio_port structure reflects the new profile definition.
// For compatibility reason: flatening the AudioProfile into audio_port structure.
@@ -62,21 +77,39 @@
}
}
}
- port->role = mRole;
- port->type = mType;
- strlcpy(port->name, mName.c_str(), AUDIO_PORT_MAX_NAME_LEN);
+ toAudioPortBase(port);
port->num_sample_rates = flatenedRates.size();
port->num_channel_masks = flatenedChannels.size();
port->num_formats = flatenedFormats.size();
std::copy(flatenedRates.begin(), flatenedRates.end(), port->sample_rates);
std::copy(flatenedChannels.begin(), flatenedChannels.end(), port->channel_masks);
std::copy(flatenedFormats.begin(), flatenedFormats.end(), port->formats);
+}
- ALOGV("AudioPort::toAudioPort() num gains %zu", mGains.size());
+void AudioPort::toAudioPort(struct audio_port_v7 *port) const {
+ toAudioPortBase(port);
+ port->num_audio_profiles = 0;
+ for (const auto& profile : mProfiles) {
+ if (profile->isValid()) {
+ const SampleRateSet &sampleRates = profile->getSampleRates();
+ const ChannelMaskSet &channelMasks = profile->getChannels();
- port->num_gains = std::min(mGains.size(), (size_t) AUDIO_PORT_MAX_GAINS);
- for (size_t i = 0; i < port->num_gains; i++) {
- port->gains[i] = mGains[i]->getGain();
+ if (sampleRates.size() > AUDIO_PORT_MAX_SAMPLING_RATES ||
+ channelMasks.size() > AUDIO_PORT_MAX_CHANNEL_MASKS ||
+ port->num_audio_profiles >= AUDIO_PORT_MAX_AUDIO_PROFILES) {
+ ALOGE("%s: bailing out: cannot export profiles to port config", __func__);
+ return;
+ }
+
+ auto& dstProfile = port->audio_profiles[port->num_audio_profiles++];
+ dstProfile.format = profile->getFormat();
+ dstProfile.num_sample_rates = sampleRates.size();
+ std::copy(sampleRates.begin(), sampleRates.end(),
+ std::begin(dstProfile.sample_rates));
+ dstProfile.num_channel_masks = channelMasks.size();
+ std::copy(channelMasks.begin(), channelMasks.end(),
+ std::begin(dstProfile.channel_masks));
+ }
}
}
diff --git a/media/libaudiofoundation/AudioProfile.cpp b/media/libaudiofoundation/AudioProfile.cpp
index 67b600e..ec52575 100644
--- a/media/libaudiofoundation/AudioProfile.cpp
+++ b/media/libaudiofoundation/AudioProfile.cpp
@@ -260,6 +260,16 @@
return false;
}
+bool AudioProfileVector::contains(const sp<AudioProfile>& profile) const
+{
+ for (const auto& audioProfile : *this) {
+ if (audioProfile->equals(profile)) {
+ return true;
+ }
+ }
+ return false;
+}
+
void AudioProfileVector::dump(std::string *dst, int spaces) const
{
dst->append(base::StringPrintf("%*s- Profiles:\n", spaces, ""));
diff --git a/media/libaudiofoundation/DeviceDescriptorBase.cpp b/media/libaudiofoundation/DeviceDescriptorBase.cpp
index 16cf71a..50bda8b 100644
--- a/media/libaudiofoundation/DeviceDescriptorBase.cpp
+++ b/media/libaudiofoundation/DeviceDescriptorBase.cpp
@@ -80,13 +80,12 @@
void DeviceDescriptorBase::toAudioPort(struct audio_port *port) const
{
ALOGV("DeviceDescriptorBase::toAudioPort() handle %d type %08x", mId, mDeviceTypeAddr.mType);
- AudioPort::toAudioPort(port);
- 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());
+ toAudioPortInternal(port);
+}
+
+void DeviceDescriptorBase::toAudioPort(struct audio_port_v7 *port) const {
+ ALOGV("DeviceDescriptorBase::toAudioPort() v7 handle %d type %08x", mId, mDeviceTypeAddr.mType);
+ toAudioPortInternal(port);
}
status_t DeviceDescriptorBase::setEncapsulationModes(uint32_t encapsulationModes) {
diff --git a/media/libaudiofoundation/include/media/AudioPort.h b/media/libaudiofoundation/include/media/AudioPort.h
index 3c013cb..622b97b 100644
--- a/media/libaudiofoundation/include/media/AudioPort.h
+++ b/media/libaudiofoundation/include/media/AudioPort.h
@@ -17,6 +17,7 @@
#pragma once
#include <string>
+#include <type_traits>
#include <binder/Parcel.h>
#include <binder/Parcelable.h>
@@ -48,6 +49,8 @@
virtual void toAudioPort(struct audio_port *port) const;
+ virtual void toAudioPort(struct audio_port_v7 *port) const;
+
virtual void addAudioProfile(const sp<AudioProfile> &profile) {
mProfiles.add(profile);
}
@@ -64,6 +67,8 @@
virtual void importAudioPort(const sp<AudioPort>& port, bool force = false);
+ virtual void importAudioPort(const audio_port_v7& port);
+
status_t checkGain(const struct audio_gain_config *gainConfig, int index) const {
if (index < 0 || (size_t)index >= mGains.size()) {
return BAD_VALUE;
@@ -92,6 +97,18 @@
audio_port_type_t mType;
audio_port_role_t mRole;
AudioProfileVector mProfiles; // AudioProfiles supported by this port (format, Rates, Channels)
+private:
+ template <typename T, std::enable_if_t<std::is_same<T, struct audio_port>::value
+ || std::is_same<T, struct audio_port_v7>::value, int> = 0>
+ void toAudioPortBase(T* port) const {
+ port->role = mRole;
+ port->type = mType;
+ strlcpy(port->name, mName.c_str(), AUDIO_PORT_MAX_NAME_LEN);
+ port->num_gains = std::min(mGains.size(), (size_t) AUDIO_PORT_MAX_GAINS);
+ for (size_t i = 0; i < port->num_gains; i++) {
+ port->gains[i] = mGains[i]->getGain();
+ }
+ }
};
diff --git a/media/libaudiofoundation/include/media/AudioProfile.h b/media/libaudiofoundation/include/media/AudioProfile.h
index 730138a..ebe855e 100644
--- a/media/libaudiofoundation/include/media/AudioProfile.h
+++ b/media/libaudiofoundation/include/media/AudioProfile.h
@@ -105,6 +105,8 @@
bool hasDynamicProfile() const;
bool hasDynamicRateFor(audio_format_t format) const;
+ bool contains(const sp<AudioProfile>& profile) const;
+
virtual void dump(std::string *dst, int spaces) const;
bool equals(const AudioProfileVector& other) const;
diff --git a/media/libaudiofoundation/include/media/DeviceDescriptorBase.h b/media/libaudiofoundation/include/media/DeviceDescriptorBase.h
index 0cbd1de..9ad8d3d 100644
--- a/media/libaudiofoundation/include/media/DeviceDescriptorBase.h
+++ b/media/libaudiofoundation/include/media/DeviceDescriptorBase.h
@@ -54,6 +54,7 @@
// AudioPort
virtual void toAudioPort(struct audio_port *port) const;
+ virtual void toAudioPort(struct audio_port_v7 *port) const;
status_t setEncapsulationModes(uint32_t encapsulationModes);
status_t setEncapsulationMetadataTypes(uint32_t encapsulationMetadataTypes);
@@ -79,6 +80,18 @@
AudioDeviceTypeAddr mDeviceTypeAddr;
uint32_t mEncapsulationModes = 0;
uint32_t mEncapsulationMetadataTypes = 0;
+private:
+ template <typename T, std::enable_if_t<std::is_same<T, struct audio_port>::value
+ || std::is_same<T, struct audio_port_v7>::value, int> = 0>
+ void toAudioPortInternal(T* port) const {
+ AudioPort::toAudioPort(port);
+ 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());
+ }
};
using DeviceDescriptorBaseVector = std::vector<sp<DeviceDescriptorBase>>;
diff --git a/media/libaudiohal/impl/DeviceHalHidl.cpp b/media/libaudiohal/impl/DeviceHalHidl.cpp
index 7d0d83d..c2f9376 100644
--- a/media/libaudiohal/impl/DeviceHalHidl.cpp
+++ b/media/libaudiohal/impl/DeviceHalHidl.cpp
@@ -388,6 +388,33 @@
return processReturn("getAudioPort", ret, retval);
}
+status_t DeviceHalHidl::getAudioPort(struct audio_port_v7 *port) {
+ if (mDevice == 0) return NO_INIT;
+ status_t status = NO_ERROR;
+#if MAJOR_VERSION >= 7
+ AudioPort hidlPort;
+ HidlUtils::audioPortFromHal(*port, &hidlPort);
+ Result retval;
+ Return<void> ret = mDevice->getAudioPort(
+ hidlPort,
+ [&](Result r, const AudioPort& p) {
+ retval = r;
+ if (retval == Result::OK) {
+ HidlUtils::audioPortToHal(p, port);
+ }
+ });
+ status = processReturn("getAudioPort", ret, retval);
+#else
+ struct audio_port audioPort = {};
+ audio_populate_audio_port(port, &audioPort);
+ status = getAudioPort(&audioPort);
+ if (status == NO_ERROR) {
+ audio_populate_audio_port_v7(&audioPort, port);
+ }
+#endif
+ return status;
+}
+
status_t DeviceHalHidl::setAudioPortConfig(const struct audio_port_config *config) {
if (mDevice == 0) return NO_INIT;
AudioPortConfig hidlConfig;
diff --git a/media/libaudiohal/impl/DeviceHalHidl.h b/media/libaudiohal/impl/DeviceHalHidl.h
index d342d4a..abd4ad5 100644
--- a/media/libaudiohal/impl/DeviceHalHidl.h
+++ b/media/libaudiohal/impl/DeviceHalHidl.h
@@ -107,6 +107,9 @@
// Fills the list of supported attributes for a given audio port.
virtual status_t getAudioPort(struct audio_port *port);
+ // Fills the list of supported attributes for a given audio port.
+ virtual status_t getAudioPort(struct audio_port_v7 *port);
+
// Set audio port configuration.
virtual status_t setAudioPortConfig(const struct audio_port_config *config);
diff --git a/media/libaudiohal/impl/DeviceHalLocal.cpp b/media/libaudiohal/impl/DeviceHalLocal.cpp
index 8021d92..aa9e477 100644
--- a/media/libaudiohal/impl/DeviceHalLocal.cpp
+++ b/media/libaudiohal/impl/DeviceHalLocal.cpp
@@ -180,6 +180,16 @@
return mDev->get_audio_port(mDev, port);
}
+status_t DeviceHalLocal::getAudioPort(struct audio_port_v7 *port) {
+ struct audio_port audioPort = {};
+ audio_populate_audio_port(port, &audioPort);
+ status_t status = getAudioPort(&audioPort);
+ if (status == NO_ERROR) {
+ audio_populate_audio_port_v7(&audioPort, port);
+ }
+ return status;
+}
+
status_t DeviceHalLocal::setAudioPortConfig(const struct audio_port_config *config) {
if (version() >= AUDIO_DEVICE_API_VERSION_3_0)
return mDev->set_audio_port_config(mDev, config);
diff --git a/media/libaudiohal/impl/DeviceHalLocal.h b/media/libaudiohal/impl/DeviceHalLocal.h
index d85e2a7..195204b 100644
--- a/media/libaudiohal/impl/DeviceHalLocal.h
+++ b/media/libaudiohal/impl/DeviceHalLocal.h
@@ -100,6 +100,9 @@
// Fills the list of supported attributes for a given audio port.
virtual status_t getAudioPort(struct audio_port *port);
+ // Fills the list of supported attributes for a given audio port.
+ virtual status_t getAudioPort(struct audio_port_v7 *port);
+
// Set audio port configuration.
virtual status_t setAudioPortConfig(const struct audio_port_config *config);
diff --git a/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h b/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h
index 1e04b21..29ef011 100644
--- a/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h
+++ b/media/libaudiohal/include/media/audiohal/DeviceHalInterface.h
@@ -106,6 +106,9 @@
// Fills the list of supported attributes for a given audio port.
virtual status_t getAudioPort(struct audio_port *port) = 0;
+ // Fills the list of supported attributes for a given audio port.
+ virtual status_t getAudioPort(struct audio_port_v7 *port) = 0;
+
// Set audio port configuration.
virtual status_t setAudioPortConfig(const struct audio_port_config *config) = 0;
diff --git a/media/libmediahelper/AudioSanitizer.cpp b/media/libmediahelper/AudioSanitizer.cpp
index 44ca956..9223823 100644
--- a/media/libmediahelper/AudioSanitizer.cpp
+++ b/media/libmediahelper/AudioSanitizer.cpp
@@ -69,15 +69,16 @@
return safetyNetLog(status, bugNumber);
}
-/** returns BAD_VALUE if sanitization was required. */
-status_t AudioSanitizer::sanitizeAudioPort(
- struct audio_port *port, const char *bugNumber)
-{
+namespace {
+
+template <typename T, std::enable_if_t<std::is_same<T, struct audio_port>::value
+ || std::is_same<T, struct audio_port_v7>::value, int> = 0>
+static status_t sanitizeAudioPortInternal(T *port, const char *bugNumber = nullptr) {
status_t status = NO_ERROR;
if (preventStringOverflow(port->name)) {
status = BAD_VALUE;
}
- if (sanitizeAudioPortConfig(&port->active_config) != NO_ERROR) {
+ if (AudioSanitizer::sanitizeAudioPortConfig(&port->active_config) != NO_ERROR) {
status = BAD_VALUE;
}
if (port->type == AUDIO_PORT_TYPE_DEVICE &&
@@ -87,6 +88,22 @@
return safetyNetLog(status, bugNumber);
}
+} // namespace
+
+/** returns BAD_VALUE if sanitization was required. */
+status_t AudioSanitizer::sanitizeAudioPort(
+ struct audio_port *port, const char *bugNumber)
+{
+ return sanitizeAudioPortInternal(port, bugNumber);
+}
+
+/** returns BAD_VALUE if sanitization was required. */
+status_t AudioSanitizer::sanitizeAudioPort(
+ struct audio_port_v7 *port, const char *bugNumber)
+{
+ return sanitizeAudioPortInternal(port, bugNumber);
+}
+
/** returns BAD_VALUE if sanitization was required. */
status_t AudioSanitizer::sanitizeAudioPatch(
struct audio_patch *patch, const char *bugNumber)
diff --git a/media/libmediahelper/include/media/AudioSanitizer.h b/media/libmediahelper/include/media/AudioSanitizer.h
index 1475c7b..84bcb62 100644
--- a/media/libmediahelper/include/media/AudioSanitizer.h
+++ b/media/libmediahelper/include/media/AudioSanitizer.h
@@ -38,6 +38,9 @@
static status_t sanitizeAudioPort(
struct audio_port *port, const char *bugNumber = nullptr);
+ static status_t sanitizeAudioPort(
+ struct audio_port_v7 *port, const char *bugNumber = nullptr);
+
static status_t sanitizeAudioPatch(
struct audio_patch *patch, const char *bugNumber = nullptr);
};
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 2ff6af5..14ed2ad 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -266,7 +266,7 @@
struct audio_port *ports);
/* Get attributes for a given audio port */
- virtual status_t getAudioPort(struct audio_port *port);
+ virtual status_t getAudioPort(struct audio_port_v7 *port);
/* Create an audio patch between several source and sink ports */
virtual status_t createAudioPatch(const struct audio_patch *patch,
diff --git a/services/audioflinger/AudioHwDevice.cpp b/services/audioflinger/AudioHwDevice.cpp
index dda164c..16b25f6 100644
--- a/services/audioflinger/AudioHwDevice.cpp
+++ b/services/audioflinger/AudioHwDevice.cpp
@@ -98,5 +98,9 @@
return mHwDevice->supportsAudioPatches(&result) == OK ? result : false;
}
+status_t AudioHwDevice::getAudioPort(struct audio_port_v7 *port) const {
+ return mHwDevice->getAudioPort(port);
+}
+
}; // namespace android
diff --git a/services/audioflinger/AudioHwDevice.h b/services/audioflinger/AudioHwDevice.h
index 6709d17..fc2c693 100644
--- a/services/audioflinger/AudioHwDevice.h
+++ b/services/audioflinger/AudioHwDevice.h
@@ -83,6 +83,8 @@
bool supportsAudioPatches() const;
+ status_t getAudioPort(struct audio_port_v7 *port) const;
+
private:
const audio_module_handle_t mHandle;
const char * const mModuleName;
diff --git a/services/audioflinger/PatchPanel.cpp b/services/audioflinger/PatchPanel.cpp
index b58fd8b..b956b96 100644
--- a/services/audioflinger/PatchPanel.cpp
+++ b/services/audioflinger/PatchPanel.cpp
@@ -55,8 +55,7 @@
}
/* Get supported attributes for a given audio port */
-status_t AudioFlinger::getAudioPort(struct audio_port *port)
-{
+status_t AudioFlinger::getAudioPort(struct audio_port_v7 *port) {
Mutex::Autolock _l(mLock);
return mPatchPanel.getAudioPort(port);
}
@@ -103,10 +102,22 @@
}
/* Get supported attributes for a given audio port */
-status_t AudioFlinger::PatchPanel::getAudioPort(struct audio_port *port __unused)
+status_t AudioFlinger::PatchPanel::getAudioPort(struct audio_port_v7 *port)
{
- ALOGV(__func__);
- return NO_ERROR;
+ if (port->type != AUDIO_PORT_TYPE_DEVICE) {
+ // Only query the HAL when the port is a device.
+ // TODO: implement getAudioPort for mix.
+ return INVALID_OPERATION;
+ }
+ AudioHwDevice* hwDevice = findAudioHwDeviceByModule(port->ext.device.hw_module);
+ if (hwDevice == nullptr) {
+ ALOGW("%s cannot find hw module %d", __func__, port->ext.device.hw_module);
+ return BAD_VALUE;
+ }
+ if (!hwDevice->supportsAudioPatches()) {
+ return INVALID_OPERATION;
+ }
+ return hwDevice->getAudioPort(port);
}
/* Connect a patch between several source and sink ports */
diff --git a/services/audioflinger/PatchPanel.h b/services/audioflinger/PatchPanel.h
index 89d4eb1..2568dd3 100644
--- a/services/audioflinger/PatchPanel.h
+++ b/services/audioflinger/PatchPanel.h
@@ -52,7 +52,7 @@
struct audio_port *ports);
/* Get supported attributes for a given audio port */
- status_t getAudioPort(struct audio_port *port);
+ status_t getAudioPort(struct audio_port_v7 *port);
/* Create a patch between several source and sink ports */
status_t createAudioPatch(const struct audio_patch *patch,
diff --git a/services/audiopolicy/AudioPolicyInterface.h b/services/audiopolicy/AudioPolicyInterface.h
index 93819f5..b00426f 100644
--- a/services/audiopolicy/AudioPolicyInterface.h
+++ b/services/audiopolicy/AudioPolicyInterface.h
@@ -444,6 +444,8 @@
// sessions to be preempted on modules that do not support sound trigger
// recognition concurrently with audio capture.
virtual void setSoundTriggerCaptureState(bool active) = 0;
+
+ virtual status_t getAudioPort(struct audio_port_v7 *port) = 0;
};
extern "C" AudioPolicyInterface* createAudioPolicyManager(AudioPolicyClientInterface *clientInterface);
diff --git a/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h
index ca29591..80190b7 100644
--- a/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h
@@ -88,6 +88,7 @@
// AudioPort
virtual void toAudioPort(struct audio_port *port) const;
+ virtual void toAudioPort(struct audio_port_v7 *port) const;
void importAudioPortAndPickAudioProfile(const sp<PolicyAudioPort>& policyPort,
bool force = false);
@@ -97,6 +98,13 @@
void dump(String8 *dst, int spaces, int index, bool verbose = true) const;
private:
+ template <typename T, std::enable_if_t<std::is_same<T, struct audio_port>::value
+ || std::is_same<T, struct audio_port_v7>::value, int> = 0>
+ void toAudioPortInternal(T* port) const {
+ DeviceDescriptorBase::toAudioPort(port);
+ port->ext.device.hw_module = getModuleHandle();
+ }
+
std::string mTagName; // Unique human readable identifier for a device port found in conf file.
FormatVector mEncodedFormats;
audio_format_t mCurrentEncodedFormat;
diff --git a/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
index 6ff1a98..e43ca0f 100644
--- a/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
@@ -160,8 +160,12 @@
void DeviceDescriptor::toAudioPort(struct audio_port *port) const
{
ALOGV("DeviceDescriptor::toAudioPort() handle %d type %08x", mId, mDeviceTypeAddr.mType);
- DeviceDescriptorBase::toAudioPort(port);
- port->ext.device.hw_module = getModuleHandle();
+ toAudioPortInternal(port);
+}
+
+void DeviceDescriptor::toAudioPort(struct audio_port_v7 *port) const {
+ ALOGV("DeviceDescriptor::toAudioPort() v7 handle %d type %08x", mId, mDeviceTypeAddr.mType);
+ toAudioPortInternal(port);
}
void DeviceDescriptor::importAudioPortAndPickAudioProfile(
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 4a3e31f..7b8a2ea 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -4833,7 +4833,15 @@
}
if (state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE) {
- // first list already open outputs that can be routed to this device
+ // first call getAudioPort to get the supported attributes from the HAL
+ struct audio_port_v7 port = {};
+ device->toAudioPort(&port);
+ status_t status = mpClientInterface->getAudioPort(&port);
+ if (status == NO_ERROR) {
+ device->importAudioPort(port);
+ }
+
+ // then 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)
@@ -4895,8 +4903,8 @@
deviceType, address.string(), profile.get(), profile->getName().c_str());
desc = new SwAudioOutputDescriptor(profile, mpClientInterface);
audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
- status_t status = desc->open(nullptr, DeviceVector(device),
- AUDIO_STREAM_DEFAULT, AUDIO_OUTPUT_FLAG_NONE, &output);
+ status = desc->open(nullptr, DeviceVector(device),
+ AUDIO_STREAM_DEFAULT, AUDIO_OUTPUT_FLAG_NONE, &output);
if (status == NO_ERROR) {
// Here is where the out_set_parameters() for card & device gets called
@@ -4920,9 +4928,8 @@
config.offload_info.channel_mask = config.channel_mask;
config.offload_info.format = config.format;
- status_t status = desc->open(&config, DeviceVector(device),
- AUDIO_STREAM_DEFAULT,
- AUDIO_OUTPUT_FLAG_NONE, &output);
+ status = desc->open(&config, DeviceVector(device),
+ AUDIO_STREAM_DEFAULT, AUDIO_OUTPUT_FLAG_NONE, &output);
if (status != NO_ERROR) {
output = AUDIO_IO_HANDLE_NONE;
}
@@ -4952,8 +4959,8 @@
// open a duplicating output thread for the new output and the primary output
sp<SwAudioOutputDescriptor> dupOutputDesc =
new SwAudioOutputDescriptor(NULL, mpClientInterface);
- status_t status = dupOutputDesc->openDuplicating(mPrimaryOutput, desc,
- &duplicatedOutput);
+ status = dupOutputDesc->openDuplicating(mPrimaryOutput, desc,
+ &duplicatedOutput);
if (status == NO_ERROR) {
// add duplicated output descriptor
addOutput(duplicatedOutput, dupOutputDesc);
diff --git a/services/audiopolicy/service/AudioPolicyClientImpl.cpp b/services/audiopolicy/service/AudioPolicyClientImpl.cpp
index 9fa7a53..1cc6d48 100644
--- a/services/audiopolicy/service/AudioPolicyClientImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyClientImpl.cpp
@@ -246,4 +246,14 @@
mAudioPolicyService->mCaptureStateNotifier.setCaptureState(active);
}
+status_t AudioPolicyService::AudioPolicyClient::getAudioPort(struct audio_port_v7 *port)
+{
+ sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
+ if (af == 0) {
+ ALOGW("%s: could not get AudioFlinger", __func__);
+ return PERMISSION_DENIED;
+ }
+ return af->getAudioPort(port);
+}
+
} // namespace android
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index 0b218c2..70a0e3a 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -765,6 +765,8 @@
void setSoundTriggerCaptureState(bool active) override;
+ status_t getAudioPort(struct audio_port_v7 *port) override;
+
private:
AudioPolicyService *mAudioPolicyService;
};
diff --git a/services/audiopolicy/tests/AudioPolicyTestClient.h b/services/audiopolicy/tests/AudioPolicyTestClient.h
index c628e70..fa6b90f 100644
--- a/services/audiopolicy/tests/AudioPolicyTestClient.h
+++ b/services/audiopolicy/tests/AudioPolicyTestClient.h
@@ -87,6 +87,9 @@
audio_session_t sessionId __unused,
bool suspended __unused) {}
void setSoundTriggerCaptureState(bool active __unused) override {};
+ status_t getAudioPort(struct audio_port_v7 *port __unused) override {
+ return INVALID_OPERATION;
+ };
};
} // namespace android