aaudio: implement sessionId for effects

If a sessionID other than AAUDIO_SESSION_ID_NONE is requested
then legacy data path will be forced.

SessionID is implemented for MMAP data path but not used.
It is easier to implement it now then try to figure
it out later.

Bug: 33268927
Test: test_session_id.cpp will be moved to CTS when stable
Change-Id: I3ea67f57c1cbe24a512980f1352b917ab3cb6387
diff --git a/media/libaaudio/src/binding/AAudioStreamConfiguration.cpp b/media/libaaudio/src/binding/AAudioStreamConfiguration.cpp
index 97672a0..959db61 100644
--- a/media/libaaudio/src/binding/AAudioStreamConfiguration.cpp
+++ b/media/libaaudio/src/binding/AAudioStreamConfiguration.cpp
@@ -56,6 +56,8 @@
     if (status != NO_ERROR) goto error;
     status = parcel->writeInt32((int32_t) getInputPreset());
     if (status != NO_ERROR) goto error;
+    status = parcel->writeInt32(getSessionId());
+    if (status != NO_ERROR) goto error;
     return NO_ERROR;
 error:
     ALOGE("AAudioStreamConfiguration.writeToParcel(): write failed = %d", status);
@@ -94,6 +96,9 @@
     status = parcel->readInt32(&value);
     if (status != NO_ERROR) goto error;
     setInputPreset((aaudio_input_preset_t) value);
+    status = parcel->readInt32(&value);
+    if (status != NO_ERROR) goto error;
+    setSessionId(value);
     return NO_ERROR;
 error:
     ALOGE("AAudioStreamConfiguration.readFromParcel(): read failed = %d", status);
diff --git a/media/libaaudio/src/client/AudioStreamInternal.cpp b/media/libaaudio/src/client/AudioStreamInternal.cpp
index 5856ec3..4980e97 100644
--- a/media/libaaudio/src/client/AudioStreamInternal.cpp
+++ b/media/libaaudio/src/client/AudioStreamInternal.cpp
@@ -133,6 +133,7 @@
     setSampleRate(configurationOutput.getSampleRate());
     setSamplesPerFrame(configurationOutput.getSamplesPerFrame());
     setDeviceId(configurationOutput.getDeviceId());
+    setSessionId(configurationOutput.getSessionId());
     setSharingMode(configurationOutput.getSharingMode());
 
     setUsage(configurationOutput.getUsage());
diff --git a/media/libaaudio/src/core/AAudioAudio.cpp b/media/libaaudio/src/core/AAudioAudio.cpp
index 9e5ca8e..df0db79 100644
--- a/media/libaaudio/src/core/AAudioAudio.cpp
+++ b/media/libaaudio/src/core/AAudioAudio.cpp
@@ -196,12 +196,19 @@
 }
 
 AAUDIO_API void AAudioStreamBuilder_setBufferCapacityInFrames(AAudioStreamBuilder* builder,
-                                                        int32_t frames)
+                                                              int32_t frames)
 {
     AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
     streamBuilder->setBufferCapacity(frames);
 }
 
+AAUDIO_API void AAudioStreamBuilder_setSessionId(AAudioStreamBuilder* builder,
+                                                 aaudio_session_id_t sessionId)
+{
+    AudioStreamBuilder *streamBuilder = convertAAudioBuilderToStreamBuilder(builder);
+    streamBuilder->setSessionId(sessionId);
+}
+
 AAUDIO_API void AAudioStreamBuilder_setDataCallback(AAudioStreamBuilder* builder,
                                                     AAudioStream_dataCallback callback,
                                                     void *userData)
@@ -483,6 +490,12 @@
     return audioStream->getInputPreset();
 }
 
