aaudio: fix EXCLUSIVE mode interfering with SHARED

The MMAP endpoints were not tracked by the EndpointManager
so it could not broker EXCLUSIVE access. To fix this the MMAP stream
was refactored to use a per-client stream and a per-device endpoint.

Cleanup close() of MMAP stream.
Add AAudioServiceEndpointShared.cpp.
Extract AAudioServiceEndpointMMAP from AAudioServiceStreamMMAP.
Track MMAP endpoints so we can manage EXCLUSIVE and SHARED access.

Bug: 64494572
Bug: 64310586
Test: see bug, use write_sine to play a shared stream and a excl stream
Change-Id: I5053193abfd9b8a69a2f7e1110739d65e2af5d64
diff --git a/media/libaaudio/src/binding/AAudioStreamConfiguration.cpp b/media/libaaudio/src/binding/AAudioStreamConfiguration.cpp
index e763934..153fce3 100644
--- a/media/libaaudio/src/binding/AAudioStreamConfiguration.cpp
+++ b/media/libaaudio/src/binding/AAudioStreamConfiguration.cpp
@@ -46,6 +46,8 @@
     if (status != NO_ERROR) goto error;
     status = parcel->writeInt32((int32_t) getFormat());
     if (status != NO_ERROR) goto error;
+    status = parcel->writeInt32((int32_t) getDirection());
+    if (status != NO_ERROR) goto error;
     status = parcel->writeInt32(getBufferCapacity());
     if (status != NO_ERROR) goto error;
     return NO_ERROR;
@@ -73,9 +75,12 @@
     setFormat(value);
     status = parcel->readInt32(&value);
     if (status != NO_ERROR) goto error;
+    setDirection((aaudio_direction_t) value);
+    status = parcel->readInt32(&value);
+    if (status != NO_ERROR) goto error;
     setBufferCapacity(value);
     return NO_ERROR;
 error:
     ALOGE("AAudioStreamConfiguration.readFromParcel(): read failed = %d", status);
     return status;
-}
\ No newline at end of file
+}
diff --git a/media/libaaudio/src/binding/AAudioStreamRequest.cpp b/media/libaaudio/src/binding/AAudioStreamRequest.cpp
index abdcf5b..1200ab2 100644
--- a/media/libaaudio/src/binding/AAudioStreamRequest.cpp
+++ b/media/libaaudio/src/binding/AAudioStreamRequest.cpp
@@ -46,9 +46,6 @@
     status_t status = parcel->writeInt32((int32_t) mUserId);
     if (status != NO_ERROR) goto error;
 
-    status = parcel->writeInt32((int32_t) mDirection);
-    if (status != NO_ERROR) goto error;
-
     status = parcel->writeBool(mSharingModeMatchRequired);
     if (status != NO_ERROR) goto error;
 
@@ -71,10 +68,6 @@
     if (status != NO_ERROR) goto error;
     mUserId = (uid_t) temp;
 
-    status = parcel->readInt32(&temp);
-    if (status != NO_ERROR) goto error;
-    mDirection = (aaudio_direction_t) temp;
-
     status = parcel->readBool(&mSharingModeMatchRequired);
     if (status != NO_ERROR) goto error;
 
@@ -98,7 +91,6 @@
 void AAudioStreamRequest::dump() const {
     ALOGD("AAudioStreamRequest mUserId    = %d", mUserId);
     ALOGD("AAudioStreamRequest mProcessId = %d", mProcessId);
-    ALOGD("AAudioStreamRequest mDirection = %d", mDirection);
     ALOGD("AAudioStreamRequest mSharingModeMatchRequired = %d", mSharingModeMatchRequired);
     ALOGD("AAudioStreamRequest mInService = %d", mInService);
     mConfiguration.dump();
diff --git a/media/libaaudio/src/binding/AAudioStreamRequest.h b/media/libaaudio/src/binding/AAudioStreamRequest.h
index b0fa96a..492f69d 100644
--- a/media/libaaudio/src/binding/AAudioStreamRequest.h
+++ b/media/libaaudio/src/binding/AAudioStreamRequest.h
@@ -52,14 +52,6 @@
         mProcessId = processId;
     }
 
-    aaudio_direction_t getDirection() const {
-        return mDirection;
-    }
-
-    void setDirection(aaudio_direction_t direction) {
-        mDirection = direction;
-    }
-
     bool isSharingModeMatchRequired() const {
         return mSharingModeMatchRequired;
     }
