diff options
| author | Chavi Weingarten <chaviw@google.com> | 2017-12-04 17:10:30 +0000 |
|---|---|---|
| committer | Android (Google) Code Review <android-gerrit@google.com> | 2017-12-04 17:10:30 +0000 |
| commit | 29fdbc67fcf0015c713840756dd343002e83fffb (patch) | |
| tree | 4dcdea8c24fb0d7455ef84379021713fc7162a13 /core/java/android | |
| parent | efb758420d4385e7064df8740611fbd9fdcdbcac (diff) | |
| parent | a69e0a7d7c11d586c5a3ff74306a41c1456fd250 (diff) | |
Merge changes from topic "hw_bitmap"
* changes:
Update screenshot requests to render proper crop and rotation.
Revert "Revert "Updated screenshot code to reflect native changes.""
Diffstat (limited to 'core/java/android')
| -rw-r--r-- | core/java/android/app/IUiAutomationConnection.aidl | 3 | ||||
| -rw-r--r-- | core/java/android/app/UiAutomation.java | 49 | ||||
| -rw-r--r-- | core/java/android/app/UiAutomationConnection.java | 7 | ||||
| -rw-r--r-- | core/java/android/view/SurfaceControl.java | 51 |
4 files changed, 45 insertions, 65 deletions
diff --git a/core/java/android/app/IUiAutomationConnection.aidl b/core/java/android/app/IUiAutomationConnection.aidl index b26117d3d31c..d01938b123b1 100644 --- a/core/java/android/app/IUiAutomationConnection.aidl +++ b/core/java/android/app/IUiAutomationConnection.aidl @@ -18,6 +18,7 @@ package android.app; import android.accessibilityservice.IAccessibilityServiceClient; import android.graphics.Bitmap; +import android.graphics.Rect; import android.view.InputEvent; import android.view.WindowContentFrameStats; import android.view.WindowAnimationFrameStats; @@ -37,7 +38,7 @@ interface IUiAutomationConnection { void disconnect(); boolean injectInputEvent(in InputEvent event, boolean sync); boolean setRotation(int rotation); - Bitmap takeScreenshot(int width, int height); + Bitmap takeScreenshot(in Rect crop, int rotation); boolean clearWindowContentFrameStats(int windowId); WindowContentFrameStats getWindowContentFrameStats(int windowId); void clearWindowAnimationFrameStats(); diff --git a/core/java/android/app/UiAutomation.java b/core/java/android/app/UiAutomation.java index c99de5ddb776..8f0168530273 100644 --- a/core/java/android/app/UiAutomation.java +++ b/core/java/android/app/UiAutomation.java @@ -26,6 +26,7 @@ import android.annotation.TestApi; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Point; +import android.graphics.Rect; import android.graphics.Region; import android.hardware.display.DisplayManagerGlobal; import android.os.IBinder; @@ -690,42 +691,15 @@ public final class UiAutomation { .getRealDisplay(Display.DEFAULT_DISPLAY); Point displaySize = new Point(); display.getRealSize(displaySize); - final int displayWidth = displaySize.x; - final int displayHeight = displaySize.y; - final float screenshotWidth; - final float screenshotHeight; - - final int rotation = display.getRotation(); - switch (rotation) { - case ROTATION_FREEZE_0: { - screenshotWidth = displayWidth; - screenshotHeight = displayHeight; - } break; - case ROTATION_FREEZE_90: { - screenshotWidth = displayHeight; - screenshotHeight = displayWidth; - } break; - case ROTATION_FREEZE_180: { - screenshotWidth = displayWidth; - screenshotHeight = displayHeight; - } break; - case ROTATION_FREEZE_270: { - screenshotWidth = displayHeight; - screenshotHeight = displayWidth; - } break; - default: { - throw new IllegalArgumentException("Invalid rotation: " - + rotation); - } - } + int rotation = display.getRotation(); // Take the screenshot Bitmap screenShot = null; try { // Calling out without a lock held. - screenShot = mUiAutomationConnection.takeScreenshot((int) screenshotWidth, - (int) screenshotHeight); + screenShot = mUiAutomationConnection.takeScreenshot( + new Rect(0, 0, displaySize.x, displaySize.y), rotation); if (screenShot == null) { return null; } @@ -734,21 +708,6 @@ public final class UiAutomation { return null; } - // Rotate the screenshot to the current orientation - if (rotation != ROTATION_FREEZE_0) { - Bitmap unrotatedScreenShot = Bitmap.createBitmap(displayWidth, displayHeight, - Bitmap.Config.ARGB_8888); - Canvas canvas = new Canvas(unrotatedScreenShot); - canvas.translate(unrotatedScreenShot.getWidth() / 2, - unrotatedScreenShot.getHeight() / 2); - canvas.rotate(getDegreesForRotation(rotation)); - canvas.translate(- screenshotWidth / 2, - screenshotHeight / 2); - canvas.drawBitmap(screenShot, 0, 0, null); - canvas.setBitmap(null); - screenShot.recycle(); - screenShot = unrotatedScreenShot; - } - // Optimization screenShot.setHasAlpha(false); diff --git a/core/java/android/app/UiAutomationConnection.java b/core/java/android/app/UiAutomationConnection.java index 5e414b837f79..d3828ab47883 100644 --- a/core/java/android/app/UiAutomationConnection.java +++ b/core/java/android/app/UiAutomationConnection.java @@ -21,6 +21,7 @@ import android.accessibilityservice.IAccessibilityServiceClient; import android.content.Context; import android.content.pm.IPackageManager; import android.graphics.Bitmap; +import android.graphics.Rect; import android.hardware.input.InputManager; import android.os.Binder; import android.os.IBinder; @@ -153,7 +154,7 @@ public final class UiAutomationConnection extends IUiAutomationConnection.Stub { } @Override - public Bitmap takeScreenshot(int width, int height) { + public Bitmap takeScreenshot(Rect crop, int rotation) { synchronized (mLock) { throwIfCalledByNotTrustedUidLocked(); throwIfShutdownLocked(); @@ -161,7 +162,9 @@ public final class UiAutomationConnection extends IUiAutomationConnection.Stub { } final long identity = Binder.clearCallingIdentity(); try { - return SurfaceControl.screenshot(width, height); + int width = crop.width(); + int height = crop.height(); + return SurfaceControl.screenshot(crop, width, height, rotation); } finally { Binder.restoreCallingIdentity(identity); } diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java index 3d01ec23b723..37550d87adf3 100644 --- a/core/java/android/view/SurfaceControl.java +++ b/core/java/android/view/SurfaceControl.java @@ -16,6 +16,9 @@ package android.view; +import static android.view.Surface.ROTATION_270; +import static android.view.Surface.ROTATION_90; + import android.annotation.Size; import android.graphics.Bitmap; import android.graphics.GraphicBuffer; @@ -55,8 +58,6 @@ public class SurfaceControl { private static native void nativeScreenshot(IBinder displayToken, Surface consumer, Rect sourceCrop, int width, int height, int minLayer, int maxLayer, boolean allLayers, boolean useIdentityTransform); - private static native void nativeCaptureLayers(IBinder layerHandleToken, Surface consumer, - Rect sourceCrop, float frameScale); private static native GraphicBuffer nativeCaptureLayers(IBinder layerHandleToken, Rect sourceCrop, float frameScale); @@ -1144,22 +1145,35 @@ public class SurfaceControl { /** * Like {@link SurfaceControl#screenshot(int, int, int, int, boolean)} but - * includes all Surfaces in the screenshot. + * includes all Surfaces in the screenshot. This will also update the orientation so it + * sends the correct coordinates to SF based on the rotation value. * + * @param sourceCrop The portion of the screen to capture into the Bitmap; + * caller may pass in 'new Rect()' if no cropping is desired. * @param width The desired width of the returned bitmap; the raw * screen will be scaled down to this size. * @param height The desired height of the returned bitmap; the raw * screen will be scaled down to this size. + * @param rotation Apply a custom clockwise rotation to the screenshot, i.e. + * Surface.ROTATION_0,90,180,270. Surfaceflinger will always take + * screenshots in its native portrait orientation by default, so this is + * useful for returning screenshots that are independent of device + * orientation. * @return Returns a Bitmap containing the screen contents, or null * if an error occurs. Make sure to call Bitmap.recycle() as soon as * possible, once its content is not needed anymore. */ - public static Bitmap screenshot(int width, int height) { + public static Bitmap screenshot(Rect sourceCrop, int width, int height, int rotation) { // TODO: should take the display as a parameter IBinder displayToken = SurfaceControl.getBuiltInDisplay( SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN); - return nativeScreenshot(displayToken, new Rect(), width, height, 0, 0, true, - false, Surface.ROTATION_0); + if (rotation == ROTATION_90 || rotation == ROTATION_270) { + rotation = (rotation == ROTATION_90) ? ROTATION_270 : ROTATION_90; + } + + SurfaceControl.rotateCropForSF(sourceCrop, rotation); + return nativeScreenshot(displayToken, sourceCrop, width, height, 0, 0, true, + false, rotation); } private static void screenshot(IBinder display, Surface consumer, Rect sourceCrop, @@ -1175,26 +1189,29 @@ public class SurfaceControl { minLayer, maxLayer, allLayers, useIdentityTransform); } + private static void rotateCropForSF(Rect crop, int rot) { + if (rot == Surface.ROTATION_90 || rot == Surface.ROTATION_270) { + int tmp = crop.top; + crop.top = crop.left; + crop.left = tmp; + tmp = crop.right; + crop.right = crop.bottom; + crop.bottom = tmp; + } + } + /** * Captures a layer and its children into the provided {@link Surface}. * * @param layerHandleToken The root layer to capture. - * @param consumer The {@link Surface} to capture the layer into. * @param sourceCrop The portion of the root surface to capture; caller may pass in 'new * Rect()' or null if no cropping is desired. * @param frameScale The desired scale of the returned buffer; the raw * screen will be scaled up/down. + * + * @return Returns a GraphicBuffer that contains the layer capture. */ - public static void captureLayers(IBinder layerHandleToken, Surface consumer, Rect sourceCrop, - float frameScale) { - nativeCaptureLayers(layerHandleToken, consumer, sourceCrop, frameScale); - } - - /** - * Same as {@link #captureLayers(IBinder, Surface, Rect, float)} except this - * captures to a {@link GraphicBuffer} instead of a {@link Surface}. - */ - public static GraphicBuffer captureLayersToBuffer(IBinder layerHandleToken, Rect sourceCrop, + public static GraphicBuffer captureLayers(IBinder layerHandleToken, Rect sourceCrop, float frameScale) { return nativeCaptureLayers(layerHandleToken, sourceCrop, frameScale); } |
