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/services/oboeservice/AAudioService.cpp b/services/oboeservice/AAudioService.cpp
index 99b0b4d..e4fa1c5 100644
--- a/services/oboeservice/AAudioService.cpp
+++ b/services/oboeservice/AAudioService.cpp
@@ -18,28 +18,29 @@
 //#define LOG_NDEBUG 0
 #include <utils/Log.h>
 
-#include <time.h>
-#include <pthread.h>
+//#include <time.h>
+//#include <pthread.h>
 
 #include <aaudio/AAudioDefinitions.h>
+#include <mediautils/SchedulingPolicyService.h>
+#include <utils/String16.h>
 
-#include "HandleTracker.h"
-#include "IAAudioService.h"
-#include "AAudioServiceDefinitions.h"
+#include "binding/AAudioServiceMessage.h"
 #include "AAudioService.h"
-#include "AAudioServiceStreamFakeHal.h"
+#include "AAudioServiceStreamMMAP.h"
+#include "AAudioServiceStreamShared.h"
+#include "AAudioServiceStreamMMAP.h"
+#include "binding/IAAudioService.h"
+#include "utility/HandleTracker.h"
 
 using namespace android;
 using namespace aaudio;
 
 typedef enum
 {
-    AAUDIO_HANDLE_TYPE_DUMMY1, // TODO remove DUMMYs
-    AAUDIO_HANDLE_TYPE_DUMMY2, // make server handles different than client
-    AAUDIO_HANDLE_TYPE_STREAM,
-    AAUDIO_HANDLE_TYPE_COUNT
+    AAUDIO_HANDLE_TYPE_STREAM
 } aaudio_service_handle_type_t;
