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

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

Merge "Revert "Send ScreenCaptureListener to native screen capture requ...""

parents 5260d2d7 797bdc99
Loading
Loading
Loading
Loading
+3 −9
Original line number Original line Diff line number Diff line
@@ -30,9 +30,8 @@


#include <binder/ProcessState.h>
#include <binder/ProcessState.h>


#include <gui/ISurfaceComposer.h>
#include <gui/SurfaceComposerClient.h>
#include <gui/SurfaceComposerClient.h>
#include <gui/SyncScreenCaptureListener.h>
#include <gui/ISurfaceComposer.h>


#include <ui/DisplayInfo.h>
#include <ui/DisplayInfo.h>
#include <ui/GraphicTypes.h>
#include <ui/GraphicTypes.h>
@@ -182,18 +181,13 @@ int main(int argc, char** argv)
    ProcessState::self()->setThreadPoolMaxThreadCount(0);
    ProcessState::self()->setThreadPoolMaxThreadCount(0);
    ProcessState::self()->startThreadPool();
    ProcessState::self()->startThreadPool();


    sp<SyncScreenCaptureListener> captureListener = new SyncScreenCaptureListener();
    ScreenCaptureResults captureResults;
    status_t result = ScreenshotClient::captureDisplay(displayId->value, captureListener);
    status_t result = ScreenshotClient::captureDisplay(displayId->value, captureResults);
    if (result != NO_ERROR) {
    if (result != NO_ERROR) {
        close(fd);
        close(fd);
        return 1;
        return 1;
    }
    }


    ScreenCaptureResults captureResults = captureListener->waitForResults();
    if (captureResults.result != NO_ERROR) {
        close(fd);
        return 1;
    }
    ui::Dataspace dataspace = captureResults.capturedDataspace;
    ui::Dataspace dataspace = captureResults.capturedDataspace;
    sp<GraphicBuffer> buffer = captureResults.buffer;
    sp<GraphicBuffer> buffer = captureResults.buffer;


+9 −87
Original line number Original line Diff line number Diff line
@@ -65,9 +65,6 @@ import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.ArrayList;
import java.util.Objects;
import java.util.Objects;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;


/**
/**
 * Handle to an on-screen Surface managed by the system compositor. The SurfaceControl is
 * Handle to an on-screen Surface managed by the system compositor. The SurfaceControl is
@@ -90,10 +87,10 @@ public final class SurfaceControl implements Parcelable {
    private static native void nativeWriteToParcel(long nativeObject, Parcel out);
    private static native void nativeWriteToParcel(long nativeObject, Parcel out);
    private static native void nativeRelease(long nativeObject);
    private static native void nativeRelease(long nativeObject);
    private static native void nativeDisconnect(long nativeObject);
    private static native void nativeDisconnect(long nativeObject);
    private static native int nativeCaptureDisplay(DisplayCaptureArgs captureArgs,
    private static native ScreenshotHardwareBuffer nativeCaptureDisplay(
            ScreenCaptureListener captureListener);
            DisplayCaptureArgs captureArgs);
    private static native int nativeCaptureLayers(LayerCaptureArgs captureArgs,
    private static native ScreenshotHardwareBuffer nativeCaptureLayers(
            ScreenCaptureListener captureListener);
            LayerCaptureArgs captureArgs);
    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();
@@ -498,8 +495,6 @@ public final class SurfaceControl implements Parcelable {
    private static final int INTERNAL_DATASPACE_DISPLAY_P3 = 143261696;
    private static final int INTERNAL_DATASPACE_DISPLAY_P3 = 143261696;
    private static final int INTERNAL_DATASPACE_SCRGB = 411107328;
    private static final int INTERNAL_DATASPACE_SCRGB = 411107328;


    private static final int SCREENSHOT_WAIT_TIME_S = 1;

    private void assignNativeObject(long nativeObject, String callsite) {
    private void assignNativeObject(long nativeObject, String callsite) {
        if (mNativeObject != 0) {
        if (mNativeObject != 0) {
            release();
            release();
@@ -617,13 +612,6 @@ public final class SurfaceControl implements Parcelable {
        }
        }
    }
    }


    /**
     * @hide
     */
    public abstract static class ScreenCaptureListener {
        abstract void onScreenCaptureComplete(ScreenshotHardwareBuffer hardwareBuffer);
    }

    /**
    /**
     * A common arguments class used for various screenshot requests. This contains arguments that
     * A common arguments class used for various screenshot requests. This contains arguments that
     * are shared between {@link DisplayCaptureArgs} and {@link LayerCaptureArgs}
     * are shared between {@link DisplayCaptureArgs} and {@link LayerCaptureArgs}
@@ -699,7 +687,7 @@ public final class SurfaceControl implements Parcelable {
    /**
    /**
     * The arguments class used to make display capture requests.
     * The arguments class used to make display capture requests.
     *
     *
     * @see #nativeCaptureDisplay(DisplayCaptureArgs, ScreenCaptureListener)
     * @see #nativeCaptureDisplay(DisplayCaptureArgs)
     * @hide
     * @hide
     */
     */
    public static class DisplayCaptureArgs extends CaptureArgs {
    public static class DisplayCaptureArgs extends CaptureArgs {
@@ -2239,16 +2227,6 @@ public final class SurfaceControl implements Parcelable {
        return getPhysicalDisplayToken(physicalDisplayIds[0]);
        return getPhysicalDisplayToken(physicalDisplayIds[0]);
    }
    }


    /**
     * @param captureArgs Arguments about how to take the screenshot
     * @param captureListener A listener to receive the screenshot callback
     * @hide
     */
    public static int captureDisplay(@NonNull DisplayCaptureArgs captureArgs,
            @NonNull ScreenCaptureListener captureListener) {
        return nativeCaptureDisplay(captureArgs, captureListener);
    }

    /**
    /**
     * Captures all the surfaces in a display and returns a {@link ScreenshotHardwareBuffer} with
     * Captures all the surfaces in a display and returns a {@link ScreenshotHardwareBuffer} with
     * the content.
     * the content.
@@ -2256,30 +2234,7 @@ public final class SurfaceControl implements Parcelable {
     * @hide
     * @hide
     */
     */
    public static ScreenshotHardwareBuffer captureDisplay(DisplayCaptureArgs captureArgs) {
    public static ScreenshotHardwareBuffer captureDisplay(DisplayCaptureArgs captureArgs) {
        final AtomicReference<ScreenshotHardwareBuffer> outHardwareBuffer =
        return nativeCaptureDisplay(captureArgs);
                new AtomicReference<>(null);

        final CountDownLatch countDownLatch = new CountDownLatch(1);
        ScreenCaptureListener screenCaptureListener = new ScreenCaptureListener() {
            @Override
            void onScreenCaptureComplete(ScreenshotHardwareBuffer hardwareBuffer) {
                outHardwareBuffer.set(hardwareBuffer);
                countDownLatch.countDown();
            }
        };

        int status = captureDisplay(captureArgs, screenCaptureListener);
        if (status != 0) {
            return null;
        }

        try {
            countDownLatch.await(SCREENSHOT_WAIT_TIME_S, TimeUnit.SECONDS);
        } catch (Exception e) {
            Log.e(TAG, "Failed to wait for captureDisplay result", e);
        }

        return outHardwareBuffer.get();
    }
    }


    /**
    /**
@@ -2324,37 +2279,14 @@ public final class SurfaceControl implements Parcelable {
                .setPixelFormat(format)
                .setPixelFormat(format)
                .build();
                .build();


        return captureLayers(captureArgs);
        return nativeCaptureLayers(captureArgs);
    }
    }


    /**
    /**
     * @hide
     * @hide
     */
     */
    public static ScreenshotHardwareBuffer captureLayers(LayerCaptureArgs captureArgs) {
    public static ScreenshotHardwareBuffer captureLayers(LayerCaptureArgs captureArgs) {
        final AtomicReference<ScreenshotHardwareBuffer> outHardwareBuffer =
        return nativeCaptureLayers(captureArgs);
                new AtomicReference<>(null);

        final CountDownLatch countDownLatch = new CountDownLatch(1);
        ScreenCaptureListener screenCaptureListener = new ScreenCaptureListener() {
            @Override
            void onScreenCaptureComplete(ScreenshotHardwareBuffer hardwareBuffer) {
                outHardwareBuffer.set(hardwareBuffer);
                countDownLatch.countDown();
            }
        };

        int status = captureLayers(captureArgs, screenCaptureListener);
        if (status != 0) {
            return null;
        }

        try {
            countDownLatch.await(SCREENSHOT_WAIT_TIME_S, TimeUnit.SECONDS);
        } catch (Exception e) {
            Log.e(TAG, "Failed to wait for captureLayers result", e);
        }

        return outHardwareBuffer.get();
    }
    }


    /**
    /**
@@ -2371,17 +2303,7 @@ public final class SurfaceControl implements Parcelable {
                .setExcludeLayers(exclude)
                .setExcludeLayers(exclude)
                .build();
                .build();


        return captureLayers(captureArgs);
        return nativeCaptureLayers(captureArgs);
    }

    /**
     * @param captureArgs Arguments about how to take the screenshot
     * @param captureListener A listener to receive the screenshot callback
     * @hide
     */
    public static int captureLayers(@NonNull LayerCaptureArgs captureArgs,
            @NonNull ScreenCaptureListener captureListener) {
        return nativeCaptureLayers(captureArgs, captureListener);
    }
    }


    /**
    /**
+34 −76
Original line number Original line Diff line number Diff line
@@ -30,7 +30,6 @@
#include <android_runtime/android_hardware_HardwareBuffer.h>
#include <android_runtime/android_hardware_HardwareBuffer.h>
#include <android_runtime/android_view_Surface.h>
#include <android_runtime/android_view_Surface.h>
#include <android_runtime/android_view_SurfaceSession.h>
#include <android_runtime/android_view_SurfaceSession.h>
#include <gui/IScreenCaptureListener.h>
#include <gui/ISurfaceComposer.h>
#include <gui/ISurfaceComposer.h>
#include <gui/Surface.h>
#include <gui/Surface.h>
#include <gui/SurfaceComposerClient.h>
#include <gui/SurfaceComposerClient.h>
@@ -187,11 +186,6 @@ static struct {
    jmethodID builder;
    jmethodID builder;
} gScreenshotHardwareBufferClassInfo;
} gScreenshotHardwareBufferClassInfo;


static struct {
    jclass clazz;
    jmethodID onScreenCaptureComplete;
} gScreenCaptureListenerClassInfo;

static struct {
static struct {
    jclass clazz;
    jclass clazz;
    jmethodID ctor;
    jmethodID ctor;
@@ -232,54 +226,6 @@ constexpr ui::Dataspace pickDataspaceFromColorMode(const ui::ColorMode colorMode
    }
    }
}
}


class ScreenCaptureListenerWrapper : public BnScreenCaptureListener {
public:
    explicit ScreenCaptureListenerWrapper(JNIEnv* env, jobject jobject) {
        env->GetJavaVM(&mVm);
        screenCaptureListenerObject = env->NewGlobalRef(jobject);
        LOG_ALWAYS_FATAL_IF(!screenCaptureListenerObject, "Failed to make global ref");
    }

    ~ScreenCaptureListenerWrapper() {
        if (screenCaptureListenerObject) {
            getenv()->DeleteGlobalRef(screenCaptureListenerObject);
            screenCaptureListenerObject = nullptr;
        }
    }

    status_t onScreenCaptureComplete(const ScreenCaptureResults& captureResults) {
        JNIEnv* env = getenv();
        if (captureResults.result != NO_ERROR || captureResults.buffer == nullptr) {
            env->CallVoidMethod(screenCaptureListenerObject,
                                gScreenCaptureListenerClassInfo.onScreenCaptureComplete, nullptr);
            return NO_ERROR;
        }
        jobject jhardwareBuffer = android_hardware_HardwareBuffer_createFromAHardwareBuffer(
                env, captureResults.buffer->toAHardwareBuffer());
        const jint namedColorSpace =
                fromDataspaceToNamedColorSpaceValue(captureResults.capturedDataspace);
        jobject screenshotHardwareBuffer =
                env->CallStaticObjectMethod(gScreenshotHardwareBufferClassInfo.clazz,
                                            gScreenshotHardwareBufferClassInfo.builder,
                                            jhardwareBuffer, namedColorSpace,
                                            captureResults.capturedSecureLayers);
        env->CallVoidMethod(screenCaptureListenerObject,
                            gScreenCaptureListenerClassInfo.onScreenCaptureComplete,
                            screenshotHardwareBuffer);
        return NO_ERROR;
    }

private:
    jobject screenCaptureListenerObject;
    JavaVM* mVm;

    JNIEnv* getenv() {
        JNIEnv* env;
        mVm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6);
        return env;
    }
};

// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------


static jlong nativeCreateTransaction(JNIEnv* env, jclass clazz) {
static jlong nativeCreateTransaction(JNIEnv* env, jclass clazz) {
@@ -381,28 +327,36 @@ static DisplayCaptureArgs displayCaptureArgsFromObject(JNIEnv* env,
    return captureArgs;
    return captureArgs;
}
}


static jint nativeCaptureDisplay(JNIEnv* env, jclass clazz, jobject displayCaptureArgsObject,
static jobject nativeCaptureDisplay(JNIEnv* env, jclass clazz, jobject displayCaptureArgsObject) {
                                 jobject screenCaptureListenerObject) {
    const DisplayCaptureArgs captureArgs =
    const DisplayCaptureArgs captureArgs =
            displayCaptureArgsFromObject(env, displayCaptureArgsObject);
            displayCaptureArgsFromObject(env, displayCaptureArgsObject);


    if (captureArgs.displayToken == NULL) {
    if (captureArgs.displayToken == NULL) {
        return BAD_VALUE;
        return NULL;
    }
    }


    sp<IScreenCaptureListener> captureListener =
    ScreenCaptureResults captureResults;
            new ScreenCaptureListenerWrapper(env, screenCaptureListenerObject);
    status_t res = ScreenshotClient::captureDisplay(captureArgs, captureResults);
    return ScreenshotClient::captureDisplay(captureArgs, captureListener);
    if (res != NO_ERROR) {
        return NULL;
    }
    }


static jint nativeCaptureLayers(JNIEnv* env, jclass clazz, jobject layerCaptureArgsObject,
    jobject jhardwareBuffer = android_hardware_HardwareBuffer_createFromAHardwareBuffer(
                                jobject screenCaptureListenerObject) {
            env, captureResults.buffer->toAHardwareBuffer());
    const jint namedColorSpace =
            fromDataspaceToNamedColorSpaceValue(captureResults.capturedDataspace);
    return env->CallStaticObjectMethod(gScreenshotHardwareBufferClassInfo.clazz,
                                       gScreenshotHardwareBufferClassInfo.builder, jhardwareBuffer,
                                       namedColorSpace, captureResults.capturedSecureLayers);
}

static jobject nativeCaptureLayers(JNIEnv* env, jclass clazz, jobject layerCaptureArgsObject) {
    LayerCaptureArgs captureArgs;
    LayerCaptureArgs captureArgs;
    getCaptureArgs(env, layerCaptureArgsObject, captureArgs);
    getCaptureArgs(env, layerCaptureArgsObject, captureArgs);
    SurfaceControl* layer = reinterpret_cast<SurfaceControl*>(
    SurfaceControl* layer = reinterpret_cast<SurfaceControl*>(
            env->GetLongField(layerCaptureArgsObject, gLayerCaptureArgsClassInfo.layer));
            env->GetLongField(layerCaptureArgsObject, gLayerCaptureArgsClassInfo.layer));
    if (layer == nullptr) {
    if (layer == nullptr) {
        return BAD_VALUE;
        return nullptr;
    }
    }


    captureArgs.layerHandle = layer->getHandle();
    captureArgs.layerHandle = layer->getHandle();
@@ -426,9 +380,19 @@ static jint nativeCaptureLayers(JNIEnv* env, jclass clazz, jobject layerCaptureA
        env->ReleaseLongArrayElements(excludeObjectArray, const_cast<jlong*>(objects), JNI_ABORT);
        env->ReleaseLongArrayElements(excludeObjectArray, const_cast<jlong*>(objects), JNI_ABORT);
    }
    }


    sp<IScreenCaptureListener> captureListener =
    ScreenCaptureResults captureResults;
            new ScreenCaptureListenerWrapper(env, screenCaptureListenerObject);
    status_t res = ScreenshotClient::captureLayers(captureArgs, captureResults);
    return ScreenshotClient::captureLayers(captureArgs, captureListener);
    if (res != NO_ERROR) {
        return NULL;
    }

    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, captureResults.capturedSecureLayers);
}
}


static void nativeApplyTransaction(JNIEnv* env, jclass clazz, jlong transactionObj, jboolean sync) {
static void nativeApplyTransaction(JNIEnv* env, jclass clazz, jlong transactionObj, jboolean sync) {
@@ -1557,7 +1521,6 @@ static void nativeSetFocusedWindow(JNIEnv* env, jclass clazz, jlong transactionO


// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------


// clang-format off
static const JNINativeMethod sSurfaceControlMethods[] = {
static const JNINativeMethod sSurfaceControlMethods[] = {
        // clang-format off
        // clang-format off
    {"nativeCreate", "(Landroid/view/SurfaceSession;Ljava/lang/String;IIIIJLandroid/os/Parcel;)J",
    {"nativeCreate", "(Landroid/view/SurfaceSession;Ljava/lang/String;IIIIJLandroid/os/Parcel;)J",
@@ -1701,10 +1664,12 @@ static const JNINativeMethod sSurfaceControlMethods[] = {
    {"nativeSetOverrideScalingMode", "(JJI)V",
    {"nativeSetOverrideScalingMode", "(JJI)V",
            (void*)nativeSetOverrideScalingMode },
            (void*)nativeSetOverrideScalingMode },
    {"nativeCaptureDisplay",
    {"nativeCaptureDisplay",
            "(Landroid/view/SurfaceControl$DisplayCaptureArgs;Landroid/view/SurfaceControl$ScreenCaptureListener;)I",
            "(Landroid/view/SurfaceControl$DisplayCaptureArgs;)"
            "Landroid/view/SurfaceControl$ScreenshotHardwareBuffer;",
            (void*)nativeCaptureDisplay },
            (void*)nativeCaptureDisplay },
    {"nativeCaptureLayers",
    {"nativeCaptureLayers",
            "(Landroid/view/SurfaceControl$LayerCaptureArgs;Landroid/view/SurfaceControl$ScreenCaptureListener;)I",
            "(Landroid/view/SurfaceControl$LayerCaptureArgs;)"
            "Landroid/view/SurfaceControl$ScreenshotHardwareBuffer;",
            (void*)nativeCaptureLayers },
            (void*)nativeCaptureLayers },
    {"nativeSetInputWindowInfo", "(JJLandroid/view/InputWindowHandle;)V",
    {"nativeSetInputWindowInfo", "(JJLandroid/view/InputWindowHandle;)V",
            (void*)nativeSetInputWindowInfo },
            (void*)nativeSetInputWindowInfo },
@@ -1742,7 +1707,6 @@ static const JNINativeMethod sSurfaceControlMethods[] = {
            (void*)nativeSetFocusedWindow},
            (void*)nativeSetFocusedWindow},
        // clang-format on
        // clang-format on
};
};
// clang-format on


int register_android_view_SurfaceControl(JNIEnv* env)
int register_android_view_SurfaceControl(JNIEnv* env)
{
{
@@ -1911,12 +1875,6 @@ int register_android_view_SurfaceControl(JNIEnv* env)
    gLayerCaptureArgsClassInfo.childrenOnly =
    gLayerCaptureArgsClassInfo.childrenOnly =
            GetFieldIDOrDie(env, layerCaptureArgsClazz, "mChildrenOnly", "Z");
            GetFieldIDOrDie(env, layerCaptureArgsClazz, "mChildrenOnly", "Z");


    jclass screenCaptureListenerClazz =
            FindClassOrDie(env, "android/view/SurfaceControl$ScreenCaptureListener");
    gScreenCaptureListenerClassInfo.clazz = MakeGlobalRefOrDie(env, screenCaptureListenerClazz);
    gScreenCaptureListenerClassInfo.onScreenCaptureComplete =
            GetMethodIDOrDie(env, screenCaptureListenerClazz, "onScreenCaptureComplete",
                             "(Landroid/view/SurfaceControl$ScreenshotHardwareBuffer;)V");
    return err;
    return err;
}
}