Merge "MediaRecorder: add getSurface() api and SURFACE video source"
diff --git a/api/current.txt b/api/current.txt
index 243c412..1495277 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -13187,6 +13187,7 @@
     ctor public MediaRecorder();
     method public static final int getAudioSourceMax();
     method public int getMaxAmplitude() throws java.lang.IllegalStateException;
+    method public android.view.Surface getSurface();
     method public void prepare() throws java.io.IOException, java.lang.IllegalStateException;
     method public void release();
     method public void reset();
@@ -13271,6 +13272,7 @@
   public final class MediaRecorder.VideoSource {
     field public static final int CAMERA = 1; // 0x1
     field public static final int DEFAULT = 0; // 0x0
+    field public static final int SURFACE = 2; // 0x2
   }
 
   public class MediaRouter {
diff --git a/media/java/android/media/MediaRecorder.java b/media/java/android/media/MediaRecorder.java
index 8dcbd6b..7b7c06c 100644
--- a/media/java/android/media/MediaRecorder.java
+++ b/media/java/android/media/MediaRecorder.java
@@ -124,6 +124,18 @@
     public native void setCamera(Camera c);
 
     /**
+     * Gets the surface to record from when using SURFACE video source.
+     * <p>
+     * Should only be called after prepare(). Frames rendered before start()
+     * will be discarded.
+     * </p>
+     * @throws IllegalStateException if it is called before prepare(), after
+     * stop() or is called when VideoSource is not set to SURFACE.
+     * @see android.media.MediaRecorder.VideoSource
+     */
+    public native Surface getSurface();
+
+    /**
      * Sets a Surface to show a preview of recorded media (video). Calls this
      * before prepare() to make sure that the desirable preview display is
      * set. If {@link #setCamera(Camera)} is used and the surface has been
@@ -225,10 +237,23 @@
        */
         private VideoSource() {}
         public static final int DEFAULT = 0;
-        /** Camera video source */
+        /** Camera video source
+         * <p>
+         * Using android.hardware.Camera as video source.
+         * </p>
+         */
         public static final int CAMERA = 1;
-        /** @hide */
-        public static final int GRALLOC_BUFFER = 2;
+        /** Surface video source
+         * <p>
+         * Using a Surface as video source.
+         * </p><p>
+         * This flag must be used when recording from an
+         * android.hardware.camera2.CameraDevice source.
+         * </p><p>
+         * When using this video source type, use {@link MediaRecorder#getSurface()}
+         * to retrieve the surface created by MediaRecorder.
+         */
+        public static final int SURFACE = 2;
     }
 
     /**
diff --git a/media/jni/android_media_MediaRecorder.cpp b/media/jni/android_media_MediaRecorder.cpp
index 9888591..ac863e1 100644
--- a/media/jni/android_media_MediaRecorder.cpp
+++ b/media/jni/android_media_MediaRecorder.cpp
@@ -344,6 +344,26 @@
     return result;
 }
 
+static jobject
+android_media_MediaRecorder_getSurface(JNIEnv *env, jobject thiz)
+{
+    ALOGV("getSurface");
+    sp<MediaRecorder> mr = getMediaRecorder(env, thiz);
+
+    sp<IGraphicBufferProducer> bufferProducer = mr->querySurfaceMediaSourceFromMediaServer();
+    if (bufferProducer == NULL) {
+        jniThrowException(
+                env,
+                "java/lang/IllegalStateException",
+                "failed to get surface");
+        return NULL;
+    }
+
+    // Wrap the IGBP in a Java-language Surface.
+    return android_view_Surface_createFromIGraphicBufferProducer(env,
+            bufferProducer);
+}
+
 static void
 android_media_MediaRecorder_start(JNIEnv *env, jobject thiz)
 {
@@ -470,6 +490,7 @@
     {"setMaxDuration",       "(I)V",                            (void *)android_media_MediaRecorder_setMaxDuration},
     {"setMaxFileSize",       "(J)V",                            (void *)android_media_MediaRecorder_setMaxFileSize},
     {"_prepare",             "()V",                             (void *)android_media_MediaRecorder_prepare},
+    {"getSurface",           "()Landroid/view/Surface;",        (void *)android_media_MediaRecorder_getSurface},
     {"getMaxAmplitude",      "()I",                             (void *)android_media_MediaRecorder_native_getMaxAmplitude},
     {"start",                "()V",                             (void *)android_media_MediaRecorder_start},
     {"stop",                 "()V",                             (void *)android_media_MediaRecorder_stop},