Loading core/java/android/app/IUiAutomationConnection.aidl +1 −0 Original line number Original line Diff line number Diff line Loading @@ -39,6 +39,7 @@ interface IUiAutomationConnection { boolean injectInputEvent(in InputEvent event, boolean sync); boolean injectInputEvent(in InputEvent event, boolean sync); void syncInputTransactions(); void syncInputTransactions(); boolean setRotation(int rotation); boolean setRotation(int rotation); Bitmap takeScreenshot(in Rect crop, int rotation); boolean clearWindowContentFrameStats(int windowId); boolean clearWindowContentFrameStats(int windowId); WindowContentFrameStats getWindowContentFrameStats(int windowId); WindowContentFrameStats getWindowContentFrameStats(int windowId); void clearWindowAnimationFrameStats(); void clearWindowAnimationFrameStats(); Loading core/java/android/app/UiAutomation.java +29 −7 Original line number Original line Diff line number Diff line Loading @@ -27,7 +27,10 @@ import android.annotation.Nullable; import android.annotation.TestApi; import android.annotation.TestApi; import android.compat.annotation.UnsupportedAppUsage; import android.compat.annotation.UnsupportedAppUsage; import android.graphics.Bitmap; import android.graphics.Bitmap; import android.graphics.Point; import android.graphics.Rect; import android.graphics.Region; import android.graphics.Region; import android.hardware.display.DisplayManagerGlobal; import android.os.Build; import android.os.Build; import android.os.Handler; import android.os.Handler; import android.os.HandlerThread; import android.os.HandlerThread; Loading Loading @@ -828,20 +831,39 @@ public final class UiAutomation { } } /** /** * Takes a screenshot of the default display and returns it by {@link Bitmap.Config#HARDWARE} * Takes a screenshot. * format. * * * @return The screenshot bitmap on success, null otherwise. * @return The screenshot bitmap on success, null otherwise. */ */ public Bitmap takeScreenshot() { public Bitmap takeScreenshot() { final int connectionId; synchronized (mLock) { synchronized (mLock) { throwIfNotConnectedLocked(); throwIfNotConnectedLocked(); connectionId = mConnectionId; } } Display display = DisplayManagerGlobal.getInstance() .getRealDisplay(Display.DEFAULT_DISPLAY); Point displaySize = new Point(); display.getRealSize(displaySize); int rotation = display.getRotation(); // Take the screenshot Bitmap screenShot = null; try { // Calling out without a lock held. // Calling out without a lock held. return AccessibilityInteractionClient.getInstance() screenShot = mUiAutomationConnection.takeScreenshot( .takeScreenshot(connectionId, Display.DEFAULT_DISPLAY); new Rect(0, 0, displaySize.x, displaySize.y), rotation); if (screenShot == null) { return null; } } catch (RemoteException re) { Log.e(LOG_TAG, "Error while taking screnshot!", re); return null; } // Optimization screenShot.setHasAlpha(false); return screenShot; } } /** /** Loading core/java/android/app/UiAutomationConnection.java +20 −2 Original line number Original line Diff line number Diff line Loading @@ -21,6 +21,8 @@ import android.accessibilityservice.IAccessibilityServiceClient; import android.annotation.Nullable; import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Rect; import android.hardware.input.InputManager; import android.hardware.input.InputManager; import android.os.Binder; import android.os.Binder; import android.os.IBinder; import android.os.IBinder; Loading Loading @@ -177,6 +179,23 @@ public final class UiAutomationConnection extends IUiAutomationConnection.Stub { return false; return false; } } @Override public Bitmap takeScreenshot(Rect crop, int rotation) { synchronized (mLock) { throwIfCalledByNotTrustedUidLocked(); throwIfShutdownLocked(); throwIfNotConnectedLocked(); } final long identity = Binder.clearCallingIdentity(); try { int width = crop.width(); int height = crop.height(); return SurfaceControl.screenshot(crop, width, height, rotation); } finally { Binder.restoreCallingIdentity(identity); } } @Override @Override public boolean clearWindowContentFrameStats(int windowId) throws RemoteException { public boolean clearWindowContentFrameStats(int windowId) throws RemoteException { synchronized (mLock) { synchronized (mLock) { Loading Loading @@ -430,8 +449,7 @@ public final class UiAutomationConnection extends IUiAutomationConnection.Stub { info.setCapabilities(AccessibilityServiceInfo.CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT info.setCapabilities(AccessibilityServiceInfo.CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT | AccessibilityServiceInfo.CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION | AccessibilityServiceInfo.CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION | AccessibilityServiceInfo.CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY | AccessibilityServiceInfo.CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY | AccessibilityServiceInfo.CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS | AccessibilityServiceInfo.CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS); | AccessibilityServiceInfo.CAPABILITY_CAN_TAKE_SCREENSHOT); try { try { // Calling out with a lock held is fine since if the system // Calling out with a lock held is fine since if the system // process is gone the client calling in will be killed. // process is gone the client calling in will be killed. Loading core/java/android/view/accessibility/AccessibilityInteractionClient.java +0 −26 Original line number Original line Diff line number Diff line Loading @@ -20,7 +20,6 @@ import android.accessibilityservice.IAccessibilityServiceConnection; import android.annotation.NonNull; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; import android.compat.annotation.UnsupportedAppUsage; import android.graphics.Bitmap; import android.os.Binder; import android.os.Binder; import android.os.Build; import android.os.Build; import android.os.Bundle; import android.os.Bundle; Loading Loading @@ -828,31 +827,6 @@ public final class AccessibilityInteractionClient } } } } /** * Takes the screenshot of the specified display and returns it by bitmap format. * * @param connectionId The id of a connection for interacting with the system. * @param displayId The logic display id, use {@link Display#DEFAULT_DISPLAY} for * default display. * @return The screenshot bitmap on success, null otherwise. */ public Bitmap takeScreenshot(int connectionId, int displayId) { Bitmap screenShot = null; try { IAccessibilityServiceConnection connection = getConnection(connectionId); if (connection != null) { screenShot = connection.takeScreenshot(displayId); } else { if (DEBUG) { Log.w(LOG_TAG, "No connection for connection id: " + connectionId); } } } catch (RemoteException re) { Log.w(LOG_TAG, "Error while calling remote takeScreenshot", re); } return screenShot; } /** /** * Clears the result state. * Clears the result state. */ */ Loading Loading
core/java/android/app/IUiAutomationConnection.aidl +1 −0 Original line number Original line Diff line number Diff line Loading @@ -39,6 +39,7 @@ interface IUiAutomationConnection { boolean injectInputEvent(in InputEvent event, boolean sync); boolean injectInputEvent(in InputEvent event, boolean sync); void syncInputTransactions(); void syncInputTransactions(); boolean setRotation(int rotation); boolean setRotation(int rotation); Bitmap takeScreenshot(in Rect crop, int rotation); boolean clearWindowContentFrameStats(int windowId); boolean clearWindowContentFrameStats(int windowId); WindowContentFrameStats getWindowContentFrameStats(int windowId); WindowContentFrameStats getWindowContentFrameStats(int windowId); void clearWindowAnimationFrameStats(); void clearWindowAnimationFrameStats(); Loading
core/java/android/app/UiAutomation.java +29 −7 Original line number Original line Diff line number Diff line Loading @@ -27,7 +27,10 @@ import android.annotation.Nullable; import android.annotation.TestApi; import android.annotation.TestApi; import android.compat.annotation.UnsupportedAppUsage; import android.compat.annotation.UnsupportedAppUsage; import android.graphics.Bitmap; import android.graphics.Bitmap; import android.graphics.Point; import android.graphics.Rect; import android.graphics.Region; import android.graphics.Region; import android.hardware.display.DisplayManagerGlobal; import android.os.Build; import android.os.Build; import android.os.Handler; import android.os.Handler; import android.os.HandlerThread; import android.os.HandlerThread; Loading Loading @@ -828,20 +831,39 @@ public final class UiAutomation { } } /** /** * Takes a screenshot of the default display and returns it by {@link Bitmap.Config#HARDWARE} * Takes a screenshot. * format. * * * @return The screenshot bitmap on success, null otherwise. * @return The screenshot bitmap on success, null otherwise. */ */ public Bitmap takeScreenshot() { public Bitmap takeScreenshot() { final int connectionId; synchronized (mLock) { synchronized (mLock) { throwIfNotConnectedLocked(); throwIfNotConnectedLocked(); connectionId = mConnectionId; } } Display display = DisplayManagerGlobal.getInstance() .getRealDisplay(Display.DEFAULT_DISPLAY); Point displaySize = new Point(); display.getRealSize(displaySize); int rotation = display.getRotation(); // Take the screenshot Bitmap screenShot = null; try { // Calling out without a lock held. // Calling out without a lock held. return AccessibilityInteractionClient.getInstance() screenShot = mUiAutomationConnection.takeScreenshot( .takeScreenshot(connectionId, Display.DEFAULT_DISPLAY); new Rect(0, 0, displaySize.x, displaySize.y), rotation); if (screenShot == null) { return null; } } catch (RemoteException re) { Log.e(LOG_TAG, "Error while taking screnshot!", re); return null; } // Optimization screenShot.setHasAlpha(false); return screenShot; } } /** /** Loading
core/java/android/app/UiAutomationConnection.java +20 −2 Original line number Original line Diff line number Diff line Loading @@ -21,6 +21,8 @@ import android.accessibilityservice.IAccessibilityServiceClient; import android.annotation.Nullable; import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Rect; import android.hardware.input.InputManager; import android.hardware.input.InputManager; import android.os.Binder; import android.os.Binder; import android.os.IBinder; import android.os.IBinder; Loading Loading @@ -177,6 +179,23 @@ public final class UiAutomationConnection extends IUiAutomationConnection.Stub { return false; return false; } } @Override public Bitmap takeScreenshot(Rect crop, int rotation) { synchronized (mLock) { throwIfCalledByNotTrustedUidLocked(); throwIfShutdownLocked(); throwIfNotConnectedLocked(); } final long identity = Binder.clearCallingIdentity(); try { int width = crop.width(); int height = crop.height(); return SurfaceControl.screenshot(crop, width, height, rotation); } finally { Binder.restoreCallingIdentity(identity); } } @Override @Override public boolean clearWindowContentFrameStats(int windowId) throws RemoteException { public boolean clearWindowContentFrameStats(int windowId) throws RemoteException { synchronized (mLock) { synchronized (mLock) { Loading Loading @@ -430,8 +449,7 @@ public final class UiAutomationConnection extends IUiAutomationConnection.Stub { info.setCapabilities(AccessibilityServiceInfo.CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT info.setCapabilities(AccessibilityServiceInfo.CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT | AccessibilityServiceInfo.CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION | AccessibilityServiceInfo.CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION | AccessibilityServiceInfo.CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY | AccessibilityServiceInfo.CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY | AccessibilityServiceInfo.CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS | AccessibilityServiceInfo.CAPABILITY_CAN_REQUEST_FILTER_KEY_EVENTS); | AccessibilityServiceInfo.CAPABILITY_CAN_TAKE_SCREENSHOT); try { try { // Calling out with a lock held is fine since if the system // Calling out with a lock held is fine since if the system // process is gone the client calling in will be killed. // process is gone the client calling in will be killed. Loading
core/java/android/view/accessibility/AccessibilityInteractionClient.java +0 −26 Original line number Original line Diff line number Diff line Loading @@ -20,7 +20,6 @@ import android.accessibilityservice.IAccessibilityServiceConnection; import android.annotation.NonNull; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; import android.compat.annotation.UnsupportedAppUsage; import android.graphics.Bitmap; import android.os.Binder; import android.os.Binder; import android.os.Build; import android.os.Build; import android.os.Bundle; import android.os.Bundle; Loading Loading @@ -828,31 +827,6 @@ public final class AccessibilityInteractionClient } } } } /** * Takes the screenshot of the specified display and returns it by bitmap format. * * @param connectionId The id of a connection for interacting with the system. * @param displayId The logic display id, use {@link Display#DEFAULT_DISPLAY} for * default display. * @return The screenshot bitmap on success, null otherwise. */ public Bitmap takeScreenshot(int connectionId, int displayId) { Bitmap screenShot = null; try { IAccessibilityServiceConnection connection = getConnection(connectionId); if (connection != null) { screenShot = connection.takeScreenshot(displayId); } else { if (DEBUG) { Log.w(LOG_TAG, "No connection for connection id: " + connectionId); } } } catch (RemoteException re) { Log.w(LOG_TAG, "Error while calling remote takeScreenshot", re); } return screenShot; } /** /** * Clears the result state. * Clears the result state. */ */ Loading