aaudio: indicate client UID and PID to audio flinger

Implement correct indication of client UID and PID to audio flinger
for AAudio MMAP streams in both exclusive mode and shared mode.
- Add start/stop client methods on MMAP streams used only when the MMAP
stream is in AAudio service and carries a mix of shared streams.
- Add "In Service'" indication from "client" side to AAudioServiceStreamMMAP
so that the behavior can be adapted accordingly.
- Modify logic on audio flinger side with regard to mmap tracks and
audio HAL stream activity:
  - use same audio session for all clients on a same stream to match
  audio policy logic to share same direct output stream for clients on same
  session. This is also more consistent with current volume and effect
  handling as all MMAP  clients sharing the same output stream have the
  same volume and use case.
  - start/stop the HAL when the stream is started/stopped with the initial client
  handle (returned when the stream is opened) but do not create a track.
  AAudioService implementation will always send an additional start command before
  first client starts and a stop command after last client stops,
  in both shared and exclusive mode.
  - start/stop a track only if the start/stop stream command is received
  with a handle different from the initial handle.
- Allow more than one active client from the same UID on a MMAP input in audio policy.

Bug: 62950008
Test: verify playback and capture in mmap mode
Change-Id: I86151bbb637ff172d2fd5f813056eab13a7bcd3c
diff --git a/services/oboeservice/AAudioService.cpp b/services/oboeservice/AAudioService.cpp
index 669bb54..3992719 100644
--- a/services/oboeservice/AAudioService.cpp
+++ b/services/oboeservice/AAudioService.cpp
@@ -50,8 +50,9 @@
 
 android::AAudioService::AAudioService()
     : BnAAudioService() {
-    mCachedProcessId = getpid();
-    mCachedUserId = getuid();   // TODO consider using geteuid()
+    mAudioClient.clientUid = getuid();   // TODO consider using geteuid()
+    mAudioClient.clientPid = getpid();
+    mAudioClient.packageName = String16("");
     AAudioClientTracker::getInstance().setAAudioService(this);
 }
 
@@ -92,7 +93,7 @@
 
     // Enforce limit on client processes.
     pid_t pid = request.getProcessId();
-    if (pid != mCachedProcessId) {
+    if (pid != mAudioClient.clientPid) {
         int32_t count = AAudioClientTracker::getInstance().getStreamCount(pid);
         if (count >= MAX_STREAMS_PER_PROCESS) {
             ALOGE("AAudioService::openStream(): exceeded max streams per process %d >= %d",
@@ -107,7 +108,13 @@
     }
 
     if (sharingMode == AAUDIO_SHARING_MODE_EXCLUSIVE) {
-        serviceStream = new AAudioServiceStreamMMAP(mCachedUserId);
+        // only trust audioserver for in service indication
+        bool inService = false;
+        if (mAudioClient.clientPid == IPCThreadState::self()->getCallingPid() &&
+                mAudioClient.clientUid == IPCThreadState::self()->getCallingUid()) {
+            inService = request.isInService();
+        }
+        serviceStream = new AAudioServiceStreamMMAP(mAudioClient, inService);
         result = serviceStream->open(request, configurationOutput);
         if (result != AAUDIO_OK) {
             // fall back to using a shared stream
@@ -132,8 +139,6 @@
               result, AAudio_convertResultToText(result));
         return result;
     } else {
-        const uid_t ownerUserId = request.getUserId(); // only set by service, not by client
-        serviceStream->setOwnerUserId(ownerUserId);
         aaudio_handle_t handle = mHandleTracker.put(AAUDIO_HANDLE_TYPE_STREAM, serviceStream.get());
         if (handle < 0) {
             ALOGE("AAudioService::openStream(): handle table full");
@@ -143,7 +148,6 @@
             ALOGD("AAudioService::openStream(): handle = 0x%08X", handle);
             serviceStream->setHandle(handle);
             pid_t pid = request.getProcessId();
-            serviceStream->setOwnerProcessId(pid);
             AAudioClientTracker::getInstance().registerClientStream(pid, serviceStream);
         }
         return handle;
@@ -181,8 +185,8 @@
         const uid_t callingUserId = IPCThreadState::self()->getCallingUid();
         const uid_t ownerUserId = serviceStream->getOwnerUserId();
         bool callerOwnsIt = callingUserId == ownerUserId;
-        bool serverCalling = callingUserId == mCachedUserId;
-        bool serverOwnsIt = ownerUserId == mCachedUserId;
+        bool serverCalling = callingUserId == mAudioClient.clientUid;
+        bool serverOwnsIt = ownerUserId == mAudioClient.clientUid;
         bool allowed = callerOwnsIt || serverCalling || serverOwnsIt;
         if (!allowed) {
             ALOGE("AAudioService: calling uid %d cannot access stream 0x%08X owned by %d",
@@ -212,6 +216,7 @@
         ALOGE("AAudioService::startStream(), illegal stream handle = 0x%0x", streamHandle);
         return AAUDIO_ERROR_INVALID_HANDLE;
     }
+
     aaudio_result_t result = serviceStream->start();
     return result;
 }
@@ -286,3 +291,26 @@
     serviceStream->setRegisteredThread(0);
     return AAUDIO_OK;
 }
+
+aaudio_result_t AAudioService::startClient(aaudio_handle_t streamHandle,
+                                  const android::AudioClient& client,
+                                  audio_port_handle_t *clientHandle) {
+    AAudioServiceStreamBase *serviceStream = convertHandleToServiceStream(streamHandle);
+    if (serviceStream == nullptr) {
+        ALOGE("AAudioService::startClient(), illegal stream handle = 0x%0x",
+              streamHandle);
+        return AAUDIO_ERROR_INVALID_HANDLE;
+    }
+    return serviceStream->startClient(client, clientHandle);
+}
+
+aaudio_result_t AAudioService::stopClient(aaudio_handle_t streamHandle,
+                                          audio_port_handle_t clientHandle) {
+    AAudioServiceStreamBase *serviceStream = convertHandleToServiceStream(streamHandle);
+    if (serviceStream == nullptr) {
+        ALOGE("AAudioService::stopClient(), illegal stream handle = 0x%0x",
+              streamHandle);
+        return AAUDIO_ERROR_INVALID_HANDLE;
+    }
+    return serviceStream->stopClient(clientHandle);
+}