Make audio port in policy not derive from audio port base
This patch aims to make the structure for libaudiofoundation and policy
stuff simpler, including:
1. Make AudioPortBase as AudioPort in libaudiofoundation. Create
PolicyAudioPort that contains policy related stuff, which is used by
audiopolicy.
2. Make AudioPortConfigBase as AudioPortConfig in libaudiofoundation.
Create PolicyAudioPortConfig that contains policy related stuff.
3. DeviceDescriptor derives from AudioPort, AudioPortConfig, PolicyAudioPort
and PolicyAudioPortConfig. IOProfile derives from AudioPort,
PolicyAudioPort. AudioInputDescriptor/AudioOutputDescriptor derives from
AudioPortConfig, PolicyAudioPortConfig.
Test: atest AudioTrackTest, AudioRecordTest, AudioManagerTest
Test: atest audiopolicy_tests, AudioHostTest
Test: audio smoke test
Bug: 135621476
Change-Id: I40299d95dda3b3fc0ea88b079f2fe38d8f7e5b31
Merged-In: I40299d95dda3b3fc0ea88b079f2fe38d8f7e5b31
diff --git a/media/libaudiofoundation/AudioPortBase.cpp b/media/libaudiofoundation/AudioPortBase.cpp
index 8b41be7..b73f8bf 100644
--- a/media/libaudiofoundation/AudioPortBase.cpp
+++ b/media/libaudiofoundation/AudioPortBase.cpp
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#define LOG_TAG "AudioPortBase"
#include <algorithm>
@@ -22,7 +23,22 @@
namespace android {
-void AudioPortBase::toAudioPort(struct audio_port *port) const {
+void AudioPort::importAudioPort(const sp<AudioPort>& port, bool force __unused)
+{
+ for (const auto& profileToImport : port->mProfiles) {
+ // Import only valid port, i.e. valid format, non empty rates and channels masks
+ if (!profileToImport->isValid()) {
+ continue;
+ }
+ if (std::find_if(mProfiles.begin(), mProfiles.end(),
+ [profileToImport](const auto &profile) {
+ return *profile == *profileToImport; }) == mProfiles.end()) {
+ addAudioProfile(profileToImport);
+ }
+ }
+}
+
+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.
FormatSet flatenedFormats;
@@ -64,7 +80,7 @@
}
}
-void AudioPortBase::dump(std::string *dst, int spaces, bool verbose) const {
+void AudioPort::dump(std::string *dst, int spaces, bool verbose) const {
if (!mName.empty()) {
dst->append(base::StringPrintf("%*s- name: %s\n", spaces, "", mName.c_str()));
}
@@ -84,4 +100,92 @@
}
}
+void AudioPort::log(const char* indent) const
+{
+ ALOGI("%s Port[nm:%s, type:%d, role:%d]", indent, mName.c_str(), mType, mRole);
+}
+
+// --- AudioPortConfig class implementation
+
+status_t AudioPortConfig::applyAudioPortConfig(
+ const struct audio_port_config *config,
+ struct audio_port_config *backupConfig __unused)
+{
+ if (config->config_mask & AUDIO_PORT_CONFIG_SAMPLE_RATE) {
+ mSamplingRate = config->sample_rate;
+ }
+ if (config->config_mask & AUDIO_PORT_CONFIG_CHANNEL_MASK) {
+ mChannelMask = config->channel_mask;
+ }
+ if (config->config_mask & AUDIO_PORT_CONFIG_FORMAT) {
+ mFormat = config->format;
+ }
+ if (config->config_mask & AUDIO_PORT_CONFIG_GAIN) {
+ mGain = config->gain;
+ }
+
+ return NO_ERROR;
+}
+
+namespace {
+
+template<typename T>
+void updateField(
+ const T& portConfigField, T audio_port_config::*port_config_field,
+ struct audio_port_config *dstConfig, const struct audio_port_config *srcConfig,
+ unsigned int configMask, T defaultValue)
+{
+ if (dstConfig->config_mask & configMask) {
+ if ((srcConfig != nullptr) && (srcConfig->config_mask & configMask)) {
+ dstConfig->*port_config_field = srcConfig->*port_config_field;
+ } else {
+ dstConfig->*port_config_field = portConfigField;
+ }
+ } else {
+ dstConfig->*port_config_field = defaultValue;
+ }
+}
+
+} // namespace
+
+void AudioPortConfig::toAudioPortConfig(
+ struct audio_port_config *dstConfig,
+ const struct audio_port_config *srcConfig) const
+{
+ updateField(mSamplingRate, &audio_port_config::sample_rate,
+ dstConfig, srcConfig, AUDIO_PORT_CONFIG_SAMPLE_RATE, 0u);
+ updateField(mChannelMask, &audio_port_config::channel_mask,
+ dstConfig, srcConfig, AUDIO_PORT_CONFIG_CHANNEL_MASK,
+ (audio_channel_mask_t)AUDIO_CHANNEL_NONE);
+ updateField(mFormat, &audio_port_config::format,
+ dstConfig, srcConfig, AUDIO_PORT_CONFIG_FORMAT, AUDIO_FORMAT_INVALID);
+ dstConfig->id = mId;
+
+ sp<AudioPort> audioport = getAudioPort();
+ if ((dstConfig->config_mask & AUDIO_PORT_CONFIG_GAIN) && audioport != NULL) {
+ dstConfig->gain = mGain;
+ if ((srcConfig != NULL) && (srcConfig->config_mask & AUDIO_PORT_CONFIG_GAIN)
+ && audioport->checkGain(&srcConfig->gain, srcConfig->gain.index) == OK) {
+ dstConfig->gain = srcConfig->gain;
+ }
+ } else {
+ dstConfig->gain.index = -1;
+ }
+ if (dstConfig->gain.index != -1) {
+ dstConfig->config_mask |= AUDIO_PORT_CONFIG_GAIN;
+ } else {
+ dstConfig->config_mask &= ~AUDIO_PORT_CONFIG_GAIN;
+ }
+}
+
+bool AudioPortConfig::hasGainController(bool canUseForVolume) const
+{
+ sp<AudioPort> audioport = getAudioPort();
+ if (!audioport) {
+ return false;
+ }
+ return canUseForVolume ? audioport->getGains().canUseForVolume()
+ : audioport->getGains().size() > 0;
+}
+
}
\ No newline at end of file
diff --git a/media/libaudiofoundation/include/media/AudioPortBase.h b/media/libaudiofoundation/include/media/AudioPortBase.h
index 869487d..b8d54de 100644
--- a/media/libaudiofoundation/include/media/AudioPortBase.h
+++ b/media/libaudiofoundation/include/media/AudioPortBase.h
@@ -27,13 +27,13 @@
namespace android {
-class AudioPortBase : public virtual RefBase
+class AudioPort : public virtual RefBase
{
public:
- AudioPortBase(const std::string& name, audio_port_type_t type, audio_port_role_t role) :
+ AudioPort(const std::string& name, audio_port_type_t type, audio_port_role_t role) :
mName(name), mType(type), mRole(role) {}
- virtual ~AudioPortBase() = default;
+ virtual ~AudioPort() = default;
void setName(const std::string &name) { mName = name; }
const std::string &getName() const { return mName; }
@@ -41,8 +41,6 @@
audio_port_type_t getType() const { return mType; }
audio_port_role_t getRole() const { return mRole; }
- virtual const std::string getTagName() const = 0;
-
void setGains(const AudioGains &gains) { mGains = gains; }
const AudioGains &getGains() const { return mGains; }
@@ -57,9 +55,13 @@
bool hasValidAudioProfile() const { return mProfiles.hasValidProfile(); }
+ bool hasDynamicAudioProfile() const { return mProfiles.hasDynamicProfile(); }
+
void setAudioProfiles(const AudioProfileVector &profiles) { mProfiles = profiles; }
AudioProfileVector &getAudioProfiles() { return mProfiles; }
+ virtual void importAudioPort(const sp<AudioPort>& port, bool force = false);
+
status_t checkGain(const struct audio_gain_config *gainConfig, int index) const {
if (index < 0 || (size_t)index >= mGains.size()) {
return BAD_VALUE;
@@ -75,6 +77,8 @@
void dump(std::string *dst, int spaces, bool verbose = true) const;
+ void log(const char* indent) const;
+
AudioGains mGains; // gain controllers
protected:
std::string mName;
@@ -84,24 +88,31 @@
};
-class AudioPortConfigBase : public virtual RefBase
+class AudioPortConfig : public virtual RefBase
{
public:
- virtual ~AudioPortConfigBase() = default;
+ virtual ~AudioPortConfig() = default;
+
+ virtual sp<AudioPort> getAudioPort() const = 0;
virtual status_t applyAudioPortConfig(const struct audio_port_config *config,
- struct audio_port_config *backupConfig = NULL) = 0;
+ struct audio_port_config *backupConfig = NULL);
+
virtual void toAudioPortConfig(struct audio_port_config *dstConfig,
- const struct audio_port_config *srcConfig = NULL) const = 0;
+ const struct audio_port_config *srcConfig = NULL) const;
unsigned int getSamplingRate() const { return mSamplingRate; }
audio_format_t getFormat() const { return mFormat; }
audio_channel_mask_t getChannelMask() const { return mChannelMask; }
+ audio_port_handle_t getId() const { return mId; }
+
+ bool hasGainController(bool canUseForVolume = false) const;
protected:
unsigned int mSamplingRate = 0u;
audio_format_t mFormat = AUDIO_FORMAT_INVALID;
audio_channel_mask_t mChannelMask = AUDIO_CHANNEL_NONE;
+ audio_port_handle_t mId = AUDIO_PORT_HANDLE_NONE;
struct audio_gain_config mGain = { .index = -1 };
};