diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java index 0f87adad2a538..50ed00cd0aa77 100644 --- a/core/java/android/view/SurfaceControl.java +++ b/core/java/android/view/SurfaceControl.java @@ -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(); @@ -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, @@ -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 { @@ -778,9 +778,13 @@ public final class SurfaceControl implements Parcelable { super(builder); mChildrenOnly = builder.mChildrenOnly; mNativeLayer = builder.mLayer.mNativeObject; - mNativeExcludeLayers = new long[builder.mExcludeLayers.length]; - for (int i = 0; i < builder.mExcludeLayers.length; i++) { - mNativeExcludeLayers[i] = builder.mExcludeLayers[i].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; } } @@ -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); } /** diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp index 905e69ddff24d..814a07e7f2df8 100644 --- a/core/jni/android_view_SurfaceControl.cpp +++ b/core/jni/android_view_SurfaceControl.cpp @@ -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); @@ -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(layerObject); - if (layer == NULL) { - return NULL; +static jobject nativeCaptureLayers(JNIEnv* env, jclass clazz, jobject layerCaptureArgsObject) { + LayerCaptureArgs captureArgs; + getCaptureArgs(env, layerCaptureArgsObject, captureArgs); + SurfaceControl* layer = reinterpret_cast( + env->GetLongField(layerCaptureArgsObject, gLayerCaptureArgsClassInfo.layer)); + if (layer == nullptr) { + return nullptr; } - Rect sourceCrop; - if (sourceCropObj != NULL) { - sourceCrop = rectFromObj(env, sourceCropObj); - } - - std::unordered_set,ISurfaceComposer::SpHash> excludeHandles; + captureArgs.layerHandle = layer->getHandle(); + captureArgs.childrenOnly = + env->GetBooleanField(layerCaptureArgsObject, gLayerCaptureArgsClassInfo.childrenOnly); + jlongArray excludeObjectArray = reinterpret_cast( + 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++) { @@ -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(objects), JNI_ABORT); } - sp buffer; - ui::Dataspace dataspace = ui::Dataspace::V0_SRGB; - sp 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(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) { @@ -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", @@ -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; }