-static_assert(AAUDIO_HANDLE_TYPE_COUNT <= HANDLE_TRACKER_MAX_TYPES, "Too many handle types.");
+static_assert(AAUDIO_HANDLE_TYPE_STREAM < HANDLE_TRACKER_MAX_TYPES, "Too many handle types.");
 
 android::AAudioService::AAudioService()
     : BnAAudioService() {
@@ -48,18 +49,50 @@
 AAudioService::~AAudioService() {
 }
 
-aaudio_handle_t AAudioService::openStream(aaudio::AAudioStreamRequest &request,
-                                                aaudio::AAudioStreamConfiguration &configuration) {
-    AAudioServiceStreamBase *serviceStream =  new AAudioServiceStreamFakeHal();
-    ALOGD("AAudioService::openStream(): created serviceStream = %p", serviceStream);
-    aaudio_result_t result = serviceStream->open(request, configuration);
-    if (result < 0) {
-        ALOGE("AAudioService::openStream(): open returned %d", result);
+aaudio_handle_t AAudioService::openStream(const aaudio::AAudioStreamRequest &request,
+                                          aaudio::AAudioStreamConfiguration &configurationOutput) {
+    aaudio_result_t result = AAUDIO_OK;
+    AAudioServiceStreamBase *serviceStream = nullptr;
+    const AAudioStreamConfiguration &configurationInput = request.getConstantConfiguration();
+    aaudio_sharing_mode_t sharingMode = configurationInput.getSharingMode();
+    ALOGE("AAudioService::openStream(): sharingMode = %d", sharingMode);
+
+    if (sharingMode != AAUDIO_SHARING_MODE_EXCLUSIVE && sharingMode != AAUDIO_SHARING_MODE_SHARED) {
+        ALOGE("AAudioService::openStream(): unrecognized sharing mode = %d", sharingMode);
+        return AAUDIO_ERROR_ILLEGAL_ARGUMENT;
+    }
+
+    if (sharingMode == AAUDIO_SHARING_MODE_EXCLUSIVE) {
+        ALOGD("AAudioService::openStream(), sharingMode = AAUDIO_SHARING_MODE_EXCLUSIVE");
+        serviceStream = new AAudioServiceStreamMMAP();
+        result = serviceStream->open(request, configurationOutput);
+        if (result != AAUDIO_OK) {
+            // fall back to using a shared stream
+            ALOGD("AAudioService::openStream(), EXCLUSIVE mode failed");
+            delete serviceStream;
+            serviceStream = nullptr;
+        } else {
+            configurationOutput.setSharingMode(AAUDIO_SHARING_MODE_EXCLUSIVE);
+        }
+    }
+
+    // if SHARED requested or if EXCLUSIVE failed
+    if (serviceStream == nullptr) {
+        ALOGD("AAudioService::openStream(), sharingMode = AAUDIO_SHARING_MODE_SHARED");
+        serviceStream =  new AAudioServiceStreamShared(*this);
+        result = serviceStream->open(request, configurationOutput);
+        configurationOutput.setSharingMode(AAUDIO_SHARING_MODE_SHARED);
+    }
+
+    if (result != AAUDIO_OK) {
+        delete serviceStream;
+        ALOGE("AAudioService::openStream(): failed, return %d", result);
         return result;
     } else {
         aaudio_handle_t handle = mHandleTracker.put(AAUDIO_HANDLE_TYPE_STREAM, serviceStream);
         ALOGD("AAudioService::openStream(): handle = 0x%08X", handle);
         if (handle < 0) {
+            ALOGE("AAudioService::openStream(): handle table full");
             delete serviceStream;
         }
         return handle;
@@ -72,7 +105,7 @@
                                   streamHandle);
     ALOGD("AAudioService.closeStream(0x%08X)", streamHandle);
     if (serviceStream != nullptr) {
-        ALOGD("AAudioService::closeStream(): deleting serviceStream = %p", serviceStream);
+        serviceStream->close();
         delete serviceStream;
         return AAUDIO_OK;
     }
@@ -89,27 +122,32 @@
                 aaudio_handle_t streamHandle,
                 aaudio::AudioEndpointParcelable &parcelable) {
     AAudioServiceStreamBase *serviceStream = convertHandleToServiceStream(streamHandle);
-    ALOGD("AAudioService::getStreamDescription(), serviceStream = %p", serviceStream);
     if (serviceStream == nullptr) {
+        ALOGE("AAudioService::getStreamDescription(), illegal stream handle = 0x%0x", streamHandle);
         return AAUDIO_ERROR_INVALID_HANDLE;
     }
-    return serviceStream->getDescription(parcelable);
+    ALOGD("AAudioService::getStreamDescription(), handle = 0x%08x", streamHandle);
+    aaudio_result_t result = serviceStream->getDescription(parcelable);
+    ALOGD("AAudioService::getStreamDescription(), result = %d", result);
+    // parcelable.dump();
+    return result;
 }
 
 aaudio_result_t AAudioService::startStream(aaudio_handle_t streamHandle) {
     AAudioServiceStreamBase *serviceStream = convertHandleToServiceStream(streamHandle);
-    ALOGD("AAudioService::startStream(), serviceStream = %p", serviceStream);
     if (serviceStream == nullptr) {
+        ALOGE("AAudioService::startStream(), illegal stream handle = 0x%0x", streamHandle);
         return AAUDIO_ERROR_INVALID_HANDLE;
     }
     aaudio_result_t result = serviceStream->start();
+    ALOGD("AAudioService::startStream(), serviceStream->start() returned %d", result);
     return result;
 }
 
 aaudio_result_t AAudioService::pauseStream(aaudio_handle_t streamHandle) {
     AAudioServiceStreamBase *serviceStream = convertHandleToServiceStream(streamHandle);
-    ALOGD("AAudioService::pauseStream(), serviceStream = %p", serviceStream);
     if (serviceStream == nullptr) {
+        ALOGE("AAudioService::pauseStream(), illegal stream handle = 0x%0x", streamHandle);
         return AAUDIO_ERROR_INVALID_HANDLE;
     }
     aaudio_result_t result = serviceStream->pause();
@@ -118,35 +156,33 @@
 
 aaudio_result_t AAudioService::flushStream(aaudio_handle_t streamHandle) {
     AAudioServiceStreamBase *serviceStream = convertHandleToServiceStream(streamHandle);
-    ALOGD("AAudioService::flushStream(), serviceStream = %p", serviceStream);
     if (serviceStream == nullptr) {
+        ALOGE("AAudioService::flushStream(), illegal stream handle = 0x%0x", streamHandle);
         return AAUDIO_ERROR_INVALID_HANDLE;
     }
     return serviceStream->flush();
 }
 
 aaudio_result_t AAudioService::registerAudioThread(aaudio_handle_t streamHandle,
+                                                         pid_t clientProcessId,
                                                          pid_t clientThreadId,
                                                          int64_t periodNanoseconds) {
     AAudioServiceStreamBase *serviceStream = convertHandleToServiceStream(streamHandle);
     ALOGD("AAudioService::registerAudioThread(), serviceStream = %p", serviceStream);
     if (serviceStream == nullptr) {
-        ALOGE("AAudioService::registerAudioThread(), serviceStream == nullptr");
+        ALOGE("AAudioService::registerAudioThread(), illegal stream handle = 0x%0x", streamHandle);
         return AAUDIO_ERROR_INVALID_HANDLE;
     }
     if (serviceStream->getRegisteredThread() != AAudioServiceStreamBase::ILLEGAL_THREAD_ID) {
         ALOGE("AAudioService::registerAudioThread(), thread already registered");
-        return AAUDIO_ERROR_INVALID_ORDER;
+        return AAUDIO_ERROR_INVALID_STATE;
     }
     serviceStream->setRegisteredThread(clientThreadId);
-    // Boost client thread to SCHED_FIFO
-    struct sched_param sp;
-    memset(&sp, 0, sizeof(sp));
-    sp.sched_priority = 2; // TODO use 'requestPriority' function from frameworks/av/media/utils
-    int err = sched_setscheduler(clientThreadId, SCHED_FIFO, &sp);
+    int err = android::requestPriority(clientProcessId, clientThreadId,
+                                       DEFAULT_AUDIO_PRIORITY, true /* isForApp */);
     if (err != 0){
-        ALOGE("AAudioService::sched_setscheduler() failed, errno = %d, priority = %d",
-              errno, sp.sched_priority);
+        ALOGE("AAudioService::registerAudioThread() failed, errno = %d, priority = %d",
+              errno, DEFAULT_AUDIO_PRIORITY);
         return AAUDIO_ERROR_INTERNAL;
     } else {
         return AAUDIO_OK;
@@ -154,11 +190,13 @@
 }
 
 aaudio_result_t AAudioService::unregisterAudioThread(aaudio_handle_t streamHandle,
-                                                           pid_t clientThreadId) {
+                                                     pid_t clientProcessId,
+                                                     pid_t clientThreadId) {
     AAudioServiceStreamBase *serviceStream = convertHandleToServiceStream(streamHandle);
     ALOGI("AAudioService::unregisterAudioThread(), serviceStream = %p", serviceStream);
     if (serviceStream == nullptr) {
-        ALOGE("AAudioService::unregisterAudioThread(), serviceStream == nullptr");
+        ALOGE("AAudioService::unregisterAudioThread(), illegal stream handle = 0x%0x",
+              streamHandle);
         return AAUDIO_ERROR_INVALID_HANDLE;
     }
     if (serviceStream->getRegisteredThread() != clientThreadId) {