Loading cmds/screencap/screencap.cpp +3 −9 Original line number Original line Diff line number Diff line Loading @@ -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> Loading Loading @@ -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; Loading core/java/android/view/SurfaceControl.java +9 −87 Original line number Original line Diff line number Diff line Loading @@ -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 Loading @@ -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(); Loading Loading @@ -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(); Loading Loading @@ -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} Loading Loading @@ -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 { Loading Loading @@ -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. Loading @@ -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(); } } /** /** Loading Loading @@ -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(); } } /** /** Loading @@ -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); } } /** /** Loading core/jni/android_view_SurfaceControl.cpp +34 −76 Original line number Original line Diff line number Diff line Loading @@ -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> Loading Loading @@ -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; Loading Loading @@ -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) { Loading Loading @@ -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(); Loading @@ -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) { Loading Loading @@ -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", Loading Loading @@ -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 }, Loading Loading @@ -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) { { Loading Loading @@ -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; } } Loading Loading
cmds/screencap/screencap.cpp +3 −9 Original line number Original line Diff line number Diff line Loading @@ -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> Loading Loading @@ -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; Loading
core/java/android/view/SurfaceControl.java +9 −87 Original line number Original line Diff line number Diff line Loading @@ -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 Loading @@ -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(); Loading Loading @@ -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(); Loading Loading @@ -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} Loading Loading @@ -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 { Loading Loading @@ -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. Loading @@ -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(); } } /** /** Loading Loading @@ -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(); } } /** /** Loading @@ -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); } } /** /** Loading
core/jni/android_view_SurfaceControl.cpp +34 −76 Original line number Original line Diff line number Diff line Loading @@ -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> Loading Loading @@ -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; Loading Loading @@ -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) { Loading Loading @@ -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(); Loading @@ -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) { Loading Loading @@ -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", Loading Loading @@ -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 }, Loading Loading @@ -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) { { Loading Loading @@ -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; } } Loading