aaudio: implement IPlayer for MMAP playback streams

Make AudioStreamInternal derive from PlayerBase to
provide playback and volume control via IPlayer interface.

Bug: 62027849
Test: verify aaudio playback in MMAP mode and registration of aaudio
players in AudioService when active

Change-Id: Ia0878d46637c0a954d8a6259868a2d3bccf19119
diff --git a/media/libaaudio/src/client/AudioStreamInternal.cpp b/media/libaaudio/src/client/AudioStreamInternal.cpp
index 3a827f0..768d9db 100644
--- a/media/libaaudio/src/client/AudioStreamInternal.cpp
+++ b/media/libaaudio/src/client/AudioStreamInternal.cpp
@@ -62,6 +62,7 @@
         , mAudioEndpoint()
         , mServiceStreamHandle(AAUDIO_HANDLE_INVALID)
         , mFramesPerBurst(16)
+        , mStreamVolume(1.0f)
         , mServiceInterface(serviceInterface)
         , mInService(inService) {
 }
@@ -175,6 +176,10 @@
         }
 
         setState(AAUDIO_STREAM_STATE_OPEN);
+        // only connect to AudioManager if this is a playback stream running in client process
+        if (!mInService && getDirection() == AAUDIO_DIRECTION_OUTPUT) {
+            init(android::PLAYER_TYPE_AAUDIO, AUDIO_USAGE_MEDIA);
+        }
     }
     return result;
 }
@@ -231,7 +236,7 @@
     startTime = AudioClock::getNanoseconds();
     mClockModel.start(startTime);
     setState(AAUDIO_STREAM_STATE_STARTING);
-    aaudio_result_t result = mServiceInterface.startStream(mServiceStreamHandle);;
+    aaudio_result_t result = AAudioConvert_androidToAAudioResult(startWithStatus());
 
     if (result == AAUDIO_OK && getDataCallbackProc() != nullptr) {
         // Launch the callback loop thread.
@@ -281,7 +286,7 @@
 
     mClockModel.stop(AudioClock::getNanoseconds());
     setState(AAUDIO_STREAM_STATE_PAUSING);
-    return mServiceInterface.pauseStream(mServiceStreamHandle);
+    return AAudioConvert_androidToAAudioResult(pauseWithStatus());
 }
 
 aaudio_result_t AudioStreamInternal::requestPause()
@@ -330,7 +335,7 @@
 
     mClockModel.stop(AudioClock::getNanoseconds());
     setState(AAUDIO_STREAM_STATE_STOPPING);
-    return mServiceInterface.stopStream(mServiceStreamHandle);
+    return AAudioConvert_androidToAAudioResult(stopWithStatus());
 }
 
 aaudio_result_t AudioStreamInternal::requestStop()
@@ -446,7 +451,8 @@
             ALOGW("WARNING - processCommands() AAUDIO_SERVICE_EVENT_DISCONNECTED");
             break;
         case AAUDIO_SERVICE_EVENT_VOLUME:
-            mVolumeRamp.setTarget((float) message->event.dataDouble);
+            mStreamVolume = (float)message->event.dataDouble;
+            doSetVolume();
             ALOGD("processCommands() AAUDIO_SERVICE_EVENT_VOLUME %lf",
                      message->event.dataDouble);
             break;
@@ -588,3 +594,32 @@
 aaudio_result_t AudioStreamInternal::joinThread(void** returnArg) {
     return AudioStream::joinThread(returnArg, calculateReasonableTimeout(getFramesPerBurst()));
 }
+
+void AudioStreamInternal::doSetVolume() {
+    // No pan and only left volume is taken into account from IPLayer interface
+    mVolumeRamp.setTarget(mStreamVolume * mVolumeMultiplierL /* * mPanMultiplierL */);
+}
+
+
+//------------------------------------------------------------------------------
+// Implementation of PlayerBase
+status_t AudioStreamInternal::playerStart() {
+    return AAudioConvert_aaudioToAndroidStatus(mServiceInterface.startStream(mServiceStreamHandle));
+}
+
+status_t AudioStreamInternal::playerPause() {
+    return AAudioConvert_aaudioToAndroidStatus(mServiceInterface.pauseStream(mServiceStreamHandle));
+}
+
+status_t AudioStreamInternal::playerStop() {
+    return AAudioConvert_aaudioToAndroidStatus(mServiceInterface.stopStream(mServiceStreamHandle));
+}
+
+status_t AudioStreamInternal::playerSetVolume() {
+    doSetVolume();
+    return NO_ERROR;
+}
+
+void AudioStreamInternal::destroy() {
+    baseDestroy();
+}
diff --git a/media/libaaudio/src/client/AudioStreamInternal.h b/media/libaaudio/src/client/AudioStreamInternal.h
index a11f309..47aedad 100644
--- a/media/libaaudio/src/client/AudioStreamInternal.h
+++ b/media/libaaudio/src/client/AudioStreamInternal.h
@@ -18,6 +18,7 @@
 #define ANDROID_AAUDIO_AUDIO_STREAM_INTERNAL_H
 
 #include <stdint.h>
