Add AudioPresentation selection support for MediaCodec

Bug: 119312182
Test: compile
Change-Id: I5cfc577b681ea6dcc1692abf71837fd5f41616ea
diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java
index 242ae46..0375de3 100644
--- a/media/java/android/media/MediaCodec.java
+++ b/media/java/android/media/MediaCodec.java
@@ -27,7 +27,6 @@
 import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
-import android.os.IBinder;
 import android.os.IHwBinder;
 import android.os.Looper;
 import android.os.Message;
@@ -1427,6 +1426,24 @@
     <td>&#9094;</td>
    </tr>
    <tr>
+    <td>(29+)</td>
+    <td>29+</td>
+    <td>29+</td>
+    <td>29+</td>
+    <td>(29+)</td>
+    <td>(29+)</td>
+    <td>-</td>
+    <td class=fn>{@link #setAudioPresentation setAudioPresentation}</td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+   </tr>
+   <tr>
     <td>-</td>
     <td>-</td>
     <td>18+</td>
@@ -3260,6 +3277,19 @@
     public native final void setVideoScalingMode(@VideoScalingMode int mode);
 
     /**
+     * Sets the audio presentation.
+     * @param presentation see {@link AudioPresentation}. In particular, id should be set.
+     */
+    public void setAudioPresentation(@NonNull AudioPresentation presentation) {
+        if (presentation == null) {
+            throw new IllegalArgumentException("audio presentation is null");
+        }
+        native_setAudioPresentation(presentation.getPresentationId(), presentation.getProgramId());
+    }
+
+    private native void native_setAudioPresentation(int presentationId, int programId);
+
+    /**
      * Get the component name. If the codec was created by createDecoderByType
      * or createEncoderByType, what component is chosen is not known beforehand.
      * @throws IllegalStateException if in the Released state.
diff --git a/media/jni/android_media_MediaCodec.cpp b/media/jni/android_media_MediaCodec.cpp
index 5037209..2578608 100644
--- a/media/jni/android_media_MediaCodec.cpp
+++ b/media/jni/android_media_MediaCodec.cpp
@@ -752,6 +752,13 @@
     }
 }
 
+void JMediaCodec::selectAudioPresentation(const int32_t presentationId, const int32_t programId) {
+    sp<AMessage> msg = new AMessage;
+    msg->setInt32("audio-presentation-presentation-id", presentationId);
+    msg->setInt32("audio-presentation-program-id", programId);
+    (void)mCodec->setParameters(msg);
+}
+
 static jthrowable createCodecException(
         JNIEnv *env, status_t err, int32_t actionCode, const char *msg = NULL) {
     ScopedLocalRef<jclass> clazz(
@@ -1874,6 +1881,18 @@
     codec->setVideoScalingMode(mode);
 }
 
+static void android_media_MediaCodec_setAudioPresentation(
+        JNIEnv *env, jobject thiz, jint presentationId, jint programId) {
+    sp<JMediaCodec> codec = getMediaCodec(env, thiz);
+
+    if (codec == NULL) {
+        throwExceptionAsNecessary(env, INVALID_OPERATION);
+        return;
+    }
+
+    codec->selectAudioPresentation((int32_t)presentationId, (int32_t)programId);
+}
+
 static void android_media_MediaCodec_native_init(JNIEnv *env) {
     ScopedLocalRef<jclass> clazz(
             env, env->FindClass("android/media/MediaCodec"));
@@ -2183,6 +2202,9 @@
     { "setVideoScalingMode", "(I)V",
       (void *)android_media_MediaCodec_setVideoScalingMode },
 
+    { "native_setAudioPresentation", "(II)V",
+      (void *)android_media_MediaCodec_setAudioPresentation },
+
     { "native_init", "()V", (void *)android_media_MediaCodec_native_init },
 
     { "native_setup", "(Ljava/lang/String;ZZ)V",
diff --git a/media/jni/android_media_MediaCodec.h b/media/jni/android_media_MediaCodec.h
index 985f55a..0a53f1a 100644
--- a/media/jni/android_media_MediaCodec.h
+++ b/media/jni/android_media_MediaCodec.h
@@ -128,6 +128,8 @@
 
     void setVideoScalingMode(int mode);
 
+    void selectAudioPresentation(const int32_t presentationId, const int32_t programId);
+
 protected:
     virtual ~JMediaCodec();