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
Merged-In: I8bdcd0da13739fc53638c78aac133336b77fb9d2
diff --git a/media/libaudiofoundation/AudioGain.cpp b/media/libaudiofoundation/AudioGain.cpp
index 9d1d6db..269de28 100644
--- a/media/libaudiofoundation/AudioGain.cpp
+++ b/media/libaudiofoundation/AudioGain.cpp
@@ -147,7 +147,7 @@
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::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;
}
diff --git a/media/libaudiofoundation/AudioPort.cpp b/media/libaudiofoundation/AudioPort.cpp
index cde31e4..7546014 100644
--- a/media/libaudiofoundation/AudioPort.cpp
+++ b/media/libaudiofoundation/AudioPort.cpp
@@ -105,6 +105,36 @@
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 @@
: 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
diff --git a/media/libaudiofoundation/AudioProfile.cpp b/media/libaudiofoundation/AudioProfile.cpp
index 1ae18c5..e8ee20b 100644
--- a/media/libaudiofoundation/AudioProfile.cpp
+++ b/media/libaudiofoundation/AudioProfile.cpp
@@ -118,6 +118,44 @@
}
}
+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 @@
}
}
+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
diff --git a/media/libaudiofoundation/DeviceDescriptorBase.cpp b/media/libaudiofoundation/DeviceDescriptorBase.cpp
index f92c05d..672d06c 100644
--- a/media/libaudiofoundation/DeviceDescriptorBase.cpp
+++ b/media/libaudiofoundation/DeviceDescriptorBase.cpp
@@ -110,4 +110,24 @@
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
diff --git a/media/libaudiofoundation/include/media/AudioPort.h b/media/libaudiofoundation/include/media/AudioPort.h
index b8d54de..503d0a7 100644
--- a/media/libaudiofoundation/include/media/AudioPort.h
+++ b/media/libaudiofoundation/include/media/AudioPort.h
@@ -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 @@
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 @@
};
-class AudioPortConfig : public virtual RefBase
+class AudioPortConfig : public virtual RefBase, public virtual Parcelable
{
public:
virtual ~AudioPortConfig() = default;
@@ -108,6 +113,9 @@
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;
diff --git a/media/libaudiofoundation/include/media/AudioProfile.h b/media/libaudiofoundation/include/media/AudioProfile.h
index f4c2e12..4bf2428 100644
--- a/media/libaudiofoundation/include/media/AudioProfile.h
+++ b/media/libaudiofoundation/include/media/AudioProfile.h
@@ -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 @@
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 @@
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 @@
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);
diff --git a/media/libaudiofoundation/include/media/DeviceDescriptorBase.h b/media/libaudiofoundation/include/media/DeviceDescriptorBase.h
index bbe0517..9f300d5 100644
--- a/media/libaudiofoundation/include/media/DeviceDescriptorBase.h
+++ b/media/libaudiofoundation/include/media/DeviceDescriptorBase.h
@@ -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 @@
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;