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

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

Merge changes I1d2263f0,Iaa2c8046,Idcf09587,I8bdcd0da,If80513b6, ...

* changes:
  Add parcelable test for classes in libaudiofoundation.
  Add export header lib headers to libaudiofoundation_headers.
  Add equals functions for classes in libaudiofoundation.
  Make audio stuff parcelable.
  Clear up bit mask usage in audio policy.
  Make AudioGain parcelable.
parents 148cbe08 8ee49b4c
Loading
Loading
Loading
Loading
+14 −3
Original line number Diff line number Diff line
@@ -2,6 +2,16 @@ cc_library_headers {
    name: "libaudiofoundation_headers",
    vendor_available: true,
    export_include_dirs: ["include"],
    header_libs: [
        "libaudio_system_headers",
        "libaudioclient_headers",
        "libmedia_headers",
    ],
    export_header_lib_headers: [
        "libaudio_system_headers",
        "libaudioclient_headers",
        "libmedia_headers",
    ],
}

cc_library_shared {
@@ -9,6 +19,7 @@ cc_library_shared {
    vendor_available: true,

    srcs: [
        "AudioContainers.cpp",
        "AudioGain.cpp",
        "AudioPort.cpp",
        "AudioProfile.cpp",
@@ -25,12 +36,12 @@ cc_library_shared {
    ],

    header_libs: [
        "libaudio_system_headers",
        "libaudioclient_headers",
        "libaudiofoundation_headers",
    ],

    export_header_lib_headers: ["libaudiofoundation_headers"],
    export_header_lib_headers: [
        "libaudiofoundation_headers",
    ],

    cflags: [
        "-Werror",
+86 −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.
 */

#include <sstream>
#include <string>

#include <media/AudioContainers.h>

namespace android {

const DeviceTypeSet& getAudioDeviceOutAllSet() {
    static const DeviceTypeSet audioDeviceOutAllSet = DeviceTypeSet(
            std::begin(AUDIO_DEVICE_OUT_ALL_ARRAY),
            std::end(AUDIO_DEVICE_OUT_ALL_ARRAY));
    return audioDeviceOutAllSet;
}

const DeviceTypeSet& getAudioDeviceOutAllA2dpSet() {
    static const DeviceTypeSet audioDeviceOutAllA2dpSet = DeviceTypeSet(
            std::begin(AUDIO_DEVICE_OUT_ALL_A2DP_ARRAY),
            std::end(AUDIO_DEVICE_OUT_ALL_A2DP_ARRAY));
    return audioDeviceOutAllA2dpSet;
}

const DeviceTypeSet& getAudioDeviceOutAllScoSet() {
    static const DeviceTypeSet audioDeviceOutAllScoSet = DeviceTypeSet(
            std::begin(AUDIO_DEVICE_OUT_ALL_SCO_ARRAY),
            std::end(AUDIO_DEVICE_OUT_ALL_SCO_ARRAY));
    return audioDeviceOutAllScoSet;
}

const DeviceTypeSet& getAudioDeviceInAllSet() {
    static const DeviceTypeSet audioDeviceInAllSet = DeviceTypeSet(
            std::begin(AUDIO_DEVICE_IN_ALL_ARRAY),
            std::end(AUDIO_DEVICE_IN_ALL_ARRAY));
    return audioDeviceInAllSet;
}

bool deviceTypesToString(const DeviceTypeSet &deviceTypes, std::string &str) {
    bool ret = true;
    for (auto it = deviceTypes.begin(); it != deviceTypes.end();) {
        std::string deviceTypeStr;
        ret = audio_is_output_device(*it) ?
              OutputDeviceConverter::toString(*it, deviceTypeStr) :
              InputDeviceConverter::toString(*it, deviceTypeStr);
        if (!ret) {
            break;
        }
        str.append(deviceTypeStr);
        if (++it != deviceTypes.end()) {
            str.append(" , ");
        }
    }
    if (!ret) {
        str = "Unknown values";
    }
    return ret;
}

std::string dumpDeviceTypes(const DeviceTypeSet &deviceTypes) {
    std::string ret;
    for (auto it = deviceTypes.begin(); it != deviceTypes.end();) {
        std::stringstream ss;
        ss << "0x" << std::hex << (*it);
        ret.append(ss.str());
        if (++it != deviceTypes.end()) {
            ret.append(" , ");
        }
    }
    return ret;
}

} // namespace android
+85 −0
Original line number Diff line number Diff line
@@ -24,6 +24,8 @@
#define ALOGVV(a...) do { } while(0)
#endif

#include <algorithm>

#include <android-base/stringprintf.h>
#include <media/AudioGain.h>
#include <utils/Log.h>
@@ -111,4 +113,87 @@ void AudioGain::dump(std::string *dst, int spaces, int index) const
    dst->append(base::StringPrintf("%*s- max_ramp_ms: %d ms\n", spaces, "", mGain.max_ramp_ms));
}

bool AudioGain::equals(const sp<AudioGain>& other) const
{
    return other != nullptr &&
           mUseInChannelMask == other->mUseInChannelMask &&
           mUseForVolume == other->mUseForVolume &&
           // Compare audio gain
           mGain.mode == other->mGain.mode &&
           mGain.channel_mask == other->mGain.channel_mask &&
           mGain.min_value == other->mGain.min_value &&
           mGain.max_value == other->mGain.max_value &&
           mGain.default_value == other->mGain.default_value &&
           mGain.step_value == other->mGain.step_value &&
           mGain.min_ramp_ms == other->mGain.min_ramp_ms &&
           mGain.max_ramp_ms == other->mGain.max_ramp_ms;
}

status_t AudioGain::writeToParcel(android::Parcel *parcel) const
{
    status_t status = NO_ERROR;
    if ((status = parcel->writeInt32(mIndex)) != NO_ERROR) return status;
    if ((status = parcel->writeBool(mUseInChannelMask)) != NO_ERROR) return status;
    if ((status = parcel->writeBool(mUseForVolume)) != NO_ERROR) return status;
    if ((status = parcel->writeUint32(mGain.mode)) != NO_ERROR) return status;
    if ((status = parcel->writeUint32(mGain.channel_mask)) != NO_ERROR) return status;
    if ((status = parcel->writeInt32(mGain.min_value)) != NO_ERROR) return status;
    if ((status = parcel->writeInt32(mGain.max_value)) != NO_ERROR) return status;
    if ((status = parcel->writeInt32(mGain.default_value)) != NO_ERROR) return status;
    if ((status = parcel->writeUint32(mGain.step_value)) != NO_ERROR) return status;
    if ((status = parcel->writeUint32(mGain.min_ramp_ms)) != NO_ERROR) return status;
    status = parcel->writeUint32(mGain.max_ramp_ms);
    return status;
}

status_t AudioGain::readFromParcel(const android::Parcel *parcel)
{
    status_t status = NO_ERROR;
    if ((status = parcel->readInt32(&mIndex)) != NO_ERROR) return status;
    if ((status = parcel->readBool(&mUseInChannelMask)) != NO_ERROR) return status;
    if ((status = parcel->readBool(&mUseForVolume)) != NO_ERROR) return status;
    if ((status = parcel->readUint32(&mGain.mode)) != NO_ERROR) return status;
    if ((status = parcel->readUint32(&mGain.channel_mask)) != NO_ERROR) return status;
    if ((status = parcel->readInt32(&mGain.min_value)) != NO_ERROR) return status;
    if ((status = parcel->readInt32(&mGain.max_value)) != NO_ERROR) return status;
    if ((status = parcel->readInt32(&mGain.default_value)) != NO_ERROR) return status;
    if ((status = parcel->readUint32(&mGain.step_value)) != NO_ERROR) return status;
    if ((status = parcel->readUint32(&mGain.min_ramp_ms)) != NO_ERROR) return status;
    status = parcel->readUint32(&mGain.max_ramp_ms);
    return status;
}

bool AudioGains::equals(const AudioGains &other) const
{
    return std::equal(begin(), end(), other.begin(), other.end(),
                      [](const sp<AudioGain>& left, const sp<AudioGain>& right) {
                          return left->equals(right);
                      });
}

status_t AudioGains::writeToParcel(android::Parcel *parcel) const {
    status_t status = NO_ERROR;
    if ((status = parcel->writeVectorSize(*this)) != NO_ERROR) return status;
    for (const auto &audioGain : *this) {
        if ((status = parcel->writeParcelable(*audioGain)) != NO_ERROR) {
            break;
        }
    }
    return status;
}

status_t AudioGains::readFromParcel(const android::Parcel *parcel) {
    status_t status = NO_ERROR;
    this->clear();
    if ((status = parcel->resizeOutVector(this)) != NO_ERROR) return status;
    for (size_t i = 0; i < this->size(); i++) {
        this->at(i) = new AudioGain(0, false);
        if ((status = parcel->readParcelable(this->at(i).get())) != NO_ERROR) {
            this->clear();
            break;
        }
    }
    return status;
}

} // namespace android
+96 −0
Original line number Diff line number Diff line
@@ -105,6 +105,46 @@ void AudioPort::log(const char* indent) const
    ALOGI("%s Port[nm:%s, type:%d, role:%d]", indent, mName.c_str(), mType, mRole);
}

bool AudioPort::equals(const sp<AudioPort> &other) const
{
    return other != nullptr &&
           mGains.equals(other->getGains()) &&
           mName.compare(other->getName()) == 0 &&
           mType == other->getType() &&
           mRole == other->getRole() &&
           mProfiles.equals(other->getAudioProfiles());
}

status_t AudioPort::writeToParcel(Parcel *parcel) const
{
    status_t status = NO_ERROR;
    if ((status = parcel->writeUtf8AsUtf16(mName)) != NO_ERROR) return status;
    if ((status = parcel->writeUint32(mType)) != NO_ERROR) return status;
    if ((status = parcel->writeUint32(mRole)) != NO_ERROR) return status;
    if ((status = parcel->writeParcelable(mProfiles)) != NO_ERROR) return status;
    if ((status = parcel->writeParcelable(mGains)) != NO_ERROR) return status;
    return status;
}

status_t AudioPort::readFromParcel(const Parcel *parcel)
{
    status_t status = NO_ERROR;
    if ((status = parcel->readUtf8FromUtf16(&mName)) != NO_ERROR) return status;
    static_assert(sizeof(mType) == sizeof(uint32_t));
    if ((status = parcel->readUint32(reinterpret_cast<uint32_t*>(&mType))) != NO_ERROR) {
        return status;
    }
    static_assert(sizeof(mRole) == sizeof(uint32_t));
    if ((status = parcel->readUint32(reinterpret_cast<uint32_t*>(&mRole))) != NO_ERROR) {
        return status;
    }
    mProfiles.clear();
    if ((status = parcel->readParcelable(&mProfiles)) != NO_ERROR) return status;
    mGains.clear();
    if ((status = parcel->readParcelable(&mGains)) != NO_ERROR) return status;
    return status;
}

// --- AudioPortConfig class implementation

status_t AudioPortConfig::applyAudioPortConfig(
@@ -188,4 +228,60 @@ bool AudioPortConfig::hasGainController(bool canUseForVolume) const
                           : audioport->getGains().size() > 0;
}

bool AudioPortConfig::equals(const sp<AudioPortConfig> &other) const
{
    return other != nullptr &&
           mSamplingRate == other->getSamplingRate() &&
           mFormat == other->getFormat() &&
           mChannelMask == other->getChannelMask() &&
           // Compare audio gain config
           mGain.index == other->mGain.index &&
           mGain.mode == other->mGain.mode &&
           mGain.channel_mask == other->mGain.channel_mask &&
           std::equal(std::begin(mGain.values), std::end(mGain.values),
                      std::begin(other->mGain.values)) &&
           mGain.ramp_duration_ms == other->mGain.ramp_duration_ms;
}

status_t AudioPortConfig::writeToParcel(Parcel *parcel) const
{
    status_t status = NO_ERROR;
    if ((status = parcel->writeUint32(mSamplingRate)) != NO_ERROR) return status;
    if ((status = parcel->writeUint32(mFormat)) != NO_ERROR) return status;
    if ((status = parcel->writeUint32(mChannelMask)) != NO_ERROR) return status;
    if ((status = parcel->writeInt32(mId)) != NO_ERROR) return status;
    // Write mGain to parcel.
    if ((status = parcel->writeInt32(mGain.index)) != NO_ERROR) return status;
    if ((status = parcel->writeUint32(mGain.mode)) != NO_ERROR) return status;
    if ((status = parcel->writeUint32(mGain.channel_mask)) != NO_ERROR) return status;
    if ((status = parcel->writeUint32(mGain.ramp_duration_ms)) != NO_ERROR) return status;
    std::vector<int> values(std::begin(mGain.values), std::end(mGain.values));
    if ((status = parcel->writeInt32Vector(values)) != NO_ERROR) return status;
    return status;
}

status_t AudioPortConfig::readFromParcel(const Parcel *parcel)
{
    status_t status = NO_ERROR;
    if ((status = parcel->readUint32(&mSamplingRate)) != NO_ERROR) return status;
    static_assert(sizeof(mFormat) == sizeof(uint32_t));
    if ((status = parcel->readUint32(reinterpret_cast<uint32_t*>(&mFormat))) != NO_ERROR) {
        return status;
    }
    if ((status = parcel->readUint32(&mChannelMask)) != NO_ERROR) return status;
    if ((status = parcel->readInt32(&mId)) != NO_ERROR) return status;
    // Read mGain from parcel.
    if ((status = parcel->readInt32(&mGain.index)) != NO_ERROR) return status;
    if ((status = parcel->readUint32(&mGain.mode)) != NO_ERROR) return status;
    if ((status = parcel->readUint32(&mGain.channel_mask)) != NO_ERROR) return status;
    if ((status = parcel->readUint32(&mGain.ramp_duration_ms)) != NO_ERROR) return status;
    std::vector<int> values;
    if ((status = parcel->readInt32Vector(&values)) != NO_ERROR) return status;
    if (values.size() != std::size(mGain.values)) {
        return BAD_VALUE;
    }
    std::copy(values.begin(), values.end(), mGain.values);
    return status;
}

} // namespace android
+85 −0
Original line number Diff line number Diff line
@@ -118,6 +118,56 @@ void AudioProfile::dump(std::string *dst, int spaces) const
    }
}

