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

Commit dd417895 authored by Rob Carr's avatar Rob Carr Committed by android-build-merger
Browse files

Merge "Careful with screenshots containing secure layers!" into qt-dev am: f8f5f029

am: cea68c79

Change-Id: Ia2649df1fe70cc01b1544de9f6f22010c932f220
parents 14d3745d cea68c79
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import android.util.SparseArray;
import android.view.Display;
import android.view.DisplayInfo;
import android.view.Surface;
import android.view.SurfaceControl;
import android.view.SurfaceControl.Transaction;

/**
@@ -64,13 +65,12 @@ public abstract class DisplayManagerInternal {
    public abstract boolean isProximitySensorAvailable();

    /**
     * Take a screenshot of the specified display into the provided {@link Surface}.
     * Take a screenshot of the specified display and return a buffer.
     *
     * @param displayId The display id to take the screenshot of.
     * @param outSurface The {@link Surface} to take the screenshot into.
     * @return True if the screenshot is taken.
     * @return The buffer or null if we have failed.
     */
    public abstract boolean screenshot(int displayId, Surface outSurface);
    public abstract SurfaceControl.ScreenshotGraphicBuffer screenshot(int displayId);

    /**
     * Returns information about the specified logical display.
+13 −3
Original line number Diff line number Diff line
@@ -439,10 +439,13 @@ public final class SurfaceControl implements Parcelable {
    public static class ScreenshotGraphicBuffer {
        private final GraphicBuffer mGraphicBuffer;
        private final ColorSpace mColorSpace;
        private final boolean mContainsSecureLayers;

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

       /**
@@ -453,13 +456,16 @@ public final class SurfaceControl implements Parcelable {
        * @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}
        * @param containsSecureLayer Indicates whether this graphic buffer contains captured contents
        *        of secure layers, in which case the screenshot should not be persisted.
        */
        private static ScreenshotGraphicBuffer createFromNative(int width, int height, int format,
                int usage, long unwrappedNativeObject, int namedColorSpace) {
                int usage, long unwrappedNativeObject, int namedColorSpace,
                boolean containsSecureLayers) {
            GraphicBuffer graphicBuffer = GraphicBuffer.createFromExisting(width, height, format,
                    usage, unwrappedNativeObject);
            ColorSpace colorSpace = ColorSpace.get(ColorSpace.Named.values()[namedColorSpace]);
            return new ScreenshotGraphicBuffer(graphicBuffer, colorSpace);
            return new ScreenshotGraphicBuffer(graphicBuffer, colorSpace, containsSecureLayers);
        }

        public ColorSpace getColorSpace() {
@@ -469,6 +475,10 @@ public final class SurfaceControl implements Parcelable {
        public GraphicBuffer getGraphicBuffer() {
            return mGraphicBuffer;
        }

        public boolean containsSecureLayers() {
            return mContainsSecureLayers;
        }
    }

    /**
+5 −3
Original line number Diff line number Diff line
@@ -250,10 +250,11 @@ static jobject nativeScreenshot(JNIEnv* env, jclass clazz,

    Rect sourceCrop = rectFromObj(env, sourceCropObj);
    sp<GraphicBuffer> buffer;
    bool capturedSecureLayers = false;
    status_t res = ScreenshotClient::capture(displayToken, dataspace,
            ui::PixelFormat::RGBA_8888,
            sourceCrop, width, height,
            useIdentityTransform, rotation, captureSecureLayers, &buffer);
            useIdentityTransform, rotation, captureSecureLayers, &buffer, capturedSecureLayers);
    if (res != NO_ERROR) {
        return NULL;
    }
@@ -266,7 +267,8 @@ static jobject nativeScreenshot(JNIEnv* env, jclass clazz,
            buffer->getPixelFormat(),
            (jint)buffer->getUsage(),
            (jlong)buffer.get(),
            namedColorSpace);
            namedColorSpace,
            capturedSecureLayers);
}

static jobject nativeCaptureLayers(JNIEnv* env, jclass clazz, jobject layerHandleToken,
@@ -1455,7 +1457,7 @@ int register_android_view_SurfaceControl(JNIEnv* env)
            MakeGlobalRefOrDie(env, screenshotGraphicsBufferClazz);
    gScreenshotGraphicBufferClassInfo.builder = GetStaticMethodIDOrDie(env,
            screenshotGraphicsBufferClazz,
            "createFromNative", "(IIIIJI)Landroid/view/SurfaceControl$ScreenshotGraphicBuffer;");
            "createFromNative", "(IIIIJIZ)Landroid/view/SurfaceControl$ScreenshotGraphicBuffer;");

    jclass displayedContentSampleClazz = FindClassOrDie(env,
            "android/hardware/display/DisplayedContentSample");
+5 −12
Original line number Diff line number Diff line
@@ -1269,21 +1269,14 @@ public final class DisplayManagerService extends SystemService {
        return null;
    }

    private boolean screenshotInternal(int displayId, Surface outSurface) {
    private SurfaceControl.ScreenshotGraphicBuffer screenshotInternal(int displayId) {
        final IBinder token = getDisplayToken(displayId);
        if (token == null) {
            return false;
            return null;
        }
        final SurfaceControl.ScreenshotGraphicBuffer gb =
                SurfaceControl.screenshotToBufferWithSecureLayersUnsafe(
        return SurfaceControl.screenshotToBufferWithSecureLayersUnsafe(
                        token, new Rect(), 0 /* width */, 0 /* height */,
                        false /* useIdentityTransform */, 0 /* rotation */);
        try {
            outSurface.attachAndQueueBuffer(gb.getGraphicBuffer());
        } catch (RuntimeException e) {
            Slog.w(TAG, "Failed to take screenshot - " + e.getMessage());
        }
        return true;
    }

    @VisibleForTesting
@@ -2354,8 +2347,8 @@ public final class DisplayManagerService extends SystemService {
        }

        @Override
        public boolean screenshot(int displayId, Surface outSurface) {
            return screenshotInternal(displayId, outSurface);
        public SurfaceControl.ScreenshotGraphicBuffer screenshot(int displayId) {
            return screenshotInternal(displayId);
        }

        @Override
+14 −1
Original line number Diff line number Diff line
@@ -275,7 +275,20 @@ class ScreenRotationAnimation {
            final int displayId = display.getDisplayId();
            final Surface surface = mService.mSurfaceFactory.make();
            surface.copyFrom(mSurfaceControl);
            if (mService.mDisplayManagerInternal.screenshot(displayId, surface)) {
            SurfaceControl.ScreenshotGraphicBuffer gb =
                mService.mDisplayManagerInternal.screenshot(displayId);
            if (gb != null) {
                try {
                    surface.attachAndQueueBuffer(gb.getGraphicBuffer());
                } catch (RuntimeException e) {
                    Slog.w(TAG, "Failed to attach screenshot - " + e.getMessage());
                }
                // If the screenshot contains secure layers, we have to make sure the
                // screenshot surface we display it in also has FLAG_SECURE so that
                // the user can not screenshot secure layers via the screenshot surface.
                if (gb.containsSecureLayers()) {
                    t.setSecure(mSurfaceControl, true);
                }
                t.setLayer(mSurfaceControl, SCREEN_FREEZE_LAYER_SCREENSHOT);
                t.setAlpha(mSurfaceControl, 0);
                t.show(mSurfaceControl);