+#include <media/PlayerBase.h>
 #include <aaudio/AAudio.h>
 
 #include "binding/IAAudioService.h"
@@ -34,7 +35,7 @@
 namespace aaudio {
 
 // A stream that talks to the AAudioService or directly to a HAL.
-class AudioStreamInternal : public AudioStream {
+class AudioStreamInternal : public AudioStream, public android::PlayerBase  {
 
 public:
     AudioStreamInternal(AAudioServiceInterface  &serviceInterface, bool inService);
@@ -89,6 +90,9 @@
     // Calculate timeout based on framesPerBurst
     int64_t calculateReasonableTimeout();
 
+    //PlayerBase virtuals
+    virtual void destroy();
+
 protected:
 
     aaudio_result_t processData(void *buffer,
@@ -124,6 +128,14 @@
     // Calculate timeout for an operation involving framesPerOperation.
     int64_t calculateReasonableTimeout(int32_t framesPerOperation);
 
+    void doSetVolume();
+
+    //PlayerBase virtuals
+    virtual status_t playerStart();
+    virtual status_t playerPause();
+    virtual status_t playerStop();
+    virtual status_t playerSetVolume();
+
     aaudio_format_t          mDeviceFormat = AAUDIO_FORMAT_UNSPECIFIED;
 
     IsochronousClockModel    mClockModel;      // timing model for chasing the HAL
@@ -135,6 +147,7 @@
     int32_t                  mXRunCount = 0;      // how many underrun events?
 
     LinearRamp               mVolumeRamp;
+    float                    mStreamVolume;
 
     // Offset from underlying frame position.
     int64_t                  mFramesOffsetFromService = 0; // offset for timestamps
diff --git a/media/libaaudio/src/utility/AAudioUtilities.cpp b/media/libaaudio/src/utility/AAudioUtilities.cpp
index 164784d..2d8ac6e 100644
--- a/media/libaaudio/src/utility/AAudioUtilities.cpp
+++ b/media/libaaudio/src/utility/AAudioUtilities.cpp
@@ -208,9 +208,12 @@
     status_t status;
     switch (result) {
     case AAUDIO_ERROR_DISCONNECTED:
-    case AAUDIO_ERROR_INVALID_HANDLE:
+    case AAUDIO_ERROR_NO_SERVICE:
         status = DEAD_OBJECT;
         break;
+    case AAUDIO_ERROR_INVALID_HANDLE:
+        status = BAD_TYPE;
+        break;
     case AAUDIO_ERROR_INVALID_STATE:
         status = INVALID_OPERATION;
         break;
@@ -233,7 +236,6 @@
     case AAUDIO_ERROR_NO_FREE_HANDLES:
     case AAUDIO_ERROR_NO_MEMORY:
     case AAUDIO_ERROR_TIMEOUT:
-    case AAUDIO_ERROR_NO_SERVICE:
     default:
         status = UNKNOWN_ERROR;
         break;
@@ -257,12 +259,12 @@
     case INVALID_OPERATION:
         result = AAUDIO_ERROR_INVALID_STATE;
         break;
-        case UNEXPECTED_NULL:
-            result = AAUDIO_ERROR_NULL;
-            break;
-        case BAD_VALUE:
-            result = AAUDIO_ERROR_ILLEGAL_ARGUMENT;
-            break;
+    case UNEXPECTED_NULL:
+        result = AAUDIO_ERROR_NULL;
+        break;
+    case BAD_VALUE:
+        result = AAUDIO_ERROR_ILLEGAL_ARGUMENT;
+        break;
     case WOULD_BLOCK:
         result = AAUDIO_ERROR_WOULD_BLOCK;
         break;