@@ -94,9 +86,8 @@
 
 protected:
     AAudioStreamConfiguration  mConfiguration;
-    uid_t                      mUserId;
-    pid_t                      mProcessId;
-    aaudio_direction_t         mDirection;
+    uid_t                      mUserId = (uid_t) -1;
+    pid_t                      mProcessId = (pid_t) -1;
     bool                       mSharingModeMatchRequired = false;
     bool                       mInService = false; // Stream opened by AAudioservice
 };
diff --git a/media/libaaudio/src/client/AudioStreamInternal.cpp b/media/libaaudio/src/client/AudioStreamInternal.cpp
index bdebf8f..036d931 100644
--- a/media/libaaudio/src/client/AudioStreamInternal.cpp
+++ b/media/libaaudio/src/client/AudioStreamInternal.cpp
@@ -105,13 +105,13 @@
     // Build the request to send to the server.
     request.setUserId(getuid());
     request.setProcessId(getpid());
-    request.setDirection(getDirection());
     request.setSharingModeMatchRequired(isSharingModeMatchRequired());
     request.setInService(mInService);
 
     request.getConfiguration().setDeviceId(getDeviceId());
     request.getConfiguration().setSampleRate(getSampleRate());
     request.getConfiguration().setSamplesPerFrame(getSamplesPerFrame());
+    request.getConfiguration().setDirection(getDirection());
     request.getConfiguration().setSharingMode(getSharingMode());
 
     request.getConfiguration().setBufferCapacity(builder.getBufferCapacity());
@@ -357,6 +357,7 @@
     if (mServiceStreamHandle == AAUDIO_HANDLE_INVALID) {
         return AAUDIO_ERROR_INVALID_STATE;
     }
+
     return mServiceInterface.startClient(mServiceStreamHandle, client, clientHandle);
 }
 
diff --git a/media/libaaudio/src/client/AudioStreamInternal.h b/media/libaaudio/src/client/AudioStreamInternal.h
index 13cf16c..3523294 100644
--- a/media/libaaudio/src/client/AudioStreamInternal.h
+++ b/media/libaaudio/src/client/AudioStreamInternal.h
@@ -93,6 +93,10 @@
 
     aaudio_result_t stopClient(audio_port_handle_t clientHandle);
 
+    aaudio_handle_t getServiceHandle() const {
+        return mServiceStreamHandle;
+    }
+
 protected:
 
     aaudio_result_t processData(void *buffer,
diff --git a/media/libaaudio/src/core/AAudioStreamParameters.cpp b/media/libaaudio/src/core/AAudioStreamParameters.cpp
index 65c2b46..82445e7 100644
--- a/media/libaaudio/src/core/AAudioStreamParameters.cpp
+++ b/media/libaaudio/src/core/AAudioStreamParameters.cpp
@@ -34,6 +34,16 @@
 AAudioStreamParameters::AAudioStreamParameters() {}
 AAudioStreamParameters::~AAudioStreamParameters() {}
 
+void AAudioStreamParameters::copyFrom(const AAudioStreamParameters &other) {
+    mSamplesPerFrame = other.mSamplesPerFrame;
+    mSampleRate      = other.mSampleRate;
+    mDeviceId        = other.mDeviceId;
+    mSharingMode     = other.mSharingMode;
+    mAudioFormat     = other.mAudioFormat;
+    mDirection       = other.mDirection;
+    mBufferCapacity  = other.mBufferCapacity;
+}
+
 aaudio_result_t AAudioStreamParameters::validate() const {
     if (mSamplesPerFrame != AAUDIO_UNSPECIFIED
         && (mSamplesPerFrame < SAMPLES_PER_FRAME_MIN || mSamplesPerFrame > SAMPLES_PER_FRAME_MAX)) {
@@ -78,6 +88,16 @@
         return AAUDIO_ERROR_OUT_OF_RANGE;
     }
 
+    switch (mDirection) {
+        case AAUDIO_DIRECTION_INPUT:
+        case AAUDIO_DIRECTION_OUTPUT:
+            break; // valid
+        default:
+            ALOGE("AAudioStreamParameters: direction not valid = %d", mDirection);
+            return AAUDIO_ERROR_ILLEGAL_ARGUMENT;
+            // break;
+    }
+
     return AAUDIO_OK;
 }
 
@@ -87,5 +107,7 @@
     ALOGD("AAudioStreamParameters mSamplesPerFrame = %d", mSamplesPerFrame);
     ALOGD("AAudioStreamParameters mSharingMode     = %d", (int)mSharingMode);
     ALOGD("AAudioStreamParameters mAudioFormat     = %d", (int)mAudioFormat);
+    ALOGD("AAudioStreamParameters mDirection       = %d", mDirection);
     ALOGD("AAudioStreamParameters mBufferCapacity  = %d", mBufferCapacity);
-}
\ No newline at end of file
+}
+
diff --git a/media/libaaudio/src/core/AAudioStreamParameters.h b/media/libaaudio/src/core/AAudioStreamParameters.h
index 97379cc..5e67c93 100644
--- a/media/libaaudio/src/core/AAudioStreamParameters.h
+++ b/media/libaaudio/src/core/AAudioStreamParameters.h
@@ -20,6 +20,7 @@
 #include <stdint.h>
 
 #include <aaudio/AAudio.h>