bool AudioProfile::equals(const sp<AudioProfile>& other) const
{
    return other != nullptr &&
           mName.compare(other->mName) == 0 &&
           mFormat == other->getFormat() &&
           mChannelMasks == other->getChannels() &&
           mSamplingRates == other->getSampleRates() &&
           mIsDynamicFormat == other->isDynamicFormat() &&
           mIsDynamicChannels == other->isDynamicChannels() &&
           mIsDynamicRate == other->isDynamicRate();
}

status_t AudioProfile::writeToParcel(Parcel *parcel) const
{
    status_t status = NO_ERROR;
    if ((status = parcel->writeUtf8AsUtf16(mName)) != NO_ERROR) return status;
    if ((status = parcel->writeUint32(mFormat)) != NO_ERROR) return status;
    std::vector<int> values(mChannelMasks.begin(), mChannelMasks.end());
    if ((status = parcel->writeInt32Vector(values)) != NO_ERROR) return status;
    values.clear();
    values.assign(mSamplingRates.begin(), mSamplingRates.end());
    if ((status = parcel->writeInt32Vector(values)) != NO_ERROR) return status;
    if ((status = parcel->writeBool(mIsDynamicFormat)) != NO_ERROR) return status;
    if ((status = parcel->writeBool(mIsDynamicChannels)) != NO_ERROR) return status;
    if ((status = parcel->writeBool(mIsDynamicRate)) != NO_ERROR) return status;
    return status;
}

