Updated display capture and screencap to match native functions

Modified Java and JNI display capture functions to match the new
function in SurfaceComposerClient. The Java method will send an args
object instead of individual arguments to SurfaceComposerClient

Test: display screenshots working
Test: adb shell screencap
Bug: 162367424

Change-Id: Ic8d9cbc626e9ef73300304ce155a50f76f017dfc
diff --git a/cmds/screencap/screencap.cpp b/cmds/screencap/screencap.cpp
index c1d8399..a46a54c 100644
--- a/cmds/screencap/screencap.cpp
+++ b/cmds/screencap/screencap.cpp
@@ -182,16 +182,17 @@
     ProcessState::self()->setThreadPoolMaxThreadCount(0);
     ProcessState::self()->startThreadPool();
 
-    ui::Dataspace outDataspace;
-    sp<GraphicBuffer> outBuffer;
-
-    status_t result = ScreenshotClient::capture(*displayId, &outDataspace, &outBuffer);
+    ScreenCaptureResults captureResults;
+    status_t result = ScreenshotClient::captureDisplay(*displayId, captureResults);
     if (result != NO_ERROR) {
         close(fd);
         return 1;
     }
 
-    result = outBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN, &base);
+    ui::Dataspace dataspace = captureResults.capturedDataspace;
+    sp<GraphicBuffer> buffer = captureResults.buffer;
+
+    result = buffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN, &base);
 
     if (base == nullptr || result != NO_ERROR) {
         String8 reason;
@@ -207,13 +208,13 @@
 
     if (png) {
         AndroidBitmapInfo info;
-        info.format = flinger2bitmapFormat(outBuffer->getPixelFormat());
+        info.format = flinger2bitmapFormat(buffer->getPixelFormat());
         info.flags = ANDROID_BITMAP_FLAGS_ALPHA_PREMUL;
-        info.width = outBuffer->getWidth();
-        info.height = outBuffer->getHeight();
-        info.stride = outBuffer->getStride() * bytesPerPixel(outBuffer->getPixelFormat());
+        info.width = buffer->getWidth();
+        info.height = buffer->getHeight();
+        info.stride = buffer->getStride() * bytesPerPixel(buffer->getPixelFormat());
 
-        int result = AndroidBitmap_compress(&info, static_cast<int32_t>(outDataspace), base,
+        int result = AndroidBitmap_compress(&info, static_cast<int32_t>(dataspace), base,
                                             ANDROID_BITMAP_COMPRESS_FORMAT_PNG, 100, &fd,
                                             [](void* fdPtr, const void* data, size_t size) -> bool {
                                                 int bytesWritten = write(*static_cast<int*>(fdPtr),
@@ -229,11 +230,11 @@
             notifyMediaScanner(fn);
         }
     } else {
-        uint32_t w = outBuffer->getWidth();
-        uint32_t h = outBuffer->getHeight();
-        uint32_t s = outBuffer->getStride();
-        uint32_t f = outBuffer->getPixelFormat();
-        uint32_t c = dataSpaceToInt(outDataspace);
+        uint32_t w = buffer->getWidth();
+        uint32_t h = buffer->getHeight();
+        uint32_t s = buffer->getStride();
+        uint32_t f = buffer->getPixelFormat();
+        uint32_t c = dataSpaceToInt(dataspace);
 
         write(fd, &w, 4);
         write(fd, &h, 4);
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index eaa7eaf..0f87ada 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -89,10 +89,8 @@
     private static native void nativeWriteToParcel(long nativeObject, Parcel out);
     private static native void nativeRelease(long nativeObject);
     private static native void nativeDisconnect(long nativeObject);
-
-    private static native ScreenshotHardwareBuffer nativeScreenshot(IBinder displayToken,
-            Rect sourceCrop, int width, int height, boolean useIdentityTransform, int rotation,
-            boolean captureSecureLayers);
+    private static native ScreenshotHardwareBuffer nativeCaptureDisplay(
+            DisplayCaptureArgs captureArgs);
     private static native ScreenshotHardwareBuffer nativeCaptureLayers(IBinder displayToken,
             long layerObject, Rect sourceCrop, float frameScale, long[] excludeLayerObjects,
             int format);
@@ -662,14 +660,14 @@
             /**
              * Each sub class should return itself to allow the builder to chain properly
              */
-            public abstract T getThis();
+            abstract T getThis();
         }
     }
 
     /**
      * The arguments class used to make display capture requests.
      *
-     * @see #nativeScreenshot(IBinder, Rect, int, int, boolean, int, boolean)
+     * @see #nativeCaptureDisplay(DisplayCaptureArgs)
      * @hide
      */
     public static class DisplayCaptureArgs extends CaptureArgs {
@@ -759,7 +757,7 @@
             }
 
             @Override
-            public Builder getThis() {
+            Builder getThis() {
                 return this;
             }
         }
@@ -837,7 +835,7 @@
             }
 
             @Override
-            public Builder getThis() {
+            Builder getThis() {
                 return this;
             }
 
@@ -2293,8 +2291,14 @@
             throw new IllegalArgumentException("displayToken must not be null");
         }
 
-        return nativeScreenshot(display, sourceCrop, width, height, useIdentityTransform, rotation,
-                false /* captureSecureLayers */);
+        DisplayCaptureArgs captureArgs = new DisplayCaptureArgs.Builder(display)
+                .setSourceCrop(sourceCrop)
+                .setSize(width, height)
+                .setUseIdentityTransform(useIdentityTransform)
+                .setRotation(rotation)
+                .build();
+
+        return nativeCaptureDisplay(captureArgs);
     }
 
     /**
@@ -2314,8 +2318,15 @@
             throw new IllegalArgumentException("displayToken must not be null");
         }
 
-        return nativeScreenshot(display, sourceCrop, width, height, useIdentityTransform, rotation,
-                true /* captureSecureLayers */);
+        DisplayCaptureArgs captureArgs = new DisplayCaptureArgs.Builder(display)
+                .setSourceCrop(sourceCrop)
+                .setSize(width, height)
+                .setUseIdentityTransform(useIdentityTransform)
+                .setRotation(rotation)
+                .setCaptureSecureLayers(true)
+                .build();
+
+        return nativeCaptureDisplay(captureArgs);
     }
 
     private static void rotateCropForSF(Rect crop, int rot) {
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index a965ab3..905e69d 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -104,6 +104,21 @@
     jfieldID top;
 } gRectClassInfo;
 
