diff options
| -rw-r--r-- | cmds/screencap/screencap.cpp | 31 | ||||
| -rw-r--r-- | core/java/android/view/SurfaceControl.java | 35 | ||||
| -rw-r--r-- | core/jni/android_view_SurfaceControl.cpp | 107 |
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; } |