AAudio: add setBufferCapacity()

This is needed so that an app can request a larger buffer.
Also fix a bug related to passing configuration data to the service.

Test: test_aaudio.cpp
Change-Id: Idd3066c84f6bac76a5d545b12081bc311025a6c3
Signed-off-by: Phil Burk <philburk@google.com>
diff --git a/media/liboboe/src/binding/AAudioStreamConfiguration.cpp b/media/liboboe/src/binding/AAudioStreamConfiguration.cpp
index 1cb2bfa..fe3a59f 100644
--- a/media/liboboe/src/binding/AAudioStreamConfiguration.cpp
+++ b/media/liboboe/src/binding/AAudioStreamConfiguration.cpp
@@ -39,6 +39,7 @@
     parcel->writeInt32(mSampleRate);
     parcel->writeInt32(mSamplesPerFrame);
     parcel->writeInt32((int32_t) mAudioFormat);
+    parcel->writeInt32(mBufferCapacity);
     return NO_ERROR; // TODO check for errors above
 }
 
@@ -49,6 +50,7 @@
     parcel->readInt32(&mSamplesPerFrame);
     parcel->readInt32(&temp);
     mAudioFormat = (aaudio_audio_format_t) temp;
+    parcel->readInt32(&mBufferCapacity);
     return NO_ERROR; // TODO check for errors above
 }
 
@@ -74,11 +76,17 @@
         ALOGE("AAudioStreamConfiguration.validate() invalid audioFormat = %d", mAudioFormat);
         return AAUDIO_ERROR_INTERNAL;
     }
+
+    if (mBufferCapacity < 0) {
+        ALOGE("AAudioStreamConfiguration.validate() invalid mBufferCapacity = %d", mBufferCapacity);
+        return AAUDIO_ERROR_INTERNAL;
+    }
     return AAUDIO_OK;
 }
 
 void AAudioStreamConfiguration::dump() {
-    ALOGD("AAudioStreamConfiguration mSampleRate = %d -----", mSampleRate);
+    ALOGD("AAudioStreamConfiguration mSampleRate      = %d -----", mSampleRate);
     ALOGD("AAudioStreamConfiguration mSamplesPerFrame = %d", mSamplesPerFrame);
-    ALOGD("AAudioStreamConfiguration mAudioFormat = %d", (int)mAudioFormat);
+    ALOGD("AAudioStreamConfiguration mAudioFormat     = %d", (int)mAudioFormat);
+    ALOGD("AAudioStreamConfiguration mBufferCapacity  = %d", mBufferCapacity);
 }
diff --git a/media/liboboe/src/binding/AAudioStreamConfiguration.h b/media/liboboe/src/binding/AAudioStreamConfiguration.h
index ef21443..efcdae8 100644
--- a/media/liboboe/src/binding/AAudioStreamConfiguration.h
+++ b/media/liboboe/src/binding/AAudioStreamConfiguration.h
@@ -66,6 +66,14 @@
         mAudioFormat = audioFormat;
     }
 
+    aaudio_size_frames_t getBufferCapacity() const {
+        return mBufferCapacity;
+    }
+
+    void setBufferCapacity(aaudio_size_frames_t frames) {
+        mBufferCapacity = frames;
+    }
+
     virtual status_t writeToParcel(Parcel* parcel) const override;
 
     virtual status_t readFromParcel(const Parcel* parcel) override;
@@ -77,8 +85,9 @@
 protected:
     aaudio_device_id_t    mDeviceId        = AAUDIO_DEVICE_UNSPECIFIED;
     aaudio_sample_rate_t  mSampleRate      = AAUDIO_UNSPECIFIED;
-    int32_t             mSamplesPerFrame = AAUDIO_UNSPECIFIED;
+    int32_t               mSamplesPerFrame = AAUDIO_UNSPECIFIED;
     aaudio_audio_format_t mAudioFormat     = AAUDIO_FORMAT_UNSPECIFIED;