+AAUDIO_API int32_t AAudioStream_getSessionId(AAudioStream* stream)
+{
+    AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
+    return audioStream->getSessionId();
+}
+
 AAUDIO_API int64_t AAudioStream_getFramesWritten(AAudioStream* stream)
 {
     AudioStream *audioStream = convertAAudioStreamToAudioStream(stream);
diff --git a/media/libaaudio/src/core/AAudioStreamParameters.cpp b/media/libaaudio/src/core/AAudioStreamParameters.cpp
index 23c4eb8..9645ea8 100644
--- a/media/libaaudio/src/core/AAudioStreamParameters.cpp
+++ b/media/libaaudio/src/core/AAudioStreamParameters.cpp
@@ -38,6 +38,7 @@
     mSamplesPerFrame = other.mSamplesPerFrame;
     mSampleRate      = other.mSampleRate;
     mDeviceId        = other.mDeviceId;
+    mSessionId       = other.mSessionId;
     mSharingMode     = other.mSharingMode;
     mAudioFormat     = other.mAudioFormat;
     mDirection       = other.mDirection;
@@ -59,6 +60,15 @@
         return AAUDIO_ERROR_OUT_OF_RANGE;
     }
 
+    // All Session ID values are legal.
+    switch (mSessionId) {
+        case AAUDIO_SESSION_ID_NONE:
+        case AAUDIO_SESSION_ID_ALLOCATE:
+            break;
+        default:
+            break;
+    }
+
     switch (mSharingMode) {
         case AAUDIO_SHARING_MODE_EXCLUSIVE:
         case AAUDIO_SHARING_MODE_SHARED:
@@ -154,6 +164,7 @@
 
 void AAudioStreamParameters::dump() const {
     ALOGD("mDeviceId        = %6d", mDeviceId);
+    ALOGD("mSessionId       = %6d", mSessionId);
     ALOGD("mSampleRate      = %6d", mSampleRate);
     ALOGD("mSamplesPerFrame = %6d", mSamplesPerFrame);
     ALOGD("mSharingMode     = %6d", (int)mSharingMode);
@@ -164,4 +175,3 @@
     ALOGD("mContentType     = %6d", mContentType);
     ALOGD("mInputPreset     = %6d", mInputPreset);
 }
-
diff --git a/media/libaaudio/src/core/AAudioStreamParameters.h b/media/libaaudio/src/core/AAudioStreamParameters.h
index 0c173f5..ce5dacd 100644
--- a/media/libaaudio/src/core/AAudioStreamParameters.h
+++ b/media/libaaudio/src/core/AAudioStreamParameters.h
@@ -112,6 +112,14 @@
         mInputPreset = inputPreset;
     }
 
+    aaudio_session_id_t getSessionId() const {
+        return mSessionId;
+    }
+
+    void setSessionId(aaudio_session_id_t sessionId) {
+        mSessionId = sessionId;
+    }
+
     int32_t calculateBytesPerFrame() const {
         return getSamplesPerFrame() * AAudioConvert_formatToSizeInBytes(getFormat());
     }
@@ -137,6 +145,7 @@
     aaudio_content_type_t      mContentType     = AAUDIO_UNSPECIFIED;
     aaudio_input_preset_t      mInputPreset     = AAUDIO_UNSPECIFIED;
     int32_t                    mBufferCapacity  = AAUDIO_UNSPECIFIED;
+    aaudio_session_id_t        mSessionId       = AAUDIO_SESSION_ID_NONE;
 };
 
 } /* namespace aaudio */
diff --git a/media/libaaudio/src/core/AudioStream.cpp b/media/libaaudio/src/core/AudioStream.cpp
index 1b2ca39..82c0667 100644
--- a/media/libaaudio/src/core/AudioStream.cpp
+++ b/media/libaaudio/src/core/AudioStream.cpp
@@ -108,8 +108,10 @@
           mSampleRate, mSamplesPerFrame, mFormat,
           AudioStream_convertSharingModeToShortText(mSharingMode),
           (getDirection() == AAUDIO_DIRECTION_OUTPUT) ? "OUTPUT" : "INPUT");
-    ALOGI("open() device = %d, perfMode = %d, callback: %s with frames = %d",
-          mDeviceId, mPerformanceMode,
+    ALOGI("open() device = %d, sessionId = %d, perfMode = %d, callback: %s with frames = %d",
+          mDeviceId,
+          mSessionId,
+          mPerformanceMode,
           (isDataCallbackSet() ? "ON" : "OFF"),
           mFramesPerDataCallback);
     ALOGI("open() usage = %d, contentType = %d, inputPreset = %d",
diff --git a/media/libaaudio/src/core/AudioStream.h b/media/libaaudio/src/core/AudioStream.h
index 21fa595..42b585f 100644
--- a/media/libaaudio/src/core/AudioStream.h
+++ b/media/libaaudio/src/core/AudioStream.h
@@ -216,6 +216,10 @@
         return mInputPreset;
     }
 
+    int32_t getSessionId() const {
+        return mSessionId;
+    }
+
     /**
      * This is only valid after setSamplesPerFrame() and setFormat() have been called.
      */
@@ -455,10 +459,15 @@
         mDeviceId = deviceId;
     }
 
