AAudio: Add AAudioStream_getHardware* functions
Add new methods to AAudioStream that allow for queries on the hardware
aspects of streams.
These will allow developers understand the hardware limitations of their
Android devices after they create AAudio streams.
Bug: 245412674
Test: atest AAudioTests
Change-Id: I104a738df89ab22aba9e0658b43402ddf053b887
diff --git a/media/libaaudio/include/aaudio/AAudio.h b/media/libaaudio/include/aaudio/AAudio.h
index 9ca24aa..8528093 100644
--- a/media/libaaudio/include/aaudio/AAudio.h
+++ b/media/libaaudio/include/aaudio/AAudio.h
@@ -1694,22 +1694,55 @@
* Available since API level 26.
*
* @param stream reference provided by AAudioStreamBuilder_openStream()
- * @return actual sample rate
+ * @return actual sample rate of the stream
*/
AAUDIO_API int32_t AAudioStream_getSampleRate(AAudioStream* stream) __INTRODUCED_IN(26);
/**
+ * There may be sample rate conversions in the Audio framework.
+ * The sample rate set in the stream builder may not be actual sample rate used in the hardware.
+ *
+ * This returns the sample rate used by the hardware.
+ *
+ * If AAudioStreamBuilder_openStream() returned AAUDIO_OK, the result should always be valid.
+ *
+ * Available since API level 34.
+ *
+ * @param stream reference provided by AAudioStreamBuilder_openStream()
+ * @return actual sample rate of the underlying hardware
+ */
+AAUDIO_API int32_t AAudioStream_getHardwareSampleRate(AAudioStream* stream)
+ __INTRODUCED_IN(__ANDROID_API_U__);
+
+/**
* A stream has one or more channels of data.
* A frame will contain one sample for each channel.
*
* Available since API level 26.
*
* @param stream reference provided by AAudioStreamBuilder_openStream()
- * @return actual number of channels
+ * @return actual number of channels of the stream
*/
AAUDIO_API int32_t AAudioStream_getChannelCount(AAudioStream* stream) __INTRODUCED_IN(26);
/**
+ * There may be channel conversions in the Audio framework.
+ * The channel count or channel mask set in the stream builder may not be actual number of
+ * channels used in the hardware.
+ *
+ * This returns the channel count used by the hardware.
+ *
+ * If AAudioStreamBuilder_openStream() returned AAUDIO_OK, the result should always be valid.
+ *
+ * Available since API level 34.
+ *
+ * @param stream reference provided by AAudioStreamBuilder_openStream()
+ * @return actual number of channels of the underlying hardware
+ */
+AAUDIO_API int32_t AAudioStream_getHardwareChannelCount(AAudioStream* stream)
+ __INTRODUCED_IN(__ANDROID_API_U__);
+
+/**
* Identical to AAudioStream_getChannelCount().
*
* Available since API level 26.
@@ -1731,11 +1764,27 @@
* Available since API level 26.
*
* @param stream reference provided by AAudioStreamBuilder_openStream()
- * @return actual data format
+ * @return actual data format of the stream
*/
AAUDIO_API aaudio_format_t AAudioStream_getFormat(AAudioStream* stream) __INTRODUCED_IN(26);
/**
+ * There may be data format conversions in the Audio framework.
+ * The data format set in the stream builder may not be actual format used in the hardware.
+ *
+ * This returns the audio format used by the hardware.
+ * AUDIO_FORMAT_PCM_8_24_BIT is currently not supported in AAudio, but the hardware may use it.
+ * If AUDIO_FORMAT_PCM_8_24_BIT is used by the hardware, return AAUDIO_FORMAT_PCM_I24_PACKED.
+ *
+ * Available since API level 34.
+ *
+ * @param stream reference provided by AAudioStreamBuilder_openStream()
+ * @return actual data format of the underlying hardware.
+ */
+AAUDIO_API aaudio_format_t AAudioStream_getHardwareFormat(AAudioStream* stream)
+ __INTRODUCED_IN(__ANDROID_API_U__);
+
+/**
* Provide actual sharing mode.
*
* Available since API level 26.
diff --git a/media/libaaudio/src/binding/AAudioStreamConfiguration.cpp b/media/libaaudio/src/binding/AAudioStreamConfiguration.cpp
index b60bac2..b1eefe4 100644
--- a/media/libaaudio/src/binding/AAudioStreamConfiguration.cpp
+++ b/media/libaaudio/src/binding/AAudioStreamConfiguration.cpp
@@ -40,6 +40,10 @@
auto convFormat = android::aidl2legacy_AudioFormatDescription_audio_format_t(
parcelable.audioFormat);
setFormat(convFormat.ok() ? convFormat.value() : AUDIO_FORMAT_INVALID);
+ if (!convFormat.ok()) {
+ ALOGE("audioFormat (%s) aidl2legacy conversion failed",
+ parcelable.hardwareAudioFormat.toString().c_str());
+ }
static_assert(sizeof(aaudio_direction_t) == sizeof(parcelable.direction));
setDirection(parcelable.direction);
static_assert(sizeof(audio_usage_t) == sizeof(parcelable.usage));
@@ -52,7 +56,6 @@
setSpatializationBehavior(parcelable.spatializationBehavior);
setIsContentSpatialized(parcelable.isContentSpatialized);
-
static_assert(sizeof(aaudio_input_preset_t) == sizeof(parcelable.inputPreset));
setInputPreset(parcelable.inputPreset);
setBufferCapacity(parcelable.bufferCapacity);
@@ -62,6 +65,15 @@
static_assert(sizeof(aaudio_session_id_t) == sizeof(parcelable.sessionId));
setSessionId(parcelable.sessionId);
setPrivacySensitive(parcelable.isPrivacySensitive);
+ setHardwareSamplesPerFrame(parcelable.hardwareSamplesPerFrame);
+ setHardwareSampleRate(parcelable.hardwareSampleRate);
+ auto convHardwareFormat = android::aidl2legacy_AudioFormatDescription_audio_format_t(
+ parcelable.hardwareAudioFormat);
+ setHardwareFormat(convHardwareFormat.ok() ? convHardwareFormat.value() : AUDIO_FORMAT_INVALID);
+ if (!convHardwareFormat.ok()) {
+ ALOGE("hardwareAudioFormat (%s) aidl2legacy conversion failed",
+ parcelable.hardwareAudioFormat.toString().c_str());
+ }
}
AAudioStreamConfiguration&
@@ -82,6 +94,8 @@
if (convAudioFormat.ok()) {
result.audioFormat = convAudioFormat.value();
} else {
+ ALOGE("audioFormat (%s) legacy2aidl conversion failed",
+ audio_format_to_string(getFormat()));
result.audioFormat = AudioFormatDescription{};
result.audioFormat.type =
android::media::audio::common::AudioFormatType::SYS_RESERVED_INVALID;
@@ -100,5 +114,18 @@
static_assert(sizeof(aaudio_session_id_t) == sizeof(result.sessionId));
result.sessionId = getSessionId();
result.isPrivacySensitive = isPrivacySensitive();
+ result.hardwareSamplesPerFrame = getHardwareSamplesPerFrame();
+ result.hardwareSampleRate = getHardwareSampleRate();
+ auto convHardwareAudioFormat = android::legacy2aidl_audio_format_t_AudioFormatDescription(
+ getHardwareFormat());
+ if (convHardwareAudioFormat.ok()) {
+ result.hardwareAudioFormat = convHardwareAudioFormat.value();
+ } else {
+ ALOGE("hardwareAudioFormat (%s) legacy2aidl conversion failed",
+ audio_format_to_string(getHardwareFormat()));
+ result.hardwareAudioFormat = AudioFormatDescription{};
+ result.hardwareAudioFormat.type =
+ android::media::audio::common::AudioFormatType::SYS_RESERVED_INVALID;
+ }
return result;
}
diff --git a/media/libaaudio/src/binding/aidl/aaudio/StreamParameters.aidl b/media/libaaudio/src/binding/aidl/aaudio/StreamParameters.aidl
index 983e193..fa46e0d 100644
--- a/media/libaaudio/src/binding/aidl/aaudio/StreamParameters.aidl
+++ b/media/libaaudio/src/binding/aidl/aaudio/StreamParameters.aidl
@@ -34,4 +34,7 @@
int /* aaudio_allowed_capture_policy_t */ allowedCapturePolicy; // = AAUDIO_UNSPECIFIED;
int /* aaudio_session_id_t */ sessionId; // = AAUDIO_SESSION_ID_NONE;
boolean isPrivacySensitive; // = false;
+ int hardwareSamplesPerFrame;//= AAUDIO_UNSPECIFIED;
+ int hardwareSampleRate; // = AAUDIO_UNSPECIFIED;
+ AudioFormatDescription hardwareAudioFormat; // = AUDIO_FORMAT_DEFAULT;
}
diff --git a/media/libaaudio/src/client/AudioStreamInternal.cpp b/media/libaaudio/src/client/AudioStreamInternal.cpp
index 2de878d..4956646 100644
--- a/media/libaaudio/src/client/AudioStreamInternal.cpp
+++ b/media/libaaudio/src/client/AudioStreamInternal.cpp
@@ -131,6 +131,10 @@
request.getConfiguration().setBufferCapacity(builder.getBufferCapacity());
+ request.getConfiguration().setHardwareSamplesPerFrame(builder.getHardwareSamplesPerFrame());
+ request.getConfiguration().setHardwareSampleRate(builder.getHardwareSampleRate());
+ request.getConfiguration().setHardwareFormat(builder.getHardwareFormat());
+
mDeviceChannelCount = getSamplesPerFrame(); // Assume it will be the same. Update if not.
mServiceStreamHandle = mServiceInterface.openStream(request, configurationOutput);
@@ -192,6 +196,10 @@
// Save device format so we can do format conversion and volume scaling together.
setDeviceFormat(configurationOutput.getFormat());
+ setHardwareSamplesPerFrame(configurationOutput.getHardwareSamplesPerFrame());
+ setHardwareSampleRate(configurationOutput.getHardwareSampleRate());
+ setHardwareFormat(configurationOutput.getHardwareFormat());
+
result = mServiceInterface.getStreamDescription(mServiceStreamHandle, mEndPointParcelable);
if (result != AAUDIO_OK) {
goto error;
diff --git a/media/libaaudio/src/core/AAudioAudio.cpp b/media/libaaudio/src/core/AAudioAudio.cpp
index 938079b..0c21e18 100644
--- a/media/libaaudio/src/core/AAudioAudio.cpp
+++ b/media/libaaudio/src/core/AAudioAudio.cpp
@@ -418,12 +418,24 @@
return audioStream->getSampleRate();
}
+AAUDIO_API int32_t AAudioStream_getHardwareSampleRate(AAudioStream* stream)
+{
+ AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
+ return audioStream->getHardwareSampleRate();
+}
+
AAUDIO_API int32_t AAudioStream_getChannelCount(AAudioStream* stream)
{
AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
return audioStream->getSamplesPerFrame();
}
+AAUDIO_API int32_t AAudioStream_getHardwareChannelCount(AAudioStream* stream)
+{
+ AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
+ return audioStream->getHardwareSamplesPerFrame();
+}
+
AAUDIO_API int32_t AAudioStream_getSamplesPerFrame(AAudioStream* stream)
{
return AAudioStream_getChannelCount(stream);
@@ -443,6 +455,14 @@
return AAudioConvert_androidToAAudioDataFormat(internalFormat);
}
+AAUDIO_API aaudio_format_t AAudioStream_getHardwareFormat(AAudioStream* stream)
+{
+ AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
+ // Use audio_format_t internally.
+ audio_format_t internalFormat = audioStream->getHardwareFormat();
+ return AAudioConvert_androidToNearestAAudioDataFormat(internalFormat);
+}
+
AAUDIO_API aaudio_result_t AAudioStream_setBufferSizeInFrames(AAudioStream* stream,
int32_t requestedFrames)
{
diff --git a/media/libaaudio/src/core/AAudioStreamParameters.cpp b/media/libaaudio/src/core/AAudioStreamParameters.cpp
index e6b00d7..c8461cc 100644
--- a/media/libaaudio/src/core/AAudioStreamParameters.cpp
+++ b/media/libaaudio/src/core/AAudioStreamParameters.cpp
@@ -49,6 +49,9 @@
mOpPackageName = other.mOpPackageName;
mAttributionTag = other.mAttributionTag;
mChannelMask = other.mChannelMask;
+ mHardwareSamplesPerFrame = other.mHardwareSamplesPerFrame;
+ mHardwareSampleRate = other.mHardwareSampleRate;
+ mHardwareAudioFormat = other.mHardwareAudioFormat;
}
static aaudio_result_t isFormatValid(audio_format_t format) {
@@ -311,4 +314,7 @@
"(null)" : mOpPackageName.value().c_str());
ALOGD("mAttributionTag = %s", !mAttributionTag.has_value() ?
"(null)" : mAttributionTag.value().c_str());
-}
+ ALOGD("mHardwareSamplesPerFrame = %6d", mHardwareSamplesPerFrame);
+ ALOGD("mHardwareSampleRate = %6d", mHardwareSampleRate);
+ ALOGD("mHardwareAudioFormat = %6d", (int)mHardwareAudioFormat);
+}
\ No newline at end of file
diff --git a/media/libaaudio/src/core/AAudioStreamParameters.h b/media/libaaudio/src/core/AAudioStreamParameters.h
index cb998bf..565d54c 100644
--- a/media/libaaudio/src/core/AAudioStreamParameters.h
+++ b/media/libaaudio/src/core/AAudioStreamParameters.h
@@ -171,6 +171,30 @@
mSamplesPerFrame = AAudioConvert_channelMaskToCount(channelMask);
}
+ int32_t getHardwareSamplesPerFrame() const {
+ return mHardwareSamplesPerFrame;
+ }
+
+ void setHardwareSamplesPerFrame(int32_t hardwareSamplesPerFrame) {
+ mHardwareSamplesPerFrame = hardwareSamplesPerFrame;
+ }
+
+ int32_t getHardwareSampleRate() const {
+ return mHardwareSampleRate;
+ }
+
+ void setHardwareSampleRate(int32_t hardwareSampleRate) {
+ mHardwareSampleRate = hardwareSampleRate;
+ }
+
+ audio_format_t getHardwareFormat() const {
+ return mHardwareAudioFormat;
+ }
+
+ void setHardwareFormat(audio_format_t hardwareAudioFormat) {
+ mHardwareAudioFormat = hardwareAudioFormat;
+ }
+
/**
* @return bytes per frame of getFormat()
*/
@@ -210,6 +234,10 @@
std::optional<std::string> mOpPackageName = {};
std::optional<std::string> mAttributionTag = {};
aaudio_channel_mask_t mChannelMask = AAUDIO_UNSPECIFIED;
+ int mHardwareSamplesPerFrame
+ = AAUDIO_UNSPECIFIED;
+ int mHardwareSampleRate = AAUDIO_UNSPECIFIED;
+ audio_format_t mHardwareAudioFormat = AUDIO_FORMAT_DEFAULT;
};
} /* namespace aaudio */
diff --git a/media/libaaudio/src/core/AudioStream.h b/media/libaaudio/src/core/AudioStream.h
index e36928d..75182dc 100644
--- a/media/libaaudio/src/core/AudioStream.h
+++ b/media/libaaudio/src/core/AudioStream.h
@@ -222,14 +222,26 @@
return mSampleRate;
}
+ aaudio_result_t getHardwareSampleRate() const {
+ return mHardwareSampleRate;
+ }
+
audio_format_t getFormat() const {
return mFormat;
}
+ audio_format_t getHardwareFormat() const {
+ return mHardwareFormat;
+ }
+
aaudio_result_t getSamplesPerFrame() const {
return mSamplesPerFrame;
}
+ aaudio_result_t getHardwareSamplesPerFrame() const {
+ return mHardwareSamplesPerFrame;
+ }
+
virtual int32_t getPerformanceMode() const {
return mPerformanceMode;
}
@@ -528,6 +540,11 @@
}
// This should not be called after the open() call.
+ void setHardwareSampleRate(int32_t hardwareSampleRate) {
+ mHardwareSampleRate = hardwareSampleRate;
+ }
+
+ // This should not be called after the open() call.
void setFramesPerBurst(int32_t framesPerBurst) {
mFramesPerBurst = framesPerBurst;
}
@@ -548,6 +565,16 @@
}
// This should not be called after the open() call.
+ void setHardwareFormat(audio_format_t format) {
+ mHardwareFormat = format;
+ }
+
+ // This should not be called after the open() call.
+ void setHardwareSamplesPerFrame(int32_t hardwareSamplesPerFrame) {
+ mHardwareSamplesPerFrame = hardwareSamplesPerFrame;
+ }
+
+ // This should not be called after the open() call.
void setDeviceFormat(audio_format_t format) {
mDeviceFormat = format;
}
@@ -685,12 +712,15 @@
// These do not change after open().
int32_t mSamplesPerFrame = AAUDIO_UNSPECIFIED;
+ int32_t mHardwareSamplesPerFrame = AAUDIO_UNSPECIFIED;
aaudio_channel_mask_t mChannelMask = AAUDIO_UNSPECIFIED;
int32_t mSampleRate = AAUDIO_UNSPECIFIED;
+ int32_t mHardwareSampleRate = AAUDIO_UNSPECIFIED;
int32_t mDeviceId = AAUDIO_UNSPECIFIED;
aaudio_sharing_mode_t mSharingMode = AAUDIO_SHARING_MODE_SHARED;
bool mSharingModeMatchRequired = false; // must match sharing mode requested
audio_format_t mFormat = AUDIO_FORMAT_DEFAULT;
+ audio_format_t mHardwareFormat = AUDIO_FORMAT_DEFAULT;
aaudio_performance_mode_t mPerformanceMode = AAUDIO_PERFORMANCE_MODE_NONE;
int32_t mFramesPerBurst = 0;
int32_t mBufferCapacity = 0;
diff --git a/media/libaaudio/src/legacy/AudioStreamRecord.cpp b/media/libaaudio/src/legacy/AudioStreamRecord.cpp
index 9a136a7..83cd45e 100644
--- a/media/libaaudio/src/legacy/AudioStreamRecord.cpp
+++ b/media/libaaudio/src/legacy/AudioStreamRecord.cpp
@@ -208,6 +208,10 @@
setBufferCapacity(getBufferCapacityFromDevice());
setFramesPerBurst(getFramesPerBurstFromDevice());
+ setHardwareSamplesPerFrame(mAudioRecord->getHalChannelCount());
+ setHardwareSampleRate(mAudioRecord->getHalSampleRate());
+ setHardwareFormat(mAudioRecord->getHalFormat());
+
// We may need to pass the data through a block size adapter to guarantee constant size.
if (mCallbackBufferSize != AAUDIO_UNSPECIFIED) {
// The block adapter runs before the format conversion.
diff --git a/media/libaaudio/src/legacy/AudioStreamTrack.cpp b/media/libaaudio/src/legacy/AudioStreamTrack.cpp
index fb3fcc1..e559d3c 100644
--- a/media/libaaudio/src/legacy/AudioStreamTrack.cpp
+++ b/media/libaaudio/src/legacy/AudioStreamTrack.cpp
@@ -202,6 +202,10 @@
setBufferCapacity(getBufferCapacityFromDevice());
setFramesPerBurst(getFramesPerBurstFromDevice());
+ setHardwareSamplesPerFrame(mAudioTrack->getHalChannelCount());
+ setHardwareSampleRate(mAudioTrack->getHalSampleRate());
+ setHardwareFormat(mAudioTrack->getHalFormat());
+
// We may need to pass the data through a block size adapter to guarantee constant size.
if (mCallbackBufferSize != AAUDIO_UNSPECIFIED) {
// This may need to change if we add format conversion before
diff --git a/media/libaaudio/src/libaaudio.map.txt b/media/libaaudio/src/libaaudio.map.txt
index f45b816..e28dcb4 100644
--- a/media/libaaudio/src/libaaudio.map.txt
+++ b/media/libaaudio/src/libaaudio.map.txt
@@ -67,6 +67,9 @@
AAudioStream_getChannelMask; # introduced=32
AAudioStream_getSpatializationBehavior; # introduced=32
AAudioStream_isContentSpatialized; # introduced=32
+ AAudioStream_getHardwareChannelCount; # introduced=UpsideDownCake
+ AAudioStream_getHardwareFormat; # introduced=UpsideDownCake
+ AAudioStream_getHardwareSampleRate; # introduced=UpsideDownCake
local:
*;
};
diff --git a/media/libaaudio/src/utility/AAudioUtilities.cpp b/media/libaaudio/src/utility/AAudioUtilities.cpp
index a197ced..69e51d6 100644
--- a/media/libaaudio/src/utility/AAudioUtilities.cpp
+++ b/media/libaaudio/src/utility/AAudioUtilities.cpp
@@ -180,6 +180,17 @@
return aaudioFormat;
}
+aaudio_format_t AAudioConvert_androidToNearestAAudioDataFormat(audio_format_t androidFormat) {
+ // Special case AUDIO_FORMAT_PCM_8_24_BIT because this function should be used to find the
+ // resolution of the data format. Setting AUDIO_FORMAT_PCM_8_24_BIT directly is not available
+ // from AAudio but hardware may use AUDIO_FORMAT_PCM_8_24_BIT under the hood.
+ if (androidFormat == AUDIO_FORMAT_PCM_8_24_BIT) {
+ ALOGD("%s() converting 8.24 to 24 bit packed", __func__);
+ return AAUDIO_FORMAT_PCM_I24_PACKED;
+ }
+ return AAudioConvert_androidToAAudioDataFormat(androidFormat);
+}
+
// Make a message string from the condition.
#define STATIC_ASSERT(condition) static_assert(condition, #condition)
diff --git a/media/libaaudio/src/utility/AAudioUtilities.h b/media/libaaudio/src/utility/AAudioUtilities.h
index b59ce1c..f3365eb 100644
--- a/media/libaaudio/src/utility/AAudioUtilities.h
+++ b/media/libaaudio/src/utility/AAudioUtilities.h
@@ -62,6 +62,7 @@
aaudio_format_t AAudioConvert_androidToAAudioDataFormat(audio_format_t format);
+aaudio_format_t AAudioConvert_androidToNearestAAudioDataFormat(audio_format_t format);
/**
* Note that this function does not validate the passed in value.
diff --git a/media/libaudioclient/AudioRecord.cpp b/media/libaudioclient/AudioRecord.cpp
index 69d73ad..12bcec6 100644
--- a/media/libaudioclient/AudioRecord.cpp
+++ b/media/libaudioclient/AudioRecord.cpp
@@ -560,6 +560,21 @@
return NO_ERROR;
}
+uint32_t AudioRecord::getHalSampleRate() const
+{
+ return mHalSampleRate;
+}
+
+uint32_t AudioRecord::getHalChannelCount() const
+{
+ return mHalChannelCount;
+}
+
+audio_format_t AudioRecord::getHalFormat() const
+{
+ return mHalFormat;
+}
+
status_t AudioRecord::getMarkerPosition(uint32_t *marker) const
{
if (marker == NULL) {
@@ -878,6 +893,9 @@
mServerFrameSize = audio_bytes_per_frame(
audio_channel_count_from_in_mask(mServerConfig.channel_mask), mServerConfig.format);
mServerSampleSize = audio_bytes_per_sample(mServerConfig.format);
+ mHalSampleRate = output.halConfig.sample_rate;
+ mHalChannelCount = audio_channel_count_from_in_mask(output.halConfig.channel_mask);
+ mHalFormat = output.halConfig.format;
if (output.cblk == 0) {
errorMessage = StringPrintf("%s(%d): Could not get control block", __func__, mPortId);
diff --git a/media/libaudioclient/AudioTrack.cpp b/media/libaudioclient/AudioTrack.cpp
index b18a569..22bd2a3 100644
--- a/media/libaudioclient/AudioTrack.cpp
+++ b/media/libaudioclient/AudioTrack.cpp
@@ -1233,6 +1233,21 @@
return mOriginalSampleRate;
}
+uint32_t AudioTrack::getHalSampleRate() const
+{
+ return mAfSampleRate;
+}
+
+uint32_t AudioTrack::getHalChannelCount() const
+{
+ return mAfChannelCount;
+}
+
+audio_format_t AudioTrack::getHalFormat() const
+{
+ return mAfFormat;
+}
+
status_t AudioTrack::setDualMonoMode(audio_dual_mono_mode_t mode)
{
AutoMutex lock(mLock);
@@ -1888,6 +1903,8 @@
mAfFrameCount = output.afFrameCount;
mAfSampleRate = output.afSampleRate;
+ mAfChannelCount = audio_channel_count_from_out_mask(output.afChannelMask);
+ mAfFormat = output.afFormat;
mAfLatency = output.afLatencyMs;
mLatency = mAfLatency + (1000LL * mFrameCount) / mSampleRate;
diff --git a/media/libaudioclient/IAudioFlinger.cpp b/media/libaudioclient/IAudioFlinger.cpp
index 6ad97d1..0c6d07a 100644
--- a/media/libaudioclient/IAudioFlinger.cpp
+++ b/media/libaudioclient/IAudioFlinger.cpp
@@ -112,6 +112,10 @@
aidl.afFrameCount = VALUE_OR_RETURN(convertIntegral<int64_t>(afFrameCount));
aidl.afSampleRate = VALUE_OR_RETURN(convertIntegral<int32_t>(afSampleRate));
aidl.afLatencyMs = VALUE_OR_RETURN(convertIntegral<int32_t>(afLatencyMs));
+ aidl.afChannelMask = VALUE_OR_RETURN(
+ legacy2aidl_audio_channel_mask_t_AudioChannelLayout(afChannelMask, false /*isInput*/));
+ aidl.afFormat = VALUE_OR_RETURN(
+ legacy2aidl_audio_format_t_AudioFormatDescription(afFormat));
aidl.outputId = VALUE_OR_RETURN(legacy2aidl_audio_io_handle_t_int32_t(outputId));
aidl.portId = VALUE_OR_RETURN(legacy2aidl_audio_port_handle_t_int32_t(portId));
aidl.audioTrack = audioTrack;
@@ -135,6 +139,11 @@
legacy.afFrameCount = VALUE_OR_RETURN(convertIntegral<size_t>(aidl.afFrameCount));
legacy.afSampleRate = VALUE_OR_RETURN(convertIntegral<uint32_t>(aidl.afSampleRate));
legacy.afLatencyMs = VALUE_OR_RETURN(convertIntegral<uint32_t>(aidl.afLatencyMs));
+ legacy.afChannelMask = VALUE_OR_RETURN(
+ aidl2legacy_AudioChannelLayout_audio_channel_mask_t(aidl.afChannelMask,
+ false /*isInput*/));
+ legacy.afFormat = VALUE_OR_RETURN(
+ aidl2legacy_AudioFormatDescription_audio_format_t(aidl.afFormat));
legacy.outputId = VALUE_OR_RETURN(aidl2legacy_int32_t_audio_io_handle_t(aidl.outputId));
legacy.portId = VALUE_OR_RETURN(aidl2legacy_int32_t_audio_port_handle_t(aidl.portId));
legacy.audioTrack = aidl.audioTrack;
@@ -199,6 +208,8 @@
aidl.audioRecord = audioRecord;
aidl.serverConfig = VALUE_OR_RETURN(
legacy2aidl_audio_config_base_t_AudioConfigBase(serverConfig, true /*isInput*/));
+ aidl.halConfig = VALUE_OR_RETURN(
+ legacy2aidl_audio_config_base_t_AudioConfigBase(halConfig, true /*isInput*/));
return aidl;
}
@@ -221,6 +232,8 @@
legacy.audioRecord = aidl.audioRecord;
legacy.serverConfig = VALUE_OR_RETURN(
aidl2legacy_AudioConfigBase_audio_config_base_t(aidl.serverConfig, true /*isInput*/));
+ legacy.halConfig = VALUE_OR_RETURN(
+ aidl2legacy_AudioConfigBase_audio_config_base_t(aidl.halConfig, true /*isInput*/));
return legacy;
}
diff --git a/media/libaudioclient/aidl/android/media/CreateRecordResponse.aidl b/media/libaudioclient/aidl/android/media/CreateRecordResponse.aidl
index 7d159d0..5f1e288 100644
--- a/media/libaudioclient/aidl/android/media/CreateRecordResponse.aidl
+++ b/media/libaudioclient/aidl/android/media/CreateRecordResponse.aidl
@@ -45,4 +45,5 @@
/** The newly created record. */
@nullable IAudioRecord audioRecord;
AudioConfigBase serverConfig;
+ AudioConfigBase halConfig;
}
diff --git a/media/libaudioclient/aidl/android/media/CreateTrackResponse.aidl b/media/libaudioclient/aidl/android/media/CreateTrackResponse.aidl
index da6f454..42e0bb4 100644
--- a/media/libaudioclient/aidl/android/media/CreateTrackResponse.aidl
+++ b/media/libaudioclient/aidl/android/media/CreateTrackResponse.aidl
@@ -16,6 +16,8 @@
package android.media;
+import android.media.audio.common.AudioChannelLayout;
+import android.media.audio.common.AudioFormatDescription;
import android.media.audio.common.AudioStreamType;
import android.media.IAudioTrack;
@@ -38,6 +40,8 @@
AudioStreamType streamType;
long afFrameCount;
int afSampleRate;
+ AudioChannelLayout afChannelMask;
+ AudioFormatDescription afFormat;
int afLatencyMs;
/** Interpreted as audio_io_handle_t. */
int outputId;
diff --git a/media/libaudioclient/include/media/AudioRecord.h b/media/libaudioclient/include/media/AudioRecord.h
index 5a1ff65..3f33d7a 100644
--- a/media/libaudioclient/include/media/AudioRecord.h
+++ b/media/libaudioclient/include/media/AudioRecord.h
@@ -326,6 +326,15 @@
*/
uint32_t getSampleRate() const { return mSampleRate; }
+ /* Return the sample rate from the AudioFlinger input thread. */
+ uint32_t getHalSampleRate() const;
+
+ /* Return the channel count from the AudioFlinger input thread. */
+ uint32_t getHalChannelCount() const;
+
+ /* Return the HAL format from the AudioFlinger input thread. */
+ audio_format_t getHalFormat() const;
+
/* Sets marker position. When record reaches the number of frames specified,
* a callback with event type EVENT_MARKER is called. Calling setMarkerPosition
* with marker == 0 cancels marker notification callback.
@@ -770,6 +779,9 @@
size_t mServerSampleSize;
std::unique_ptr<uint8_t[]> mFormatConversionBufRaw;
Buffer mFormatConversionBuffer;
+ uint32_t mHalSampleRate; // AudioFlinger thread sample rate
+ uint32_t mHalChannelCount; // AudioFlinger thread channel count
+ audio_format_t mHalFormat; // AudioFlinger thread format
private:
class DeathNotifier : public IBinder::DeathRecipient {
diff --git a/media/libaudioclient/include/media/AudioTrack.h b/media/libaudioclient/include/media/AudioTrack.h
index e873607..31f81be 100644
--- a/media/libaudioclient/include/media/AudioTrack.h
+++ b/media/libaudioclient/include/media/AudioTrack.h
@@ -655,6 +655,15 @@
*/
uint32_t getOriginalSampleRate() const;
+ /* Return the sample rate from the AudioFlinger output thread. */
+ uint32_t getHalSampleRate() const;
+
+ /* Return the channel count from the AudioFlinger output thread. */
+ uint32_t getHalChannelCount() const;
+
+ /* Return the HAL format from the AudioFlinger output thread. */
+ audio_format_t getHalFormat() const;
+
/* Sets the Dual Mono mode presentation on the output device. */
status_t setDualMonoMode(audio_dual_mono_mode_t mode);
@@ -1270,12 +1279,14 @@
size_t mReqFrameCount; // frame count to request the first or next time
// a new IAudioTrack is needed, non-decreasing
- // The following AudioFlinger server-side values are cached in createAudioTrack_l().
+ // The following AudioFlinger server-side values are cached in createTrack_l().
// These values can be used for informational purposes until the track is invalidated,
// whereupon restoreTrack_l() calls createTrack_l() to update the values.
uint32_t mAfLatency; // AudioFlinger latency in ms
size_t mAfFrameCount; // AudioFlinger frame count
uint32_t mAfSampleRate; // AudioFlinger sample rate
+ uint32_t mAfChannelCount; // AudioFlinger channel count
+ audio_format_t mAfFormat; // AudioFlinger format
// constant after constructor or set()
audio_format_t mFormat; // as requested by client, not forced to 16-bit
diff --git a/media/libaudioclient/include/media/IAudioFlinger.h b/media/libaudioclient/include/media/IAudioFlinger.h
index c891ae6..d58bba1 100644
--- a/media/libaudioclient/include/media/IAudioFlinger.h
+++ b/media/libaudioclient/include/media/IAudioFlinger.h
@@ -116,6 +116,8 @@
size_t afFrameCount;
uint32_t afSampleRate;
uint32_t afLatencyMs;
+ audio_channel_mask_t afChannelMask;
+ audio_format_t afFormat;
audio_io_handle_t outputId;
audio_port_handle_t portId;
sp<media::IAudioTrack> audioTrack;
@@ -169,6 +171,7 @@
audio_port_handle_t portId;
sp<media::IAudioRecord> audioRecord;
audio_config_base_t serverConfig;
+ audio_config_base_t halConfig;
ConversionResult<media::CreateRecordResponse> toAidl() const;
static ConversionResult<CreateRecordOutput>
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 7f0fc1f..1419008 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -1166,6 +1166,9 @@
output.afFrameCount = thread->frameCount();
output.afSampleRate = thread->sampleRate();
+ output.afChannelMask = static_cast<audio_channel_mask_t>(thread->channelMask() |
+ thread->hapticChannelMask());
+ output.afFormat = thread->format();
output.afLatencyMs = thread->latency();
output.portId = portId;
@@ -2403,6 +2406,12 @@
};
}
+ output.halConfig = {
+ thread->sampleRate(),
+ thread->channelMask(),
+ thread->format()
+ };
+
// Check if one effect chain was awaiting for an AudioRecord to be created on this
// session and move it to this thread.
sp<EffectChain> chain = getOrphanEffectChain_l(sessionId);
diff --git a/services/oboeservice/AAudioServiceEndpoint.cpp b/services/oboeservice/AAudioServiceEndpoint.cpp
index b55b601..fd546f6 100644
--- a/services/oboeservice/AAudioServiceEndpoint.cpp
+++ b/services/oboeservice/AAudioServiceEndpoint.cpp
@@ -69,6 +69,10 @@
result << " Reference Count: " << mOpenCount << "\n";
result << " Session Id: " << getSessionId() << "\n";
result << " Privacy Sensitive: " << isPrivacySensitive() << "\n";
+ result << " Hardware Channel Count:" << getHardwareSamplesPerFrame() << "\n";
+ result << " Hardware Format: " << getHardwareFormat() << " ("
+ << audio_format_to_string(getHardwareFormat()) << ")\n";
+ result << " Hardware Sample Rate: " << getHardwareSampleRate() << "\n";
result << " Connected: " << mConnected.load() << "\n";
result << " Registered Streams:" << "\n";
result << AAudioServiceStreamShared::dumpHeader() << "\n";
diff --git a/services/oboeservice/AAudioServiceEndpointMMAP.cpp b/services/oboeservice/AAudioServiceEndpointMMAP.cpp
index 133b9b4..e03fba0 100644
--- a/services/oboeservice/AAudioServiceEndpointMMAP.cpp
+++ b/services/oboeservice/AAudioServiceEndpointMMAP.cpp
@@ -227,6 +227,9 @@
setFormat(config.format);
setSampleRate(config.sample_rate);
+ setHardwareSampleRate(getSampleRate());
+ setHardwareFormat(getFormat());
+ setHardwareSamplesPerFrame(AAudioConvert_channelMaskToCount(getChannelMask()));
// If the position is not updated while the timestamp is updated for more than a certain amount,
// the timestamp reported from the HAL may not be accurate. Here, a timestamp grace period is
diff --git a/services/oboeservice/AAudioServiceEndpointShared.cpp b/services/oboeservice/AAudioServiceEndpointShared.cpp
index dd421fe..02202d8 100644
--- a/services/oboeservice/AAudioServiceEndpointShared.cpp
+++ b/services/oboeservice/AAudioServiceEndpointShared.cpp
@@ -82,6 +82,9 @@
setDeviceId(mStreamInternal->getDeviceId());
setSessionId(mStreamInternal->getSessionId());
setFormat(AUDIO_FORMAT_PCM_FLOAT); // force for mixer
+ setHardwareSampleRate(mStreamInternal->getHardwareSampleRate());
+ setHardwareFormat(mStreamInternal->getHardwareFormat());
+ setHardwareSamplesPerFrame(mStreamInternal->getHardwareSamplesPerFrame());
mFramesPerBurst = mStreamInternal->getFramesPerBurst();
return result;
diff --git a/services/oboeservice/AAudioServiceStreamBase.cpp b/services/oboeservice/AAudioServiceStreamBase.cpp
index 9f48f80..17e64ee 100644
--- a/services/oboeservice/AAudioServiceStreamBase.cpp
+++ b/services/oboeservice/AAudioServiceStreamBase.cpp
@@ -84,7 +84,8 @@
std::string AAudioServiceStreamBase::dumpHeader() {
return std::string(
- " T Handle UId Port Run State Format Burst Chan Mask Capacity");
+ " T Handle UId Port Run State Format Burst Chan Mask Capacity"
+ " HwFormat HwChan HwRate");
}
std::string AAudioServiceStreamBase::dump() const {
@@ -101,6 +102,9 @@
result << std::setw(5) << getSamplesPerFrame();
result << std::setw(8) << std::hex << getChannelMask() << std::dec;
result << std::setw(9) << getBufferCapacity();
+ result << std::setw(9) << getHardwareFormat();
+ result << std::setw(7) << getHardwareSamplesPerFrame();
+ result << std::setw(7) << getHardwareSampleRate();
return result.str();
}
diff --git a/services/oboeservice/fuzzer/Android.bp b/services/oboeservice/fuzzer/Android.bp
index 605ac01..91ae511 100644
--- a/services/oboeservice/fuzzer/Android.bp
+++ b/services/oboeservice/fuzzer/Android.bp
@@ -29,6 +29,9 @@
cc_fuzz {
name: "oboeservice_fuzzer",
+ defaults: [
+ "latest_android_media_audio_common_types_cpp_shared",
+ ],
srcs: [
"oboeservice_fuzzer.cpp",
],
diff --git a/services/oboeservice/fuzzer/README.md b/services/oboeservice/fuzzer/README.md
index ae7af3eb..617822f 100644
--- a/services/oboeservice/fuzzer/README.md
+++ b/services/oboeservice/fuzzer/README.md
@@ -23,21 +23,24 @@
12. InputPreset
13. BufferCapacity
-| Parameter| Valid Input Values| Configured Value|
-|------------- |-------------| ----- |
-| `AAudioFormat` | `AAUDIO_FORMAT_UNSPECIFIED`, `AAUDIO_FORMAT_PCM_I16`, `AAUDIO_FORMAT_PCM_FLOAT` | Value chosen from valid values by obtaining index from FuzzedDataProvider |
-| `UserId` | `INT32_MIN` to `INT32_MAX` | Value obtained from getuid() |
-| `ProcessId` | `INT32_MIN` to `INT32_MAX` | Value obtained from getpid() |
-| `InService` | `bool` | Value obtained from FuzzedDataProvider |
-| `DeviceId` | `INT32_MIN` to `INT32_MAX` | Value obtained from FuzzedDataProvider |
-| `SampleRate` | `INT32_MIN` to `INT32_MAX` | Value obtained from FuzzedDataProvider |
-| `ChannelMask` | `AAUDIO_UNSPECIFIED`, `AAUDIO_CHANNEL_INDEX_MASK_1`, `AAUDIO_CHANNEL_INDEX_MASK_2`, `AAUDIO_CHANNEL_INDEX_MASK_3`, `AAUDIO_CHANNEL_INDEX_MASK_4`, `AAUDIO_CHANNEL_INDEX_MASK_5`, `AAUDIO_CHANNEL_INDEX_MASK_6`, `AAUDIO_CHANNEL_INDEX_MASK_7`, `AAUDIO_CHANNEL_INDEX_MASK_8`, `AAUDIO_CHANNEL_INDEX_MASK_9`, `AAUDIO_CHANNEL_INDEX_MASK_10`, `AAUDIO_CHANNEL_INDEX_MASK_11`, `AAUDIO_CHANNEL_INDEX_MASK_12`, `AAUDIO_CHANNEL_INDEX_MASK_13`, `AAUDIO_CHANNEL_INDEX_MASK_14`, `AAUDIO_CHANNEL_INDEX_MASK_15`, `AAUDIO_CHANNEL_INDEX_MASK_16`, `AAUDIO_CHANNEL_INDEX_MASK_17`, `AAUDIO_CHANNEL_INDEX_MASK_18`, `AAUDIO_CHANNEL_INDEX_MASK_19`, `AAUDIO_CHANNEL_INDEX_MASK_20`, `AAUDIO_CHANNEL_INDEX_MASK_21`, `AAUDIO_CHANNEL_INDEX_MASK_22`, `AAUDIO_CHANNEL_INDEX_MASK_23`, `AAUDIO_CHANNEL_INDEX_MASK_24`, `AAUDIO_CHANNEL_MONO`, `AAUDIO_CHANNEL_STEREO`, `AAUDIO_CHANNEL_FRONT_BACK`, `AAUDIO_CHANNEL_2POINT0POINT2`, `AAUDIO_CHANNEL_2POINT1POINT2`, `AAUDIO_CHANNEL_3POINT0POINT2`, `AAUDIO_CHANNEL_3POINT1POINT2`, `AAUDIO_CHANNEL_5POINT1`, `AAUDIO_CHANNEL_MONO`, `AAUDIO_CHANNEL_STEREO`, `AAUDIO_CHANNEL_2POINT1`, `AAUDIO_CHANNEL_TRI`, `AAUDIO_CHANNEL_TRI_BACK`, `AAUDIO_CHANNEL_3POINT1`, `AAUDIO_CHANNEL_2POINT0POINT2`, `AAUDIO_CHANNEL_2POINT1POINT2`, `AAUDIO_CHANNEL_3POINT0POINT2`, `AAUDIO_CHANNEL_3POINT1POINT2`, `AAUDIO_CHANNEL_QUAD`, `AAUDIO_CHANNEL_QUAD_SIDE`, `AAUDIO_CHANNEL_SURROUND`, `AAUDIO_CHANNEL_PENTA`, `AAUDIO_CHANNEL_5POINT1`, `AAUDIO_CHANNEL_5POINT1_SIDE`, `AAUDIO_CHANNEL_5POINT1POINT2`, `AAUDIO_CHANNEL_5POINT1POINT4`, `AAUDIO_CHANNEL_6POINT1`, `AAUDIO_CHANNEL_7POINT1`, `AAUDIO_CHANNEL_7POINT1POINT2`, `AAUDIO_CHANNEL_7POINT1POINT4`, `AAUDIO_CHANNEL_9POINT1POINT4`, `AAUDIO_CHANNEL_9POINT1POINT6` | Value obtained from FuzzedDataProvider |
-| `Direction` | `AAUDIO_DIRECTION_OUTPUT`, `AAUDIO_DIRECTION_INPUT` | Value chosen from valid values by obtaining index from FuzzedDataProvider |
-| `SharingMode` | `AAUDIO_SHARING_MODE_EXCLUSIVE`, `AAUDIO_SHARING_MODE_SHARED` | Value chosen from valid values by obtaining index from FuzzedDataProvider |
-| `Usage` | `AAUDIO_USAGE_MEDIA`, `AAUDIO_USAGE_VOICE_COMMUNICATION`, `AAUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING`, `AAUDIO_USAGE_ALARM`, `AAUDIO_USAGE_NOTIFICATION`, `AAUDIO_USAGE_NOTIFICATION_RINGTONE`, `AAUDIO_USAGE_NOTIFICATION_EVENT`, `AAUDIO_USAGE_ASSISTANCE_ACCESSIBILITY`, `AAUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE`, `AAUDIO_USAGE_ASSISTANCE_SONIFICATION`, `AAUDIO_USAGE_GAME`, `AAUDIO_USAGE_ASSISTANT`, `AAUDIO_SYSTEM_USAGE_EMERGENCY`, `AAUDIO_SYSTEM_USAGE_SAFETY`, `AAUDIO_SYSTEM_USAGE_VEHICLE_STATUS`, `AAUDIO_SYSTEM_USAGE_ANNOUNCEMENT` | Value chosen from valid values by obtaining index from FuzzedDataProvider |
-| `ContentType` | `AAUDIO_CONTENT_TYPE_SPEECH`, `AAUDIO_CONTENT_TYPE_MUSIC`, `AAUDIO_CONTENT_TYPE_MOVIE`, `AAUDIO_CONTENT_TYPE_SONIFICATION` | Value chosen from valid values by obtaining index from FuzzedDataProvider |
-| `InputPreset` | `AAUDIO_INPUT_PRESET_GENERIC`, `AAUDIO_INPUT_PRESET_CAMCORDER`, `AAUDIO_INPUT_PRESET_VOICE_RECOGNITION`, `AAUDIO_INPUT_PRESET_VOICE_COMMUNICATION`, `AAUDIO_INPUT_PRESET_UNPROCESSED`, `AAUDIO_INPUT_PRESET_VOICE_PERFORMANCE` | Value chosen from valid values by obtaining index from FuzzedDataProvider |
-| `BufferCapacity` | `INT32_MIN` to `INT32_MAX` | Value obtained from FuzzedDataProvider |
+| Parameter | Valid Input Values| Configured Value|
+|---------------------------|-------------| ----- |
+| `Format` | `AAUDIO_FORMAT_UNSPECIFIED`, `AAUDIO_FORMAT_PCM_I16`, `AAUDIO_FORMAT_PCM_FLOAT`, `AAUDIO_FORMAT_IEC61937`, `AAUDIO_FORMAT_PCM_I24_PACKED`, `AAUDIO_FORMAT_PCM_I32` | Value chosen from valid values by obtaining index from FuzzedDataProvider |
+| `UserId` | `INT32_MIN` to `INT32_MAX` | Value obtained from getuid() |
+| `ProcessId` | `INT32_MIN` to `INT32_MAX` | Value obtained from getpid() |
+| `InService` | `bool` | Value obtained from FuzzedDataProvider |
+| `DeviceId` | `INT32_MIN` to `INT32_MAX` | Value obtained from FuzzedDataProvider |
+| `SampleRate` | `INT32_MIN` to `INT32_MAX` | Value obtained from FuzzedDataProvider |
+| `ChannelMask` | `AAUDIO_UNSPECIFIED`, `AAUDIO_CHANNEL_INDEX_MASK_1`, `AAUDIO_CHANNEL_INDEX_MASK_2`, `AAUDIO_CHANNEL_INDEX_MASK_3`, `AAUDIO_CHANNEL_INDEX_MASK_4`, `AAUDIO_CHANNEL_INDEX_MASK_5`, `AAUDIO_CHANNEL_INDEX_MASK_6`, `AAUDIO_CHANNEL_INDEX_MASK_7`, `AAUDIO_CHANNEL_INDEX_MASK_8`, `AAUDIO_CHANNEL_INDEX_MASK_9`, `AAUDIO_CHANNEL_INDEX_MASK_10`, `AAUDIO_CHANNEL_INDEX_MASK_11`, `AAUDIO_CHANNEL_INDEX_MASK_12`, `AAUDIO_CHANNEL_INDEX_MASK_13`, `AAUDIO_CHANNEL_INDEX_MASK_14`, `AAUDIO_CHANNEL_INDEX_MASK_15`, `AAUDIO_CHANNEL_INDEX_MASK_16`, `AAUDIO_CHANNEL_INDEX_MASK_17`, `AAUDIO_CHANNEL_INDEX_MASK_18`, `AAUDIO_CHANNEL_INDEX_MASK_19`, `AAUDIO_CHANNEL_INDEX_MASK_20`, `AAUDIO_CHANNEL_INDEX_MASK_21`, `AAUDIO_CHANNEL_INDEX_MASK_22`, `AAUDIO_CHANNEL_INDEX_MASK_23`, `AAUDIO_CHANNEL_INDEX_MASK_24`, `AAUDIO_CHANNEL_MONO`, `AAUDIO_CHANNEL_STEREO`, `AAUDIO_CHANNEL_FRONT_BACK`, `AAUDIO_CHANNEL_2POINT0POINT2`, `AAUDIO_CHANNEL_2POINT1POINT2`, `AAUDIO_CHANNEL_3POINT0POINT2`, `AAUDIO_CHANNEL_3POINT1POINT2`, `AAUDIO_CHANNEL_5POINT1`, `AAUDIO_CHANNEL_MONO`, `AAUDIO_CHANNEL_STEREO`, `AAUDIO_CHANNEL_2POINT1`, `AAUDIO_CHANNEL_TRI`, `AAUDIO_CHANNEL_TRI_BACK`, `AAUDIO_CHANNEL_3POINT1`, `AAUDIO_CHANNEL_2POINT0POINT2`, `AAUDIO_CHANNEL_2POINT1POINT2`, `AAUDIO_CHANNEL_3POINT0POINT2`, `AAUDIO_CHANNEL_3POINT1POINT2`, `AAUDIO_CHANNEL_QUAD`, `AAUDIO_CHANNEL_QUAD_SIDE`, `AAUDIO_CHANNEL_SURROUND`, `AAUDIO_CHANNEL_PENTA`, `AAUDIO_CHANNEL_5POINT1`, `AAUDIO_CHANNEL_5POINT1_SIDE`, `AAUDIO_CHANNEL_5POINT1POINT2`, `AAUDIO_CHANNEL_5POINT1POINT4`, `AAUDIO_CHANNEL_6POINT1`, `AAUDIO_CHANNEL_7POINT1`, `AAUDIO_CHANNEL_7POINT1POINT2`, `AAUDIO_CHANNEL_7POINT1POINT4`, `AAUDIO_CHANNEL_9POINT1POINT4`, `AAUDIO_CHANNEL_9POINT1POINT6` | Value obtained from FuzzedDataProvider |
+| `Direction` | `AAUDIO_DIRECTION_OUTPUT`, `AAUDIO_DIRECTION_INPUT` | Value chosen from valid values by obtaining index from FuzzedDataProvider |
+| `SharingMode` | `AAUDIO_SHARING_MODE_EXCLUSIVE`, `AAUDIO_SHARING_MODE_SHARED` | Value chosen from valid values by obtaining index from FuzzedDataProvider |
+| `Usage` | `AAUDIO_USAGE_MEDIA`, `AAUDIO_USAGE_VOICE_COMMUNICATION`, `AAUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING`, `AAUDIO_USAGE_ALARM`, `AAUDIO_USAGE_NOTIFICATION`, `AAUDIO_USAGE_NOTIFICATION_RINGTONE`, `AAUDIO_USAGE_NOTIFICATION_EVENT`, `AAUDIO_USAGE_ASSISTANCE_ACCESSIBILITY`, `AAUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE`, `AAUDIO_USAGE_ASSISTANCE_SONIFICATION`, `AAUDIO_USAGE_GAME`, `AAUDIO_USAGE_ASSISTANT`, `AAUDIO_SYSTEM_USAGE_EMERGENCY`, `AAUDIO_SYSTEM_USAGE_SAFETY`, `AAUDIO_SYSTEM_USAGE_VEHICLE_STATUS`, `AAUDIO_SYSTEM_USAGE_ANNOUNCEMENT` | Value chosen from valid values by obtaining index from FuzzedDataProvider |
+| `ContentType` | `AAUDIO_CONTENT_TYPE_SPEECH`, `AAUDIO_CONTENT_TYPE_MUSIC`, `AAUDIO_CONTENT_TYPE_MOVIE`, `AAUDIO_CONTENT_TYPE_SONIFICATION` | Value chosen from valid values by obtaining index from FuzzedDataProvider |
+| `InputPreset` | `AAUDIO_INPUT_PRESET_GENERIC`, `AAUDIO_INPUT_PRESET_CAMCORDER`, `AAUDIO_INPUT_PRESET_VOICE_RECOGNITION`, `AAUDIO_INPUT_PRESET_VOICE_COMMUNICATION`, `AAUDIO_INPUT_PRESET_UNPROCESSED`, `AAUDIO_INPUT_PRESET_VOICE_PERFORMANCE` | Value chosen from valid values by obtaining index from FuzzedDataProvider |
+| `BufferCapacity` | `INT32_MIN` to `INT32_MAX` | Value obtained from FuzzedDataProvider |
+| `HardwareSampleRate` | `INT32_MIN` to `INT32_MAX` | Value obtained from FuzzedDataProvider |
+| `HardwareSamplesPerFrame` | `INT32_MIN` to `INT32_MAX` | Value obtained from FuzzedDataProvider |
+| `HardwareFormat` | `AAUDIO_FORMAT_UNSPECIFIED`, `AAUDIO_FORMAT_PCM_I16`, `AAUDIO_FORMAT_PCM_FLOAT`, `AAUDIO_FORMAT_IEC61937`, `AAUDIO_FORMAT_PCM_I24_PACKED`, `AAUDIO_FORMAT_PCM_I32` | Value chosen from valid values by obtaining index from FuzzedDataProvider |
This also ensures that the plugin is always deterministic for any given input.
diff --git a/services/oboeservice/fuzzer/oboeservice_fuzzer.cpp b/services/oboeservice/fuzzer/oboeservice_fuzzer.cpp
index 5e48955..6dc6eff 100644
--- a/services/oboeservice/fuzzer/oboeservice_fuzzer.cpp
+++ b/services/oboeservice/fuzzer/oboeservice_fuzzer.cpp
@@ -34,6 +34,9 @@
AAUDIO_FORMAT_UNSPECIFIED,
AAUDIO_FORMAT_PCM_I16,
AAUDIO_FORMAT_PCM_FLOAT,
+ AAUDIO_FORMAT_PCM_I24_PACKED,
+ AAUDIO_FORMAT_PCM_I32,
+ AAUDIO_FORMAT_IEC61937
};
aaudio_usage_t kAAudioUsages[] = {
@@ -400,6 +403,13 @@
request.getConfiguration().setBufferCapacity(fdp.ConsumeIntegral<int32_t>());
+ request.getConfiguration().setHardwareSampleRate(fdp.ConsumeIntegral<int32_t>());
+ request.getConfiguration().setHardwareSamplesPerFrame(fdp.ConsumeIntegral<int32_t>());
+ request.getConfiguration().setHardwareFormat((audio_format_t)(
+ fdp.ConsumeBool()
+ ? fdp.ConsumeIntegral<int32_t>()
+ : kAAudioFormats[fdp.ConsumeIntegralInRange<int32_t>(0, kNumAAudioFormats - 1)]));
+
aaudio_handle_t stream = mClient->openStream(request, configurationOutput);
if (stream < 0) {
// invalid request, stream not opened.