+    aaudio_size_frames_t  mBufferCapacity  = AAUDIO_UNSPECIFIED;
 };
 
 } /* namespace aaudio */
diff --git a/media/liboboe/src/binding/IAAudioService.h b/media/liboboe/src/binding/IAAudioService.h
index 7d2fd29..f3b297e 100644
--- a/media/liboboe/src/binding/IAAudioService.h
+++ b/media/liboboe/src/binding/IAAudioService.h
@@ -38,6 +38,11 @@
 
     DECLARE_META_INTERFACE(AAudioService);
 
+    /**
+     * @param request info needed to create the stream
+     * @param configuration contains information about the created stream
+     * @return handle to the stream or a negative error
+     */
     virtual aaudio_handle_t openStream(aaudio::AAudioStreamRequest &request,
                                      aaudio::AAudioStreamConfiguration &configuration) = 0;
 
diff --git a/media/liboboe/src/binding/SharedMemoryParcelable.cpp b/media/liboboe/src/binding/SharedMemoryParcelable.cpp
index 277a992..1102dec 100644
--- a/media/liboboe/src/binding/SharedMemoryParcelable.cpp
+++ b/media/liboboe/src/binding/SharedMemoryParcelable.cpp
@@ -87,9 +87,9 @@
 }
 
 aaudio_result_t SharedMemoryParcelable::validate() {
-    if (mSizeInBytes < 0 || mSizeInBytes >= MAX_MMAP_SIZE) {
+    if (mSizeInBytes < 0 || mSizeInBytes >= MAX_MMAP_SIZE_BYTES) {
         ALOGE("SharedMemoryParcelable invalid mSizeInBytes = %d", mSizeInBytes);
-        return AAUDIO_ERROR_INTERNAL;
+        return AAUDIO_ERROR_OUT_OF_RANGE;
     }
     if (mSizeInBytes > 0) {
         if (mFd == -1) {
diff --git a/media/liboboe/src/binding/SharedMemoryParcelable.h b/media/liboboe/src/binding/SharedMemoryParcelable.h
index 5768ea9..7e0bf1a 100644
--- a/media/liboboe/src/binding/SharedMemoryParcelable.h
+++ b/media/liboboe/src/binding/SharedMemoryParcelable.h
@@ -31,8 +31,8 @@
 
 // Arbitrary limits for sanity checks. TODO remove after debugging.
 #define MAX_SHARED_MEMORIES (32)
-#define MAX_MMAP_OFFSET (32 * 1024)
-#define MAX_MMAP_SIZE (32 * 1024)
+#define MAX_MMAP_OFFSET_BYTES (32 * 1024 * 8)
+#define MAX_MMAP_SIZE_BYTES (32 * 1024 * 8)
 
 /**
  * This is a parcelable description of a shared memory referenced by a file descriptor.
diff --git a/media/liboboe/src/binding/SharedRegionParcelable.cpp b/media/liboboe/src/binding/SharedRegionParcelable.cpp
index a3e0111..8ca0023 100644
--- a/media/liboboe/src/binding/SharedRegionParcelable.cpp
+++ b/media/liboboe/src/binding/SharedRegionParcelable.cpp
@@ -75,14 +75,14 @@
 }
 
 aaudio_result_t SharedRegionParcelable::validate() {
-    if (mSizeInBytes < 0 || mSizeInBytes >= MAX_MMAP_SIZE) {
+    if (mSizeInBytes < 0 || mSizeInBytes >= MAX_MMAP_SIZE_BYTES) {
         ALOGE("SharedRegionParcelable invalid mSizeInBytes = %d", mSizeInBytes);
-        return AAUDIO_ERROR_INTERNAL;
+        return AAUDIO_ERROR_OUT_OF_RANGE;
     }
     if (mSizeInBytes > 0) {
-        if (mOffsetInBytes < 0 || mOffsetInBytes >= MAX_MMAP_OFFSET) {
+        if (mOffsetInBytes < 0 || mOffsetInBytes >= MAX_MMAP_OFFSET_BYTES) {
             ALOGE("SharedRegionParcelable invalid mOffsetInBytes = %d", mOffsetInBytes);
-            return AAUDIO_ERROR_INTERNAL;
+            return AAUDIO_ERROR_OUT_OF_RANGE;
         }
         if (mSharedMemoryIndex < 0 || mSharedMemoryIndex >= MAX_SHARED_MEMORIES) {
             ALOGE("SharedRegionParcelable invalid mSharedMemoryIndex = %d", mSharedMemoryIndex);
diff --git a/media/liboboe/src/client/AudioStreamInternal.cpp b/media/liboboe/src/client/AudioStreamInternal.cpp
index 8d7e93f..19f2300 100644
--- a/media/liboboe/src/client/AudioStreamInternal.cpp
+++ b/media/liboboe/src/client/AudioStreamInternal.cpp
@@ -33,6 +33,7 @@
 #include "binding/IAAudioService.h"
 #include "binding/AAudioServiceMessage.h"
 
+#include "core/AudioStreamBuilder.h"
 #include "AudioStreamInternal.h"
 
 #define LOG_TIMESTAMPS   0
@@ -110,6 +111,7 @@
     request.getConfiguration().setSampleRate(getSampleRate());
     request.getConfiguration().setSamplesPerFrame(getSamplesPerFrame());
     request.getConfiguration().setAudioFormat(getFormat());
+    request.getConfiguration().setBufferCapacity(builder.getBufferCapacity());
     request.dump();
 
     mServiceStreamHandle = service->openStream(request, configuration);
@@ -142,7 +144,6 @@
         // Configure endpoint based on descriptor.
         mAudioEndpoint.configure(&mEndpointDescriptor);
 
-
         mFramesPerBurst = mEndpointDescriptor.downDataQueueDescriptor.framesPerBurst;
         assert(mFramesPerBurst >= 16);
         assert(mEndpointDescriptor.downDataQueueDescriptor.capacityInFrames < 10 * 1024);
diff --git a/media/liboboe/src/core/AAudioAudio.cpp b/media/liboboe/src/core/AAudioAudio.cpp
index c1fa7cf..04dbda1 100644
--- a/media/liboboe/src/core/AAudioAudio.cpp
+++ b/media/liboboe/src/core/AAudioAudio.cpp
@@ -256,6 +256,26 @@
     return AAUDIO_OK;
 }
 
+AAUDIO_API aaudio_result_t AAudioStreamBuilder_setBufferCapacity(AAudioStreamBuilder builder,
+                                                        aaudio_size_frames_t frames)
+{
+    AudioStreamBuilder *streamBuilder = CONVERT_BUILDER_HANDLE_OR_RETURN();
+    if (frames < 0) {
+        return AAUDIO_ERROR_ILLEGAL_ARGUMENT;
+    } else {
+        streamBuilder->setBufferCapacity(frames);
+        return AAUDIO_OK;
+    }
+}
+
+AAUDIO_API aaudio_result_t AAudioStreamBuilder_getBufferCapacity(AAudioStreamBuilder builder,
+                                                        aaudio_size_frames_t *frames)
+{
+    AudioStreamBuilder *streamBuilder = COMMON_GET_FROM_BUILDER_OR_RETURN(frames);
+    *frames = streamBuilder->getBufferCapacity();
+    return AAUDIO_OK;
+}
+
 static aaudio_result_t  AAudioInternal_openStream(AudioStreamBuilder *streamBuilder,
                                               AAudioStream *streamPtr)
 {
diff --git a/media/liboboe/src/core/AudioStreamBuilder.h b/media/liboboe/src/core/AudioStreamBuilder.h
index 9e1a1a7..e72633d 100644
--- a/media/liboboe/src/core/AudioStreamBuilder.h
+++ b/media/liboboe/src/core/AudioStreamBuilder.h
@@ -83,6 +83,15 @@
         return this;
     }
 
+    aaudio_size_frames_t getBufferCapacity() const {
+        return mBufferCapacity;
+    }
+
+    AudioStreamBuilder* setBufferCapacity(aaudio_size_frames_t frames) {
+        mBufferCapacity = frames;
+        return this;
+    }
+
     aaudio_device_id_t getDeviceId() const {
         return mDeviceId;
     }
@@ -95,12 +104,13 @@
     aaudio_result_t build(AudioStream **streamPtr);
 
 private:
-    int32_t              mSamplesPerFrame = AAUDIO_UNSPECIFIED;
+    int32_t                mSamplesPerFrame = AAUDIO_UNSPECIFIED;
     aaudio_sample_rate_t   mSampleRate = AAUDIO_UNSPECIFIED;
     aaudio_device_id_t     mDeviceId = AAUDIO_DEVICE_UNSPECIFIED;
     aaudio_sharing_mode_t  mSharingMode = AAUDIO_SHARING_MODE_LEGACY;
     aaudio_audio_format_t  mFormat = AAUDIO_FORMAT_UNSPECIFIED;
     aaudio_direction_t     mDirection = AAUDIO_DIRECTION_OUTPUT;
+    aaudio_size_frames_t   mBufferCapacity = AAUDIO_UNSPECIFIED;
 };
 
 } /* namespace aaudio */
diff --git a/media/liboboe/src/legacy/AudioStreamRecord.cpp b/media/liboboe/src/legacy/AudioStreamRecord.cpp
index 2d1785f..17d0a54 100644
--- a/media/liboboe/src/legacy/AudioStreamRecord.cpp
+++ b/media/liboboe/src/legacy/AudioStreamRecord.cpp
@@ -60,6 +60,8 @@
     AudioRecord::callback_t callback = nullptr;
     audio_input_flags_t flags = (audio_input_flags_t) AUDIO_INPUT_FLAG_NONE;
 
+    size_t frameCount = (builder.getBufferCapacity() == AAUDIO_UNSPECIFIED) ? 0
+                        : builder.getBufferCapacity();
     // TODO implement an unspecified Android format then use that.
     audio_format_t format = (getFormat() == AAUDIO_UNSPECIFIED)
             ? AUDIO_FORMAT_PCM_FLOAT
@@ -70,20 +72,18 @@
             getSampleRate(),
             format,
             channelMask,
-
             mOpPackageName, // const String16& opPackageName TODO does not compile
-
-            0,    //    size_t frameCount = 0,
+            frameCount,
             callback,
             nullptr, //    void* user = nullptr,
             0,    //    uint32_t notificationFrames = 0,
             AUDIO_SESSION_ALLOCATE,
             AudioRecord::TRANSFER_DEFAULT,
             flags
-             //   int uid = -1,
-             //   pid_t pid = -1,
-             //   const audio_attributes_t* pAttributes = nullptr
-             );
+            //   int uid = -1,
+            //   pid_t pid = -1,
+            //   const audio_attributes_t* pAttributes = nullptr
+            );
 
     // Did we get a valid track?
     status_t status = mAudioRecord->initCheck();
diff --git a/media/liboboe/src/legacy/AudioStreamTrack.cpp b/media/liboboe/src/legacy/AudioStreamTrack.cpp
index a60b5b4..b7d8664 100644
--- a/media/liboboe/src/legacy/AudioStreamTrack.cpp
+++ b/media/liboboe/src/legacy/AudioStreamTrack.cpp
@@ -64,7 +64,8 @@
     AudioTrack::callback_t callback = nullptr;
     // TODO add more performance options
     audio_output_flags_t flags = (audio_output_flags_t) AUDIO_OUTPUT_FLAG_FAST;
-    size_t frameCount = 0;
+    size_t frameCount = (builder.getBufferCapacity() == AAUDIO_UNSPECIFIED) ? 0
+                        : builder.getBufferCapacity();
     // TODO implement an unspecified AudioTrack format then use that.
     audio_format_t format = (getFormat() == AAUDIO_UNSPECIFIED)
             ? AUDIO_FORMAT_PCM_FLOAT