+    void setSessionId(int32_t sessionId) {
+        mSessionId = sessionId;
+    }
+
     std::atomic<bool>    mCallbackEnabled{false};
 
     float                mDuckAndMuteVolume = 1.0f;
 
+
 protected:
 
     void setPeriodNanoseconds(int64_t periodNanoseconds) {
@@ -505,10 +514,13 @@
     aaudio_format_t             mFormat = AAUDIO_FORMAT_UNSPECIFIED;
     aaudio_stream_state_t       mState = AAUDIO_STREAM_STATE_UNINITIALIZED;
     aaudio_performance_mode_t   mPerformanceMode = AAUDIO_PERFORMANCE_MODE_NONE;
+
     aaudio_usage_t              mUsage           = AAUDIO_USAGE_MEDIA;
     aaudio_content_type_t       mContentType     = AAUDIO_CONTENT_TYPE_MUSIC;
     aaudio_input_preset_t       mInputPreset     = AAUDIO_INPUT_PRESET_GENERIC;
 
+    int32_t                     mSessionId = AAUDIO_UNSPECIFIED;
+
     // callback ----------------------------------
 
     AAudioStream_dataCallback   mDataCallbackProc = nullptr;  // external callback functions
diff --git a/media/libaaudio/src/core/AudioStreamBuilder.cpp b/media/libaaudio/src/core/AudioStreamBuilder.cpp
index f7cb8d6..293a6a8 100644
--- a/media/libaaudio/src/core/AudioStreamBuilder.cpp
+++ b/media/libaaudio/src/core/AudioStreamBuilder.cpp
@@ -141,6 +141,13 @@
     // TODO Support other performance settings in MMAP mode.
     // Disable MMAP if low latency not requested.
     if (getPerformanceMode() != AAUDIO_PERFORMANCE_MODE_LOW_LATENCY) {
+        ALOGD("build() MMAP not available because AAUDIO_PERFORMANCE_MODE_LOW_LATENCY not used.");
+        allowMMap = false;
+    }
+
+    // SessionID and Effects are only supported in Legacy mode.
+    if (getSessionId() != AAUDIO_SESSION_ID_NONE) {
+        ALOGD("build() MMAP not available because sessionId used.");
         allowMMap = false;
     }
 
diff --git a/media/libaaudio/src/legacy/AudioStreamRecord.cpp b/media/libaaudio/src/legacy/AudioStreamRecord.cpp
index 5f4ab9b..61a0f8a 100644
--- a/media/libaaudio/src/legacy/AudioStreamRecord.cpp
+++ b/media/libaaudio/src/legacy/AudioStreamRecord.cpp
@@ -117,6 +117,9 @@
             .tags = ""
     };
 
+    aaudio_session_id_t requestedSessionId = builder.getSessionId();
+    audio_session_t sessionId = AAudioConvert_aaudioToAndroidSessionId(requestedSessionId);
+
     mAudioRecord = new AudioRecord(
             mOpPackageName // const String16& opPackageName TODO does not compile
             );
@@ -130,7 +133,7 @@
             callbackData,
             notificationFrames,
             false /*threadCanCallJava*/,
-            AUDIO_SESSION_ALLOCATE,
+            sessionId,
             streamTransferType,
             flags,
             AUDIO_UID_INVALID, // DEFAULT uid
@@ -189,6 +192,13 @@
 
     setState(AAUDIO_STREAM_STATE_OPEN);
     setDeviceId(mAudioRecord->getRoutedDeviceId());
+
+    aaudio_session_id_t actualSessionId =
+            (requestedSessionId == AAUDIO_SESSION_ID_NONE)
+            ? AAUDIO_SESSION_ID_NONE
+            : (aaudio_session_id_t) mAudioRecord->getSessionId();
+    setSessionId(actualSessionId);
+
     mAudioRecord->addAudioDeviceCallback(mDeviceCallback);
 
     return AAUDIO_OK;
