Loading cmds/screencap/screencap.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -141,7 +141,7 @@ int main(int argc, char** argv) ScreenshotClient screenshot; sp<IBinder> display = SurfaceComposerClient::getBuiltInDisplay(displayId); if (display != NULL && screenshot.update(display, false) == NO_ERROR) { if (display != NULL && screenshot.update(display, Rect(), false) == NO_ERROR) { base = screenshot.getPixels(); w = screenshot.getWidth(); h = screenshot.getHeight(); Loading core/java/android/view/SurfaceControl.java +18 −16 Original line number Diff line number Diff line Loading @@ -38,11 +38,11 @@ public class SurfaceControl { private static native void nativeDestroy(long nativeObject); private static native Bitmap nativeScreenshot(IBinder displayToken, int width, int height, int minLayer, int maxLayer, boolean allLayers, boolean useIdentityTransform); Rect sourceCrop, int width, int height, int minLayer, int maxLayer, boolean allLayers, boolean useIdentityTransform); private static native void nativeScreenshot(IBinder displayToken, Surface consumer, int width, int height, int minLayer, int maxLayer, boolean allLayers, boolean useIdentityTransform); Rect sourceCrop, int width, int height, int minLayer, int maxLayer, boolean allLayers, boolean useIdentityTransform); private static native void nativeOpenTransaction(); private static native void nativeCloseTransaction(); Loading Loading @@ -597,8 +597,8 @@ public class SurfaceControl { public static void screenshot(IBinder display, Surface consumer, int width, int height, int minLayer, int maxLayer, boolean useIdentityTransform) { screenshot(display, consumer, width, height, minLayer, maxLayer, false, useIdentityTransform); screenshot(display, consumer, new Rect(), width, height, minLayer, maxLayer, false, useIdentityTransform); } /** Loading @@ -613,7 +613,7 @@ public class SurfaceControl { */ public static void screenshot(IBinder display, Surface consumer, int width, int height) { screenshot(display, consumer, width, height, 0, 0, true, false); screenshot(display, consumer, new Rect(), width, height, 0, 0, true, false); } /** Loading @@ -623,7 +623,7 @@ public class SurfaceControl { * @param consumer The {@link Surface} to take the screenshot into. */ public static void screenshot(IBinder display, Surface consumer) { screenshot(display, consumer, 0, 0, 0, 0, true, false); screenshot(display, consumer, new Rect(), 0, 0, 0, 0, true, false); } /** Loading @@ -634,6 +634,8 @@ public class SurfaceControl { * the versions that use a {@link Surface} instead, such as * {@link SurfaceControl#screenshot(IBinder, Surface)}. * * @param sourceCrop The portion of the screen to capture into the Bitmap; * caller may pass in 'new Rect()' if no cropping is desired. * @param width The desired width of the returned bitmap; the raw * screen will be scaled down to this size. * @param height The desired height of the returned bitmap; the raw Loading @@ -649,13 +651,13 @@ public class SurfaceControl { * if an error occurs. Make sure to call Bitmap.recycle() as soon as * possible, once its content is not needed anymore. */ public static Bitmap screenshot(int width, int height, int minLayer, int maxLayer, boolean useIdentityTransform) { public static Bitmap screenshot(Rect sourceCrop, int width, int height, int minLayer, int maxLayer, boolean useIdentityTransform) { // TODO: should take the display as a parameter IBinder displayToken = SurfaceControl.getBuiltInDisplay( SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN); return nativeScreenshot(displayToken, width, height, minLayer, maxLayer, false, useIdentityTransform); return nativeScreenshot(displayToken, sourceCrop, width, height, minLayer, maxLayer, false, useIdentityTransform); } /** Loading @@ -674,10 +676,10 @@ public class SurfaceControl { // TODO: should take the display as a parameter IBinder displayToken = SurfaceControl.getBuiltInDisplay( SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN); return nativeScreenshot(displayToken, width, height, 0, 0, true, false); return nativeScreenshot(displayToken, new Rect(), width, height, 0, 0, true, false); } private static void screenshot(IBinder display, Surface consumer, private static void screenshot(IBinder display, Surface consumer, Rect sourceCrop, int width, int height, int minLayer, int maxLayer, boolean allLayers, boolean useIdentityTransform) { if (display == null) { Loading @@ -686,7 +688,7 @@ public class SurfaceControl { if (consumer == null) { throw new IllegalArgumentException("consumer must not be null"); } nativeScreenshot(display, consumer, width, height, minLayer, maxLayer, allLayers, useIdentityTransform); nativeScreenshot(display, consumer, sourceCrop, width, height, minLayer, maxLayer, allLayers, useIdentityTransform); } } core/jni/android_view_SurfaceControl.cpp +40 −15 Original line number Diff line number Diff line Loading @@ -61,6 +61,13 @@ static struct { jfieldID secure; } gPhysicalDisplayInfoClassInfo; static struct { jfieldID bottom; jfieldID left; jfieldID right; jfieldID top; } gRectClassInfo; // Implements SkMallocPixelRef::ReleaseProc, to delete the screenshot on unref. void DeleteScreenshot(void* addr, void* context) { SkASSERT(addr == ((ScreenshotClient*) context)->getPixels()); Loading Loading @@ -104,25 +111,32 @@ static void nativeDestroy(JNIEnv* env, jclass clazz, jlong nativeObject) { ctrl->decStrong((void *)nativeCreate); } static jobject nativeScreenshotBitmap(JNIEnv* env, jclass clazz, jobject displayTokenObj, jint width, jint height, jint minLayer, jint maxLayer, bool allLayers, bool useIdentityTransform) { static jobject nativeScreenshotBitmap(JNIEnv* env, jclass clazz, jobject displayTokenObj, jobject sourceCropObj, jint width, jint height, jint minLayer, jint maxLayer, bool allLayers, bool useIdentityTransform) { sp<IBinder> displayToken = ibinderForJavaObject(env, displayTokenObj); if (displayToken == NULL) { return NULL; } int left = env->GetIntField(sourceCropObj, gRectClassInfo.left); int top = env->GetIntField(sourceCropObj, gRectClassInfo.top); int right = env->GetIntField(sourceCropObj, gRectClassInfo.right); int bottom = env->GetIntField(sourceCropObj, gRectClassInfo.bottom); Rect sourceCrop(left, top, right, bottom); ScreenshotClient* screenshot = new ScreenshotClient(); status_t res; if (width > 0 && height > 0) { if (allLayers) { res = screenshot->update(displayToken, width, height, useIdentityTransform); } else { res = screenshot->update(displayToken, width, height, minLayer, maxLayer, res = screenshot->update(displayToken, sourceCrop, width, height, useIdentityTransform); } else { res = screenshot->update(displayToken, sourceCrop, width, height, minLayer, maxLayer, useIdentityTransform); } } else { res = screenshot->update(displayToken, useIdentityTransform); res = screenshot->update(displayToken, sourceCrop, useIdentityTransform); } if (res != NO_ERROR) { delete screenshot; Loading Loading @@ -174,20 +188,25 @@ static jobject nativeScreenshotBitmap(JNIEnv* env, jclass clazz, jobject display GraphicsJNI::kBitmapCreateFlag_Premultiplied, NULL); } static void nativeScreenshot(JNIEnv* env, jclass clazz, jobject displayTokenObj, jobject surfaceObj, jint width, jint height, jint minLayer, jint maxLayer, bool allLayers, bool useIdentityTransform) { static void nativeScreenshot(JNIEnv* env, jclass clazz, jobject displayTokenObj, jobject surfaceObj, jobject sourceCropObj, jint width, jint height, jint minLayer, jint maxLayer, bool allLayers, bool useIdentityTransform) { sp<IBinder> displayToken = ibinderForJavaObject(env, displayTokenObj); if (displayToken != NULL) { sp<Surface> consumer = android_view_Surface_getSurface(env, surfaceObj); if (consumer != NULL) { int left = env->GetIntField(sourceCropObj, gRectClassInfo.left); int top = env->GetIntField(sourceCropObj, gRectClassInfo.top); int right = env->GetIntField(sourceCropObj, gRectClassInfo.right); int bottom = env->GetIntField(sourceCropObj, gRectClassInfo.bottom); Rect sourceCrop(left, top, right, bottom); if (allLayers) { minLayer = 0; maxLayer = -1; } ScreenshotClient::capture( displayToken, consumer->getIGraphicBufferProducer(), ScreenshotClient::capture(displayToken, consumer->getIGraphicBufferProducer(), sourceCrop, width, height, uint32_t(minLayer), uint32_t(maxLayer), useIdentityTransform); } Loading Loading @@ -563,9 +582,9 @@ static JNINativeMethod sSurfaceControlMethods[] = { (void*)nativeRelease }, {"nativeDestroy", "(J)V", (void*)nativeDestroy }, {"nativeScreenshot", "(Landroid/os/IBinder;IIIIZZ)Landroid/graphics/Bitmap;", {"nativeScreenshot", "(Landroid/os/IBinder;Landroid/graphics/Rect;IIIIZZ)Landroid/graphics/Bitmap;", (void*)nativeScreenshotBitmap }, {"nativeScreenshot", "(Landroid/os/IBinder;Landroid/view/Surface;IIIIZZ)V", {"nativeScreenshot", "(Landroid/os/IBinder;Landroid/view/Surface;Landroid/graphics/Rect;IIIIZZ)V", (void*)nativeScreenshot }, {"nativeOpenTransaction", "()V", (void*)nativeOpenTransaction }, Loading Loading @@ -640,6 +659,12 @@ int register_android_view_SurfaceControl(JNIEnv* env) gPhysicalDisplayInfoClassInfo.yDpi = env->GetFieldID(clazz, "yDpi", "F"); gPhysicalDisplayInfoClassInfo.secure = env->GetFieldID(clazz, "secure", "Z"); jclass rectClazz = env->FindClass("android/graphics/Rect"); gRectClassInfo.bottom = env->GetFieldID(rectClazz, "bottom", "I"); gRectClassInfo.left = env->GetFieldID(rectClazz, "left", "I"); gRectClassInfo.right = env->GetFieldID(rectClazz, "right", "I"); gRectClassInfo.top = env->GetFieldID(rectClazz, "top", "I"); jclass frameStatsClazz = env->FindClass("android/view/FrameStats"); jfieldID undefined_time_nano_field = env->GetStaticFieldID(frameStatsClazz, "UNDEFINED_TIME_NANO", "J"); nsecs_t undefined_time_nano = env->GetStaticLongField(frameStatsClazz, undefined_time_nano_field); Loading services/core/java/com/android/server/wm/WindowManagerService.java +3 −1 Original line number Diff line number Diff line Loading @@ -5802,7 +5802,9 @@ public class WindowManagerService extends IWindowManager.Stub // whether the screenshot should use the identity transformation matrix // (e.g., enable it when taking a screenshot for recents, since we might be in // the middle of the rotation animation, but don't want a rotated recent image). rawss = SurfaceControl.screenshot(dw, dh, minLayer, maxLayer, false); // TODO: Replace 'new Rect()' with the portion of the screen to capture for the // screenshot. rawss = SurfaceControl.screenshot(new Rect(), dw, dh, minLayer, maxLayer, false); } } while (!screenshotReady && retryCount <= MAX_SCREENSHOT_RETRIES); if (retryCount > MAX_SCREENSHOT_RETRIES) Slog.i(TAG, "Screenshot max retries " + Loading Loading
cmds/screencap/screencap.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -141,7 +141,7 @@ int main(int argc, char** argv) ScreenshotClient screenshot; sp<IBinder> display = SurfaceComposerClient::getBuiltInDisplay(displayId); if (display != NULL && screenshot.update(display, false) == NO_ERROR) { if (display != NULL && screenshot.update(display, Rect(), false) == NO_ERROR) { base = screenshot.getPixels(); w = screenshot.getWidth(); h = screenshot.getHeight(); Loading
core/java/android/view/SurfaceControl.java +18 −16 Original line number Diff line number Diff line Loading @@ -38,11 +38,11 @@ public class SurfaceControl { private static native void nativeDestroy(long nativeObject); private static native Bitmap nativeScreenshot(IBinder displayToken, int width, int height, int minLayer, int maxLayer, boolean allLayers, boolean useIdentityTransform); Rect sourceCrop, int width, int height, int minLayer, int maxLayer, boolean allLayers, boolean useIdentityTransform); private static native void nativeScreenshot(IBinder displayToken, Surface consumer, int width, int height, int minLayer, int maxLayer, boolean allLayers, boolean useIdentityTransform); Rect sourceCrop, int width, int height, int minLayer, int maxLayer, boolean allLayers, boolean useIdentityTransform); private static native void nativeOpenTransaction(); private static native void nativeCloseTransaction(); Loading Loading @@ -597,8 +597,8 @@ public class SurfaceControl { public static void screenshot(IBinder display, Surface consumer, int width, int height, int minLayer, int maxLayer, boolean useIdentityTransform) { screenshot(display, consumer, width, height, minLayer, maxLayer, false, useIdentityTransform); screenshot(display, consumer, new Rect(), width, height, minLayer, maxLayer, false, useIdentityTransform); } /** Loading @@ -613,7 +613,7 @@ public class SurfaceControl { */ public static void screenshot(IBinder display, Surface consumer, int width, int height) { screenshot(display, consumer, width, height, 0, 0, true, false); screenshot(display, consumer, new Rect(), width, height, 0, 0, true, false); } /** Loading @@ -623,7 +623,7 @@ public class SurfaceControl { * @param consumer The {@link Surface} to take the screenshot into. */ public static void screenshot(IBinder display, Surface consumer) { screenshot(display, consumer, 0, 0, 0, 0, true, false); screenshot(display, consumer, new Rect(), 0, 0, 0, 0, true, false); } /** Loading @@ -634,6 +634,8 @@ public class SurfaceControl { * the versions that use a {@link Surface} instead, such as * {@link SurfaceControl#screenshot(IBinder, Surface)}. * * @param sourceCrop The portion of the screen to capture into the Bitmap; * caller may pass in 'new Rect()' if no cropping is desired. * @param width The desired width of the returned bitmap; the raw * screen will be scaled down to this size. * @param height The desired height of the returned bitmap; the raw Loading @@ -649,13 +651,13 @@ public class SurfaceControl { * if an error occurs. Make sure to call Bitmap.recycle() as soon as * possible, once its content is not needed anymore. */ public static Bitmap screenshot(int width, int height, int minLayer, int maxLayer, boolean useIdentityTransform) { public static Bitmap screenshot(Rect sourceCrop, int width, int height, int minLayer, int maxLayer, boolean useIdentityTransform) { // TODO: should take the display as a parameter IBinder displayToken = SurfaceControl.getBuiltInDisplay( SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN); return nativeScreenshot(displayToken, width, height, minLayer, maxLayer, false, useIdentityTransform); return nativeScreenshot(displayToken, sourceCrop, width, height, minLayer, maxLayer, false, useIdentityTransform); } /** Loading @@ -674,10 +676,10 @@ public class SurfaceControl { // TODO: should take the display as a parameter IBinder displayToken = SurfaceControl.getBuiltInDisplay( SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN); return nativeScreenshot(displayToken, width, height, 0, 0, true, false); return nativeScreenshot(displayToken, new Rect(), width, height, 0, 0, true, false); } private static void screenshot(IBinder display, Surface consumer, private static void screenshot(IBinder display, Surface consumer, Rect sourceCrop, int width, int height, int minLayer, int maxLayer, boolean allLayers, boolean useIdentityTransform) { if (display == null) { Loading @@ -686,7 +688,7 @@ public class SurfaceControl { if (consumer == null) { throw new IllegalArgumentException("consumer must not be null"); } nativeScreenshot(display, consumer, width, height, minLayer, maxLayer, allLayers, useIdentityTransform); nativeScreenshot(display, consumer, sourceCrop, width, height, minLayer, maxLayer, allLayers, useIdentityTransform); } }
core/jni/android_view_SurfaceControl.cpp +40 −15 Original line number Diff line number Diff line Loading @@ -61,6 +61,13 @@ static struct { jfieldID secure; } gPhysicalDisplayInfoClassInfo; static struct { jfieldID bottom; jfieldID left; jfieldID right; jfieldID top; } gRectClassInfo; // Implements SkMallocPixelRef::ReleaseProc, to delete the screenshot on unref. void DeleteScreenshot(void* addr, void* context) { SkASSERT(addr == ((ScreenshotClient*) context)->getPixels()); Loading Loading @@ -104,25 +111,32 @@ static void nativeDestroy(JNIEnv* env, jclass clazz, jlong nativeObject) { ctrl->decStrong((void *)nativeCreate); } static jobject nativeScreenshotBitmap(JNIEnv* env, jclass clazz, jobject displayTokenObj, jint width, jint height, jint minLayer, jint maxLayer, bool allLayers, bool useIdentityTransform) { static jobject nativeScreenshotBitmap(JNIEnv* env, jclass clazz, jobject displayTokenObj, jobject sourceCropObj, jint width, jint height, jint minLayer, jint maxLayer, bool allLayers, bool useIdentityTransform) { sp<IBinder> displayToken = ibinderForJavaObject(env, displayTokenObj); if (displayToken == NULL) { return NULL; } int left = env->GetIntField(sourceCropObj, gRectClassInfo.left); int top = env->GetIntField(sourceCropObj, gRectClassInfo.top); int right = env->GetIntField(sourceCropObj, gRectClassInfo.right); int bottom = env->GetIntField(sourceCropObj, gRectClassInfo.bottom); Rect sourceCrop(left, top, right, bottom); ScreenshotClient* screenshot = new ScreenshotClient(); status_t res; if (width > 0 && height > 0) { if (allLayers) { res = screenshot->update(displayToken, width, height, useIdentityTransform); } else { res = screenshot->update(displayToken, width, height, minLayer, maxLayer, res = screenshot->update(displayToken, sourceCrop, width, height, useIdentityTransform); } else { res = screenshot->update(displayToken, sourceCrop, width, height, minLayer, maxLayer, useIdentityTransform); } } else { res = screenshot->update(displayToken, useIdentityTransform); res = screenshot->update(displayToken, sourceCrop, useIdentityTransform); } if (res != NO_ERROR) { delete screenshot; Loading Loading @@ -174,20 +188,25 @@ static jobject nativeScreenshotBitmap(JNIEnv* env, jclass clazz, jobject display GraphicsJNI::kBitmapCreateFlag_Premultiplied, NULL); } static void nativeScreenshot(JNIEnv* env, jclass clazz, jobject displayTokenObj, jobject surfaceObj, jint width, jint height, jint minLayer, jint maxLayer, bool allLayers, bool useIdentityTransform) { static void nativeScreenshot(JNIEnv* env, jclass clazz, jobject displayTokenObj, jobject surfaceObj, jobject sourceCropObj, jint width, jint height, jint minLayer, jint maxLayer, bool allLayers, bool useIdentityTransform) { sp<IBinder> displayToken = ibinderForJavaObject(env, displayTokenObj); if (displayToken != NULL) { sp<Surface> consumer = android_view_Surface_getSurface(env, surfaceObj); if (consumer != NULL) { int left = env->GetIntField(sourceCropObj, gRectClassInfo.left); int top = env->GetIntField(sourceCropObj, gRectClassInfo.top); int right = env->GetIntField(sourceCropObj, gRectClassInfo.right); int bottom = env->GetIntField(sourceCropObj, gRectClassInfo.bottom); Rect sourceCrop(left, top, right, bottom); if (allLayers) { minLayer = 0; maxLayer = -1; } ScreenshotClient::capture( displayToken, consumer->getIGraphicBufferProducer(), ScreenshotClient::capture(displayToken, consumer->getIGraphicBufferProducer(), sourceCrop, width, height, uint32_t(minLayer), uint32_t(maxLayer), useIdentityTransform); } Loading Loading @@ -563,9 +582,9 @@ static JNINativeMethod sSurfaceControlMethods[] = { (void*)nativeRelease }, {"nativeDestroy", "(J)V", (void*)nativeDestroy }, {"nativeScreenshot", "(Landroid/os/IBinder;IIIIZZ)Landroid/graphics/Bitmap;", {"nativeScreenshot", "(Landroid/os/IBinder;Landroid/graphics/Rect;IIIIZZ)Landroid/graphics/Bitmap;", (void*)nativeScreenshotBitmap }, {"nativeScreenshot", "(Landroid/os/IBinder;Landroid/view/Surface;IIIIZZ)V", {"nativeScreenshot", "(Landroid/os/IBinder;Landroid/view/Surface;Landroid/graphics/Rect;IIIIZZ)V", (void*)nativeScreenshot }, {"nativeOpenTransaction", "()V", (void*)nativeOpenTransaction }, Loading Loading @@ -640,6 +659,12 @@ int register_android_view_SurfaceControl(JNIEnv* env) gPhysicalDisplayInfoClassInfo.yDpi = env->GetFieldID(clazz, "yDpi", "F"); gPhysicalDisplayInfoClassInfo.secure = env->GetFieldID(clazz, "secure", "Z"); jclass rectClazz = env->FindClass("android/graphics/Rect"); gRectClassInfo.bottom = env->GetFieldID(rectClazz, "bottom", "I"); gRectClassInfo.left = env->GetFieldID(rectClazz, "left", "I"); gRectClassInfo.right = env->GetFieldID(rectClazz, "right", "I"); gRectClassInfo.top = env->GetFieldID(rectClazz, "top", "I"); jclass frameStatsClazz = env->FindClass("android/view/FrameStats"); jfieldID undefined_time_nano_field = env->GetStaticFieldID(frameStatsClazz, "UNDEFINED_TIME_NANO", "J"); nsecs_t undefined_time_nano = env->GetStaticLongField(frameStatsClazz, undefined_time_nano_field); Loading
services/core/java/com/android/server/wm/WindowManagerService.java +3 −1 Original line number Diff line number Diff line Loading @@ -5802,7 +5802,9 @@ public class WindowManagerService extends IWindowManager.Stub // whether the screenshot should use the identity transformation matrix // (e.g., enable it when taking a screenshot for recents, since we might be in // the middle of the rotation animation, but don't want a rotated recent image). rawss = SurfaceControl.screenshot(dw, dh, minLayer, maxLayer, false); // TODO: Replace 'new Rect()' with the portion of the screen to capture for the // screenshot. rawss = SurfaceControl.screenshot(new Rect(), dw, dh, minLayer, maxLayer, false); } } while (!screenshotReady && retryCount <= MAX_SCREENSHOT_RETRIES); if (retryCount > MAX_SCREENSHOT_RETRIES) Slog.i(TAG, "Screenshot max retries " + Loading