Re-implement HIDL stream read and write using FMQ

Result: no hwbinder calls due read / write session.

Test: make, perform Loopback RTT, check traces
Bug: 30222631

Change-Id: I4a8792525ec374111302cfd5c0a2e41f9f4cc418
diff --git a/media/libaudiohal/StreamHalHidl.h b/media/libaudiohal/StreamHalHidl.h
index 377acb4..0093957 100644
--- a/media/libaudiohal/StreamHalHidl.h
+++ b/media/libaudiohal/StreamHalHidl.h
@@ -20,6 +20,8 @@
 #include <android/hardware/audio/2.0/IStream.h>
 #include <android/hardware/audio/2.0/IStreamIn.h>
 #include <android/hardware/audio/2.0/IStreamOut.h>
+#include <fmq/EventFlag.h>
+#include <fmq/MessageQueue.h>
 #include <media/audiohal/StreamHalInterface.h>
 
 #include "ConversionHelperHidl.h"
@@ -27,7 +29,11 @@
 using ::android::hardware::audio::V2_0::IStream;
 using ::android::hardware::audio::V2_0::IStreamIn;
 using ::android::hardware::audio::V2_0::IStreamOut;
+using ::android::hardware::EventFlag;
+using ::android::hardware::MessageQueue;
 using ::android::hardware::Return;
+using ReadStatus = ::android::hardware::audio::V2_0::IStreamIn::ReadStatus;
+using WriteStatus = ::android::hardware::audio::V2_0::IStreamOut::WriteStatus;
 
 namespace android {
 
@@ -80,6 +86,10 @@
     // Get current read/write position in the mmap buffer
     virtual status_t getMmapPosition(struct audio_mmap_position *position);
 
+    // Set the priority of the thread that interacts with the HAL
+    // (must match the priority of the audioflinger's thread that calls 'read' / 'write')
+    virtual status_t setHalThreadPriority(int priority);
+
   protected:
     // Subclasses can not be constructed directly by clients.
     explicit StreamHalHidl(IStream *stream);
@@ -87,6 +97,8 @@
     // The destructor automatically closes the stream.
     virtual ~StreamHalHidl();
 
+    int mHalThreadPriority;
+
   private:
     IStream *mStream;
 };
@@ -143,14 +155,25 @@
 
   private:
     friend class DeviceHalHidl;
+    typedef MessageQueue<uint8_t, hardware::kSynchronizedReadWrite> DataMQ;
+    typedef MessageQueue<WriteStatus, hardware::kSynchronizedReadWrite> StatusMQ;
 
     wp<StreamOutHalInterfaceCallback> mCallback;
     sp<IStreamOut> mStream;
+    std::unique_ptr<DataMQ> mDataMQ;
+    std::unique_ptr<StatusMQ> mStatusMQ;
+    EventFlag* mEfGroup;
+    bool mGetPresentationPositionNotSupported;
+    uint64_t mPPosFromWriteObtained;
+    uint64_t mPPosFromWriteFrames;
+    struct timespec mPPosFromWriteTS;
 
     // Can not be constructed directly by clients.
     StreamOutHalHidl(const sp<IStreamOut>& stream);
 
     virtual ~StreamOutHalHidl();
+
+    status_t prepareForWriting(size_t bufferSize);
 };
 
 class StreamInHalHidl : public StreamInHalInterface, public StreamHalHidl {
@@ -173,13 +196,20 @@
 
   private:
     friend class DeviceHalHidl;
+    typedef MessageQueue<uint8_t, hardware::kSynchronizedReadWrite> DataMQ;
+    typedef MessageQueue<ReadStatus, hardware::kSynchronizedReadWrite> StatusMQ;
 
     sp<IStreamIn> mStream;
+    std::unique_ptr<DataMQ> mDataMQ;
+    std::unique_ptr<StatusMQ> mStatusMQ;
+    EventFlag* mEfGroup;
 
     // Can not be constructed directly by clients.
     StreamInHalHidl(const sp<IStreamIn>& stream);
 
     virtual ~StreamInHalHidl();
+
+    status_t prepareForReading(size_t bufferSize);
 };
 
 } // namespace android