Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0b81adca authored by Riley Andrews's avatar Riley Andrews Committed by Android (Google) Code Review
Browse files

Merge "Use surfaceflinger for recents thumbnail rotations." into lmp-dev

parents b5052984 1d134065
Loading
Loading
Loading
Loading
+11 −4
Original line number Diff line number Diff line
@@ -39,7 +39,7 @@ public class SurfaceControl {

    private static native Bitmap nativeScreenshot(IBinder displayToken,
            Rect sourceCrop, int width, int height, int minLayer, int maxLayer,
            boolean allLayers, boolean useIdentityTransform);
            boolean allLayers, boolean useIdentityTransform, int rotation);
    private static native void nativeScreenshot(IBinder displayToken, Surface consumer,
            Rect sourceCrop, int width, int height, int minLayer, int maxLayer,
            boolean allLayers, boolean useIdentityTransform);
@@ -688,17 +688,23 @@ public class SurfaceControl {
     * @param useIdentityTransform Replace whatever transformation (rotation,
     * scaling, translation) the surface layers are currently using with the
     * identity transformation while taking the screenshot.
     * @param rotation Apply a custom clockwise rotation to the screenshot, i.e.
     * Surface.ROTATION_0,90,180,270. Surfaceflinger will always take
     * screenshots in its native portrait orientation by default, so this is
     * useful for returning screenshots that are independent of device
     * orientation.
     * @return Returns a Bitmap containing the screen contents, or null
     * 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(Rect sourceCrop, int width, int height,
            int minLayer, int maxLayer, boolean useIdentityTransform) {
            int minLayer, int maxLayer, boolean useIdentityTransform,
            int rotation) {
        // TODO: should take the display as a parameter
        IBinder displayToken = SurfaceControl.getBuiltInDisplay(
                SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN);
        return nativeScreenshot(displayToken, sourceCrop, width, height,
                minLayer, maxLayer, false, useIdentityTransform);
                minLayer, maxLayer, false, useIdentityTransform, rotation);
    }

    /**
@@ -717,7 +723,8 @@ public class SurfaceControl {
        // TODO: should take the display as a parameter
        IBinder displayToken = SurfaceControl.getBuiltInDisplay(
                SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN);
        return nativeScreenshot(displayToken, new Rect(), width, height, 0, 0, true, false);
        return nativeScreenshot(displayToken, new Rect(), width, height, 0, 0, true,
                false, Surface.ROTATION_0);
    }

    private static void screenshot(IBinder display, Surface consumer, Rect sourceCrop,
+9 −12
Original line number Diff line number Diff line
@@ -117,7 +117,8 @@ static void nativeDestroy(JNIEnv* env, jclass clazz, jlong nativeObject) {

static jobject nativeScreenshotBitmap(JNIEnv* env, jclass clazz,
        jobject displayTokenObj, jobject sourceCropObj, jint width, jint height,
        jint minLayer, jint maxLayer, bool allLayers, bool useIdentityTransform) {
        jint minLayer, jint maxLayer, bool allLayers, bool useIdentityTransform,
        int rotation) {
    sp<IBinder> displayToken = ibinderForJavaObject(env, displayTokenObj);
    if (displayToken == NULL) {
        return NULL;
@@ -131,17 +132,13 @@ static jobject nativeScreenshotBitmap(JNIEnv* env, jclass clazz,

    SkAutoTDelete<ScreenshotClient> screenshot(new ScreenshotClient());
    status_t res;
    if (width > 0 && height > 0) {
    if (allLayers) {
            res = screenshot->update(displayToken, sourceCrop, width, height,
                    useIdentityTransform);
        } else {
            res = screenshot->update(displayToken, sourceCrop, width, height,
                    minLayer, maxLayer, useIdentityTransform);
        }
    } else {
        res = screenshot->update(displayToken, sourceCrop, useIdentityTransform);
        minLayer = 0;
        maxLayer = -1UL;
    }

    res = screenshot->update(displayToken, sourceCrop, width, height,
        minLayer, maxLayer, useIdentityTransform, static_cast<uint32_t>(rotation));
    if (res != NO_ERROR) {
        return NULL;
    }
@@ -588,7 +585,7 @@ static JNINativeMethod sSurfaceControlMethods[] = {
            (void*)nativeRelease },
    {"nativeDestroy", "(J)V",
            (void*)nativeDestroy },
    {"nativeScreenshot", "(Landroid/os/IBinder;Landroid/graphics/Rect;IIIIZZ)Landroid/graphics/Bitmap;",
    {"nativeScreenshot", "(Landroid/os/IBinder;Landroid/graphics/Rect;IIIIZZI)Landroid/graphics/Bitmap;",
            (void*)nativeScreenshotBitmap },
    {"nativeScreenshot", "(Landroid/os/IBinder;Landroid/view/Surface;Landroid/graphics/Rect;IIIIZZ)V",
            (void*)nativeScreenshot },
+12 −22
Original line number Diff line number Diff line
@@ -5931,7 +5931,7 @@ public class WindowManagerService extends IWindowManager.Stub
    @Override
    public Bitmap screenshotApplications(IBinder appToken, int displayId, int width,
            int height, boolean force565) {
        if (!checkCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
        if (!checkCallingPermission(Manifest.permission.READ_FRAME_BUFFER,
                "screenshotApplications()")) {
            throw new SecurityException("Requires READ_FRAME_BUFFER permission");
        }
@@ -5951,7 +5951,7 @@ public class WindowManagerService extends IWindowManager.Stub
            return null;
        }

        Bitmap rawss = null;
        Bitmap bm = null;

        int maxLayer = 0;
        final Rect frame = new Rect();
@@ -6092,10 +6092,8 @@ public class WindowManagerService extends IWindowManager.Stub

                // The screenshot API does not apply the current screen rotation.
                rot = getDefaultDisplayContentLocked().getDisplay().getRotation();

                if (rot == Surface.ROTATION_90 || rot == Surface.ROTATION_270) {
                    final int tmp = width;
                    width = height;
                    height = tmp;
                    rot = (rot == Surface.ROTATION_90) ? Surface.ROTATION_270 : Surface.ROTATION_90;
                }

@@ -6121,9 +6119,9 @@ public class WindowManagerService extends IWindowManager.Stub
                if (DEBUG_SCREENSHOT && inRotation) Slog.v(TAG,
                        "Taking screenshot while rotating");

                rawss = SurfaceControl.screenshot(crop, width, height, minLayer, maxLayer,
                        inRotation);
                if (rawss == null) {
                bm = SurfaceControl.screenshot(crop, width, height, minLayer, maxLayer,
                        inRotation, rot);
                if (bm == null) {
                    Slog.w(TAG, "Screenshot failure taking screenshot for (" + dw + "x" + dh
                            + ") to layer " + maxLayer);
                    return null;
@@ -6133,17 +6131,6 @@ public class WindowManagerService extends IWindowManager.Stub
            break;
        }

        Bitmap bm = Bitmap.createBitmap(width, height, force565 ?
                Config.RGB_565 : rawss.getConfig());
        if (DEBUG_SCREENSHOT) {
            bm.eraseColor(0xFF000000);
        }
        Matrix matrix = new Matrix();
        ScreenRotationAnimation.createRotationMatrix(rot, width, height, matrix);
        Canvas canvas = new Canvas(bm);
        canvas.drawBitmap(rawss, matrix, null);
        canvas.setBitmap(null);

        if (DEBUG_SCREENSHOT) {
            // TEST IF IT's ALL BLACK
            int[] buffer = new int[bm.getWidth() * bm.getHeight()];
@@ -6164,9 +6151,12 @@ public class WindowManagerService extends IWindowManager.Stub
            }
        }

        rawss.recycle();

        return bm;
        // Copy the screenshot bitmap to another buffer so that the gralloc backed
        // bitmap will not have a long lifetime. Gralloc memory can be pinned or
        // duplicated and might have a higher cost than a skia backed buffer.
        Bitmap ret = bm.copy(bm.getConfig(),true);
        bm.recycle();
        return ret;
    }

    /**