Loading core/java/android/view/SurfaceControl.java +29 −19 Original line number Diff line number Diff line Loading @@ -91,9 +91,8 @@ public final class SurfaceControl implements Parcelable { private static native void nativeDisconnect(long nativeObject); private static native ScreenshotHardwareBuffer nativeCaptureDisplay( DisplayCaptureArgs captureArgs); private static native ScreenshotHardwareBuffer nativeCaptureLayers(IBinder displayToken, long layerObject, Rect sourceCrop, float frameScale, long[] excludeLayerObjects, int format); private static native ScreenshotHardwareBuffer nativeCaptureLayers( LayerCaptureArgs captureArgs); private static native long nativeMirrorSurface(long mirrorOfObject); private static native long nativeCreateTransaction(); private static native long nativeGetNativeTransactionFinalizer(); Loading Loading @@ -570,7 +569,8 @@ public final class SurfaceControl implements Parcelable { * Create ScreenshotHardwareBuffer from an existing HardwareBuffer object. * @param hardwareBuffer The existing HardwareBuffer object * @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. */ private static ScreenshotHardwareBuffer createFromNative(HardwareBuffer hardwareBuffer, Loading Loading @@ -766,7 +766,7 @@ public final class SurfaceControl implements Parcelable { /** * The arguments class used to make layer capture requests. * * @see #nativeCaptureLayers(IBinder, long, Rect, float, long[], int) * @see #nativeCaptureLayers(LayerCaptureArgs) * @hide */ public static class LayerCaptureArgs extends CaptureArgs { Loading @@ -778,10 +778,14 @@ public final class SurfaceControl implements Parcelable { super(builder); mChildrenOnly = builder.mChildrenOnly; mNativeLayer = builder.mLayer.mNativeObject; if (builder.mExcludeLayers != null) { mNativeExcludeLayers = new long[builder.mExcludeLayers.length]; for (int i = 0; i < builder.mExcludeLayers.length; i++) { mNativeExcludeLayers[i] = builder.mExcludeLayers[i].mNativeObject; } } else { mNativeExcludeLayers = null; } } /** Loading Loading @@ -2376,24 +2380,30 @@ public final class SurfaceControl implements Parcelable { */ public static ScreenshotHardwareBuffer captureLayers(SurfaceControl layer, Rect sourceCrop, float frameScale, int format) { final IBinder displayToken = SurfaceControl.getInternalDisplayToken(); return nativeCaptureLayers(displayToken, layer.mNativeObject, sourceCrop, frameScale, null, format); LayerCaptureArgs captureArgs = new LayerCaptureArgs.Builder(layer) .setSourceCrop(sourceCrop) .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 */ public static ScreenshotHardwareBuffer captureLayersExcluding(SurfaceControl layer, Rect sourceCrop, float frameScale, int format, SurfaceControl[] exclude) { final IBinder displayToken = SurfaceControl.getInternalDisplayToken(); long[] nativeExcludeObjects = new long[exclude.length]; for (int i = 0; i < exclude.length; i++) { nativeExcludeObjects[i] = exclude[i].mNativeObject; } return nativeCaptureLayers(displayToken, layer.mNativeObject, sourceCrop, frameScale, nativeExcludeObjects, PixelFormat.RGBA_8888); LayerCaptureArgs captureArgs = new LayerCaptureArgs.Builder(layer) .setSourceCrop(sourceCrop) .setFrameScale(frameScale) .setPixelFormat(format) .setExcludeLayers(exclude) .build(); return nativeCaptureLayers(captureArgs); } /** Loading core/jni/android_view_SurfaceControl.cpp +37 −33 Original line number Diff line number Diff line Loading @@ -119,6 +119,12 @@ static struct { jfieldID rotation; } gDisplayCaptureArgsClassInfo; static struct { jfieldID layer; jfieldID excludeLayers; jfieldID childrenOnly; } gLayerCaptureArgsClassInfo; // Implements SkMallocPixelRef::ReleaseProc, to delete the screenshot on unref. void DeleteScreenshot(void* addr, void* context) { delete ((ScreenshotClient*) context); Loading Loading @@ -347,24 +353,23 @@ static jobject nativeCaptureDisplay(JNIEnv* env, jclass clazz, jobject displayCa namedColorSpace, captureResults.capturedSecureLayers); } static jobject nativeCaptureLayers(JNIEnv* env, jclass clazz, jobject displayTokenObj, jlong layerObject, jobject sourceCropObj, jfloat frameScale, jlongArray excludeObjectArray, jint format) { auto layer = reinterpret_cast<SurfaceControl *>(layerObject); if (layer == NULL) { return NULL; } Rect sourceCrop; if (sourceCropObj != NULL) { sourceCrop = rectFromObj(env, sourceCropObj); static jobject nativeCaptureLayers(JNIEnv* env, jclass clazz, jobject layerCaptureArgsObject) { LayerCaptureArgs captureArgs; getCaptureArgs(env, layerCaptureArgsObject, captureArgs); SurfaceControl* layer = reinterpret_cast<SurfaceControl*>( env->GetLongField(layerCaptureArgsObject, gLayerCaptureArgsClassInfo.layer)); if (layer == nullptr) { return nullptr; } 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) { const jsize len = env->GetArrayLength(excludeObjectArray); excludeHandles.reserve(len); captureArgs.excludeHandles.reserve(len); const jlong* objects = env->GetLongArrayElements(excludeObjectArray, nullptr); for (jsize i = 0; i < len; i++) { Loading @@ -373,33 +378,24 @@ static jobject nativeCaptureLayers(JNIEnv* env, jclass clazz, jobject displayTok jniThrowNullPointerException(env, "Exclude layer is null"); return NULL; } excludeHandles.emplace(excludeObject->getHandle()); captureArgs.excludeHandles.emplace(excludeObject->getHandle()); } env->ReleaseLongArrayElements(excludeObjectArray, const_cast<jlong*>(objects), JNI_ABORT); } sp<GraphicBuffer> buffer; ui::Dataspace dataspace = ui::Dataspace::V0_SRGB; 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); ScreenCaptureResults captureResults; status_t res = ScreenshotClient::captureLayers(captureArgs, captureResults); if (res != NO_ERROR) { return NULL; } jobject jhardwareBuffer = android_hardware_HardwareBuffer_createFromAHardwareBuffer(env, buffer->toAHardwareBuffer()); const jint namedColorSpace = fromDataspaceToNamedColorSpaceValue(dataspace); jobject jhardwareBuffer = android_hardware_HardwareBuffer_createFromAHardwareBuffer( env, captureResults.buffer->toAHardwareBuffer()); const jint namedColorSpace = fromDataspaceToNamedColorSpaceValue(captureResults.capturedDataspace); return env->CallStaticObjectMethod(gScreenshotHardwareBufferClassInfo.clazz, gScreenshotHardwareBufferClassInfo.builder, jhardwareBuffer, namedColorSpace, false /* capturedSecureLayers */); namedColorSpace, captureResults.capturedSecureLayers); } static void nativeApplyTransaction(JNIEnv* env, jclass clazz, jlong transactionObj, jboolean sync) { Loading Loading @@ -1659,8 +1655,7 @@ static const JNINativeMethod sSurfaceControlMethods[] = { "Landroid/view/SurfaceControl$ScreenshotHardwareBuffer;", (void*)nativeCaptureDisplay }, {"nativeCaptureLayers", "(Landroid/os/IBinder;JLandroid/graphics/Rect;" "F[JI)" "(Landroid/view/SurfaceControl$LayerCaptureArgs;)" "Landroid/view/SurfaceControl$ScreenshotHardwareBuffer;", (void*)nativeCaptureLayers }, {"nativeSetInputWindowInfo", "(JJLandroid/view/InputWindowHandle;)V", Loading Loading @@ -1856,6 +1851,15 @@ int register_android_view_SurfaceControl(JNIEnv* env) gDisplayCaptureArgsClassInfo.rotation = 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; } Loading Loading
core/java/android/view/SurfaceControl.java +29 −19 Original line number Diff line number Diff line Loading @@ -91,9 +91,8 @@ public final class SurfaceControl implements Parcelable { private static native void nativeDisconnect(long nativeObject); private static native ScreenshotHardwareBuffer nativeCaptureDisplay( DisplayCaptureArgs captureArgs); private static native ScreenshotHardwareBuffer nativeCaptureLayers(IBinder displayToken, long layerObject, Rect sourceCrop, float frameScale, long[] excludeLayerObjects, int format); private static native ScreenshotHardwareBuffer nativeCaptureLayers( LayerCaptureArgs captureArgs); private static native long nativeMirrorSurface(long mirrorOfObject); private static native long nativeCreateTransaction(); private static native long nativeGetNativeTransactionFinalizer(); Loading Loading @@ -570,7 +569,8 @@ public final class SurfaceControl implements Parcelable { * Create ScreenshotHardwareBuffer from an existing HardwareBuffer object. * @param hardwareBuffer The existing HardwareBuffer object * @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. */ private static ScreenshotHardwareBuffer createFromNative(HardwareBuffer hardwareBuffer, Loading Loading @@ -766,7 +766,7 @@ public final class SurfaceControl implements Parcelable { /** * The arguments class used to make layer capture requests. * * @see #nativeCaptureLayers(IBinder, long, Rect, float, long[], int) * @see #nativeCaptureLayers(LayerCaptureArgs) * @hide */ public static class LayerCaptureArgs extends CaptureArgs { Loading @@ -778,10 +778,14 @@ public final class SurfaceControl implements Parcelable { super(builder); mChildrenOnly = builder.mChildrenOnly; mNativeLayer = builder.mLayer.mNativeObject; if (builder.mExcludeLayers != null) { mNativeExcludeLayers = new long[builder.mExcludeLayers.length]; for (int i = 0; i < builder.mExcludeLayers.length; i++) { mNativeExcludeLayers[i] = builder.mExcludeLayers[i].mNativeObject; } } else { mNativeExcludeLayers = null; } } /** Loading Loading @@ -2376,24 +2380,30 @@ public final class SurfaceControl implements Parcelable { */ public static ScreenshotHardwareBuffer captureLayers(SurfaceControl layer, Rect sourceCrop, float frameScale, int format) { final IBinder displayToken = SurfaceControl.getInternalDisplayToken(); return nativeCaptureLayers(displayToken, layer.mNativeObject, sourceCrop, frameScale, null, format); LayerCaptureArgs captureArgs = new LayerCaptureArgs.Builder(layer) .setSourceCrop(sourceCrop) .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 */ public static ScreenshotHardwareBuffer captureLayersExcluding(SurfaceControl layer, Rect sourceCrop, float frameScale, int format, SurfaceControl[] exclude) { final IBinder displayToken = SurfaceControl.getInternalDisplayToken(); long[] nativeExcludeObjects = new long[exclude.length]; for (int i = 0; i < exclude.length; i++) { nativeExcludeObjects[i] = exclude[i].mNativeObject; } return nativeCaptureLayers(displayToken, layer.mNativeObject, sourceCrop, frameScale, nativeExcludeObjects, PixelFormat.RGBA_8888); LayerCaptureArgs captureArgs = new LayerCaptureArgs.Builder(layer) .setSourceCrop(sourceCrop) .setFrameScale(frameScale) .setPixelFormat(format) .setExcludeLayers(exclude) .build(); return nativeCaptureLayers(captureArgs); } /** Loading
core/jni/android_view_SurfaceControl.cpp +37 −33 Original line number Diff line number Diff line Loading @@ -119,6 +119,12 @@ static struct { jfieldID rotation; } gDisplayCaptureArgsClassInfo; static struct { jfieldID layer; jfieldID excludeLayers; jfieldID childrenOnly; } gLayerCaptureArgsClassInfo; // Implements SkMallocPixelRef::ReleaseProc, to delete the screenshot on unref. void DeleteScreenshot(void* addr, void* context) { delete ((ScreenshotClient*) context); Loading Loading @@ -347,24 +353,23 @@ static jobject nativeCaptureDisplay(JNIEnv* env, jclass clazz, jobject displayCa namedColorSpace, captureResults.capturedSecureLayers); } static jobject nativeCaptureLayers(JNIEnv* env, jclass clazz, jobject displayTokenObj, jlong layerObject, jobject sourceCropObj, jfloat frameScale, jlongArray excludeObjectArray, jint format) { auto layer = reinterpret_cast<SurfaceControl *>(layerObject); if (layer == NULL) { return NULL; } Rect sourceCrop; if (sourceCropObj != NULL) { sourceCrop = rectFromObj(env, sourceCropObj); static jobject nativeCaptureLayers(JNIEnv* env, jclass clazz, jobject layerCaptureArgsObject) { LayerCaptureArgs captureArgs; getCaptureArgs(env, layerCaptureArgsObject, captureArgs); SurfaceControl* layer = reinterpret_cast<SurfaceControl*>( env->GetLongField(layerCaptureArgsObject, gLayerCaptureArgsClassInfo.layer)); if (layer == nullptr) { return nullptr; } 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) { const jsize len = env->GetArrayLength(excludeObjectArray); excludeHandles.reserve(len); captureArgs.excludeHandles.reserve(len); const jlong* objects = env->GetLongArrayElements(excludeObjectArray, nullptr); for (jsize i = 0; i < len; i++) { Loading @@ -373,33 +378,24 @@ static jobject nativeCaptureLayers(JNIEnv* env, jclass clazz, jobject displayTok jniThrowNullPointerException(env, "Exclude layer is null"); return NULL; } excludeHandles.emplace(excludeObject->getHandle()); captureArgs.excludeHandles.emplace(excludeObject->getHandle()); } env->ReleaseLongArrayElements(excludeObjectArray, const_cast<jlong*>(objects), JNI_ABORT); } sp<GraphicBuffer> buffer; ui::Dataspace dataspace = ui::Dataspace::V0_SRGB; 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); ScreenCaptureResults captureResults; status_t res = ScreenshotClient::captureLayers(captureArgs, captureResults); if (res != NO_ERROR) { return NULL; } jobject jhardwareBuffer = android_hardware_HardwareBuffer_createFromAHardwareBuffer(env, buffer->toAHardwareBuffer()); const jint namedColorSpace = fromDataspaceToNamedColorSpaceValue(dataspace); jobject jhardwareBuffer = android_hardware_HardwareBuffer_createFromAHardwareBuffer( env, captureResults.buffer->toAHardwareBuffer()); const jint namedColorSpace = fromDataspaceToNamedColorSpaceValue(captureResults.capturedDataspace); return env->CallStaticObjectMethod(gScreenshotHardwareBufferClassInfo.clazz, gScreenshotHardwareBufferClassInfo.builder, jhardwareBuffer, namedColorSpace, false /* capturedSecureLayers */); namedColorSpace, captureResults.capturedSecureLayers); } static void nativeApplyTransaction(JNIEnv* env, jclass clazz, jlong transactionObj, jboolean sync) { Loading Loading @@ -1659,8 +1655,7 @@ static const JNINativeMethod sSurfaceControlMethods[] = { "Landroid/view/SurfaceControl$ScreenshotHardwareBuffer;", (void*)nativeCaptureDisplay }, {"nativeCaptureLayers", "(Landroid/os/IBinder;JLandroid/graphics/Rect;" "F[JI)" "(Landroid/view/SurfaceControl$LayerCaptureArgs;)" "Landroid/view/SurfaceControl$ScreenshotHardwareBuffer;", (void*)nativeCaptureLayers }, {"nativeSetInputWindowInfo", "(JJLandroid/view/InputWindowHandle;)V", Loading Loading @@ -1856,6 +1851,15 @@ int register_android_view_SurfaceControl(JNIEnv* env) gDisplayCaptureArgsClassInfo.rotation = 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; } Loading