+#include <utility/AAudioUtilities.h>
 
 namespace aaudio {
 
@@ -79,6 +80,24 @@
         mBufferCapacity = frames;
     }
 
+    aaudio_direction_t getDirection() const {
+        return mDirection;
+    }
+
+    void setDirection(aaudio_direction_t direction) {
+        mDirection = direction;
+    }
+
+    int32_t calculateBytesPerFrame() const {
+        return getSamplesPerFrame() * AAudioConvert_formatToSizeInBytes(getFormat());
+    }
+
+    /**
+     * Copy variables defined in other AAudioStreamParameters instance to this one.
+     * @param other
+     */
+    void copyFrom(const AAudioStreamParameters &other);
+
     virtual aaudio_result_t validate() const;
 
     void dump() const;
@@ -89,9 +108,10 @@
     int32_t                    mDeviceId        = AAUDIO_UNSPECIFIED;
     aaudio_sharing_mode_t      mSharingMode     = AAUDIO_SHARING_MODE_SHARED;
     aaudio_format_t            mAudioFormat     = AAUDIO_FORMAT_UNSPECIFIED;
+    aaudio_direction_t         mDirection       = AAUDIO_DIRECTION_OUTPUT;
     int32_t                    mBufferCapacity  = AAUDIO_UNSPECIFIED;
 };
 
 } /* namespace aaudio */
 
-#endif //AAUDIO_STREAM_PARAMETERS_H
\ No newline at end of file
+#endif //AAUDIO_STREAM_PARAMETERS_H
diff --git a/media/libaaudio/src/core/AudioStreamBuilder.cpp b/media/libaaudio/src/core/AudioStreamBuilder.cpp
index 43a1ef1..09ebb3e 100644
--- a/media/libaaudio/src/core/AudioStreamBuilder.cpp
+++ b/media/libaaudio/src/core/AudioStreamBuilder.cpp
@@ -184,16 +184,6 @@
         return result;
     }
 
-    switch (mDirection) {
-        case AAUDIO_DIRECTION_INPUT:
-        case AAUDIO_DIRECTION_OUTPUT:
-            break; // valid
-        default:
-            ALOGE("AudioStreamBuilder: direction not valid = %d", mDirection);
-            return AAUDIO_ERROR_ILLEGAL_ARGUMENT;
-            // break;
-    }
-
     switch (mPerformanceMode) {
         case AAUDIO_PERFORMANCE_MODE_NONE:
         case AAUDIO_PERFORMANCE_MODE_POWER_SAVING:
diff --git a/media/libaaudio/src/core/AudioStreamBuilder.h b/media/libaaudio/src/core/AudioStreamBuilder.h
index 6e548b1..a43cfa8 100644
--- a/media/libaaudio/src/core/AudioStreamBuilder.h
+++ b/media/libaaudio/src/core/AudioStreamBuilder.h
@@ -35,15 +35,6 @@
 
     ~AudioStreamBuilder();
 
-    aaudio_direction_t getDirection() const {
-        return mDirection;
-    }
-
-    AudioStreamBuilder* setDirection(aaudio_direction_t direction) {
-        mDirection = direction;
-        return this;
-    }
-
     bool isSharingModeMatchRequired() const {
         return mSharingModeMatchRequired;
     }
@@ -113,7 +104,6 @@
 
 private:
     bool                       mSharingModeMatchRequired = false; // must match sharing mode requested
-    aaudio_direction_t         mDirection = AAUDIO_DIRECTION_OUTPUT;
     aaudio_performance_mode_t  mPerformanceMode = AAUDIO_PERFORMANCE_MODE_NONE;
 
     AAudioStream_dataCallback  mDataCallbackProc = nullptr;  // external callback functions