Snapshot Task with the app window crop for Recents

Snapshot a specific task and its children instead of taking a snapshot
of the whole screen with max and min layer values. This makes it clear
what the desired screenshot is instead of trying to determine what the
max and min z layers should be.

In the process of updating the snapshot code, I split the code that
captures a layer from the code that captures the whole screen. This
simplified the code so the capture screen doesn't need to invoke the
frame calculations since it will be capturing the whole screen anyway.

Test: Recents snapshots work correctly without the IME, status, and
navigation bar

Change-Id: I8776c1ddb9cd8a23a482b045720960702796fd5f
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index bb1bfad..f77e6c4 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -291,7 +291,7 @@
 }
 
 static void nativeCaptureLayers(JNIEnv* env, jclass clazz, jobject layerHandleToken,
-        jobject surfaceObj, int rotation) {
+        jobject surfaceObj, jobject sourceCropObj, jfloat frameScale) {
 
     sp<IBinder> layerHandle = ibinderForJavaObject(env, layerHandleToken);
     if (layerHandle == NULL) {
@@ -303,7 +303,42 @@
         return;
     }
 
-    ScreenshotClient::captureLayers(layerHandle, consumer->getIGraphicBufferProducer(), rotation);
+    Rect sourceCrop;
+    if (sourceCropObj != NULL) {
+        sourceCrop = rectFromObj(env, sourceCropObj);
+    }
+
+    ScreenshotClient::captureLayers(layerHandle, consumer->getIGraphicBufferProducer(), sourceCrop,
+            frameScale);
+}
+
+static jobject nativeCaptureLayersToBuffer(JNIEnv* env, jclass clazz, jobject layerHandleToken,
+        jobject sourceCropObj, jfloat frameScale) {
+
+    sp<IBinder> layerHandle = ibinderForJavaObject(env, layerHandleToken);
+    if (layerHandle == NULL) {
+        return NULL;
+    }
+
+    Rect sourceCrop;
+    if (sourceCropObj != NULL) {
+        sourceCrop = rectFromObj(env, sourceCropObj);
+    }
+
+    sp<GraphicBuffer> buffer;
+    status_t res = ScreenshotClient::captureLayersToBuffer(layerHandle, sourceCrop, frameScale,
+            &buffer);
+    if (res != NO_ERROR) {
+        return NULL;
+    }
+
+    return env->CallStaticObjectMethod(gGraphicBufferClassInfo.clazz,
+                                       gGraphicBufferClassInfo.builder,
+                                       buffer->getWidth(),
+                                       buffer->getHeight(),
+                                       buffer->getPixelFormat(),
+                                       (jint)buffer->getUsage(),
+                                       (jlong)buffer.get());
 }
 
 static void nativeApplyTransaction(JNIEnv* env, jclass clazz, jlong transactionObj, jboolean sync) {
@@ -975,8 +1010,10 @@
     {"nativeScreenshotToBuffer",
      "(Landroid/os/IBinder;Landroid/graphics/Rect;IIIIZZI)Landroid/graphics/GraphicBuffer;",
      (void*)nativeScreenshotToBuffer },
-    {"nativeCaptureLayers", "(Landroid/os/IBinder;Landroid/view/Surface;I)V",
+    {"nativeCaptureLayers", "(Landroid/os/IBinder;Landroid/view/Surface;Landroid/graphics/Rect;F)V",
             (void*)nativeCaptureLayers },
+    {"nativeCaptureLayers", "(Landroid/os/IBinder;Landroid/graphics/Rect;F)Landroid/graphics/GraphicBuffer;",
+            (void*)nativeCaptureLayersToBuffer },
 };
 
 int register_android_view_SurfaceControl(JNIEnv* env)