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

Commit 21e499ac authored by Peiyong Lin's avatar Peiyong Lin
Browse files

Determine the dataspace of the screenshot buffer based on display color mode.

Previously when we capture layers into graphic buffer we always assume SRGB
dataspace, however, if we have an app that is in wide color gamut mode, we want
to show the difference. This patch adds the ability to determine the dataspace
screenshot graphic buffer based on the color mode of the display.

BUG: 116112787
Test: Build, flash and boot. Verify with WCG Photos.
Change-Id: Ie2df32cad056576c256b9299a67855ed73714f50
parent bef3d76b
Loading
Loading
Loading
Loading
+13 −7
Original line number Diff line number Diff line
@@ -1787,17 +1787,17 @@ public class ActivityManager {
        private final float mScale;
        private final int mSystemUiVisibility;
        private final boolean mIsTranslucent;

        // TODO(b/116112787) TaskSnapshot must also book keep the color space from hardware bitmap
        // when created.
        private final ColorSpace mColorSpace = ColorSpace.get(ColorSpace.Named.SRGB);
        // Must be one of the named color spaces, otherwise, always use SRGB color space.
        private final ColorSpace mColorSpace;

        public TaskSnapshot(@NonNull ComponentName topActivityComponent, GraphicBuffer snapshot,
                int orientation, Rect contentInsets, boolean reducedResolution, float scale,
                boolean isRealSnapshot, int windowingMode, int systemUiVisibility,
                boolean isTranslucent) {
                @NonNull ColorSpace colorSpace, int orientation, Rect contentInsets,
                boolean reducedResolution, float scale, boolean isRealSnapshot, int windowingMode,
                int systemUiVisibility, boolean isTranslucent) {
            mTopActivityComponent = topActivityComponent;
            mSnapshot = snapshot;
            mColorSpace = colorSpace.getId() < 0
                    ? ColorSpace.get(ColorSpace.Named.SRGB) : colorSpace;
            mOrientation = orientation;
            mContentInsets = new Rect(contentInsets);
            mReducedResolution = reducedResolution;
@@ -1811,6 +1811,10 @@ public class ActivityManager {
        private TaskSnapshot(Parcel source) {
            mTopActivityComponent = ComponentName.readFromParcel(source);
            mSnapshot = source.readParcelable(null /* classLoader */);
            int colorSpaceId = source.readInt();
            mColorSpace = colorSpaceId >= 0
                    ? ColorSpace.get(ColorSpace.Named.values()[colorSpaceId])
                    : ColorSpace.get(ColorSpace.Named.SRGB);
            mOrientation = source.readInt();
            mContentInsets = source.readParcelable(null /* classLoader */);
            mReducedResolution = source.readBoolean();
@@ -1917,6 +1921,7 @@ public class ActivityManager {
        public void writeToParcel(Parcel dest, int flags) {
            ComponentName.writeToParcel(mTopActivityComponent, dest);
            dest.writeParcelable(mSnapshot, 0);
            dest.writeInt(mColorSpace.getId());
            dest.writeInt(mOrientation);
            dest.writeParcelable(mContentInsets, 0);
            dest.writeBoolean(mReducedResolution);
@@ -1934,6 +1939,7 @@ public class ActivityManager {
            return "TaskSnapshot{"
                    + " mTopActivityComponent=" + mTopActivityComponent.flattenToShortString()
                    + " mSnapshot=" + mSnapshot + " (" + width + "x" + height + ")"
                    + " mColorSpace=" + mColorSpace.toString()
                    + " mOrientation=" + mOrientation
                    + " mContentInsets=" + mContentInsets.toShortString()
                    + " mReducedResolution=" + mReducedResolution + " mScale=" + mScale
+6 −4
Original line number Diff line number Diff line
@@ -91,8 +91,8 @@ public final class SurfaceControl implements Parcelable {
    private static native ScreenshotGraphicBuffer nativeScreenshot(IBinder displayToken,
            Rect sourceCrop, int width, int height, boolean useIdentityTransform, int rotation,
            boolean captureSecureLayers);
    private static native ScreenshotGraphicBuffer nativeCaptureLayers(IBinder layerHandleToken,
            Rect sourceCrop, float frameScale, IBinder[] excludeLayers);
    private static native ScreenshotGraphicBuffer nativeCaptureLayers(IBinder displayToken,
            IBinder layerHandleToken, Rect sourceCrop, float frameScale, IBinder[] excludeLayers);

    private static native long nativeCreateTransaction();
    private static native long nativeGetNativeTransactionFinalizer();
@@ -2001,7 +2001,8 @@ public final class SurfaceControl implements Parcelable {
     */
    public static ScreenshotGraphicBuffer captureLayers(IBinder layerHandleToken, Rect sourceCrop,
            float frameScale) {
        return nativeCaptureLayers(layerHandleToken, sourceCrop, frameScale, null);
        final IBinder displayToken = SurfaceControl.getInternalDisplayToken();
        return nativeCaptureLayers(displayToken, layerHandleToken, sourceCrop, frameScale, null);
    }

    /**
@@ -2010,7 +2011,8 @@ public final class SurfaceControl implements Parcelable {
     */
    public static ScreenshotGraphicBuffer captureLayersExcluding(IBinder layerHandleToken,
            Rect sourceCrop, float frameScale, IBinder[] exclude) {
        return nativeCaptureLayers(layerHandleToken, sourceCrop, frameScale, exclude);
        final IBinder displayToken = SurfaceControl.getInternalDisplayToken();
        return nativeCaptureLayers(displayToken, layerHandleToken, sourceCrop, frameScale, exclude);
    }

    /**
+11 −4
Original line number Diff line number Diff line
@@ -271,8 +271,9 @@ static jobject nativeScreenshot(JNIEnv* env, jclass clazz,
            capturedSecureLayers);
}

static jobject nativeCaptureLayers(JNIEnv* env, jclass clazz, jobject layerHandleToken,
        jobject sourceCropObj, jfloat frameScale, jobjectArray excludeArray) {
static jobject nativeCaptureLayers(JNIEnv* env, jclass clazz, jobject displayTokenObj,
        jobject layerHandleToken, jobject sourceCropObj, jfloat frameScale,
        jobjectArray excludeArray) {

    sp<IBinder> layerHandle = ibinderForJavaObject(env, layerHandleToken);
    if (layerHandle == NULL) {
@@ -301,7 +302,12 @@ static jobject nativeCaptureLayers(JNIEnv* env, jclass clazz, jobject layerHandl
    }

    sp<GraphicBuffer> buffer;
    const ui::Dataspace dataspace = ui::Dataspace::V0_SRGB;
    ui::Dataspace dataspace = ui::Dataspace::V0_SRGB;
    sp<IBinder> displayToken = ibinderForJavaObject(env, displayTokenObj);
    if (displayToken != nullptr) {
        const ui::ColorMode colorMode = SurfaceComposerClient::getActiveColorMode(displayToken);
        dataspace = pickDataspaceFromColorMode(colorMode);
    }
    status_t res = ScreenshotClient::captureChildLayers(layerHandle, dataspace,
                                                        ui::PixelFormat::RGBA_8888, sourceCrop,
                                                        excludeHandles, frameScale, &buffer);
@@ -1373,7 +1379,8 @@ static const JNINativeMethod sSurfaceControlMethods[] = {
            "Landroid/view/SurfaceControl$ScreenshotGraphicBuffer;",
            (void*)nativeScreenshot },
    {"nativeCaptureLayers",
            "(Landroid/os/IBinder;Landroid/graphics/Rect;F[Landroid/os/IBinder;)"
            "(Landroid/os/IBinder;Landroid/os/IBinder;Landroid/graphics/Rect;"
            "F[Landroid/os/IBinder;)"
            "Landroid/view/SurfaceControl$ScreenshotGraphicBuffer;",
            (void*)nativeCaptureLayers },
    {"nativeSetInputWindowInfo", "(JJLandroid/view/InputWindowHandle;)V",
+7 −7
Original line number Diff line number Diff line
@@ -292,9 +292,9 @@ class TaskSnapshotController {
        }
        final boolean isWindowTranslucent = mainWindow.getAttrs().format != PixelFormat.OPAQUE;
        return new TaskSnapshot(appWindowToken.mActivityComponent, buffer,
                appWindowToken.getConfiguration().orientation, getInsets(mainWindow),
                isLowRamDevice /* reduced */, scaleFraction /* scale */, true /* isRealSnapshot */,
                task.getWindowingMode(), getSystemUiVisibility(task),
                screenshotBuffer.getColorSpace(), appWindowToken.getConfiguration().orientation,
                getInsets(mainWindow), isLowRamDevice /* reduced */, scaleFraction /* scale */,
                true /* isRealSnapshot */, task.getWindowingMode(), getSystemUiVisibility(task),
                !appWindowToken.fillsParent() || isWindowTranslucent);
    }

@@ -385,10 +385,10 @@ class TaskSnapshotController {
        // Note, the app theme snapshot is never translucent because we enforce a non-translucent
        // color above
        return new TaskSnapshot(topChild.mActivityComponent, hwBitmap.createGraphicBufferHandle(),
                topChild.getConfiguration().orientation, mainWindow.getStableInsets(),
                ActivityManager.isLowRamDeviceStatic() /* reduced */, 1.0f /* scale */,
                false /* isRealSnapshot */, task.getWindowingMode(), getSystemUiVisibility(task),
                false);
                hwBitmap.getColorSpace(), topChild.getConfiguration().orientation,
                mainWindow.getStableInsets(), ActivityManager.isLowRamDeviceStatic() /* reduced */,
                1.0f /* scale */, false /* isRealSnapshot */, task.getWindowingMode(),
                getSystemUiVisibility(task), false);
    }

    /**
+2 −1
Original line number Diff line number Diff line
@@ -89,7 +89,8 @@ class TaskSnapshotLoader {
            }
            ComponentName topActivityComponent = ComponentName.unflattenFromString(
                    proto.topActivityComponent);
            return new TaskSnapshot(topActivityComponent, buffer, proto.orientation,
            return new TaskSnapshot(topActivityComponent, buffer, bitmap.getColorSpace(),
                    proto.orientation,
                    new Rect(proto.insetLeft, proto.insetTop, proto.insetRight, proto.insetBottom),
                    reducedResolution, reducedResolution ? mPersister.getReducedScale() : 1f,
                    proto.isRealSnapshot, proto.windowingMode, proto.systemUiVisibility,
Loading