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

Commit 36ae1ded authored by Peiyong Lin's avatar Peiyong Lin Committed by Android (Google) Code Review
Browse files

Merge "Revert "Allow screenshot to carry more information.""

parents 912eb6e9 bf9d677a
Loading
Loading
Loading
Loading
+15 −54
Original line number Diff line number Diff line
@@ -88,10 +88,10 @@ public final class SurfaceControl implements Parcelable {
    private static native void nativeDestroy(long nativeObject);
    private static native void nativeDisconnect(long nativeObject);

    private static native ScreenshotGraphicBuffer nativeScreenshot(IBinder displayToken,
    private static native GraphicBuffer nativeScreenshot(IBinder displayToken,
            Rect sourceCrop, int width, int height, boolean useIdentityTransform, int rotation,
            boolean captureSecureLayers);
    private static native ScreenshotGraphicBuffer nativeCaptureLayers(IBinder layerHandleToken,
    private static native GraphicBuffer nativeCaptureLayers(IBinder layerHandleToken,
            Rect sourceCrop, float frameScale);

    private static native long nativeCreateTransaction();
@@ -430,46 +430,6 @@ public final class SurfaceControl implements Parcelable {
     */
    public static final int METADATA_TASK_ID = 3;

    /**
     * A wrapper around GraphicBuffer that contains extra information about how to
     * interpret the screenshot GraphicBuffer.
     * @hide
     */
    public static class ScreenshotGraphicBuffer {
        private final GraphicBuffer mGraphicBuffer;
        private final ColorSpace mColorSpace;

        public ScreenshotGraphicBuffer(GraphicBuffer graphicBuffer, ColorSpace colorSpace) {
            mGraphicBuffer = graphicBuffer;
            mColorSpace = colorSpace;
        }

       /**
        * Create ScreenshotGraphicBuffer from existing native GraphicBuffer object.
        * @param width The width in pixels of the buffer
        * @param height The height in pixels of the buffer
        * @param format The format of each pixel as specified in {@link PixelFormat}
        * @param usage Hint indicating how the buffer will be used
        * @param unwrappedNativeObject The native object of GraphicBuffer
        * @param namedColorSpace Integer value of a named color space {@link ColorSpace.Named}
        */
        private static ScreenshotGraphicBuffer createFromNative(int width, int height, int format,
                int usage, long unwrappedNativeObject, int namedColorSpace) {
            GraphicBuffer graphicBuffer = GraphicBuffer.createFromExisting(width, height, format,
                    usage, unwrappedNativeObject);
            ColorSpace colorSpace = ColorSpace.get(ColorSpace.Named.values()[namedColorSpace]);
            return new ScreenshotGraphicBuffer(graphicBuffer, colorSpace);
        }

        public ColorSpace getColorSpace() {
            return mColorSpace;
        }

        public GraphicBuffer getGraphicBuffer() {
            return mGraphicBuffer;
        }
    }

    /**
     * Builder class for {@link SurfaceControl} objects.
     */
@@ -1855,10 +1815,10 @@ public final class SurfaceControl implements Parcelable {
            throw new IllegalArgumentException("consumer must not be null");
        }

        final ScreenshotGraphicBuffer buffer = screenshotToBuffer(display, sourceCrop, width,
                height, useIdentityTransform, rotation);
        final GraphicBuffer buffer = screenshotToBuffer(display, sourceCrop, width, height,
                useIdentityTransform, rotation);
        try {
            consumer.attachAndQueueBuffer(buffer.getGraphicBuffer());
            consumer.attachAndQueueBuffer(buffer);
        } catch (RuntimeException e) {
            Log.w(TAG, "Failed to take screenshot - " + e.getMessage());
        }
@@ -1901,16 +1861,17 @@ public final class SurfaceControl implements Parcelable {
        }

        SurfaceControl.rotateCropForSF(sourceCrop, rotation);
        final ScreenshotGraphicBuffer buffer = screenshotToBuffer(displayToken, sourceCrop, width,
                height, useIdentityTransform, rotation);
        final GraphicBuffer buffer = screenshotToBuffer(displayToken, sourceCrop, width, height,
                useIdentityTransform, rotation);

        if (buffer == null) {
            Log.w(TAG, "Failed to take screenshot");
            return null;
        }
        return Bitmap.wrapHardwareBuffer(
                HardwareBuffer.createFromGraphicBuffer(buffer.getGraphicBuffer()),
                buffer.getColorSpace());
        // TODO(b/116112787) Now that hardware bitmap creation can take color space, we
        // should continue to fix screenshot.
        return Bitmap.wrapHardwareBuffer(HardwareBuffer.createFromGraphicBuffer(buffer),
                ColorSpace.get(ColorSpace.Named.SRGB));
    }

    /**
@@ -1936,8 +1897,8 @@ public final class SurfaceControl implements Parcelable {
     * @return Returns a GraphicBuffer that contains the captured content.
     * @hide
     */
    public static ScreenshotGraphicBuffer screenshotToBuffer(IBinder display, Rect sourceCrop,
            int width, int height, boolean useIdentityTransform, int rotation) {
    public static GraphicBuffer screenshotToBuffer(IBinder display, Rect sourceCrop, int width,
            int height, boolean useIdentityTransform, int rotation) {
        if (display == null) {
            throw new IllegalArgumentException("displayToken must not be null");
        }
@@ -1956,7 +1917,7 @@ public final class SurfaceControl implements Parcelable {
     *
     * @hide
     */
    public static ScreenshotGraphicBuffer screenshotToBufferWithSecureLayersUnsafe(IBinder display,
    public static GraphicBuffer screenshotToBufferWithSecureLayersUnsafe(IBinder display,
            Rect sourceCrop, int width, int height, boolean useIdentityTransform,
            int rotation) {
        if (display == null) {
@@ -1990,7 +1951,7 @@ public final class SurfaceControl implements Parcelable {
     * @return Returns a GraphicBuffer that contains the layer capture.
     * @hide
     */
    public static ScreenshotGraphicBuffer captureLayers(IBinder layerHandleToken, Rect sourceCrop,
    public static GraphicBuffer captureLayers(IBinder layerHandleToken, Rect sourceCrop,
            float frameScale) {
        return nativeCaptureLayers(layerHandleToken, sourceCrop, frameScale);
    }
+10 −65
Original line number Diff line number Diff line
@@ -126,41 +126,6 @@ static struct {
    jfieldID white;
} gDisplayPrimariesClassInfo;

static struct {
    jclass clazz;
    jmethodID builder;
} gScreenshotGraphicBufferClassInfo;

class JNamedColorSpace {
public:
    // ColorSpace.Named.SRGB.ordinal() = 0;
    static constexpr jint SRGB = 0;

    // ColorSpace.Named.DISPLAY_P3.ordinal() = 6;
    static constexpr jint DISPLAY_P3 = 6;
};

constexpr jint fromDataspaceToNamedColorSpaceValue(const ui::Dataspace dataspace) {
    switch (dataspace) {
        case ui::Dataspace::DISPLAY_P3:
            return JNamedColorSpace::DISPLAY_P3;
        default:
            return JNamedColorSpace::SRGB;
    }
}

constexpr ui::Dataspace pickDataspaceFromColorMode(const ui::ColorMode colorMode) {
    switch (colorMode) {
        case ui::ColorMode::DISPLAY_P3:
        case ui::ColorMode::BT2100_PQ:
        case ui::ColorMode::BT2100_HLG:
        case ui::ColorMode::DISPLAY_BT2020:
            return ui::Dataspace::DISPLAY_P3;
        default:
            return ui::Dataspace::V0_SRGB;
    }
}

// ----------------------------------------------------------------------------

static jlong nativeCreateTransaction(JNIEnv* env, jclass clazz) {
@@ -245,12 +210,9 @@ static jobject nativeScreenshot(JNIEnv* env, jclass clazz,
    if (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;
    status_t res = ScreenshotClient::capture(displayToken, dataspace,
    status_t res = ScreenshotClient::capture(displayToken, ui::Dataspace::V0_SRGB,
            ui::PixelFormat::RGBA_8888,
            sourceCrop, width, height,
            useIdentityTransform, rotation, captureSecureLayers, &buffer);
@@ -258,15 +220,13 @@ static jobject nativeScreenshot(JNIEnv* env, jclass clazz,
        return NULL;
    }

    const jint namedColorSpace = fromDataspaceToNamedColorSpaceValue(dataspace);
    return env->CallStaticObjectMethod(gScreenshotGraphicBufferClassInfo.clazz,
            gScreenshotGraphicBufferClassInfo.builder,
    return env->CallStaticObjectMethod(gGraphicBufferClassInfo.clazz,
            gGraphicBufferClassInfo.builder,
            buffer->getWidth(),
            buffer->getHeight(),
            buffer->getPixelFormat(),
            (jint)buffer->getUsage(),
            (jlong)buffer.get(),
            namedColorSpace);
            (jlong)buffer.get());
}

static jobject nativeCaptureLayers(JNIEnv* env, jclass clazz, jobject layerHandleToken,
@@ -283,23 +243,20 @@ static jobject nativeCaptureLayers(JNIEnv* env, jclass clazz, jobject layerHandl
    }

    sp<GraphicBuffer> buffer;
    const ui::Dataspace dataspace = ui::Dataspace::V0_SRGB;
    status_t res = ScreenshotClient::captureChildLayers(layerHandle, dataspace,
    status_t res = ScreenshotClient::captureChildLayers(layerHandle, ui::Dataspace::V0_SRGB,
                                                        ui::PixelFormat::RGBA_8888, sourceCrop,
                                                        frameScale, &buffer);
    if (res != NO_ERROR) {
        return NULL;
    }

    const jint namedColorSpace = fromDataspaceToNamedColorSpaceValue(dataspace);
    return env->CallStaticObjectMethod(gScreenshotGraphicBufferClassInfo.clazz,
                                       gScreenshotGraphicBufferClassInfo.builder,
    return env->CallStaticObjectMethod(gGraphicBufferClassInfo.clazz,
                                       gGraphicBufferClassInfo.builder,
                                       buffer->getWidth(),
                                       buffer->getHeight(),
                                       buffer->getPixelFormat(),
                                       (jint)buffer->getUsage(),
                                       (jlong)buffer.get(),
                                       namedColorSpace);
                                       (jlong)buffer.get());
}

static void nativeApplyTransaction(JNIEnv* env, jclass clazz, jlong transactionObj, jboolean sync) {
@@ -1349,13 +1306,9 @@ static const JNINativeMethod sSurfaceControlMethods[] = {
            (void*)nativeSetOverrideScalingMode },
    {"nativeGetHandle", "(J)Landroid/os/IBinder;",
            (void*)nativeGetHandle },
    {"nativeScreenshot",
            "(Landroid/os/IBinder;Landroid/graphics/Rect;IIZIZ)"
            "Landroid/view/SurfaceControl$ScreenshotGraphicBuffer;",
    {"nativeScreenshot", "(Landroid/os/IBinder;Landroid/graphics/Rect;IIZIZ)Landroid/graphics/GraphicBuffer;",
            (void*)nativeScreenshot },
    {"nativeCaptureLayers",
            "(Landroid/os/IBinder;Landroid/graphics/Rect;F)"
            "Landroid/view/SurfaceControl$ScreenshotGraphicBuffer;",
    {"nativeCaptureLayers", "(Landroid/os/IBinder;Landroid/graphics/Rect;F)Landroid/graphics/GraphicBuffer;",
            (void*)nativeCaptureLayers },
    {"nativeSetInputWindowInfo", "(JJLandroid/view/InputWindowHandle;)V",
            (void*)nativeSetInputWindowInfo },
@@ -1433,14 +1386,6 @@ int register_android_view_SurfaceControl(JNIEnv* env)
    gGraphicBufferClassInfo.builder = GetStaticMethodIDOrDie(env, graphicsBufferClazz,
            "createFromExisting", "(IIIIJ)Landroid/graphics/GraphicBuffer;");

    jclass screenshotGraphicsBufferClazz = FindClassOrDie(env,
            "android/view/SurfaceControl$ScreenshotGraphicBuffer");
    gScreenshotGraphicBufferClassInfo.clazz =
            MakeGlobalRefOrDie(env, screenshotGraphicsBufferClazz);
    gScreenshotGraphicBufferClassInfo.builder = GetStaticMethodIDOrDie(env,
            screenshotGraphicsBufferClazz,
            "createFromNative", "(IIIIJI)Landroid/view/SurfaceControl$ScreenshotGraphicBuffer;");

    jclass displayedContentSampleClazz = FindClassOrDie(env,
            "android/hardware/display/DisplayedContentSample");
    gDisplayedContentSampleClassInfo.clazz = MakeGlobalRefOrDie(env, displayedContentSampleClazz);
+5 −5
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@ import android.content.pm.ParceledListSlice;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.ColorSpace;
import android.graphics.GraphicBuffer;
import android.graphics.Point;
import android.graphics.Rect;
import android.hardware.SensorManager;
@@ -1274,12 +1275,11 @@ public final class DisplayManagerService extends SystemService {
        if (token == null) {
            return false;
        }
        final SurfaceControl.ScreenshotGraphicBuffer gb =
                SurfaceControl.screenshotToBufferWithSecureLayersUnsafe(
                        token, new Rect(), 0 /* width */, 0 /* height */,
                        false /* useIdentityTransform */, 0 /* rotation */);
        final GraphicBuffer gb = SurfaceControl.screenshotToBufferWithSecureLayersUnsafe(
                token, new Rect(), 0 /* width */, 0 /* height */, false /* useIdentityTransform */,
                0 /* rotation */);
        try {
            outSurface.attachAndQueueBuffer(gb.getGraphicBuffer());
            outSurface.attachAndQueueBuffer(gb);
        } catch (RuntimeException e) {
            Slog.w(TAG, "Failed to take screenshot - " + e.getMessage());
        }
+2 −5
Original line number Diff line number Diff line
@@ -279,11 +279,8 @@ class TaskSnapshotController {
            Slog.w(TAG_WM, "Failed to take screenshot. No main window for " + task);
            return null;
        }
        final SurfaceControl.ScreenshotGraphicBuffer screenshotBuffer =
                SurfaceControl.captureLayers(
        final GraphicBuffer buffer = SurfaceControl.captureLayers(
                task.getSurfaceControl().getHandle(), mTmpRect, scaleFraction);
        final GraphicBuffer buffer = screenshotBuffer != null ? screenshotBuffer.getGraphicBuffer()
                : null;
        if (buffer == null || buffer.getWidth() <= 1 || buffer.getHeight() <= 1) {
            if (DEBUG_SCREENSHOT) {
                Slog.w(TAG_WM, "Failed to take screenshot for " + task);
+7 −4
Original line number Diff line number Diff line
@@ -34,6 +34,8 @@ import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import static com.android.server.wm.WindowManagerService.H.WALLPAPER_DRAW_PENDING_TIMEOUT;

import android.graphics.Bitmap;
import android.graphics.ColorSpace;
import android.graphics.GraphicBuffer;
import android.graphics.Rect;
import android.hardware.HardwareBuffer;
import android.os.Bundle;
@@ -736,16 +738,17 @@ class WallpaperController {
        final Rect bounds = wallpaperWindowState.getBounds();
        bounds.offsetTo(0, 0);

        SurfaceControl.ScreenshotGraphicBuffer wallpaperBuffer = SurfaceControl.captureLayers(
        GraphicBuffer wallpaperBuffer = SurfaceControl.captureLayers(
                wallpaperWindowState.getSurfaceControl().getHandle(), bounds, 1 /* frameScale */);

        if (wallpaperBuffer == null) {
            Slog.w(TAG_WM, "Failed to screenshot wallpaper");
            return null;
        }
        return Bitmap.wrapHardwareBuffer(
                HardwareBuffer.createFromGraphicBuffer(wallpaperBuffer.getGraphicBuffer()),
                wallpaperBuffer.getColorSpace());
        // TODO(b/116112787) Now that hardware bitmap creation can take color space, we
        // should continue to fix screenshot.
        return Bitmap.wrapHardwareBuffer(HardwareBuffer.createFromGraphicBuffer(wallpaperBuffer),
                                         ColorSpace.get(ColorSpace.Named.SRGB));
    }

    private WindowState getTopVisibleWallpaper() {