Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f21a5174 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge changes I70ebe6bc,I9a6d6401,Icbde26fe,I40299d95,Ifd8eb281, ...

* changes:
  Create DeviceDescriptorBase.
  Copy DeviceDescriptor to libaudiofoundation.
  Rename AudioPort and PolicyAudioPort accordingly.
  Make audio port in policy not derive from audio port base
  Rename AudioProfileVector.h as AudioProfileVectorHelper.h
  Leave AudioProfileVector only in libaudiofoundation.
parents a9c48964 6713a382
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -10,11 +10,13 @@ cc_library_shared {

    srcs: [
        "AudioGain.cpp",
        "AudioPortBase.cpp",
        "AudioPort.cpp",
        "AudioProfile.cpp",
        "DeviceDescriptorBase.cpp",
    ],

    shared_libs: [
        "libaudioutils",
        "libbase",
        "libbinder",
        "liblog",
+191 −0
Original line number Diff line number Diff line
@@ -13,22 +13,38 @@
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#define LOG_TAG "AudioPort"

#include <algorithm>

#include <android-base/stringprintf.h>
#include <media/AudioPortBase.h>
#include <media/AudioPort.h>
#include <utils/Log.h>

namespace android {

void AudioPortFoundation::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;
    SampleRateSet flatenedRates;
    ChannelMaskSet flatenedChannels;
    for (const auto& profile : *getAudioProfileVectorBase()) {
    for (const auto& profile : mProfiles) {
        if (profile->isValid()) {
            audio_format_t formatToExport = profile->getFormat();
            const SampleRateSet &ratesToExport = profile->getSampleRates();
@@ -64,13 +80,13 @@ void AudioPortFoundation::toAudioPort(struct audio_port *port) const {
    }
}

void AudioPortFoundation::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()));
    }
    if (verbose) {
        std::string profilesStr;
        getAudioProfileVectorBase()->dump(&profilesStr, spaces);
        mProfiles.dump(&profilesStr, spaces);
        dst->append(profilesStr);

        if (mGains.size() != 0) {
@@ -84,4 +100,92 @@ void AudioPortFoundation::dump(std::string *dst, int spaces, bool verbose) const
    }
}

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;
}

}
+11 −11
Original line number Diff line number Diff line
/*
 * Copyright (C) 2015 The Android Open Source Project
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
@@ -118,14 +118,14 @@ void AudioProfile::dump(std::string *dst, int spaces) const
    }
}

ssize_t AudioProfileVectorBase::add(const sp<AudioProfile> &profile)
ssize_t AudioProfileVector::add(const sp<AudioProfile> &profile)
{
    ssize_t index = size();
    push_back(profile);
    return index;
}

void AudioProfileVectorBase::clearProfiles()
void AudioProfileVector::clearProfiles()
{
    for (auto it = begin(); it != end();) {
        if ((*it)->isDynamicFormat() && (*it)->hasValidFormat()) {
@@ -137,7 +137,7 @@ void AudioProfileVectorBase::clearProfiles()
    }
}

sp<AudioProfile> AudioProfileVectorBase::getFirstValidProfile() const
sp<AudioProfile> AudioProfileVector::getFirstValidProfile() const
{
    for (const auto &profile : *this) {
        if (profile->isValid()) {
@@ -147,7 +147,7 @@ sp<AudioProfile> AudioProfileVectorBase::getFirstValidProfile() const
    return nullptr;
}

sp<AudioProfile> AudioProfileVectorBase::getFirstValidProfileFor(audio_format_t format) const
sp<AudioProfile> AudioProfileVector::getFirstValidProfileFor(audio_format_t format) const
{
    for (const auto &profile : *this) {
        if (profile->isValid() && profile->getFormat() == format) {
@@ -157,7 +157,7 @@ sp<AudioProfile> AudioProfileVectorBase::getFirstValidProfileFor(audio_format_t
    return nullptr;
}

FormatVector AudioProfileVectorBase::getSupportedFormats() const
FormatVector AudioProfileVector::getSupportedFormats() const
{
    FormatVector supportedFormats;
    for (const auto &profile : *this) {
@@ -168,7 +168,7 @@ FormatVector AudioProfileVectorBase::getSupportedFormats() const
    return supportedFormats;
}

bool AudioProfileVectorBase::hasDynamicChannelsFor(audio_format_t format) const
bool AudioProfileVector::hasDynamicChannelsFor(audio_format_t format) const
{
    for (const auto &profile : *this) {
        if (profile->getFormat() == format && profile->isDynamicChannels()) {
@@ -178,7 +178,7 @@ bool AudioProfileVectorBase::hasDynamicChannelsFor(audio_format_t format) const
    return false;
}

bool AudioProfileVectorBase::hasDynamicFormat() const
bool AudioProfileVector::hasDynamicFormat() const
{
    for (const auto &profile : *this) {
        if (profile->isDynamicFormat()) {
@@ -188,7 +188,7 @@ bool AudioProfileVectorBase::hasDynamicFormat() const
    return false;
}

bool AudioProfileVectorBase::hasDynamicProfile() const
bool AudioProfileVector::hasDynamicProfile() const
{
    for (const auto &profile : *this) {
        if (profile->isDynamic()) {
@@ -198,7 +198,7 @@ bool AudioProfileVectorBase::hasDynamicProfile() const
    return false;
}

bool AudioProfileVectorBase::hasDynamicRateFor(audio_format_t format) const
bool AudioProfileVector::hasDynamicRateFor(audio_format_t format) const
{
    for (const auto &profile : *this) {
        if (profile->getFormat() == format && profile->isDynamicRate()) {
@@ -208,7 +208,7 @@ bool AudioProfileVectorBase::hasDynamicRateFor(audio_format_t format) const
    return false;
}

void AudioProfileVectorBase::dump(std::string *dst, int spaces) const
void AudioProfileVector::dump(std::string *dst, int spaces) const
{
    dst->append(base::StringPrintf("%*s- Profiles:\n", spaces, ""));
    for (size_t i = 0; i < size(); i++) {
+113 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#define LOG_TAG "DeviceDescriptorBase"
//#define LOG_NDEBUG 0

#include <android-base/stringprintf.h>
#include <audio_utils/string.h>
#include <media/DeviceDescriptorBase.h>
#include <media/TypeConverter.h>

namespace android {

DeviceDescriptorBase::DeviceDescriptorBase(audio_devices_t type) :
    AudioPort("", AUDIO_PORT_TYPE_DEVICE,
              audio_is_output_device(type) ? AUDIO_PORT_ROLE_SINK :
                                             AUDIO_PORT_ROLE_SOURCE),
    mDeviceType(type)
{
    if (audio_is_remote_submix_device(type)) {
        mAddress = "0";
    }
}

void DeviceDescriptorBase::toAudioPortConfig(struct audio_port_config *dstConfig,
                                             const struct audio_port_config *srcConfig) const
{
    dstConfig->config_mask = AUDIO_PORT_CONFIG_GAIN;
    if (mSamplingRate != 0) {
        dstConfig->config_mask |= AUDIO_PORT_CONFIG_SAMPLE_RATE;
    }
    if (mChannelMask != AUDIO_CHANNEL_NONE) {
        dstConfig->config_mask |= AUDIO_PORT_CONFIG_CHANNEL_MASK;
    }
    if (mFormat != AUDIO_FORMAT_INVALID) {
        dstConfig->config_mask |= AUDIO_PORT_CONFIG_FORMAT;
    }

    if (srcConfig != NULL) {
        dstConfig->config_mask |= srcConfig->config_mask;
    }

    AudioPortConfig::toAudioPortConfig(dstConfig, srcConfig);

    dstConfig->role = audio_is_output_device(mDeviceType) ?
                        AUDIO_PORT_ROLE_SINK : AUDIO_PORT_ROLE_SOURCE;
    dstConfig->type = AUDIO_PORT_TYPE_DEVICE;
    dstConfig->ext.device.type = mDeviceType;

    (void)audio_utils_strlcpy_zerofill(dstConfig->ext.device.address, mAddress.c_str());
}

void DeviceDescriptorBase::toAudioPort(struct audio_port *port) const
{
    ALOGV("DeviceDescriptorBase::toAudioPort() handle %d type %08x", mId, mDeviceType);
    AudioPort::toAudioPort(port);
    toAudioPortConfig(&port->active_config);
    port->id = mId;
    port->ext.device.type = mDeviceType;
    (void)audio_utils_strlcpy_zerofill(port->ext.device.address, mAddress.c_str());
}

void DeviceDescriptorBase::dump(std::string *dst, int spaces, int index,
                                const char* extraInfo, bool verbose) const
{
    dst->append(base::StringPrintf("%*sDevice %d:\n", spaces, "", index + 1));
    if (mId != 0) {
        dst->append(base::StringPrintf("%*s- id: %2d\n", spaces, "", mId));
    }

    if (extraInfo != nullptr) {
        dst->append(extraInfo);
    }

    dst->append(base::StringPrintf("%*s- type: %-48s\n",
            spaces, "", ::android::toString(mDeviceType).c_str()));

    if (mAddress.size() != 0) {
        dst->append(base::StringPrintf("%*s- address: %-32s\n", spaces, "", mAddress.c_str()));
    }
    AudioPort::dump(dst, spaces, verbose);
}

std::string DeviceDescriptorBase::toString() const
{
    std::stringstream sstream;
    sstream << "type:0x" << std::hex << type() << ",@:" << mAddress;
    return sstream.str();
}

void DeviceDescriptorBase::log() const
{
    ALOGI("Device id:%d type:0x%08X:%s, addr:%s", mId,  mDeviceType,
          ::android::toString(mDeviceType).c_str(),
          mAddress.c_str());

    AudioPort::log("  ");
}

} // namespace android
+27 −38
Original line number Diff line number Diff line
@@ -27,13 +27,13 @@

namespace android {

class AudioPortFoundation : public virtual RefBase
class AudioPort : public virtual RefBase
{
public:
    AudioPortFoundation(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 ~AudioPortFoundation() = default;
    virtual ~AudioPort() = default;

    void setName(const std::string &name) { mName = name; }
    const std::string &getName() const { return mName; }
@@ -41,22 +41,26 @@ public:
    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; }

    virtual void toAudioPort(struct audio_port *port) const;

    virtual AudioProfileVectorBase* getAudioProfileVectorBase() const = 0;
    virtual void addAudioProfile(const sp<AudioProfile> &profile) {
        getAudioProfileVectorBase()->add(profile);
        mProfiles.add(profile);
    }
    virtual void clearAudioProfiles() {
        getAudioProfileVectorBase()->clearProfiles();
        mProfiles.clearProfiles();
    }

    bool hasValidAudioProfile() const { return getAudioProfileVectorBase()->hasValidProfile(); }
    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()) {
@@ -73,57 +77,42 @@ public:

    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;
    audio_port_type_t mType;
    audio_port_role_t mRole;
    AudioProfileVector mProfiles; // AudioProfiles supported by this port (format, Rates, Channels)
};

template <typename ProfileVector,
          typename = typename std::enable_if<std::is_base_of<
                  AudioProfileVectorBase, ProfileVector>::value>::type>
class AudioPortBase : public AudioPortFoundation
{
public:
    AudioPortBase(const std::string& name, audio_port_type_t type,  audio_port_role_t role) :
            AudioPortFoundation(name, type, role) {}

    virtual ~AudioPortBase() {}

    AudioProfileVectorBase* getAudioProfileVectorBase() const override {
        return static_cast<AudioProfileVectorBase*>(const_cast<ProfileVector*>(&mProfiles));
    }

    void addAudioProfile(const sp<AudioProfile> &profile) override { mProfiles.add(profile); }
    void clearAudioProfiles() override { return mProfiles.clearProfiles(); }

    void setAudioProfiles(const ProfileVector &profiles) { mProfiles = profiles; }
    ProfileVector &getAudioProfiles() { return mProfiles; }

protected:
    ProfileVector mProfiles; // AudioProfiles supported by this port (format, Rates, Channels)
};


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 };
};

Loading