Updated layer capture in JNI to match updated function
Modified Java and JNI layer capture functions to match the new function in SurfaceComposerClient. The Java method will send an args object instead of individual arguments to SurfaceComposerClient Test: Layer screenshots in recents Bug: 162367424 Change-Id: Ib060a0238e47edfc19f6f34a5c6a508fc6c9f7fd
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user