Add a per-thread heap that is read-only to clients

Change-Id: I401263566ca20fbfb565689c8fa99458d3b283b2
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index a916b32..2c5a0eb 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -143,6 +143,12 @@
 // See the client's minBufCount and mNotificationFramesAct calculations for details.
 static const int kFastTrackMultiplier = 2;
 
+// See Thread::readOnlyHeap().
+// Initially this heap is used to allocate client buffers for "fast" AudioRecord.
+// Eventually it will be the single buffer that FastCapture writes into via HAL read(),
+// and that all "fast" AudioRecord clients read from.  In either case, the size can be small.
+static const size_t kRecordThreadReadOnlyHeapSize = 0x1000;
+
 // ----------------------------------------------------------------------------
 
 #ifdef ADD_BATTERY_DATA
@@ -4635,6 +4641,8 @@
 #ifdef TEE_SINK
     , mTeeSink(teeSink)
 #endif
+    , mReadOnlyHeap(new MemoryDealer(kRecordThreadReadOnlyHeapSize,
+            "RecordThreadRO", MemoryHeapBase::READ_ONLY))
 {
     snprintf(mName, kNameLength, "AudioIn_%X", id);
     mNBLogWriter = audioFlinger->newWriter_l(kLogSize, mName);
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index 5617c0c..8ea8683 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -226,6 +226,13 @@
                 virtual status_t    setSyncEvent(const sp<SyncEvent>& event) = 0;
                 virtual bool        isValidSyncEvent(const sp<SyncEvent>& event) const = 0;
 
+                // Return a reference to a per-thread heap which can be used to allocate IMemory
+                // objects that will be read-only to client processes, read/write to mediaserver,
+                // and shared by all client processes of the thread.
+                // The heap is per-thread rather than common across all threads, because
+                // clients can't be trusted not to modify the offset of the IMemory they receive.
+                // If a thread does not have such a heap, this method returns 0.
+                virtual sp<MemoryDealer>    readOnlyHeap() const { return 0; }
 
     mutable     Mutex                   mLock;
 
@@ -947,6 +954,8 @@
 
     virtual status_t    initCheck() const { return (mInput == NULL) ? NO_INIT : NO_ERROR; }
 
+    virtual sp<MemoryDealer>    readOnlyHeap() const { return mReadOnlyHeap; }
+
             sp<AudioFlinger::RecordThread::RecordTrack>  createRecordTrack_l(
                     const sp<AudioFlinger::Client>& client,
                     uint32_t sampleRate,
@@ -1021,4 +1030,6 @@
 
             // For dumpsys
             const sp<NBAIO_Sink>                mTeeSink;
+
+            const sp<MemoryDealer>              mReadOnlyHeap;
 };