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

Commit 80ffad94 authored by jiabin's avatar jiabin Committed by android-build-merger
Browse files

Merge changes I70ebe6bc,I9a6d6401,Icbde26fe,I40299d95,Ifd8eb281, ... am: f21a5174

am: 2350fffd

Change-Id: I7e5b5fc77af7a343fd11fd07d4b4a172294c3d88
parents 5f90ad42 2350fffd
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