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

am: f8f5f0290e

Change-Id: Ide698ce98fb2fde3ae30c410c508c7790fd59683
This commit is contained in:
Rob Carr
2019-04-08 19:52:49 -07:00
committed by android-build-merger
5 changed files with 41 additions and 23 deletions

View File

@@ -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.

View File

@@ -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;
}
}
/**

View File

@@ -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");

View File

@@ -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

View File

@@ -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);