Make audio stuff parcelable.

Make some generic audio classes parcelable so that they can be easily
used in binder call, including AudioProfile, AudioPort, AudioPortConfig,
DeviceDescriptorBase.

Bug: 135621476
Test: make
Change-Id: I8bdcd0da13739fc53638c78aac133336b77fb9d2
gugelfrei
jiabin 5 years ago
parent 1865ec9e8a
commit 17058fa562

@ -147,7 +147,7 @@ status_t AudioGain::readFromParcel(const android::Parcel *parcel)
status_t AudioGains::writeToParcel(android::Parcel *parcel) const {
status_t status = NO_ERROR;
if ((status = parcel->writeUint64(this->size())) != NO_ERROR) return status;
if ((status = parcel->writeVectorSize(*this)) != NO_ERROR) return status;
for (const auto &audioGain : *this) {
if ((status = parcel->writeParcelable(*audioGain)) != NO_ERROR) {
break;
@ -158,15 +158,14 @@ status_t AudioGains::writeToParcel(android::Parcel *parcel) const {
status_t AudioGains::readFromParcel(const android::Parcel *parcel) {
status_t status = NO_ERROR;
uint64_t count;
if ((status = parcel->readUint64(&count)) != NO_ERROR) return status;
for (uint64_t i = 0; i < count; i++) {
sp<AudioGain> audioGain = new AudioGain(0, false);
if ((status = parcel->readParcelable(audioGain.get())) != 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;
}
this->push_back(audioGain);
}
return status;
}

@ -105,6 +105,36 @@ void AudioPort::log(const char* indent) const
ALOGI("%s Port[nm:%s, type:%d, role:%d]", indent, mName.c_str(), mType, mRole);
}
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 +218,45 @@ bool AudioPortConfig::hasGainController(bool canUseForVolume) const
: audioport->getGains().size() > 0;
}
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

@ -118,6 +118,44 @@ void AudioProfile::dump(std::string *dst, int spaces) const
}
}
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 +257,31 @@ 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;
}
} // namespace android

@ -110,4 +110,24 @@ void DeviceDescriptorBase::log() const
AudioPort::log(" ");
}
status_t DeviceDescriptorBase::writeToParcel(Parcel *parcel) const
{
status_t status = NO_ERROR;
if ((status = AudioPort::writeToParcel(parcel)) != NO_ERROR) return status;
if ((status = AudioPortConfig::writeToParcel(parcel)) != NO_ERROR) return status;
if ((status = parcel->writeUtf8AsUtf16(mAddress)) != NO_ERROR) return status;
if ((status = parcel->writeUint32(mDeviceType)) != NO_ERROR) return status;
return status;
}
status_t DeviceDescriptorBase::readFromParcel(const Parcel *parcel)
{
status_t status = NO_ERROR;
if ((status = AudioPort::readFromParcel(parcel)) != NO_ERROR) return status;
if ((status = AudioPortConfig::readFromParcel(parcel)) != NO_ERROR) return status;
if ((status = parcel->readUtf8FromUtf16(&mAddress)) != NO_ERROR) return status;
if ((status = parcel->readUint32(&mDeviceType)) != NO_ERROR) return status;
return status;
}
} // namespace android

@ -18,6 +18,8 @@
#include <string>
#include <binder/Parcel.h>
#include <binder/Parcelable.h>
#include <media/AudioGain.h>
#include <media/AudioProfile.h>
#include <utils/Errors.h>
@ -27,7 +29,7 @@
namespace android {
class AudioPort : public virtual RefBase
class AudioPort : public virtual RefBase, public virtual Parcelable
{
public:
AudioPort(const std::string& name, audio_port_type_t type, audio_port_role_t role) :
@ -79,6 +81,9 @@ public:
void log(const char* indent) const;
status_t writeToParcel(Parcel* parcel) const override;
status_t readFromParcel(const Parcel* parcel) override;
AudioGains mGains; // gain controllers
protected:
std::string mName;
@ -88,7 +93,7 @@ protected:
};
class AudioPortConfig : public virtual RefBase
class AudioPortConfig : public virtual RefBase, public virtual Parcelable
{
public:
virtual ~AudioPortConfig() = default;
@ -108,6 +113,9 @@ public:
bool hasGainController(bool canUseForVolume = false) const;
status_t writeToParcel(Parcel* parcel) const override;
status_t readFromParcel(const Parcel* parcel) override;
protected:
unsigned int mSamplingRate = 0u;
audio_format_t mFormat = AUDIO_FORMAT_INVALID;

@ -19,13 +19,15 @@
#include <string>
#include <vector>
#include <binder/Parcel.h>
#include <binder/Parcelable.h>
#include <media/AudioContainers.h>
#include <system/audio.h>
#include <utils/RefBase.h>
namespace android {
class AudioProfile final : public RefBase
class AudioProfile final : public RefBase, public Parcelable
{
public:
static sp<AudioProfile> createFullDynamic(audio_format_t dynamicFormat = AUDIO_FORMAT_DEFAULT);
@ -66,6 +68,9 @@ public:
void dump(std::string *dst, int spaces) const;
status_t writeToParcel(Parcel* parcel) const override;
status_t readFromParcel(const Parcel* parcel) override;
private:
std::string mName;
audio_format_t mFormat; // The format for an audio profile should only be set when initialized.
@ -77,7 +82,7 @@ private:
bool mIsDynamicRate = false;
};
class AudioProfileVector : public std::vector<sp<AudioProfile>>
class AudioProfileVector : public std::vector<sp<AudioProfile>>, public Parcelable
{
public:
virtual ~AudioProfileVector() = default;
@ -99,6 +104,9 @@ public:
bool hasDynamicRateFor(audio_format_t format) const;
virtual void dump(std::string *dst, int spaces) const;
status_t writeToParcel(Parcel* parcel) const override;
status_t readFromParcel(const Parcel* parcel) override;
};
bool operator == (const AudioProfile &left, const AudioProfile &right);

@ -16,6 +16,8 @@
#pragma once
#include <binder/Parcel.h>
#include <binder/Parcelable.h>
#include <media/AudioPort.h>
#include <utils/Errors.h>
#include <cutils/config_utils.h>
@ -51,6 +53,9 @@ public:
void log() const;
std::string toString() const;
status_t writeToParcel(Parcel* parcel) const override;
status_t readFromParcel(const Parcel* parcel) override;
protected:
std::string mAddress{""};
audio_devices_t mDeviceType;

Loading…
Cancel
Save