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

Commit 02b7943a authored by Automerger Merge Worker's avatar Automerger Merge Worker Committed by Android (Google) Code Review
Browse files

Merge "Merge "Support both HDR and display-native screenshots." into udc-dev...

Merge "Merge "Support both HDR and display-native screenshots." into udc-dev am: 8c01119c am: 20b31f1c"
parents dccc634f 7550fd2a
Loading
Loading
Loading
Loading
+29 −6
Original line number Diff line number Diff line
@@ -198,17 +198,21 @@ public class ScreenCapture {
         * Create ScreenshotHardwareBuffer from an existing HardwareBuffer object.
         *
         * @param hardwareBuffer       The existing HardwareBuffer object
         * @param namedColorSpace      Integer value of a named color space {@link ColorSpace.Named}
         * @param dataspace            Dataspace describing the content.
         *                             {@see android.hardware.DataSpace}
         * @param containsSecureLayers Indicates whether this graphic buffer contains captured
         *                             contents of secure layers, in which case the screenshot
         *                             should not be persisted.
         * @param containsHdrLayers    Indicates whether this graphic buffer contains HDR content.
         */
        private static ScreenshotHardwareBuffer createFromNative(HardwareBuffer hardwareBuffer,
                int namedColorSpace, boolean containsSecureLayers, boolean containsHdrLayers) {
            ColorSpace colorSpace = ColorSpace.get(ColorSpace.Named.values()[namedColorSpace]);
                int dataspace, boolean containsSecureLayers, boolean containsHdrLayers) {
            ColorSpace colorSpace = ColorSpace.getFromDataSpace(dataspace);
            return new ScreenshotHardwareBuffer(
                    hardwareBuffer, colorSpace, containsSecureLayers, containsHdrLayers);
                    hardwareBuffer,
                    colorSpace != null ? colorSpace : ColorSpace.get(ColorSpace.Named.SRGB),
                    containsSecureLayers,
                    containsHdrLayers);
        }

        public ColorSpace getColorSpace() {
@@ -271,8 +275,8 @@ public class ScreenCapture {
        public final boolean mAllowProtected;
        public final long mUid;
        public final boolean mGrayscale;

        final SurfaceControl[] mExcludeLayers;
        public final boolean mHintForSeamlessTransition;

        private CaptureArgs(CaptureArgs.Builder<? extends CaptureArgs.Builder<?>> builder) {
            mPixelFormat = builder.mPixelFormat;
@@ -284,6 +288,7 @@ public class ScreenCapture {
            mUid = builder.mUid;
            mGrayscale = builder.mGrayscale;
            mExcludeLayers = builder.mExcludeLayers;
            mHintForSeamlessTransition = builder.mHintForSeamlessTransition;
        }

        private CaptureArgs(Parcel in) {
@@ -305,6 +310,7 @@ public class ScreenCapture {
            } else {
                mExcludeLayers = null;
            }
            mHintForSeamlessTransition = in.readBoolean();
        }

        /** Release any layers if set using {@link Builder#setExcludeLayers(SurfaceControl[])}. */
@@ -352,6 +358,7 @@ public class ScreenCapture {
            private long mUid = -1;
            private boolean mGrayscale;
            private SurfaceControl[] mExcludeLayers;
            private boolean mHintForSeamlessTransition;

            /**
             * Construct a new {@link CaptureArgs} with the set parameters. The builder remains
@@ -448,6 +455,21 @@ public class ScreenCapture {
                return getThis();
            }

            /**
             * Set whether the screenshot will be used in a system animation.
             * This hint is used for picking the "best" colorspace for the screenshot, in particular
             * for mixing HDR and SDR content.
             * E.g., hintForSeamlessTransition is false, then a colorspace suitable for file
             * encoding, such as BT2100, may be chosen. Otherwise, then the display's color space
             * would be chosen, with the possibility of having an extended brightness range. This
             * is important for screenshots that are directly re-routed to a SurfaceControl in
             * order to preserve accurate colors.
             */
            public T setHintForSeamlessTransition(boolean hintForSeamlessTransition) {
                mHintForSeamlessTransition = hintForSeamlessTransition;
                return getThis();
            }

            /**
             * Each sub class should return itself to allow the builder to chain properly
             */
@@ -471,7 +493,6 @@ public class ScreenCapture {
            dest.writeBoolean(mAllowProtected);
            dest.writeLong(mUid);
            dest.writeBoolean(mGrayscale);

            if (mExcludeLayers != null) {
                dest.writeInt(mExcludeLayers.length);
                for (SurfaceControl excludeLayer : mExcludeLayers) {
@@ -480,6 +501,7 @@ public class ScreenCapture {
            } else {
                dest.writeInt(0);
            }
            dest.writeBoolean(mHintForSeamlessTransition);
        }

        public static final Parcelable.Creator<CaptureArgs> CREATOR =
@@ -627,6 +649,7 @@ public class ScreenCapture {
                setUid(args.mUid);
                setGrayscale(args.mGrayscale);
                setExcludeLayers(args.mExcludeLayers);
                setHintForSeamlessTransition(args.mHintForSeamlessTransition);
            }

            public Builder(SurfaceControl layer) {
+8 −21
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ static struct {
    jfieldID uid;
    jfieldID grayscale;
    jmethodID getNativeExcludeLayers;
    jfieldID hintForSeamlessTransition;
} gCaptureArgsClassInfo;

static struct {
@@ -69,23 +70,6 @@ static struct {
    jmethodID builder;
} gScreenshotHardwareBufferClassInfo;

enum JNamedColorSpace : jint {
    // ColorSpace.Named.SRGB.ordinal() = 0;
    SRGB = 0,

    // ColorSpace.Named.DISPLAY_P3.ordinal() = 7;
    DISPLAY_P3 = 7,
};

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

static void checkAndClearException(JNIEnv* env, const char* methodName) {
    if (env->ExceptionCheck()) {
        ALOGE("An exception was thrown by callback '%s'.", methodName);
@@ -119,12 +103,11 @@ public:
        captureResults.fenceResult.value()->waitForever(LOG_TAG);
        jobject jhardwareBuffer = android_hardware_HardwareBuffer_createFromAHardwareBuffer(
                env, captureResults.buffer->toAHardwareBuffer());
        const jint namedColorSpace =
                fromDataspaceToNamedColorSpaceValue(captureResults.capturedDataspace);
        jobject screenshotHardwareBuffer =
                env->CallStaticObjectMethod(gScreenshotHardwareBufferClassInfo.clazz,
                                            gScreenshotHardwareBufferClassInfo.builder,
                                            jhardwareBuffer, namedColorSpace,
                                            jhardwareBuffer,
                                            static_cast<jint>(captureResults.capturedDataspace),
                                            captureResults.capturedSecureLayers,
                                            captureResults.capturedHdrLayers);
        checkAndClearException(env, "builder");
@@ -185,6 +168,9 @@ static void getCaptureArgs(JNIEnv* env, jobject captureArgsObject, CaptureArgs&
            captureArgs.excludeHandles.emplace(excludeObject->getHandle());
        }
    }
    captureArgs.hintForSeamlessTransition =
            env->GetBooleanField(captureArgsObject,
                                 gCaptureArgsClassInfo.hintForSeamlessTransition);
}

static DisplayCaptureArgs displayCaptureArgsFromObject(JNIEnv* env,
@@ -318,9 +304,10 @@ int register_android_window_ScreenCapture(JNIEnv* env) {
            GetFieldIDOrDie(env, captureArgsClazz, "mAllowProtected", "Z");
    gCaptureArgsClassInfo.uid = GetFieldIDOrDie(env, captureArgsClazz, "mUid", "J");
    gCaptureArgsClassInfo.grayscale = GetFieldIDOrDie(env, captureArgsClazz, "mGrayscale", "Z");

    gCaptureArgsClassInfo.getNativeExcludeLayers =
            GetMethodIDOrDie(env, captureArgsClazz, "getNativeExcludeLayers", "()[J");
    gCaptureArgsClassInfo.hintForSeamlessTransition =
            GetFieldIDOrDie(env, captureArgsClazz, "mHintForSeamlessTransition", "Z");

    jclass displayCaptureArgsClazz =
            FindClassOrDie(env, "android/window/ScreenCapture$DisplayCaptureArgs");
+1 −0
Original line number Diff line number Diff line
@@ -144,6 +144,7 @@ class ScreenRotationAnimation {
                                .setCaptureSecureLayers(true)
                                .setAllowProtected(true)
                                .setSourceCrop(new Rect(0, 0, mStartWidth, mStartHeight))
                                .setHintForSeamlessTransition(true)
                                .build();
                ScreenCapture.ScreenshotHardwareBuffer screenshotBuffer =
                        ScreenCapture.captureLayers(args);
+2 −0
Original line number Diff line number Diff line
@@ -193,6 +193,7 @@ class ScreenRotationAnimation {
                                .setSourceCrop(new Rect(0, 0, width, height))
                                .setAllowProtected(true)
                                .setCaptureSecureLayers(true)
                                .setHintForSeamlessTransition(true)
                                .build();
                screenshotBuffer = ScreenCapture.captureDisplay(captureArgs);
            } else {
@@ -202,6 +203,7 @@ class ScreenRotationAnimation {
                                .setCaptureSecureLayers(true)
                                .setAllowProtected(true)
                                .setSourceCrop(new Rect(0, 0, width, height))
                                .setHintForSeamlessTransition(true)
                                .build();
                screenshotBuffer = ScreenCapture.captureLayers(captureArgs);
            }
+3 −2
Original line number Diff line number Diff line
@@ -2999,11 +2999,14 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {

            Rect cropBounds = new Rect(bounds);
            cropBounds.offsetTo(0, 0);
            final boolean isDisplayRotation = wc.asDisplayContent() != null
                    && wc.asDisplayContent().isRotationChanging();
            ScreenCapture.LayerCaptureArgs captureArgs =
                    new ScreenCapture.LayerCaptureArgs.Builder(wc.getSurfaceControl())
                            .setSourceCrop(cropBounds)
                            .setCaptureSecureLayers(true)
                            .setAllowProtected(true)
                            .setHintForSeamlessTransition(isDisplayRotation)
                            .build();
            ScreenCapture.ScreenshotHardwareBuffer screenshotBuffer =
                    ScreenCapture.captureLayers(captureArgs);
@@ -3014,8 +3017,6 @@ class Transition implements BLASTSyncEngine.TransactionReadyListener {
                Slog.w(TAG, "Failed to capture screenshot for " + wc);
                return false;
            }
            final boolean isDisplayRotation = wc.asDisplayContent() != null
                    && wc.asDisplayContent().isRotationChanging();
            // Some tests may check the name "RotationLayer" to detect display rotation.
            final String name = isDisplayRotation ? "RotationLayer" : "transition snapshot: " + wc;
            SurfaceControl snapshotSurface = wc.makeAnimationLeash()