summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmds/screencap/screencap.cpp31
-rw-r--r--core/java/android/view/SurfaceControl.java35
-rw-r--r--core/jni/android_view_SurfaceControl.cpp107
3 files changed, 123 insertions, 50 deletions
diff --git a/cmds/screencap/screencap.cpp b/cmds/screencap/screencap.cpp
index c1d8399d91a5..a46a54cc2063 100644
--- a/cmds/screencap/screencap.cpp
+++ b/cmds/screencap/screencap.cpp
@@ -182,16 +182,17 @@ int main(int argc, char** argv)
ProcessState::self()->setThreadPoolMaxThreadCount(0);
ProcessState::self()->startThreadPool();
- ui::Dataspace outDataspace;
- sp<GraphicBuffer> outBuffer;
-
- status_t result = ScreenshotClient::capture(*displayId, &outDataspace, &outBuffer);
+ ScreenCaptureResults captureResults;
+ status_t result = ScreenshotClient::captureDisplay(*displayId, captureResults);
if (result != NO_ERROR) {
close(fd);
return 1;
}
- result = outBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN, &base);
+ ui::Dataspace dataspace = captureResults.capturedDataspace;
+ sp<GraphicBuffer> buffer = captureResults.buffer;
+
+ result = buffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN, &base);
if (base == nullptr || result != NO_ERROR) {
String8 reason;
@@ -207,13 +208,13 @@ int main(int argc, char** argv)
if (png) {
AndroidBitmapInfo info;
- info.format = flinger2bitmapFormat(outBuffer->getPixelFormat());
+ info.format = flinger2bitmapFormat(buffer->getPixelFormat());
info.flags = ANDROID_BITMAP_FLAGS_ALPHA_PREMUL;
- info.width = outBuffer->getWidth();
- info.height = outBuffer->getHeight();
- info.stride = outBuffer->getStride() * bytesPerPixel(outBuffer->getPixelFormat());
+ info.width = buffer->getWidth();
+ info.height = buffer->getHeight();
+ info.stride = buffer->getStride() * bytesPerPixel(buffer->getPixelFormat());
- int result = AndroidBitmap_compress(&info, static_cast<int32_t>(outDataspace), base,
+ int result = AndroidBitmap_compress(&info, static_cast<int32_t>(dataspace), base,
ANDROID_BITMAP_COMPRESS_FORMAT_PNG, 100, &fd,
[](void* fdPtr, const void* data, size_t size) -> bool {
int bytesWritten = write(*static_cast<int*>(fdPtr),
@@ -229,11 +230,11 @@ int main(int argc, char** argv)
notifyMediaScanner(fn);
}
} else {
- uint32_t w = outBuffer->getWidth();
- uint32_t h = outBuffer->getHeight();
- uint32_t s = outBuffer->getStride();
- uint32_t f = outBuffer->getPixelFormat();
- uint32_t c = dataSpaceToInt(outDataspace);
+ uint32_t w = buffer->getWidth();
+ uint32_t h = buffer->getHeight();
+ uint32_t s = buffer->getStride();
+ uint32_t f = buffer->getPixelFormat();
+ uint32_t c = dataSpaceToInt(dataspace);
write(fd, &w, 4);
write(fd, &h, 4);
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index eaa7eafc23cc..0f87adad2a53 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -89,10 +89,8 @@ public final class SurfaceControl implements Parcelable {
private static native void nativeWriteToParcel(long nativeObject, Parcel out);
private static native void nativeRelease(long nativeObject);
private static native void nativeDisconnect(long nativeObject);
-
- private static native ScreenshotHardwareBuffer nativeScreenshot(IBinder displayToken,
- Rect sourceCrop, int width, int height, boolean useIdentityTransform, int rotation,
- boolean captureSecureLayers);
+ private static native ScreenshotHardwareBuffer nativeCaptureDisplay(
+ DisplayCaptureArgs captureArgs);
private static native ScreenshotHardwareBuffer nativeCaptureLayers(IBinder displayToken,
long layerObject, Rect sourceCrop, float frameScale, long[] excludeLayerObjects,
int format);
@@ -662,14 +660,14 @@ public final class SurfaceControl implements Parcelable {
/**
* Each sub class should return itself to allow the builder to chain properly
*/
- public abstract T getThis();
+ abstract T getThis();
}
}
/**
* The arguments class used to make display capture requests.
*
- * @see #nativeScreenshot(IBinder, Rect, int, int, boolean, int, boolean)
+ * @see #nativeCaptureDisplay(DisplayCaptureArgs)
* @hide
*/
public static class DisplayCaptureArgs extends CaptureArgs {
@@ -759,7 +757,7 @@ public final class SurfaceControl implements Parcelable {
}
@Override
- public Builder getThis() {
+ Builder getThis() {
return this;
}
}
@@ -837,7 +835,7 @@ public final class SurfaceControl implements Parcelable {
}
@Override
- public Builder getThis() {
+ Builder getThis() {
return this;
}
@@ -2293,8 +2291,14 @@ public final class SurfaceControl implements Parcelable {
throw new IllegalArgumentException("displayToken must not be null");
}
- return nativeScreenshot(display, sourceCrop, width, height, useIdentityTransform, rotation,
- false /* captureSecureLayers */);
+ DisplayCaptureArgs captureArgs = new DisplayCaptureArgs.Builder(display)
+ .setSourceCrop(sourceCrop)
+ .setSize(width, height)
+ .setUseIdentityTransform(useIdentityTransform)
+ .setRotation(rotation)
+ .build();
+
+ return nativeCaptureDisplay(captureArgs);
}
/**
@@ -2314,8 +2318,15 @@ public final class SurfaceControl implements Parcelable {
throw new IllegalArgumentException("displayToken must not be null");
}
- return nativeScreenshot(display, sourceCrop, width, height, useIdentityTransform, rotation,
- true /* captureSecureLayers */);
+ DisplayCaptureArgs captureArgs = new DisplayCaptureArgs.Builder(display)
+ .setSourceCrop(sourceCrop)
+ .setSize(width, height)
+ .setUseIdentityTransform(useIdentityTransform)
+ .setRotation(rotation)
+ .setCaptureSecureLayers(true)
+ .build();
+
+ return nativeCaptureDisplay(captureArgs);
}
private static void rotateCropForSF(Rect crop, int rot) {
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index a965ab310205..905e69ddff24 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -104,6 +104,21 @@ static struct {
jfieldID top;
} gRectClassInfo;
+static struct {
+ jfieldID pixelFormat;
+ jfieldID sourceCrop;
+ jfieldID frameScale;
+ jfieldID captureSecureLayers;
+} gCaptureArgsClassInfo;
+
+static struct {
+ jfieldID displayToken;
+ jfieldID width;
+ jfieldID height;
+ jfieldID useIdentityTransform;
+ jfieldID rotation;
+} gDisplayCaptureArgsClassInfo;
+
// Implements SkMallocPixelRef::ReleaseProc, to delete the screenshot on unref.
void DeleteScreenshot(void* addr, void* context) {
delete ((ScreenshotClient*) context);
@@ -276,35 +291,60 @@ static Rect rectFromObj(JNIEnv* env, jobject rectObj) {
return Rect(left, top, right, bottom);
}
-static jobject nativeScreenshot(JNIEnv* env, jclass clazz,
- jobject displayTokenObj, jobject sourceCropObj, jint width, jint height,
- bool useIdentityTransform, int rotation, bool captureSecureLayers) {
- sp<IBinder> displayToken = ibinderForJavaObject(env, displayTokenObj);
- if (displayToken == NULL) {
+static void getCaptureArgs(JNIEnv* env, jobject captureArgsObject, CaptureArgs& captureArgs) {
+ captureArgs.pixelFormat = static_cast<ui::PixelFormat>(
+ env->GetIntField(captureArgsObject, gCaptureArgsClassInfo.pixelFormat));
+ captureArgs.sourceCrop =
+ rectFromObj(env,
+ env->GetObjectField(captureArgsObject, gCaptureArgsClassInfo.sourceCrop));
+ captureArgs.frameScale =
+ env->GetFloatField(captureArgsObject, gCaptureArgsClassInfo.frameScale);
+ captureArgs.captureSecureLayers =
+ env->GetBooleanField(captureArgsObject, gCaptureArgsClassInfo.captureSecureLayers);
+}
+
+static DisplayCaptureArgs displayCaptureArgsFromObject(JNIEnv* env,
+ jobject displayCaptureArgsObject) {
+ DisplayCaptureArgs captureArgs;
+ getCaptureArgs(env, displayCaptureArgsObject, captureArgs);
+
+ captureArgs.displayToken =
+ ibinderForJavaObject(env,
+ env->GetObjectField(displayCaptureArgsObject,
+ gDisplayCaptureArgsClassInfo.displayToken));
+ captureArgs.width =
+ env->GetIntField(displayCaptureArgsObject, gDisplayCaptureArgsClassInfo.width);
+ captureArgs.height =
+ env->GetIntField(displayCaptureArgsObject, gDisplayCaptureArgsClassInfo.height);
+ captureArgs.useIdentityTransform =
+ env->GetBooleanField(displayCaptureArgsObject,
+ gDisplayCaptureArgsClassInfo.useIdentityTransform);
+ captureArgs.rotation = ui::toRotation(
+ env->GetIntField(displayCaptureArgsObject, gDisplayCaptureArgsClassInfo.rotation));
+ return captureArgs;
+}
+
+static jobject nativeCaptureDisplay(JNIEnv* env, jclass clazz, jobject displayCaptureArgsObject) {
+ const DisplayCaptureArgs captureArgs =
+ displayCaptureArgsFromObject(env, displayCaptureArgsObject);
+
+ if (captureArgs.displayToken == NULL) {
return NULL;
}
- const ui::ColorMode colorMode = SurfaceComposerClient::getActiveColorMode(displayToken);
- const ui::Dataspace dataspace = pickDataspaceFromColorMode(colorMode);
- Rect sourceCrop = rectFromObj(env, sourceCropObj);
- sp<GraphicBuffer> buffer;
- bool capturedSecureLayers = false;
- status_t res = ScreenshotClient::capture(displayToken, dataspace,
- ui::PixelFormat::RGBA_8888,
- sourceCrop, width, height,
- useIdentityTransform, ui::toRotation(rotation),
- captureSecureLayers, &buffer, capturedSecureLayers);
+ ScreenCaptureResults captureResults;
+ status_t res = ScreenshotClient::captureDisplay(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, capturedSecureLayers);
+ namedColorSpace, captureResults.capturedSecureLayers);
}
static jobject nativeCaptureLayers(JNIEnv* env, jclass clazz, jobject displayTokenObj,
@@ -1614,10 +1654,10 @@ static const JNINativeMethod sSurfaceControlMethods[] = {
(void*)nativeSeverChildren } ,
{"nativeSetOverrideScalingMode", "(JJI)V",
(void*)nativeSetOverrideScalingMode },
- {"nativeScreenshot",
- "(Landroid/os/IBinder;Landroid/graphics/Rect;IIZIZ)"
+ {"nativeCaptureDisplay",
+ "(Landroid/view/SurfaceControl$DisplayCaptureArgs;)"
"Landroid/view/SurfaceControl$ScreenshotHardwareBuffer;",
- (void*)nativeScreenshot },
+ (void*)nativeCaptureDisplay },
{"nativeCaptureLayers",
"(Landroid/os/IBinder;JLandroid/graphics/Rect;"
"F[JI)"
@@ -1795,6 +1835,27 @@ int register_android_view_SurfaceControl(JNIEnv* env)
gDesiredDisplayConfigSpecsClassInfo.appRequestRefreshRateMax =
GetFieldIDOrDie(env, desiredDisplayConfigSpecsClazz, "appRequestRefreshRateMax", "F");
+ jclass captureArgsClazz = FindClassOrDie(env, "android/view/SurfaceControl$CaptureArgs");
+ gCaptureArgsClassInfo.pixelFormat = GetFieldIDOrDie(env, captureArgsClazz, "mPixelFormat", "I");
+ gCaptureArgsClassInfo.sourceCrop =
+ GetFieldIDOrDie(env, captureArgsClazz, "mSourceCrop", "Landroid/graphics/Rect;");
+ gCaptureArgsClassInfo.frameScale = GetFieldIDOrDie(env, captureArgsClazz, "mFrameScale", "F");
+ gCaptureArgsClassInfo.captureSecureLayers =
+ GetFieldIDOrDie(env, captureArgsClazz, "mCaptureSecureLayers", "Z");
+
+ jclass displayCaptureArgsClazz =
+ FindClassOrDie(env, "android/view/SurfaceControl$DisplayCaptureArgs");
+ gDisplayCaptureArgsClassInfo.displayToken =
+ GetFieldIDOrDie(env, displayCaptureArgsClazz, "mDisplayToken", "Landroid/os/IBinder;");
+ gDisplayCaptureArgsClassInfo.width =
+ GetFieldIDOrDie(env, displayCaptureArgsClazz, "mWidth", "I");
+ gDisplayCaptureArgsClassInfo.height =
+ GetFieldIDOrDie(env, displayCaptureArgsClazz, "mHeight", "I");
+ gDisplayCaptureArgsClassInfo.useIdentityTransform =
+ GetFieldIDOrDie(env, displayCaptureArgsClazz, "mUseIdentityTransform", "Z");
+ gDisplayCaptureArgsClassInfo.rotation =
+ GetFieldIDOrDie(env, displayCaptureArgsClazz, "mRotation", "I");
+
return err;
}