Merge "Updated layer capture in JNI to match updated function"

This commit is contained in:
Chavi Weingarten
2020-08-04 00:13:10 +00:00
committed by Android (Google) Code Review
2 changed files with 66 additions and 52 deletions

View File

@@ -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);
}
/**

View File

@@ -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<SurfaceControl *>(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<SurfaceControl*>(
env->GetLongField(layerCaptureArgsObject, gLayerCaptureArgsClassInfo.layer));
if (layer == nullptr) {
return nullptr;
}
Rect sourceCrop;
if (sourceCropObj != NULL) {
sourceCrop = rectFromObj(env, sourceCropObj);
}
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++) {
@@ -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) {
@@ -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;
}