diff --git a/media/libaaudio/src/legacy/AudioStreamTrack.cpp b/media/libaaudio/src/legacy/AudioStreamTrack.cpp
index 17a8d52..52c7822 100644
--- a/media/libaaudio/src/legacy/AudioStreamTrack.cpp
+++ b/media/libaaudio/src/legacy/AudioStreamTrack.cpp
@@ -134,6 +134,11 @@
             .tags = ""
     };
 
+    static_assert(AAUDIO_UNSPECIFIED == AUDIO_SESSION_ALLOCATE, "Session IDs should match");
+
+    aaudio_session_id_t requestedSessionId = builder.getSessionId();
+    audio_session_t sessionId = AAudioConvert_aaudioToAndroidSessionId(requestedSessionId);
+
     mAudioTrack = new AudioTrack();
     mAudioTrack->set(
             AUDIO_STREAM_DEFAULT,  // ignored because we pass attributes below
@@ -147,7 +152,7 @@
             notificationFrames,
             0,       // DEFAULT sharedBuffer*/,
             false,   // DEFAULT threadCanCallJava
-            AUDIO_SESSION_ALLOCATE,
+            sessionId,
             streamTransferType,
             NULL,    // DEFAULT audio_offload_info_t
             AUDIO_UID_INVALID, // DEFAULT uid
@@ -193,6 +198,13 @@
 
     setState(AAUDIO_STREAM_STATE_OPEN);
     setDeviceId(mAudioTrack->getRoutedDeviceId());
+
+    aaudio_session_id_t actualSessionId =
+            (requestedSessionId == AAUDIO_SESSION_ID_NONE)
+            ? AAUDIO_SESSION_ID_NONE
+            : (aaudio_session_id_t) mAudioTrack->getSessionId();
+    setSessionId(actualSessionId);
+
     mAudioTrack->addAudioDeviceCallback(mDeviceCallback);
 
     // Update performance mode based on the actual stream flags.
diff --git a/media/libaaudio/src/utility/AAudioUtilities.cpp b/media/libaaudio/src/utility/AAudioUtilities.cpp
index c6adf33..2bee6e3 100644
--- a/media/libaaudio/src/utility/AAudioUtilities.cpp
+++ b/media/libaaudio/src/utility/AAudioUtilities.cpp
@@ -250,6 +250,13 @@
     return result;
 }
 
+audio_session_t AAudioConvert_aaudioToAndroidSessionId(aaudio_session_id_t sessionId) {
+    // If not a valid sessionId then convert to a safe value of AUDIO_SESSION_ALLOCATE.
+    return (sessionId < AAUDIO_SESSION_ID_MIN)
+           ? AUDIO_SESSION_ALLOCATE
+           : (audio_session_t) sessionId;
+}
+
 audio_format_t AAudioConvert_aaudioToAndroidDataFormat(aaudio_format_t aaudioFormat) {
     audio_format_t androidFormat;
     switch (aaudioFormat) {
diff --git a/media/libaaudio/src/utility/AAudioUtilities.h b/media/libaaudio/src/utility/AAudioUtilities.h
index f2347f5..0c59f6d 100644
--- a/media/libaaudio/src/utility/AAudioUtilities.h
+++ b/media/libaaudio/src/utility/AAudioUtilities.h
@@ -27,6 +27,9 @@
 
 #include "aaudio/AAudio.h"
 
+
+constexpr aaudio_session_id_t AAUDIO_SESSION_ID_MIN = 1; // must be positive
+
 /**
  * Convert an AAudio result into the closest matching Android status.
  */
@@ -38,6 +41,13 @@
 aaudio_result_t AAudioConvert_androidToAAudioResult(android::status_t status);
 
 /**
+ * Convert an aaudio_session_id_t to a value that is safe to pass to AudioFlinger.
+ * @param sessionId
+ * @return safe value
+ */
+audio_session_t AAudioConvert_aaudioToAndroidSessionId(aaudio_session_id_t sessionId);
+
+/**
  * Convert an array of floats to an array of int16_t.
  *
  * @param source