Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4c365410 authored by Chavi Weingarten's avatar Chavi Weingarten Committed by Android (Google) Code Review
Browse files

Merge "Updated layer capture in JNI to match updated function"

parents e14b11be 45acebc8
Loading
Loading
Loading
Loading
+29 −19
Original line number Original line Diff line number Diff line
@@ -91,9 +91,8 @@ public final class SurfaceControl implements Parcelable {
    private static native void nativeDisconnect(long nativeObject);
    private static native void nativeDisconnect(long nativeObject);
    private static native ScreenshotHardwareBuffer nativeCaptureDisplay(
    private static native ScreenshotHardwareBuffer nativeCaptureDisplay(
            DisplayCaptureArgs captureArgs);
            DisplayCaptureArgs captureArgs);
    private static native ScreenshotHardwareBuffer nativeCaptureLayers(IBinder displayToken,
    private static native ScreenshotHardwareBuffer nativeCaptureLayers(
            long layerObject, Rect sourceCrop, float frameScale, long[] excludeLayerObjects,
            LayerCaptureArgs captureArgs);
            int format);
    private static native long nativeMirrorSurface(long mirrorOfObject);
    private static native long nativeMirrorSurface(long mirrorOfObject);
    private static native long nativeCreateTransaction();
    private static native long nativeCreateTransaction();
    private static native long nativeGetNativeTransactionFinalizer();
    private static native long nativeGetNativeTransactionFinalizer();
@@ -570,7 +569,8 @@ public final class SurfaceControl implements Parcelable {
        * Create ScreenshotHardwareBuffer from an existing HardwareBuffer object.
        * Create ScreenshotHardwareBuffer from an existing HardwareBuffer object.
        * @param hardwareBuffer The existing HardwareBuffer object
        * @param hardwareBuffer The existing HardwareBuffer object
        * @param namedColorSpace Integer value of a named color space {@link ColorSpace.Named}
        * @param namedColorSpace Integer value of a named color space {@link ColorSpace.Named}
        * @param containsSecureLayer Indicates whether this graphic buffer contains captured contents
        * @param containsSecureLayers Indicates whether this graphic buffer contains captured
        *                             contents
        *        of secure layers, in which case the screenshot should not be persisted.
        *        of secure layers, in which case the screenshot should not be persisted.
        */
        */
        private static ScreenshotHardwareBuffer createFromNative(HardwareBuffer hardwareBuffer,
        private static ScreenshotHardwareBuffer createFromNative(HardwareBuffer hardwareBuffer,
@@ -766,7 +766,7 @@ public final class SurfaceControl implements Parcelable {
    /**
    /**
     * The arguments class used to make layer capture requests.
     * The arguments class used to make layer capture requests.
     *
     *
     * @see #nativeCaptureLayers(IBinder, long, Rect, float, long[], int)
     * @see #nativeCaptureLayers(LayerCaptureArgs)
     * @hide
     * @hide
     */
     */
    public static class LayerCaptureArgs extends CaptureArgs {
    public static class LayerCaptureArgs extends CaptureArgs {
@@ -778,10 +778,14 @@ public final class SurfaceControl implements Parcelable {
            super(builder);
            super(builder);
            mChildrenOnly = builder.mChildrenOnly;
            mChildrenOnly = builder.mChildrenOnly;
            mNativeLayer = builder.mLayer.mNativeObject;
            mNativeLayer = builder.mLayer.mNativeObject;
            if (builder.mExcludeLayers != null) {
                mNativeExcludeLayers = new long[builder.mExcludeLayers.length];
                mNativeExcludeLayers = new long[builder.mExcludeLayers.length];
                for (int i = 0; i < builder.mExcludeLayers.length; i++) {
                for (int i = 0; i < builder.mExcludeLayers.length; i++) {
                    mNativeExcludeLayers[i] = builder.mExcludeLayers[i].mNativeObject;
                    mNativeExcludeLayers[i] = builder.mExcludeLayers[i].mNativeObject;
                }
                }
            } else {
                mNativeExcludeLayers = null;
            }
        }
        }


        /**
        /**
@@ -2376,24 +2380,30 @@ public final class SurfaceControl implements Parcelable {
     */
     */
    public static ScreenshotHardwareBuffer captureLayers(SurfaceControl layer, Rect sourceCrop,
    public static ScreenshotHardwareBuffer captureLayers(SurfaceControl layer, Rect sourceCrop,
            float frameScale, int format) {
            float frameScale, int format) {
        final IBinder displayToken = SurfaceControl.getInternalDisplayToken();
        LayerCaptureArgs captureArgs = new LayerCaptureArgs.Builder(layer)
        return nativeCaptureLayers(displayToken, layer.mNativeObject, sourceCrop, frameScale, null,
                .setSourceCrop(sourceCrop)
                format);
                .setFrameScale(frameScale)
                .setPixelFormat(format)
                .build();

        return nativeCaptureLayers(captureArgs);
    }
    }


    /**
    /**
     * Like {@link captureLayers} but with an array of layer handles to exclude.
     * Like {@link #captureLayers(SurfaceControl, Rect, float, int)} but with an array of layer
     * handles to exclude.
     * @hide
     * @hide
     */
     */
    public static ScreenshotHardwareBuffer captureLayersExcluding(SurfaceControl layer,
    public static ScreenshotHardwareBuffer captureLayersExcluding(SurfaceControl layer,
            Rect sourceCrop, float frameScale, int format, SurfaceControl[] exclude) {
            Rect sourceCrop, float frameScale, int format, SurfaceControl[] exclude) {
        final IBinder displayToken = SurfaceControl.getInternalDisplayToken();
        LayerCaptureArgs captureArgs = new LayerCaptureArgs.Builder(layer)
        long[] nativeExcludeObjects = new long[exclude.length];
                .setSourceCrop(sourceCrop)
        for (int i = 0; i < exclude.length; i++) {
                .setFrameScale(frameScale)
            nativeExcludeObjects[i] = exclude[i].mNativeObject;
                .setPixelFormat(format)
        }
                .setExcludeLayers(exclude)
        return nativeCaptureLayers(displayToken, layer.mNativeObject, sourceCrop, frameScale,
                .build();
                nativeExcludeObjects, PixelFormat.RGBA_8888);

        return nativeCaptureLayers(captureArgs);
    }
    }


    /**
    /**
+37 −33
Original line number Original line Diff line number Diff line
@@ -119,6 +119,12 @@ static struct {
    jfieldID rotation;
    jfieldID rotation;
} gDisplayCaptureArgsClassInfo;
} gDisplayCaptureArgsClassInfo;


static struct {
    jfieldID layer;
    jfieldID excludeLayers;
    jfieldID childrenOnly;
} gLayerCaptureArgsClassInfo;

// Implements SkMallocPixelRef::ReleaseProc, to delete the screenshot on unref.
// Implements SkMallocPixelRef::ReleaseProc, to delete the screenshot on unref.
void DeleteScreenshot(void* addr, void* context) {
void DeleteScreenshot(void* addr, void* context) {
    delete ((ScreenshotClient*) context);
    delete ((ScreenshotClient*) context);
@@ -347,24 +353,23 @@ static jobject nativeCaptureDisplay(JNIEnv* env, jclass clazz, jobject displayCa
                                       namedColorSpace, captureResults.capturedSecureLayers);
                                       namedColorSpace, captureResults.capturedSecureLayers);
}
}


static jobject nativeCaptureLayers(JNIEnv* env, jclass clazz, jobject displayTokenObj,
static jobject nativeCaptureLayers(JNIEnv* env, jclass clazz, jobject layerCaptureArgsObject) {
        jlong layerObject, jobject sourceCropObj, jfloat frameScale,
    LayerCaptureArgs captureArgs;
        jlongArray excludeObjectArray, jint format) {
    getCaptureArgs(env, layerCaptureArgsObject, captureArgs);

    SurfaceControl* layer = reinterpret_cast<SurfaceControl*>(
    auto layer = reinterpret_cast<SurfaceControl *>(layerObject);
            env->GetLongField(layerCaptureArgsObject, gLayerCaptureArgsClassInfo.layer));
    if (layer == NULL) {
    if (layer == nullptr) {
        return NULL;
        return nullptr;
    }

    Rect sourceCrop;
    if (sourceCropObj != NULL) {
        sourceCrop = rectFromObj(env, sourceCropObj);
    }
    }


    std::unordered_set<sp<IBinder>,ISurfaceComposer::SpHash<IBinder>> excludeHandles;
    captureArgs.layerHandle = layer->getHandle();
    captureArgs.childrenOnly =
            env->GetBooleanField(layerCaptureArgsObject, gLayerCaptureArgsClassInfo.childrenOnly);
    jlongArray excludeObjectArray = reinterpret_cast<jlongArray>(
            env->GetObjectField(layerCaptureArgsObject, gLayerCaptureArgsClassInfo.excludeLayers));
    if (excludeObjectArray != NULL) {
    if (excludeObjectArray != NULL) {
        const jsize len = env->GetArrayLength(excludeObjectArray);
        const jsize len = env->GetArrayLength(excludeObjectArray);
        excludeHandles.reserve(len);
        captureArgs.excludeHandles.reserve(len);


        const jlong* objects = env->GetLongArrayElements(excludeObjectArray, nullptr);
        const jlong* objects = env->GetLongArrayElements(excludeObjectArray, nullptr);
        for (jsize i = 0; i < len; i++) {
        for (jsize i = 0; i < len; i++) {
@@ -373,33 +378,24 @@ static jobject nativeCaptureLayers(JNIEnv* env, jclass clazz, jobject displayTok
                jniThrowNullPointerException(env, "Exclude layer is null");
                jniThrowNullPointerException(env, "Exclude layer is null");
                return NULL;
                return NULL;
            }
            }
            excludeHandles.emplace(excludeObject->getHandle());
            captureArgs.excludeHandles.emplace(excludeObject->getHandle());
        }
        }
        env->ReleaseLongArrayElements(excludeObjectArray, const_cast<jlong*>(objects), JNI_ABORT);
        env->ReleaseLongArrayElements(excludeObjectArray, const_cast<jlong*>(objects), JNI_ABORT);
    }
    }


    sp<GraphicBuffer> buffer;
    ScreenCaptureResults captureResults;
    ui::Dataspace dataspace = ui::Dataspace::V0_SRGB;
    status_t res = ScreenshotClient::captureLayers(captureArgs, captureResults);
    sp<IBinder> displayToken = ibinderForJavaObject(env, displayTokenObj);
    if (displayToken != nullptr) {
        const ui::ColorMode colorMode = SurfaceComposerClient::getActiveColorMode(displayToken);
        dataspace = pickDataspaceFromColorMode(colorMode);
    }
    status_t res = ScreenshotClient::captureChildLayers(layer->getHandle(), dataspace,
                                                        static_cast<ui::PixelFormat>(format),
                                                        sourceCrop, excludeHandles, frameScale,
                                                        &buffer);
    if (res != NO_ERROR) {
    if (res != NO_ERROR) {
        return NULL;
        return NULL;
    }
    }


    jobject jhardwareBuffer =
    jobject jhardwareBuffer = android_hardware_HardwareBuffer_createFromAHardwareBuffer(
            android_hardware_HardwareBuffer_createFromAHardwareBuffer(env,
            env, captureResults.buffer->toAHardwareBuffer());
                                                                      buffer->toAHardwareBuffer());
    const jint namedColorSpace =
    const jint namedColorSpace = fromDataspaceToNamedColorSpaceValue(dataspace);
            fromDataspaceToNamedColorSpaceValue(captureResults.capturedDataspace);
    return env->CallStaticObjectMethod(gScreenshotHardwareBufferClassInfo.clazz,
    return env->CallStaticObjectMethod(gScreenshotHardwareBufferClassInfo.clazz,
                                       gScreenshotHardwareBufferClassInfo.builder, jhardwareBuffer,
                                       gScreenshotHardwareBufferClassInfo.builder, jhardwareBuffer,
                                       namedColorSpace, false /* capturedSecureLayers */);
                                       namedColorSpace, captureResults.capturedSecureLayers);
}
}


static void nativeApplyTransaction(JNIEnv* env, jclass clazz, jlong transactionObj, jboolean sync) {
static void nativeApplyTransaction(JNIEnv* env, jclass clazz, jlong transactionObj, jboolean sync) {
@@ -1659,8 +1655,7 @@ static const JNINativeMethod sSurfaceControlMethods[] = {
            "Landroid/view/SurfaceControl$ScreenshotHardwareBuffer;",
            "Landroid/view/SurfaceControl$ScreenshotHardwareBuffer;",
            (void*)nativeCaptureDisplay },
            (void*)nativeCaptureDisplay },
    {"nativeCaptureLayers",
    {"nativeCaptureLayers",
            "(Landroid/os/IBinder;JLandroid/graphics/Rect;"
            "(Landroid/view/SurfaceControl$LayerCaptureArgs;)"
            "F[JI)"
            "Landroid/view/SurfaceControl$ScreenshotHardwareBuffer;",
            "Landroid/view/SurfaceControl$ScreenshotHardwareBuffer;",
            (void*)nativeCaptureLayers },
            (void*)nativeCaptureLayers },
    {"nativeSetInputWindowInfo", "(JJLandroid/view/InputWindowHandle;)V",
    {"nativeSetInputWindowInfo", "(JJLandroid/view/InputWindowHandle;)V",
@@ -1856,6 +1851,15 @@ int register_android_view_SurfaceControl(JNIEnv* env)
    gDisplayCaptureArgsClassInfo.rotation =
    gDisplayCaptureArgsClassInfo.rotation =
            GetFieldIDOrDie(env, displayCaptureArgsClazz, "mRotation", "I");
            GetFieldIDOrDie(env, displayCaptureArgsClazz, "mRotation", "I");


    jclass layerCaptureArgsClazz =
            FindClassOrDie(env, "android/view/SurfaceControl$LayerCaptureArgs");
    gLayerCaptureArgsClassInfo.layer =
            GetFieldIDOrDie(env, layerCaptureArgsClazz, "mNativeLayer", "J");
    gLayerCaptureArgsClassInfo.excludeLayers =
            GetFieldIDOrDie(env, layerCaptureArgsClazz, "mNativeExcludeLayers", "[J");
    gLayerCaptureArgsClassInfo.childrenOnly =
            GetFieldIDOrDie(env, layerCaptureArgsClazz, "mChildrenOnly", "Z");

    return err;
    return err;
}
}