+static struct {
+    jfieldID pixelFormat;
+    jfieldID sourceCrop;
+    jfieldID frameScale;
+    jfieldID captureSecureLayers;
+} gCaptureArgsClassInfo;
+
+static struct {
+    jfieldID displayToken;
+    jfieldID width;
+    jfieldID height;
+    jfieldID useIdentityTransform;
+    jfieldID rotation;
+} gDisplayCaptureArgsClassInfo;
+
 // Implements SkMallocPixelRef::ReleaseProc, to delete the screenshot on unref.
 void DeleteScreenshot(void* addr, void* context) {
     delete ((ScreenshotClient*) context);
@@ -276,35 +291,60 @@
     return Rect(left, top, right, bottom);
 }
 
-static jobject nativeScreenshot(JNIEnv* env, jclass clazz,
-        jobject displayTokenObj, jobject sourceCropObj, jint width, jint height,
-        bool useIdentityTransform, int rotation, bool captureSecureLayers) {
-    sp<IBinder> displayToken = ibinderForJavaObject(env, displayTokenObj);
-    if (displayToken == NULL) {
+static void getCaptureArgs(JNIEnv* env, jobject captureArgsObject, CaptureArgs& captureArgs) {
+    captureArgs.pixelFormat = static_cast<ui::PixelFormat>(
+            env->GetIntField(captureArgsObject, gCaptureArgsClassInfo.pixelFormat));
+    captureArgs.sourceCrop =
+            rectFromObj(env,
+                        env->GetObjectField(captureArgsObject, gCaptureArgsClassInfo.sourceCrop));
+    captureArgs.frameScale =
+            env->GetFloatField(captureArgsObject, gCaptureArgsClassInfo.frameScale);
+    captureArgs.captureSecureLayers =
+            env->GetBooleanField(captureArgsObject, gCaptureArgsClassInfo.captureSecureLayers);
+}
+
+static DisplayCaptureArgs displayCaptureArgsFromObject(JNIEnv* env,
+                                                       jobject displayCaptureArgsObject) {
+    DisplayCaptureArgs captureArgs;
+    getCaptureArgs(env, displayCaptureArgsObject, captureArgs);
+
+    captureArgs.displayToken =
+            ibinderForJavaObject(env,
+                                 env->GetObjectField(displayCaptureArgsObject,
+                                                     gDisplayCaptureArgsClassInfo.displayToken));
+    captureArgs.width =
+            env->GetIntField(displayCaptureArgsObject, gDisplayCaptureArgsClassInfo.width);
+    captureArgs.height =
+            env->GetIntField(displayCaptureArgsObject, gDisplayCaptureArgsClassInfo.height);
+    captureArgs.useIdentityTransform =
+            env->GetBooleanField(displayCaptureArgsObject,
+                                 gDisplayCaptureArgsClassInfo.useIdentityTransform);
+    captureArgs.rotation = ui::toRotation(
+            env->GetIntField(displayCaptureArgsObject, gDisplayCaptureArgsClassInfo.rotation));
+    return captureArgs;
+}
+
+static jobject nativeCaptureDisplay(JNIEnv* env, jclass clazz, jobject displayCaptureArgsObject) {
+    const DisplayCaptureArgs captureArgs =
+            displayCaptureArgsFromObject(env, displayCaptureArgsObject);
+
+    if (captureArgs.displayToken == NULL) {
         return NULL;
     }
-    const ui::ColorMode colorMode = SurfaceComposerClient::getActiveColorMode(displayToken);
-    const ui::Dataspace dataspace = pickDataspaceFromColorMode(colorMode);
 
-    Rect sourceCrop = rectFromObj(env, sourceCropObj);
-    sp<GraphicBuffer> buffer;
-    bool capturedSecureLayers = false;
-    status_t res = ScreenshotClient::capture(displayToken, dataspace,
-            ui::PixelFormat::RGBA_8888,
-            sourceCrop, width, height,
-            useIdentityTransform, ui::toRotation(rotation),
-            captureSecureLayers, &buffer, capturedSecureLayers);
+    ScreenCaptureResults captureResults;
+    status_t res = ScreenshotClient::captureDisplay(captureArgs, captureResults);
     if (res != NO_ERROR) {
         return NULL;
     }
 
-    jobject jhardwareBuffer =
-            android_hardware_HardwareBuffer_createFromAHardwareBuffer(env,
-                                                                      buffer->toAHardwareBuffer());
-    const jint namedColorSpace = fromDataspaceToNamedColorSpaceValue(dataspace);
+    jobject jhardwareBuffer = android_hardware_HardwareBuffer_createFromAHardwareBuffer(
+            env, captureResults.buffer->toAHardwareBuffer());
+    const jint namedColorSpace =
+            fromDataspaceToNamedColorSpaceValue(captureResults.capturedDataspace);
     return env->CallStaticObjectMethod(gScreenshotHardwareBufferClassInfo.clazz,
                                        gScreenshotHardwareBufferClassInfo.builder, jhardwareBuffer,
-                                       namedColorSpace, capturedSecureLayers);
+                                       namedColorSpace, captureResults.capturedSecureLayers);
 }
 
 static jobject nativeCaptureLayers(JNIEnv* env, jclass clazz, jobject displayTokenObj,
@@ -1614,10 +1654,10 @@
             (void*)nativeSeverChildren } ,
     {"nativeSetOverrideScalingMode", "(JJI)V",
             (void*)nativeSetOverrideScalingMode },
-    {"nativeScreenshot",
-            "(Landroid/os/IBinder;Landroid/graphics/Rect;IIZIZ)"
+    {"nativeCaptureDisplay",
+            "(Landroid/view/SurfaceControl$DisplayCaptureArgs;)"
             "Landroid/view/SurfaceControl$ScreenshotHardwareBuffer;",
-            (void*)nativeScreenshot },
+            (void*)nativeCaptureDisplay },
     {"nativeCaptureLayers",
             "(Landroid/os/IBinder;JLandroid/graphics/Rect;"
             "F[JI)"
@@ -1795,6 +1835,27 @@
     gDesiredDisplayConfigSpecsClassInfo.appRequestRefreshRateMax =
             GetFieldIDOrDie(env, desiredDisplayConfigSpecsClazz, "appRequestRefreshRateMax", "F");
 
+    jclass captureArgsClazz = FindClassOrDie(env, "android/view/SurfaceControl$CaptureArgs");
+    gCaptureArgsClassInfo.pixelFormat = GetFieldIDOrDie(env, captureArgsClazz, "mPixelFormat", "I");
+    gCaptureArgsClassInfo.sourceCrop =
+            GetFieldIDOrDie(env, captureArgsClazz, "mSourceCrop", "Landroid/graphics/Rect;");
+    gCaptureArgsClassInfo.frameScale = GetFieldIDOrDie(env, captureArgsClazz, "mFrameScale", "F");
+    gCaptureArgsClassInfo.captureSecureLayers =
+            GetFieldIDOrDie(env, captureArgsClazz, "mCaptureSecureLayers", "Z");
+
+    jclass displayCaptureArgsClazz =
+            FindClassOrDie(env, "android/view/SurfaceControl$DisplayCaptureArgs");
+    gDisplayCaptureArgsClassInfo.displayToken =
+            GetFieldIDOrDie(env, displayCaptureArgsClazz, "mDisplayToken", "Landroid/os/IBinder;");
+    gDisplayCaptureArgsClassInfo.width =
+            GetFieldIDOrDie(env, displayCaptureArgsClazz, "mWidth", "I");
+    gDisplayCaptureArgsClassInfo.height =
+            GetFieldIDOrDie(env, displayCaptureArgsClazz, "mHeight", "I");
+    gDisplayCaptureArgsClassInfo.useIdentityTransform =
+            GetFieldIDOrDie(env, displayCaptureArgsClazz, "mUseIdentityTransform", "Z");
+    gDisplayCaptureArgsClassInfo.rotation =
+            GetFieldIDOrDie(env, displayCaptureArgsClazz, "mRotation", "I");
+
     return err;
 }