aaudio: fix SHARED MMAP mode in server plus other bugs

Fixed some buffer miscalculations, and some NPEs in the close() code.
Added debugging and some general cleanup.
Fixed data conversion.
Fixed start/pause/flush in server.
Added reference counting in server for endpoints.
Programs can now be ran more than once.
General code cleanup.
Reconnect with service if server dies.
Move stop() logic into server for better synchronization.
Add sleep to prevent race condition when closing an MMAP stream.

Bug: 33398120
Test: two write_sine_callback.cpp can be run simultaneously
Change-Id: Ibb006215a498868c222228d675ff961d7e0bf514
Signed-off-by: Phil Burk <philburk@google.com>
diff --git a/media/libaaudio/src/binding/AAudioBinderClient.cpp b/media/libaaudio/src/binding/AAudioBinderClient.cpp
index 8315c40..3f1bba3 100644
--- a/media/libaaudio/src/binding/AAudioBinderClient.cpp
+++ b/media/libaaudio/src/binding/AAudioBinderClient.cpp
@@ -75,6 +75,10 @@
     return gAAudioService;
 }
 
+static void dropAAudioService() {
+    Mutex::Autolock _l(gServiceLock);
+    gAAudioService.clear(); // force a reconnect
+}
 
 AAudioBinderClient::AAudioBinderClient()
         : AAudioServiceInterface() {}
@@ -88,14 +92,26 @@
 */
 aaudio_handle_t AAudioBinderClient::openStream(const AAudioStreamRequest &request,
                                                AAudioStreamConfiguration &configurationOutput) {
+    aaudio_handle_t stream;
+    for (int i = 0; i < 2; i++) {
+        const sp<IAAudioService> &service = getAAudioService();
+        if (service == 0) {
+            return AAUDIO_ERROR_NO_SERVICE;
+        }
 
-    const sp<IAAudioService> &service = getAAudioService();
-    if (service == 0) return AAUDIO_ERROR_NO_SERVICE;
-    return service->openStream(request, configurationOutput);
+        stream = service->openStream(request, configurationOutput);
+
+        if (stream == AAUDIO_ERROR_NO_SERVICE) {
+            ALOGE("AAudioBinderClient: lost connection to AAudioService.");
+            dropAAudioService(); // force a reconnect
+        } else {
+            break;
+        }
+    }
+    return stream;
 }
 
 aaudio_result_t AAudioBinderClient::closeStream(aaudio_handle_t streamHandle) {
-
     const sp<IAAudioService> &service = getAAudioService();
     if (service == 0) return AAUDIO_ERROR_NO_SERVICE;
     return service->closeStream(streamHandle);
@@ -106,37 +122,33 @@
 */
 aaudio_result_t AAudioBinderClient::getStreamDescription(aaudio_handle_t streamHandle,
                                                          AudioEndpointParcelable &parcelable) {
-
     const sp<IAAudioService> &service = getAAudioService();
     if (service == 0) return AAUDIO_ERROR_NO_SERVICE;
     return service->getStreamDescription(streamHandle, parcelable);
 }
 
-/**
-* Start the flow of data.
-*/
 aaudio_result_t AAudioBinderClient::startStream(aaudio_handle_t streamHandle) {
     const sp<IAAudioService> &service = getAAudioService();
     if (service == 0) return AAUDIO_ERROR_NO_SERVICE;
     return service->startStream(streamHandle);
 }
 
-/**
-* Stop the flow of data such that start() can resume without loss of data.
-*/
 aaudio_result_t AAudioBinderClient::pauseStream(aaudio_handle_t streamHandle) {
     const sp<IAAudioService> &service = getAAudioService();
     if (service == 0) return AAUDIO_ERROR_NO_SERVICE;
-    return service->startStream(streamHandle);
+    return service->pauseStream(streamHandle);
 }
 
-/**
-*  Discard any data held by the underlying HAL or Service.
-*/
+aaudio_result_t AAudioBinderClient::stopStream(aaudio_handle_t streamHandle) {
+    const sp<IAAudioService> &service = getAAudioService();
+    if (service == 0) return AAUDIO_ERROR_NO_SERVICE;
+    return service->stopStream(streamHandle);
+}
+
 aaudio_result_t AAudioBinderClient::flushStream(aaudio_handle_t streamHandle) {
     const sp<IAAudioService> &service = getAAudioService();
     if (service == 0) return AAUDIO_ERROR_NO_SERVICE;
-    return service->startStream(streamHandle);
+    return service->flushStream(streamHandle);
 }
 
 /**
@@ -163,5 +175,3 @@
                                           clientProcessId,
                                           clientThreadId);
 }
-
-