status_t AudioProfile::readFromParcel(const Parcel *parcel)
{
    status_t status = NO_ERROR;
    if ((status = parcel->readUtf8FromUtf16(&mName)) != NO_ERROR) return status;
    static_assert(sizeof(mFormat) == sizeof(uint32_t));
    if ((status = parcel->readUint32(reinterpret_cast<uint32_t*>(&mFormat))) != NO_ERROR) {
        return status;
    }
    std::vector<int> values;
    if ((status = parcel->readInt32Vector(&values)) != NO_ERROR) return status;
    mChannelMasks.clear();
    mChannelMasks.insert(values.begin(), values.end());
    values.clear();
    if ((status = parcel->readInt32Vector(&values)) != NO_ERROR) return status;
    mSamplingRates.clear();
    mSamplingRates.insert(values.begin(), values.end());
    if ((status = parcel->readBool(&mIsDynamicFormat)) != NO_ERROR) return status;
    if ((status = parcel->readBool(&mIsDynamicChannels)) != NO_ERROR) return status;
    if ((status = parcel->readBool(&mIsDynamicRate)) != NO_ERROR) return status;
    return status;
}

ssize_t AudioProfileVector::add(const sp<AudioProfile> &profile)
{
    ssize_t index = size();
@@ -219,4 +269,39 @@ void AudioProfileVector::dump(std::string *dst, int spaces) const
    }
}

status_t AudioProfileVector::writeToParcel(Parcel *parcel) const
{
    status_t status = NO_ERROR;
    if ((status = parcel->writeVectorSize(*this)) != NO_ERROR) return status;
    for (const auto &audioProfile : *this) {
        if ((status = parcel->writeParcelable(*audioProfile)) != NO_ERROR) {
            break;
        }
    }
    return status;
}

status_t AudioProfileVector::readFromParcel(const Parcel *parcel)
{
    status_t status = NO_ERROR;
    this->clear();
    if ((status = parcel->resizeOutVector(this)) != NO_ERROR) return status;
    for (size_t i = 0; i < this->size(); ++i) {
        this->at(i) = new AudioProfile(AUDIO_FORMAT_DEFAULT, AUDIO_CHANNEL_NONE, 0 /*sampleRate*/);
        if ((status = parcel->readParcelable(this->at(i).get())) != NO_ERROR) {
            this->clear();
            break;
        }
    }
    return status;
}

bool AudioProfileVector::equals(const AudioProfileVector& other) const
{
    return std::equal(begin(), end(), other.begin(), other.end(),
                      [](const sp<AudioProfile>& left, const sp<AudioProfile>& right) {
                          return left->equals(right);
                      });
}

} // namespace android
Loading