Merge "Obtain correct screenshot based on device orientation" into rvc-dev

This commit is contained in:
Jacky Kao
2020-04-22 00:19:35 +00:00
committed by Android (Google) Code Review
4 changed files with 51 additions and 22 deletions

View File

@@ -65,21 +65,23 @@ public abstract class DisplayManagerInternal {
public abstract boolean isProximitySensorAvailable(); public abstract boolean isProximitySensorAvailable();
/** /**
* Take a screenshot of the specified display and return a buffer. * Screenshot for internal system-only use such as rotation, etc. This method includes
* secure layers and the result should never be exposed to non-system applications.
* This method does not apply any rotation and provides the output in natural orientation.
* *
* @param displayId The display id to take the screenshot of. * @param displayId The display id to take the screenshot of.
* @return The buffer or null if we have failed. * @return The buffer or null if we have failed.
*/ */
public abstract SurfaceControl.ScreenshotGraphicBuffer screenshot(int displayId); public abstract SurfaceControl.ScreenshotGraphicBuffer systemScreenshot(int displayId);
/** /**
* Take a screenshot without secure layer of the specified display and return a buffer. * General screenshot functionality that excludes secure layers and applies appropriate
* rotation that the device is currently in.
* *
* @param displayId The display id to take the screenshot of. * @param displayId The display id to take the screenshot of.
* @return The buffer or null if we have failed. * @return The buffer or null if we have failed.
*/ */
public abstract SurfaceControl.ScreenshotGraphicBuffer screenshotWithoutSecureLayer( public abstract SurfaceControl.ScreenshotGraphicBuffer userScreenshot(int displayId);
int displayId);
/** /**
* Returns information about the specified logical display. * Returns information about the specified logical display.

View File

@@ -1023,8 +1023,7 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ
try { try {
mMainHandler.post(PooledLambda.obtainRunnable((nonArg) -> { mMainHandler.post(PooledLambda.obtainRunnable((nonArg) -> {
final ScreenshotGraphicBuffer screenshotBuffer = LocalServices final ScreenshotGraphicBuffer screenshotBuffer = LocalServices
.getService(DisplayManagerInternal.class) .getService(DisplayManagerInternal.class).userScreenshot(displayId);
.screenshotWithoutSecureLayer(displayId);
if (screenshotBuffer != null) { if (screenshotBuffer != null) {
sendScreenshotSuccess(screenshotBuffer, callback); sendScreenshotSuccess(screenshotBuffer, callback);
} else { } else {

View File

@@ -28,6 +28,8 @@ import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_SHOUL
import static android.hardware.display.DisplayViewport.VIEWPORT_EXTERNAL; import static android.hardware.display.DisplayViewport.VIEWPORT_EXTERNAL;
import static android.hardware.display.DisplayViewport.VIEWPORT_INTERNAL; import static android.hardware.display.DisplayViewport.VIEWPORT_INTERNAL;
import static android.hardware.display.DisplayViewport.VIEWPORT_VIRTUAL; import static android.hardware.display.DisplayViewport.VIEWPORT_VIRTUAL;
import static android.view.Surface.ROTATION_270;
import static android.view.Surface.ROTATION_90;
import android.Manifest; import android.Manifest;
import android.annotation.NonNull; import android.annotation.NonNull;
@@ -1363,8 +1365,7 @@ public final class DisplayManagerService extends SystemService {
return null; return null;
} }
private SurfaceControl.ScreenshotGraphicBuffer screenshotInternal(int displayId, private SurfaceControl.ScreenshotGraphicBuffer systemScreenshotInternal(int displayId) {
boolean captureSecureLayer) {
synchronized (mSyncRoot) { synchronized (mSyncRoot) {
final IBinder token = getDisplayToken(displayId); final IBinder token = getDisplayToken(displayId);
if (token == null) { if (token == null) {
@@ -1376,16 +1377,43 @@ public final class DisplayManagerService extends SystemService {
} }
final DisplayInfo displayInfo = logicalDisplay.getDisplayInfoLocked(); final DisplayInfo displayInfo = logicalDisplay.getDisplayInfoLocked();
if (captureSecureLayer) {
return SurfaceControl.screenshotToBufferWithSecureLayersUnsafe(token, new Rect(), return SurfaceControl.screenshotToBufferWithSecureLayersUnsafe(token, new Rect(),
displayInfo.getNaturalWidth(), displayInfo.getNaturalHeight(), displayInfo.getNaturalWidth(), displayInfo.getNaturalHeight(),
false /* useIdentityTransform */, 0 /* rotation */); false /* useIdentityTransform */, 0 /* rotation */);
} else {
return SurfaceControl.screenshotToBuffer(token, new Rect(),
displayInfo.getNaturalWidth(), displayInfo.getNaturalHeight(),
false /* useIdentityTransform */, 0 /* rotation */);
} }
} }
private SurfaceControl.ScreenshotGraphicBuffer userScreenshotInternal(int displayId) {
synchronized (mSyncRoot) {
final IBinder token = getDisplayToken(displayId);
if (token == null) {
return null;
}
final LogicalDisplay logicalDisplay = mLogicalDisplays.get(displayId);
if (logicalDisplay == null) {
return null;
}
final DisplayInfo displayInfo = logicalDisplay.getDisplayInfoLocked();
// Takes screenshot based on current device orientation.
final Display display = DisplayManagerGlobal.getInstance()
.getRealDisplay(displayId);
if (display == null) {
return null;
}
final Point displaySize = new Point();
display.getRealSize(displaySize);
int rotation = displayInfo.rotation;
// TODO (b/153382624) : This workaround solution would be removed after
// SurfaceFlinger fixes the inconsistency with rotation direction issue.
if (rotation == ROTATION_90 || rotation == ROTATION_270) {
rotation = (rotation == ROTATION_90) ? ROTATION_270 : ROTATION_90;
}
return SurfaceControl.screenshotToBuffer(token, new Rect(), displaySize.x,
displaySize.y, false /* useIdentityTransform */, rotation /* rotation */);
}
} }
@VisibleForTesting @VisibleForTesting
@@ -2502,13 +2530,13 @@ public final class DisplayManagerService extends SystemService {
} }
@Override @Override
public SurfaceControl.ScreenshotGraphicBuffer screenshot(int displayId) { public SurfaceControl.ScreenshotGraphicBuffer systemScreenshot(int displayId) {
return screenshotInternal(displayId, true); return systemScreenshotInternal(displayId);
} }
@Override @Override
public SurfaceControl.ScreenshotGraphicBuffer screenshotWithoutSecureLayer(int displayId) { public SurfaceControl.ScreenshotGraphicBuffer userScreenshot(int displayId) {
return screenshotInternal(displayId, false); return userScreenshotInternal(displayId);
} }
@Override @Override

View File

@@ -212,7 +212,7 @@ class ScreenRotationAnimation {
final Surface surface = mService.mSurfaceFactory.get(); final Surface surface = mService.mSurfaceFactory.get();
surface.copyFrom(mScreenshotLayer); surface.copyFrom(mScreenshotLayer);
SurfaceControl.ScreenshotGraphicBuffer gb = SurfaceControl.ScreenshotGraphicBuffer gb =
mService.mDisplayManagerInternal.screenshot(displayId); mService.mDisplayManagerInternal.systemScreenshot(displayId);
if (gb != null) { if (gb != null) {
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER,
"ScreenRotationAnimation#getMedianBorderLuma"); "ScreenRotationAnimation#getMedianBorderLuma");