Merge "Reenable task snapshots without using RenderThread in SystemServer."
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 2ba6282..345a7ae 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -133,7 +133,7 @@
     public final static boolean ENABLE_TASK_SNAPSHOTS;
 
     static {
-        ENABLE_TASK_SNAPSHOTS = SystemProperties.getBoolean("persist.enable_task_snapshots", false);
+        ENABLE_TASK_SNAPSHOTS = SystemProperties.getBoolean("persist.enable_task_snapshots", true);
     }
 
     static final class UidObserver extends IUidObserver.Stub {
diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java
index ecd5e3b..8bb3fa9 100644
--- a/core/java/android/view/Surface.java
+++ b/core/java/android/view/Surface.java
@@ -19,6 +19,7 @@
 import android.annotation.IntDef;
 import android.content.res.CompatibilityInfo.Translator;
 import android.graphics.Canvas;
+import android.graphics.GraphicBuffer;
 import android.graphics.Matrix;
 import android.graphics.Rect;
 import android.graphics.SurfaceTexture;
@@ -72,6 +73,7 @@
     private static native int nativeSetScalingMode(long nativeObject, int scalingMode);
     private static native void nativeSetBuffersTransform(long nativeObject, long transform);
     private static native int nativeForceScopedDisconnect(long nativeObject);
+    private static native int nativeAttachAndQueueBuffer(long nativeObject, GraphicBuffer buffer);
 
     public static final Parcelable.Creator<Surface> CREATOR =
             new Parcelable.Creator<Surface>() {
@@ -562,6 +564,21 @@
     }
 
     /**
+     * Transfer ownership of buffer and present it on the Surface.
+     * @hide
+     */
+    public void attachAndQueueBuffer(GraphicBuffer buffer) {
+        synchronized (mLock) {
+            checkNotReleasedLocked();
+            int err = nativeAttachAndQueueBuffer(mNativeObject, buffer);
+            if (err != 0) {
+                throw new RuntimeException(
+                        "Failed to attach and queue buffer to Surface (bad object?)");
+            }
+        }
+    }
+
+    /**
      * Returns whether or not this Surface is backed by a single-buffered SurfaceTexture
      * @hide
      */
diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp
index 6192271..713287e 100644
--- a/core/jni/android_view_Surface.cpp
+++ b/core/jni/android_view_Surface.cpp
@@ -21,6 +21,7 @@
 #include "jni.h"
 #include "JNIHelp.h"
 #include "android_os_Parcel.h"
+#include "android/graphics/GraphicBuffer.h"
 #include "android/graphics/GraphicsJNI.h"
 
 #include "core_jni_helpers.h"
@@ -496,6 +497,30 @@
     return surface->disconnect(-1, IGraphicBufferProducer::DisconnectMode::AllLocal);
 }
 
+static jint nativeAttachAndQueueBuffer(JNIEnv *env, jclass clazz, jlong nativeObject,
+        jobject graphicBuffer) {
+    Surface* surface = reinterpret_cast<Surface*>(nativeObject);
+    sp<GraphicBuffer> bp = graphicBufferForJavaObject(env, graphicBuffer);
+    if (bp == nullptr) {
+        return BAD_VALUE;
+    }
+    int err = ((ANativeWindow*)surface)->perform(surface, NATIVE_WINDOW_API_CONNECT,
+            NATIVE_WINDOW_API_CPU);
+    if (err != OK) {
+        return err;
+    }
+    err = surface->attachBuffer(bp->getNativeBuffer());
+    if (err != OK) {
+        return err;
+    }
+    err = ((ANativeWindow*)surface)->queueBuffer(surface, bp->getNativeBuffer(), -1);
+    if (err != OK) {
+        return err;
+    }
+    err = surface->disconnect(NATIVE_WINDOW_API_CPU);
+    return err;
+}
+
 namespace uirenderer {
 
 using namespace android::uirenderer::renderthread;
@@ -574,6 +599,7 @@
     {"nativeGetNextFrameNumber", "(J)J", (void*)nativeGetNextFrameNumber },
     {"nativeSetScalingMode", "(JI)I", (void*)nativeSetScalingMode },
     {"nativeForceScopedDisconnect", "(J)I", (void*)nativeForceScopedDisconnect},
+    {"nativeAttachAndQueueBuffer", "(JLandroid/graphics/GraphicBuffer;)I", (void*)nativeAttachAndQueueBuffer},
 
     // HWUI context
     {"nHwuiCreate", "(JJ)J", (void*) hwui::create },
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotSurface.java b/services/core/java/com/android/server/wm/TaskSnapshotSurface.java
index 9f34bd7..76fb522 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotSurface.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotSurface.java
@@ -151,21 +151,7 @@
     }
 
     private void drawSnapshot(GraphicBuffer snapshot) {
-
-        // TODO: Just wrap the buffer here without any copying.
-        final Canvas c = mSurface.lockHardwareCanvas();
-        final Bitmap b = Bitmap.createHardwareBitmap(snapshot);
-        fillEmptyBackground(c, b);
-        c.drawBitmap(b, 0, 0, null);
-        mSurface.unlockCanvasAndPost(c);
-        final boolean reportNextDraw;
-        synchronized (mService.mWindowMap) {
-            mHasDrawn = true;
-            reportNextDraw = mReportNextDraw;
-        }
-        if (reportNextDraw) {
-            reportDrawn();
-        }
+        mSurface.attachAndQueueBuffer(snapshot);
         mSurface.release();
     }