Loading core/java/android/app/IUiAutomationConnection.aidl +4 −2 Original line number Diff line number Diff line Loading @@ -24,6 +24,8 @@ import android.view.SurfaceControl; import android.view.WindowContentFrameStats; import android.view.WindowAnimationFrameStats; import android.os.ParcelFileDescriptor; import android.window.ScreenCapture.ScreenCaptureListener; import android.window.ScreenCapture.LayerCaptureArgs; import java.util.List; Loading @@ -43,8 +45,8 @@ interface IUiAutomationConnection { void injectInputEventToInputFilter(in InputEvent event); void syncInputTransactions(boolean waitForAnimations); boolean setRotation(int rotation); Bitmap takeScreenshot(in Rect crop); Bitmap takeSurfaceControlScreenshot(in SurfaceControl surfaceControl); boolean takeScreenshot(in Rect crop, in ScreenCaptureListener listener); boolean takeSurfaceControlScreenshot(in SurfaceControl surfaceControl, in ScreenCaptureListener listener); boolean clearWindowContentFrameStats(int windowId); WindowContentFrameStats getWindowContentFrameStats(int windowId); void clearWindowAnimationFrameStats(); Loading core/java/android/app/UiAutomation.java +39 −13 Original line number Diff line number Diff line Loading @@ -37,6 +37,7 @@ import android.graphics.Bitmap; import android.graphics.Point; import android.graphics.Rect; import android.graphics.Region; import android.hardware.HardwareBuffer; import android.hardware.display.DisplayManagerGlobal; import android.os.Build; import android.os.Handler; Loading Loading @@ -71,6 +72,8 @@ import android.view.accessibility.AccessibilityNodeInfo; import android.view.accessibility.AccessibilityWindowInfo; import android.view.accessibility.IAccessibilityInteractionConnection; import android.view.inputmethod.EditorInfo; import android.window.ScreenCapture; import android.window.ScreenCapture.ScreenshotHardwareBuffer; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; Loading Loading @@ -1160,17 +1163,12 @@ public final class UiAutomation { Point displaySize = new Point(); display.getRealSize(displaySize); int rotation = display.getRotation(); // Take the screenshot Bitmap screenShot = null; ScreenCapture.SynchronousScreenCaptureListener syncScreenCapture = ScreenCapture.createSyncCaptureListener(); try { // Calling out without a lock held. screenShot = mUiAutomationConnection.takeScreenshot( new Rect(0, 0, displaySize.x, displaySize.y)); if (screenShot == null) { Log.e(LOG_TAG, "mUiAutomationConnection.takeScreenshot() returned null for display " + mDisplayId); if (!mUiAutomationConnection.takeScreenshot( new Rect(0, 0, displaySize.x, displaySize.y), syncScreenCapture)) { return null; } } catch (RemoteException re) { Loading @@ -1178,10 +1176,23 @@ public final class UiAutomation { return null; } // Optimization screenShot.setHasAlpha(false); final ScreenshotHardwareBuffer screenshotBuffer = syncScreenCapture.getBuffer(); Bitmap screenShot = screenshotBuffer.asBitmap(); if (screenShot == null) { Log.e(LOG_TAG, "mUiAutomationConnection.takeScreenshot() returned null for display " + mDisplayId); return null; } Bitmap swBitmap; try (HardwareBuffer buffer = screenshotBuffer.getHardwareBuffer()) { swBitmap = screenShot.copy(Bitmap.Config.ARGB_8888, false); } screenShot.recycle(); return screenShot; // Optimization swBitmap.setHasAlpha(false); return swBitmap; } /** Loading Loading @@ -1218,12 +1229,27 @@ public final class UiAutomation { // Apply a sync transaction to ensure SurfaceFlinger is flushed before capturing a // screenshot. new SurfaceControl.Transaction().apply(true); ScreenCapture.SynchronousScreenCaptureListener syncScreenCapture = ScreenCapture.createSyncCaptureListener(); try { return mUiAutomationConnection.takeSurfaceControlScreenshot(sc); if (!mUiAutomationConnection.takeSurfaceControlScreenshot(sc, syncScreenCapture)) { return null; } } catch (RemoteException re) { Log.e(LOG_TAG, "Error while taking screenshot!", re); return null; } ScreenCapture.ScreenshotHardwareBuffer captureBuffer = syncScreenCapture.getBuffer(); Bitmap screenShot = captureBuffer.asBitmap(); Bitmap swBitmap; try (HardwareBuffer buffer = captureBuffer.getHardwareBuffer()) { swBitmap = screenShot.copy(Bitmap.Config.ARGB_8888, false); } screenShot.recycle(); return swBitmap; } /** Loading core/java/android/app/UiAutomationConnection.java +16 −21 Original line number Diff line number Diff line Loading @@ -25,7 +25,6 @@ import android.annotation.Nullable; import android.annotation.UserIdInt; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Rect; import android.hardware.input.InputManager; import android.hardware.input.InputManagerGlobal; Loading @@ -51,8 +50,6 @@ import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.IAccessibilityManager; import android.window.ScreenCapture; import android.window.ScreenCapture.CaptureArgs; import android.window.ScreenCapture.ScreenshotHardwareBuffer; import android.window.ScreenCapture.SynchronousScreenCaptureListener; import libcore.io.IoUtils; Loading Loading @@ -224,56 +221,54 @@ public final class UiAutomationConnection extends IUiAutomationConnection.Stub { } @Override public Bitmap takeScreenshot(Rect crop) { public boolean takeScreenshot(Rect crop, ScreenCapture.ScreenCaptureListener listener) { synchronized (mLock) { throwIfCalledByNotTrustedUidLocked(); throwIfShutdownLocked(); throwIfNotConnectedLocked(); } final long identity = Binder.clearCallingIdentity(); try { final CaptureArgs captureArgs = new CaptureArgs.Builder<>() .setSourceCrop(crop) .build(); SynchronousScreenCaptureListener syncScreenCapture = ScreenCapture.createSyncCaptureListener(); mWindowManager.captureDisplay(DEFAULT_DISPLAY, captureArgs, syncScreenCapture); final ScreenshotHardwareBuffer screenshotBuffer = syncScreenCapture.getBuffer(); return screenshotBuffer == null ? null : screenshotBuffer.asBitmap(); mWindowManager.captureDisplay(DEFAULT_DISPLAY, captureArgs, listener); } catch (RemoteException re) { re.rethrowAsRuntimeException(); } finally { Binder.restoreCallingIdentity(identity); } return null; return true; } @Nullable @Override public Bitmap takeSurfaceControlScreenshot(@NonNull SurfaceControl surfaceControl) { public boolean takeSurfaceControlScreenshot(@NonNull SurfaceControl surfaceControl, ScreenCapture.ScreenCaptureListener listener) { synchronized (mLock) { throwIfCalledByNotTrustedUidLocked(); throwIfShutdownLocked(); throwIfNotConnectedLocked(); } ScreenCapture.ScreenshotHardwareBuffer captureBuffer; final long identity = Binder.clearCallingIdentity(); try { captureBuffer = ScreenCapture.captureLayers( ScreenCapture.LayerCaptureArgs args = new ScreenCapture.LayerCaptureArgs.Builder(surfaceControl) .setChildrenOnly(false) .build()); .build(); int status = ScreenCapture.captureLayers(args, listener); if (status != 0) { return false; } } finally { Binder.restoreCallingIdentity(identity); } if (captureBuffer == null) { return null; } return captureBuffer.asBitmap(); return true; } @Override Loading Loading
core/java/android/app/IUiAutomationConnection.aidl +4 −2 Original line number Diff line number Diff line Loading @@ -24,6 +24,8 @@ import android.view.SurfaceControl; import android.view.WindowContentFrameStats; import android.view.WindowAnimationFrameStats; import android.os.ParcelFileDescriptor; import android.window.ScreenCapture.ScreenCaptureListener; import android.window.ScreenCapture.LayerCaptureArgs; import java.util.List; Loading @@ -43,8 +45,8 @@ interface IUiAutomationConnection { void injectInputEventToInputFilter(in InputEvent event); void syncInputTransactions(boolean waitForAnimations); boolean setRotation(int rotation); Bitmap takeScreenshot(in Rect crop); Bitmap takeSurfaceControlScreenshot(in SurfaceControl surfaceControl); boolean takeScreenshot(in Rect crop, in ScreenCaptureListener listener); boolean takeSurfaceControlScreenshot(in SurfaceControl surfaceControl, in ScreenCaptureListener listener); boolean clearWindowContentFrameStats(int windowId); WindowContentFrameStats getWindowContentFrameStats(int windowId); void clearWindowAnimationFrameStats(); Loading
core/java/android/app/UiAutomation.java +39 −13 Original line number Diff line number Diff line Loading @@ -37,6 +37,7 @@ import android.graphics.Bitmap; import android.graphics.Point; import android.graphics.Rect; import android.graphics.Region; import android.hardware.HardwareBuffer; import android.hardware.display.DisplayManagerGlobal; import android.os.Build; import android.os.Handler; Loading Loading @@ -71,6 +72,8 @@ import android.view.accessibility.AccessibilityNodeInfo; import android.view.accessibility.AccessibilityWindowInfo; import android.view.accessibility.IAccessibilityInteractionConnection; import android.view.inputmethod.EditorInfo; import android.window.ScreenCapture; import android.window.ScreenCapture.ScreenshotHardwareBuffer; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; Loading Loading @@ -1160,17 +1163,12 @@ public final class UiAutomation { Point displaySize = new Point(); display.getRealSize(displaySize); int rotation = display.getRotation(); // Take the screenshot Bitmap screenShot = null; ScreenCapture.SynchronousScreenCaptureListener syncScreenCapture = ScreenCapture.createSyncCaptureListener(); try { // Calling out without a lock held. screenShot = mUiAutomationConnection.takeScreenshot( new Rect(0, 0, displaySize.x, displaySize.y)); if (screenShot == null) { Log.e(LOG_TAG, "mUiAutomationConnection.takeScreenshot() returned null for display " + mDisplayId); if (!mUiAutomationConnection.takeScreenshot( new Rect(0, 0, displaySize.x, displaySize.y), syncScreenCapture)) { return null; } } catch (RemoteException re) { Loading @@ -1178,10 +1176,23 @@ public final class UiAutomation { return null; } // Optimization screenShot.setHasAlpha(false); final ScreenshotHardwareBuffer screenshotBuffer = syncScreenCapture.getBuffer(); Bitmap screenShot = screenshotBuffer.asBitmap(); if (screenShot == null) { Log.e(LOG_TAG, "mUiAutomationConnection.takeScreenshot() returned null for display " + mDisplayId); return null; } Bitmap swBitmap; try (HardwareBuffer buffer = screenshotBuffer.getHardwareBuffer()) { swBitmap = screenShot.copy(Bitmap.Config.ARGB_8888, false); } screenShot.recycle(); return screenShot; // Optimization swBitmap.setHasAlpha(false); return swBitmap; } /** Loading Loading @@ -1218,12 +1229,27 @@ public final class UiAutomation { // Apply a sync transaction to ensure SurfaceFlinger is flushed before capturing a // screenshot. new SurfaceControl.Transaction().apply(true); ScreenCapture.SynchronousScreenCaptureListener syncScreenCapture = ScreenCapture.createSyncCaptureListener(); try { return mUiAutomationConnection.takeSurfaceControlScreenshot(sc); if (!mUiAutomationConnection.takeSurfaceControlScreenshot(sc, syncScreenCapture)) { return null; } } catch (RemoteException re) { Log.e(LOG_TAG, "Error while taking screenshot!", re); return null; } ScreenCapture.ScreenshotHardwareBuffer captureBuffer = syncScreenCapture.getBuffer(); Bitmap screenShot = captureBuffer.asBitmap(); Bitmap swBitmap; try (HardwareBuffer buffer = captureBuffer.getHardwareBuffer()) { swBitmap = screenShot.copy(Bitmap.Config.ARGB_8888, false); } screenShot.recycle(); return swBitmap; } /** Loading
core/java/android/app/UiAutomationConnection.java +16 −21 Original line number Diff line number Diff line Loading @@ -25,7 +25,6 @@ import android.annotation.Nullable; import android.annotation.UserIdInt; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Rect; import android.hardware.input.InputManager; import android.hardware.input.InputManagerGlobal; Loading @@ -51,8 +50,6 @@ import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.IAccessibilityManager; import android.window.ScreenCapture; import android.window.ScreenCapture.CaptureArgs; import android.window.ScreenCapture.ScreenshotHardwareBuffer; import android.window.ScreenCapture.SynchronousScreenCaptureListener; import libcore.io.IoUtils; Loading Loading @@ -224,56 +221,54 @@ public final class UiAutomationConnection extends IUiAutomationConnection.Stub { } @Override public Bitmap takeScreenshot(Rect crop) { public boolean takeScreenshot(Rect crop, ScreenCapture.ScreenCaptureListener listener) { synchronized (mLock) { throwIfCalledByNotTrustedUidLocked(); throwIfShutdownLocked(); throwIfNotConnectedLocked(); } final long identity = Binder.clearCallingIdentity(); try { final CaptureArgs captureArgs = new CaptureArgs.Builder<>() .setSourceCrop(crop) .build(); SynchronousScreenCaptureListener syncScreenCapture = ScreenCapture.createSyncCaptureListener(); mWindowManager.captureDisplay(DEFAULT_DISPLAY, captureArgs, syncScreenCapture); final ScreenshotHardwareBuffer screenshotBuffer = syncScreenCapture.getBuffer(); return screenshotBuffer == null ? null : screenshotBuffer.asBitmap(); mWindowManager.captureDisplay(DEFAULT_DISPLAY, captureArgs, listener); } catch (RemoteException re) { re.rethrowAsRuntimeException(); } finally { Binder.restoreCallingIdentity(identity); } return null; return true; } @Nullable @Override public Bitmap takeSurfaceControlScreenshot(@NonNull SurfaceControl surfaceControl) { public boolean takeSurfaceControlScreenshot(@NonNull SurfaceControl surfaceControl, ScreenCapture.ScreenCaptureListener listener) { synchronized (mLock) { throwIfCalledByNotTrustedUidLocked(); throwIfShutdownLocked(); throwIfNotConnectedLocked(); } ScreenCapture.ScreenshotHardwareBuffer captureBuffer; final long identity = Binder.clearCallingIdentity(); try { captureBuffer = ScreenCapture.captureLayers( ScreenCapture.LayerCaptureArgs args = new ScreenCapture.LayerCaptureArgs.Builder(surfaceControl) .setChildrenOnly(false) .build()); .build(); int status = ScreenCapture.captureLayers(args, listener); if (status != 0) { return false; } } finally { Binder.restoreCallingIdentity(identity); } if (captureBuffer == null) { return null; } return captureBuffer.asBitmap(); return true; } @Override Loading