MediaCodec: Allow getting the chosen component name

Currently, when the codec was opened by createDecoder/EncoderByType,
the caller does not know what codec actually was chosen, and
(for encoders) thus cannot know what color formats it supports.

This adds new public API.

Change-Id: Ie471f40f8104b37d27ced3dba5a54facc6504b1b
diff --git a/api/current.txt b/api/current.txt
index 6b893d5..4fe1a07 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -11200,6 +11200,7 @@
     method public final int dequeueOutputBuffer(android.media.MediaCodec.BufferInfo, long);
     method public final void flush();
     method public java.nio.ByteBuffer[] getInputBuffers();
+    method public final java.lang.String getName();
     method public java.nio.ByteBuffer[] getOutputBuffers();
     method public final android.media.MediaFormat getOutputFormat();
     method public final void queueInputBuffer(int, int, int, long, int) throws android.media.MediaCodec.CryptoException;
diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java
index 99db066..cacc338 100644
--- a/media/java/android/media/MediaCodec.java
+++ b/media/java/android/media/MediaCodec.java
@@ -498,6 +498,12 @@
      */
     public native final void setVideoScalingMode(int mode);
 
+    /**
+     * Get the component name. If the codec was created by createDecoderByType
+     * or createEncoderByType, what component is chosen is not known beforehand.
+     */
+    public native final String getName();
+
     private native final ByteBuffer[] getBuffers(boolean input);
 
     private static native final void native_init();
diff --git a/media/jni/android_media_MediaCodec.cpp b/media/jni/android_media_MediaCodec.cpp
index f91c9a0..dab2de1 100644
--- a/media/jni/android_media_MediaCodec.cpp
+++ b/media/jni/android_media_MediaCodec.cpp
@@ -264,6 +264,20 @@
     return OK;
 }
 
+status_t JMediaCodec::getName(JNIEnv *env, jstring *nameStr) const {
+    AString name;
+
+    status_t err = mCodec->getName(&name);
+
+    if (err != OK) {
+        return err;
+    }
+
+    *nameStr = env->NewStringUTF(name.c_str());
+
+    return OK;
+}
+
 void JMediaCodec::setVideoScalingMode(int mode) {
     if (mSurfaceTextureClient != NULL) {
         native_window_set_scaling_mode(mSurfaceTextureClient.get(), mode);
@@ -706,6 +720,29 @@
     return NULL;
 }
 
+static jobject android_media_MediaCodec_getName(
+        JNIEnv *env, jobject thiz) {
+    ALOGV("android_media_MediaCodec_getName");
+
+    sp<JMediaCodec> codec = getMediaCodec(env, thiz);
+
+    if (codec == NULL) {
+        jniThrowException(env, "java/lang/IllegalStateException", NULL);
+        return NULL;
+    }
+
+    jstring name;
+    status_t err = codec->getName(env, &name);
+
+    if (err == OK) {
+        return name;
+    }
+
+    throwExceptionAsNecessary(env, err);
+
+    return NULL;
+}
+
 static void android_media_MediaCodec_setVideoScalingMode(
         JNIEnv *env, jobject thiz, jint mode) {
     sp<JMediaCodec> codec = getMediaCodec(env, thiz);
@@ -826,6 +863,9 @@
     { "getBuffers", "(Z)[Ljava/nio/ByteBuffer;",
       (void *)android_media_MediaCodec_getBuffers },
 
+    { "getName", "()Ljava/lang/String;",
+      (void *)android_media_MediaCodec_getName },
+
     { "setVideoScalingMode", "(I)V",
       (void *)android_media_MediaCodec_setVideoScalingMode },
 
diff --git a/media/jni/android_media_MediaCodec.h b/media/jni/android_media_MediaCodec.h
index 4936b53..bc9ad50 100644
--- a/media/jni/android_media_MediaCodec.h
+++ b/media/jni/android_media_MediaCodec.h
@@ -81,6 +81,8 @@
     status_t getBuffers(
             JNIEnv *env, bool input, jobjectArray *bufArray) const;
 
+    status_t getName(JNIEnv *env, jstring *name) const;
+
     void setVideoScalingMode(int mode);
 
 protected: