Loading cmds/screencap/screencap.cpp +9 −3 Original line number Diff line number Diff line Loading @@ -30,8 +30,9 @@ #include <binder/ProcessState.h> #include <gui/SurfaceComposerClient.h> #include <gui/ISurfaceComposer.h> #include <gui/SurfaceComposerClient.h> #include <gui/SyncScreenCaptureListener.h> #include <ui/DisplayInfo.h> #include <ui/GraphicTypes.h> Loading Loading @@ -181,13 +182,18 @@ int main(int argc, char** argv) ProcessState::self()->setThreadPoolMaxThreadCount(0); ProcessState::self()->startThreadPool(); ScreenCaptureResults captureResults; status_t result = ScreenshotClient::captureDisplay(displayId->value, captureResults); sp<SyncScreenCaptureListener> captureListener = new SyncScreenCaptureListener(); status_t result = ScreenshotClient::captureDisplay(displayId->value, captureListener); if (result != NO_ERROR) { close(fd); return 1; } ScreenCaptureResults captureResults = captureListener->waitForResults(); if (captureResults.result != NO_ERROR) { close(fd); return 1; } ui::Dataspace dataspace = captureResults.capturedDataspace; sp<GraphicBuffer> buffer = captureResults.buffer; Loading core/java/android/view/SurfaceControl.java +87 −9 Original line number Diff line number Diff line Loading @@ -65,6 +65,9 @@ import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.ArrayList; 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 Loading @@ -87,10 +90,10 @@ public final class SurfaceControl implements Parcelable { 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 nativeCaptureDisplay( DisplayCaptureArgs captureArgs); private static native ScreenshotHardwareBuffer nativeCaptureLayers( LayerCaptureArgs captureArgs); private static native int nativeCaptureDisplay(DisplayCaptureArgs captureArgs, ScreenCaptureListener captureListener); private static native int nativeCaptureLayers(LayerCaptureArgs captureArgs, ScreenCaptureListener captureListener); private static native long nativeMirrorSurface(long mirrorOfObject); private static native long nativeCreateTransaction(); private static native long nativeGetNativeTransactionFinalizer(); Loading Loading @@ -493,6 +496,8 @@ public final class SurfaceControl implements Parcelable { private static final int INTERNAL_DATASPACE_DISPLAY_P3 = 143261696; private static final int INTERNAL_DATASPACE_SCRGB = 411107328; private static final int SCREENSHOT_WAIT_TIME_S = 1; private void assignNativeObject(long nativeObject, String callsite) { if (mNativeObject != 0) { release(); Loading Loading @@ -610,6 +615,13 @@ 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 * are shared between {@link DisplayCaptureArgs} and {@link LayerCaptureArgs} Loading Loading @@ -685,7 +697,7 @@ public final class SurfaceControl implements Parcelable { /** * The arguments class used to make display capture requests. * * @see #nativeCaptureDisplay(DisplayCaptureArgs) * @see #nativeCaptureDisplay(DisplayCaptureArgs, ScreenCaptureListener) * @hide */ public static class DisplayCaptureArgs extends CaptureArgs { Loading Loading @@ -2225,6 +2237,16 @@ public final class SurfaceControl implements Parcelable { 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 * the content. Loading @@ -2232,7 +2254,30 @@ public final class SurfaceControl implements Parcelable { * @hide */ public static ScreenshotHardwareBuffer captureDisplay(DisplayCaptureArgs captureArgs) { return nativeCaptureDisplay(captureArgs); final AtomicReference<ScreenshotHardwareBuffer> outHardwareBuffer = 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(); } /** Loading Loading @@ -2277,14 +2322,37 @@ public final class SurfaceControl implements Parcelable { .setPixelFormat(format) .build(); return nativeCaptureLayers(captureArgs); return captureLayers(captureArgs); } /** * @hide */ public static ScreenshotHardwareBuffer captureLayers(LayerCaptureArgs captureArgs) { return nativeCaptureLayers(captureArgs); final AtomicReference<ScreenshotHardwareBuffer> outHardwareBuffer = 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(); } /** Loading @@ -2301,7 +2369,17 @@ public final class SurfaceControl implements Parcelable { .setExcludeLayers(exclude) .build(); return nativeCaptureLayers(captureArgs); return captureLayers(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); } /** Loading core/jni/android_view_SurfaceControl.cpp +76 −34 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ #include <android_runtime/android_hardware_HardwareBuffer.h> #include <android_runtime/android_view_Surface.h> #include <android_runtime/android_view_SurfaceSession.h> #include <gui/IScreenCaptureListener.h> #include <gui/ISurfaceComposer.h> #include <gui/Surface.h> #include <gui/SurfaceComposerClient.h> Loading Loading @@ -186,6 +187,11 @@ static struct { jmethodID builder; } gScreenshotHardwareBufferClassInfo; static struct { jclass clazz; jmethodID onScreenCaptureComplete; } gScreenCaptureListenerClassInfo; static struct { jclass clazz; jmethodID ctor; Loading Loading @@ -226,6 +232,54 @@ 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) { Loading Loading @@ -327,36 +381,28 @@ static DisplayCaptureArgs displayCaptureArgsFromObject(JNIEnv* env, return captureArgs; } static jobject nativeCaptureDisplay(JNIEnv* env, jclass clazz, jobject displayCaptureArgsObject) { static jint nativeCaptureDisplay(JNIEnv* env, jclass clazz, jobject displayCaptureArgsObject, jobject screenCaptureListenerObject) { const DisplayCaptureArgs captureArgs = displayCaptureArgsFromObject(env, displayCaptureArgsObject); if (captureArgs.displayToken == NULL) { return NULL; } ScreenCaptureResults captureResults; status_t res = ScreenshotClient::captureDisplay(captureArgs, captureResults); if (res != NO_ERROR) { return NULL; return BAD_VALUE; } 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); sp<IScreenCaptureListener> captureListener = new ScreenCaptureListenerWrapper(env, screenCaptureListenerObject); return ScreenshotClient::captureDisplay(captureArgs, captureListener); } static jobject nativeCaptureLayers(JNIEnv* env, jclass clazz, jobject layerCaptureArgsObject) { static jint nativeCaptureLayers(JNIEnv* env, jclass clazz, jobject layerCaptureArgsObject, jobject screenCaptureListenerObject) { LayerCaptureArgs captureArgs; getCaptureArgs(env, layerCaptureArgsObject, captureArgs); SurfaceControl* layer = reinterpret_cast<SurfaceControl*>( env->GetLongField(layerCaptureArgsObject, gLayerCaptureArgsClassInfo.layer)); if (layer == nullptr) { return nullptr; return BAD_VALUE; } captureArgs.layerHandle = layer->getHandle(); Loading @@ -380,19 +426,9 @@ static jobject nativeCaptureLayers(JNIEnv* env, jclass clazz, jobject layerCaptu env->ReleaseLongArrayElements(excludeObjectArray, const_cast<jlong*>(objects), JNI_ABORT); } ScreenCaptureResults captureResults; status_t res = ScreenshotClient::captureLayers(captureArgs, captureResults); 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); sp<IScreenCaptureListener> captureListener = new ScreenCaptureListenerWrapper(env, screenCaptureListenerObject); return ScreenshotClient::captureLayers(captureArgs, captureListener); } static void nativeApplyTransaction(JNIEnv* env, jclass clazz, jlong transactionObj, jboolean sync) { Loading Loading @@ -1507,6 +1543,7 @@ static jlong nativeGetHandle(JNIEnv* env, jclass clazz, jlong nativeObject) { // ---------------------------------------------------------------------------- // clang-format off static const JNINativeMethod sSurfaceControlMethods[] = { {"nativeCreate", "(Landroid/view/SurfaceSession;Ljava/lang/String;IIIIJLandroid/os/Parcel;)J", (void*)nativeCreate }, Loading Loading @@ -1649,12 +1686,10 @@ static const JNINativeMethod sSurfaceControlMethods[] = { {"nativeSetOverrideScalingMode", "(JJI)V", (void*)nativeSetOverrideScalingMode }, {"nativeCaptureDisplay", "(Landroid/view/SurfaceControl$DisplayCaptureArgs;)" "Landroid/view/SurfaceControl$ScreenshotHardwareBuffer;", "(Landroid/view/SurfaceControl$DisplayCaptureArgs;Landroid/view/SurfaceControl$ScreenCaptureListener;)I", (void*)nativeCaptureDisplay }, {"nativeCaptureLayers", "(Landroid/view/SurfaceControl$LayerCaptureArgs;)" "Landroid/view/SurfaceControl$ScreenshotHardwareBuffer;", "(Landroid/view/SurfaceControl$LayerCaptureArgs;Landroid/view/SurfaceControl$ScreenCaptureListener;)I", (void*)nativeCaptureLayers }, {"nativeSetInputWindowInfo", "(JJLandroid/view/InputWindowHandle;)V", (void*)nativeSetInputWindowInfo }, Loading Loading @@ -1688,6 +1723,7 @@ static const JNINativeMethod sSurfaceControlMethods[] = { (void*)nativeGetHandle }, {"nativeSetFixedTransformHint", "(JJI)V", (void*)nativeSetFixedTransformHint}, }; // clang-format on int register_android_view_SurfaceControl(JNIEnv* env) { Loading Loading @@ -1856,6 +1892,12 @@ int register_android_view_SurfaceControl(JNIEnv* env) gLayerCaptureArgsClassInfo.childrenOnly = 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; } Loading Loading
cmds/screencap/screencap.cpp +9 −3 Original line number Diff line number Diff line Loading @@ -30,8 +30,9 @@ #include <binder/ProcessState.h> #include <gui/SurfaceComposerClient.h> #include <gui/ISurfaceComposer.h> #include <gui/SurfaceComposerClient.h> #include <gui/SyncScreenCaptureListener.h> #include <ui/DisplayInfo.h> #include <ui/GraphicTypes.h> Loading Loading @@ -181,13 +182,18 @@ int main(int argc, char** argv) ProcessState::self()->setThreadPoolMaxThreadCount(0); ProcessState::self()->startThreadPool(); ScreenCaptureResults captureResults; status_t result = ScreenshotClient::captureDisplay(displayId->value, captureResults); sp<SyncScreenCaptureListener> captureListener = new SyncScreenCaptureListener(); status_t result = ScreenshotClient::captureDisplay(displayId->value, captureListener); if (result != NO_ERROR) { close(fd); return 1; } ScreenCaptureResults captureResults = captureListener->waitForResults(); if (captureResults.result != NO_ERROR) { close(fd); return 1; } ui::Dataspace dataspace = captureResults.capturedDataspace; sp<GraphicBuffer> buffer = captureResults.buffer; Loading
core/java/android/view/SurfaceControl.java +87 −9 Original line number Diff line number Diff line Loading @@ -65,6 +65,9 @@ import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.ArrayList; 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 Loading @@ -87,10 +90,10 @@ public final class SurfaceControl implements Parcelable { 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 nativeCaptureDisplay( DisplayCaptureArgs captureArgs); private static native ScreenshotHardwareBuffer nativeCaptureLayers( LayerCaptureArgs captureArgs); private static native int nativeCaptureDisplay(DisplayCaptureArgs captureArgs, ScreenCaptureListener captureListener); private static native int nativeCaptureLayers(LayerCaptureArgs captureArgs, ScreenCaptureListener captureListener); private static native long nativeMirrorSurface(long mirrorOfObject); private static native long nativeCreateTransaction(); private static native long nativeGetNativeTransactionFinalizer(); Loading Loading @@ -493,6 +496,8 @@ public final class SurfaceControl implements Parcelable { private static final int INTERNAL_DATASPACE_DISPLAY_P3 = 143261696; private static final int INTERNAL_DATASPACE_SCRGB = 411107328; private static final int SCREENSHOT_WAIT_TIME_S = 1; private void assignNativeObject(long nativeObject, String callsite) { if (mNativeObject != 0) { release(); Loading Loading @@ -610,6 +615,13 @@ 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 * are shared between {@link DisplayCaptureArgs} and {@link LayerCaptureArgs} Loading Loading @@ -685,7 +697,7 @@ public final class SurfaceControl implements Parcelable { /** * The arguments class used to make display capture requests. * * @see #nativeCaptureDisplay(DisplayCaptureArgs) * @see #nativeCaptureDisplay(DisplayCaptureArgs, ScreenCaptureListener) * @hide */ public static class DisplayCaptureArgs extends CaptureArgs { Loading Loading @@ -2225,6 +2237,16 @@ public final class SurfaceControl implements Parcelable { 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 * the content. Loading @@ -2232,7 +2254,30 @@ public final class SurfaceControl implements Parcelable { * @hide */ public static ScreenshotHardwareBuffer captureDisplay(DisplayCaptureArgs captureArgs) { return nativeCaptureDisplay(captureArgs); final AtomicReference<ScreenshotHardwareBuffer> outHardwareBuffer = 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(); } /** Loading Loading @@ -2277,14 +2322,37 @@ public final class SurfaceControl implements Parcelable { .setPixelFormat(format) .build(); return nativeCaptureLayers(captureArgs); return captureLayers(captureArgs); } /** * @hide */ public static ScreenshotHardwareBuffer captureLayers(LayerCaptureArgs captureArgs) { return nativeCaptureLayers(captureArgs); final AtomicReference<ScreenshotHardwareBuffer> outHardwareBuffer = 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(); } /** Loading @@ -2301,7 +2369,17 @@ public final class SurfaceControl implements Parcelable { .setExcludeLayers(exclude) .build(); return nativeCaptureLayers(captureArgs); return captureLayers(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); } /** Loading
core/jni/android_view_SurfaceControl.cpp +76 −34 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ #include <android_runtime/android_hardware_HardwareBuffer.h> #include <android_runtime/android_view_Surface.h> #include <android_runtime/android_view_SurfaceSession.h> #include <gui/IScreenCaptureListener.h> #include <gui/ISurfaceComposer.h> #include <gui/Surface.h> #include <gui/SurfaceComposerClient.h> Loading Loading @@ -186,6 +187,11 @@ static struct { jmethodID builder; } gScreenshotHardwareBufferClassInfo; static struct { jclass clazz; jmethodID onScreenCaptureComplete; } gScreenCaptureListenerClassInfo; static struct { jclass clazz; jmethodID ctor; Loading Loading @@ -226,6 +232,54 @@ 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) { Loading Loading @@ -327,36 +381,28 @@ static DisplayCaptureArgs displayCaptureArgsFromObject(JNIEnv* env, return captureArgs; } static jobject nativeCaptureDisplay(JNIEnv* env, jclass clazz, jobject displayCaptureArgsObject) { static jint nativeCaptureDisplay(JNIEnv* env, jclass clazz, jobject displayCaptureArgsObject, jobject screenCaptureListenerObject) { const DisplayCaptureArgs captureArgs = displayCaptureArgsFromObject(env, displayCaptureArgsObject); if (captureArgs.displayToken == NULL) { return NULL; } ScreenCaptureResults captureResults; status_t res = ScreenshotClient::captureDisplay(captureArgs, captureResults); if (res != NO_ERROR) { return NULL; return BAD_VALUE; } 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); sp<IScreenCaptureListener> captureListener = new ScreenCaptureListenerWrapper(env, screenCaptureListenerObject); return ScreenshotClient::captureDisplay(captureArgs, captureListener); } static jobject nativeCaptureLayers(JNIEnv* env, jclass clazz, jobject layerCaptureArgsObject) { static jint nativeCaptureLayers(JNIEnv* env, jclass clazz, jobject layerCaptureArgsObject, jobject screenCaptureListenerObject) { LayerCaptureArgs captureArgs; getCaptureArgs(env, layerCaptureArgsObject, captureArgs); SurfaceControl* layer = reinterpret_cast<SurfaceControl*>( env->GetLongField(layerCaptureArgsObject, gLayerCaptureArgsClassInfo.layer)); if (layer == nullptr) { return nullptr; return BAD_VALUE; } captureArgs.layerHandle = layer->getHandle(); Loading @@ -380,19 +426,9 @@ static jobject nativeCaptureLayers(JNIEnv* env, jclass clazz, jobject layerCaptu env->ReleaseLongArrayElements(excludeObjectArray, const_cast<jlong*>(objects), JNI_ABORT); } ScreenCaptureResults captureResults; status_t res = ScreenshotClient::captureLayers(captureArgs, captureResults); 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); sp<IScreenCaptureListener> captureListener = new ScreenCaptureListenerWrapper(env, screenCaptureListenerObject); return ScreenshotClient::captureLayers(captureArgs, captureListener); } static void nativeApplyTransaction(JNIEnv* env, jclass clazz, jlong transactionObj, jboolean sync) { Loading Loading @@ -1507,6 +1543,7 @@ static jlong nativeGetHandle(JNIEnv* env, jclass clazz, jlong nativeObject) { // ---------------------------------------------------------------------------- // clang-format off static const JNINativeMethod sSurfaceControlMethods[] = { {"nativeCreate", "(Landroid/view/SurfaceSession;Ljava/lang/String;IIIIJLandroid/os/Parcel;)J", (void*)nativeCreate }, Loading Loading @@ -1649,12 +1686,10 @@ static const JNINativeMethod sSurfaceControlMethods[] = { {"nativeSetOverrideScalingMode", "(JJI)V", (void*)nativeSetOverrideScalingMode }, {"nativeCaptureDisplay", "(Landroid/view/SurfaceControl$DisplayCaptureArgs;)" "Landroid/view/SurfaceControl$ScreenshotHardwareBuffer;", "(Landroid/view/SurfaceControl$DisplayCaptureArgs;Landroid/view/SurfaceControl$ScreenCaptureListener;)I", (void*)nativeCaptureDisplay }, {"nativeCaptureLayers", "(Landroid/view/SurfaceControl$LayerCaptureArgs;)" "Landroid/view/SurfaceControl$ScreenshotHardwareBuffer;", "(Landroid/view/SurfaceControl$LayerCaptureArgs;Landroid/view/SurfaceControl$ScreenCaptureListener;)I", (void*)nativeCaptureLayers }, {"nativeSetInputWindowInfo", "(JJLandroid/view/InputWindowHandle;)V", (void*)nativeSetInputWindowInfo }, Loading Loading @@ -1688,6 +1723,7 @@ static const JNINativeMethod sSurfaceControlMethods[] = { (void*)nativeGetHandle }, {"nativeSetFixedTransformHint", "(JJI)V", (void*)nativeSetFixedTransformHint}, }; // clang-format on int register_android_view_SurfaceControl(JNIEnv* env) { Loading Loading @@ -1856,6 +1892,12 @@ int register_android_view_SurfaceControl(JNIEnv* env) gLayerCaptureArgsClassInfo.childrenOnly = 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; } Loading