AAudioService: integrated with audioserver

Call the MmapStreamInterface from AudioFlinger instead of the FakeHAL.
Fix sending timestamps from the thread.
Add shared mode in service.

Bug: 35260844
Bug: 33398120
Test: CTS test_aaudio.cpp
Change-Id: I44c7e4ecae4ce205611b6b73a72e0ae8a5b243e5
Signed-off-by: Phil Burk <philburk@google.com>
(cherry picked from commit 7f6b40d78b1976c78d1300e8a51fda36eeb50c5d)
diff --git a/media/libaaudio/src/fifo/FifoBuffer.cpp b/media/libaaudio/src/fifo/FifoBuffer.cpp
index c5489f1..857780c 100644
--- a/media/libaaudio/src/fifo/FifoBuffer.cpp
+++ b/media/libaaudio/src/fifo/FifoBuffer.cpp
@@ -17,6 +17,7 @@
 #include <cstring>
 #include <unistd.h>
 
+
 #define LOG_TAG "FifoBuffer"
 //#define LOG_NDEBUG 0
 #include <utils/Log.h>
@@ -26,6 +27,8 @@
 #include "FifoControllerIndirect.h"
 #include "FifoBuffer.h"
 
+using namespace android; // TODO just import names needed
+
 FifoBuffer::FifoBuffer(int32_t bytesPerFrame, fifo_frames_t capacityInFrames)
         : mFrameCapacity(capacityInFrames)
         , mBytesPerFrame(bytesPerFrame)
@@ -79,80 +82,102 @@
     return frames * mBytesPerFrame;
 }
 
-fifo_frames_t FifoBuffer::read(void *buffer, fifo_frames_t numFrames) {
-    size_t numBytes;
-    fifo_frames_t framesAvailable = mFifo->getFullFramesAvailable();
-    fifo_frames_t framesToRead = numFrames;
-    // Is there enough data in the FIFO
-    if (framesToRead > framesAvailable) {
-        framesToRead = framesAvailable;
-    }
-    if (framesToRead == 0) {
-        return 0;
-    }
+void FifoBuffer::fillWrappingBuffer(WrappingBuffer *wrappingBuffer,
+                                    int32_t framesAvailable,
+                                    int32_t startIndex) {
+    wrappingBuffer->data[1] = nullptr;
+    wrappingBuffer->numFrames[1] = 0;
+    if (framesAvailable > 0) {
 
-    fifo_frames_t readIndex = mFifo->getReadIndex();
-    uint8_t *destination = (uint8_t *) buffer;
-    uint8_t *source = &mStorage[convertFramesToBytes(readIndex)];
-    if ((readIndex + framesToRead) > mFrameCapacity) {
-        // read in two parts, first part here
-        fifo_frames_t frames1 = mFrameCapacity - readIndex;
-        int32_t numBytes = convertFramesToBytes(frames1);
-        memcpy(destination, source, numBytes);
-        destination += numBytes;
-        // read second part
-        source = &mStorage[0];
-        fifo_frames_t frames2 = framesToRead - frames1;
-        numBytes = convertFramesToBytes(frames2);
-        memcpy(destination, source, numBytes);
+        uint8_t *source = &mStorage[convertFramesToBytes(startIndex)];
+        // Does the available data cross the end of the FIFO?
+        if ((startIndex + framesAvailable) > mFrameCapacity) {
+            wrappingBuffer->data[0] = source;
+            wrappingBuffer->numFrames[0] = mFrameCapacity - startIndex;
+            wrappingBuffer->data[1] = &mStorage[0];
+            wrappingBuffer->numFrames[1] = mFrameCapacity - startIndex;
+
+        } else {
+            wrappingBuffer->data[0] = source;
+            wrappingBuffer->numFrames[0] = framesAvailable;
+        }
     } else {
-        // just read in one shot
-        numBytes = convertFramesToBytes(framesToRead);
-        memcpy(destination, source, numBytes);
+        wrappingBuffer->data[0] = nullptr;
+        wrappingBuffer->numFrames[0] = 0;
     }
-    mFifo->advanceReadIndex(framesToRead);
 
-    return framesToRead;
 }
 
-fifo_frames_t FifoBuffer::write(const void *buffer, fifo_frames_t framesToWrite) {
+void FifoBuffer::getFullDataAvailable(WrappingBuffer *wrappingBuffer) {
+    fifo_frames_t framesAvailable = mFifo->getFullFramesAvailable();
+    fifo_frames_t startIndex = mFifo->getReadIndex();
+    fillWrappingBuffer(wrappingBuffer, framesAvailable, startIndex);
+}
+
+void FifoBuffer::getEmptyRoomAvailable(WrappingBuffer *wrappingBuffer) {
     fifo_frames_t framesAvailable = mFifo->getEmptyFramesAvailable();
-//    ALOGD("FifoBuffer::write() framesToWrite = %d, framesAvailable = %d",
-//         framesToWrite, framesAvailable);
-    if (framesToWrite > framesAvailable) {
-        framesToWrite = framesAvailable;
-    }
-    if (framesToWrite <= 0) {
-        return 0;
-    }
+    fifo_frames_t startIndex = mFifo->getWriteIndex();
+    fillWrappingBuffer(wrappingBuffer, framesAvailable, startIndex);
+}
 
-    size_t numBytes;
-    fifo_frames_t writeIndex = mFifo->getWriteIndex();
-    int byteIndex = convertFramesToBytes(writeIndex);
-    const uint8_t *source = (const uint8_t *) buffer;
-    uint8_t *destination = &mStorage[byteIndex];
-    if ((writeIndex + framesToWrite) > mFrameCapacity) {
-        // write in two parts, first part here
-        fifo_frames_t frames1 = mFrameCapacity - writeIndex;
-        numBytes = convertFramesToBytes(frames1);
-        memcpy(destination, source, numBytes);
-//        ALOGD("FifoBuffer::write(%p to %p, numBytes = %d", source, destination, numBytes);
-        // read second part
-        source += convertFramesToBytes(frames1);
-        destination = &mStorage[0];
-        fifo_frames_t framesLeft = framesToWrite - frames1;
-        numBytes = convertFramesToBytes(framesLeft);
-//        ALOGD("FifoBuffer::write(%p to %p, numBytes = %d", source, destination, numBytes);
-        memcpy(destination, source, numBytes);
-    } else {
-        // just write in one shot
-        numBytes = convertFramesToBytes(framesToWrite);
-//        ALOGD("FifoBuffer::write(%p to %p, numBytes = %d", source, destination, numBytes);
-        memcpy(destination, source, numBytes);
-    }
-    mFifo->advanceWriteIndex(framesToWrite);
+fifo_frames_t FifoBuffer::read(void *buffer, fifo_frames_t numFrames) {
+    WrappingBuffer wrappingBuffer;
+    uint8_t *destination = (uint8_t *) buffer;
+    fifo_frames_t framesLeft = numFrames;
 
-    return framesToWrite;
+    getFullDataAvailable(&wrappingBuffer);
+
+    // Read data in one or two parts.
+    int partIndex = 0;
+    while (framesLeft > 0 && partIndex < WrappingBuffer::SIZE) {
+        fifo_frames_t framesToRead = framesLeft;
+        fifo_frames_t framesAvailable = wrappingBuffer.numFrames[partIndex];
+        //ALOGD("FifoProcessor::read() framesAvailable = %d, partIndex = %d",
+        //      framesAvailable, partIndex);
+        if (framesAvailable > 0) {
+            if (framesToRead > framesAvailable) {
+                framesToRead = framesAvailable;
+            }
+            int32_t numBytes = convertFramesToBytes(framesToRead);
+            memcpy(destination, wrappingBuffer.data[partIndex], numBytes);
+
+            destination += numBytes;
+            framesLeft -= framesToRead;
+        }
+        partIndex++;
+    }
+    fifo_frames_t framesRead = numFrames - framesLeft;
+    mFifo->advanceReadIndex(framesRead);
+    return framesRead;
+}
+
+fifo_frames_t FifoBuffer::write(const void *buffer, fifo_frames_t numFrames) {
+    WrappingBuffer wrappingBuffer;
+    uint8_t *source = (uint8_t *) buffer;
+    fifo_frames_t framesLeft = numFrames;
+
+    getEmptyRoomAvailable(&wrappingBuffer);
+
+    // Read data in one or two parts.
+    int partIndex = 0;
+    while (framesLeft > 0 && partIndex < WrappingBuffer::SIZE) {
+        fifo_frames_t framesToWrite = framesLeft;
+        fifo_frames_t framesAvailable = wrappingBuffer.numFrames[partIndex];
+        if (framesAvailable > 0) {
+            if (framesToWrite > framesAvailable) {
+                framesToWrite = framesAvailable;
+            }
+            int32_t numBytes = convertFramesToBytes(framesToWrite);
+            memcpy(wrappingBuffer.data[partIndex], source, numBytes);
+
+            source += numBytes;
+            framesLeft -= framesToWrite;
+        }
+        partIndex++;
+    }
+    fifo_frames_t framesWritten = numFrames - framesLeft;
+    mFifo->advanceWriteIndex(framesWritten);
+    return framesWritten;
 }
 
 fifo_frames_t FifoBuffer::readNow(void *buffer, fifo_frames_t numFrames) {
diff --git a/media/libaaudio/src/fifo/FifoBuffer.h b/media/libaaudio/src/fifo/FifoBuffer.h
index faa9ae2..2b262a1 100644
--- a/media/libaaudio/src/fifo/FifoBuffer.h
+++ b/media/libaaudio/src/fifo/FifoBuffer.h
@@ -21,15 +21,29 @@
 
 #include "FifoControllerBase.h"
 
+namespace android {
+
+/**
+ * Structure that represents a region in a circular buffer that might be at the
+ * end of the array and split in two.
+ */
+struct WrappingBuffer {
+    enum {
+        SIZE = 2
+    };
+    void *data[SIZE];
+    int32_t numFrames[SIZE];
+};
+
 class FifoBuffer {
 public:
     FifoBuffer(int32_t bytesPerFrame, fifo_frames_t capacityInFrames);
 
-    FifoBuffer(int32_t   bytesPerFrame,
-               fifo_frames_t   capacityInFrames,
-               fifo_counter_t * readCounterAddress,
-               fifo_counter_t * writeCounterAddress,
-               void * dataStorageAddress);
+    FifoBuffer(int32_t bytesPerFrame,
+               fifo_frames_t capacityInFrames,
+               fifo_counter_t *readCounterAddress,
+               fifo_counter_t *writeCounterAddress,
+               void *dataStorageAddress);
 
     ~FifoBuffer();
 
@@ -40,10 +54,33 @@
     fifo_frames_t write(const void *source, fifo_frames_t framesToWrite);
 
     fifo_frames_t getThreshold();
+
     void setThreshold(fifo_frames_t threshold);
 
     fifo_frames_t getBufferCapacityInFrames();
 
+    /**
+     * Return pointer to available full frames in data1 and set size in numFrames1.
+     * if the data is split across the end of the FIFO then set data2 and numFrames2.
+     * Other wise set them to null
+     * @param wrappingBuffer
+     */
+    void getFullDataAvailable(WrappingBuffer *wrappingBuffer);
+
+    /**
+     * Return pointer to available empty frames in data1 and set size in numFrames1.
+     * if the room is split across the end of the FIFO then set data2 and numFrames2.
+     * Other wise set them to null
+     * @param wrappingBuffer
+     */
+    void getEmptyRoomAvailable(WrappingBuffer *wrappingBuffer);
+
+    /**
+     * Copy data from the FIFO into the buffer.
+     * @param buffer
+     * @param numFrames
+     * @return
+     */
     fifo_frames_t readNow(void *buffer, fifo_frames_t numFrames);
 
     int64_t getNextReadTime(int32_t frameRate);
@@ -73,15 +110,21 @@
     }
 
 private:
+
+    void fillWrappingBuffer(WrappingBuffer *wrappingBuffer,
+                            int32_t framesAvailable, int32_t startIndex);
+
     const fifo_frames_t mFrameCapacity;
-    const int32_t       mBytesPerFrame;
-    uint8_t *           mStorage;
-    bool                mStorageOwned; // did this object allocate the storage?
+    const int32_t mBytesPerFrame;
+    uint8_t *mStorage;
+    bool mStorageOwned; // did this object allocate the storage?
     FifoControllerBase *mFifo;
-    fifo_counter_t      mFramesReadCount;
-    fifo_counter_t      mFramesUnderrunCount;
-    int32_t             mUnderrunCount; // need? just use frames
-    int32_t             mLastReadSize;
+    fifo_counter_t mFramesReadCount;
+    fifo_counter_t mFramesUnderrunCount;
+    int32_t mUnderrunCount; // need? just use frames
+    int32_t mLastReadSize;
 };
 
+}  // android
+
 #endif //FIFO_FIFO_BUFFER_H
diff --git a/media/libaaudio/src/fifo/FifoController.h b/media/libaaudio/src/fifo/FifoController.h
index 7434634..79d98a1 100644
--- a/media/libaaudio/src/fifo/FifoController.h
+++ b/media/libaaudio/src/fifo/FifoController.h
@@ -22,6 +22,8 @@
 
 #include "FifoControllerBase.h"
 
+namespace android {
+
 /**
  * A FIFO with counters contained in the class.
  */
@@ -55,5 +57,6 @@
     std::atomic<fifo_counter_t> mWriteCounter;
 };
 
+}  // android
 
 #endif //FIFO_FIFO_CONTROLLER_H
diff --git a/media/libaaudio/src/fifo/FifoControllerBase.cpp b/media/libaaudio/src/fifo/FifoControllerBase.cpp
index 33a253e..14a2be1 100644
--- a/media/libaaudio/src/fifo/FifoControllerBase.cpp
+++ b/media/libaaudio/src/fifo/FifoControllerBase.cpp
@@ -21,6 +21,8 @@
 #include <stdint.h>
 #include "FifoControllerBase.h"
 
+using namespace android;  // TODO just import names needed
+
 FifoControllerBase::FifoControllerBase(fifo_frames_t capacity, fifo_frames_t threshold)
         : mCapacity(capacity)
         , mThreshold(threshold)
diff --git a/media/libaaudio/src/fifo/FifoControllerBase.h b/media/libaaudio/src/fifo/FifoControllerBase.h
index c543519..64af777 100644
--- a/media/libaaudio/src/fifo/FifoControllerBase.h
+++ b/media/libaaudio/src/fifo/FifoControllerBase.h
@@ -19,6 +19,8 @@
 
 #include <stdint.h>
 
+namespace android {
+
 typedef int64_t fifo_counter_t;
 typedef int32_t fifo_frames_t;
 
@@ -118,4 +120,6 @@
     fifo_frames_t mThreshold;
 };
 
+}  // android
+
 #endif // FIFO_FIFO_CONTROLLER_BASE_H
diff --git a/media/libaaudio/src/fifo/FifoControllerIndirect.h b/media/libaaudio/src/fifo/FifoControllerIndirect.h
index 1aaf9ea..5832d9c 100644
--- a/media/libaaudio/src/fifo/FifoControllerIndirect.h
+++ b/media/libaaudio/src/fifo/FifoControllerIndirect.h
@@ -22,6 +22,8 @@
 
 #include "FifoControllerBase.h"
 
+namespace android {
+
 /**
  * A FifoControllerBase with counters external to the class.
  *
@@ -66,4 +68,6 @@
     std::atomic<fifo_counter_t> * mWriteCounterAddress;
 };
 
+}  // android
+
 #endif //FIFO_FIFO_CONTROLLER_INDIRECT_H