Merge "Added takeScreenshot of a Window to UiAutomation" into sc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
7131ac5913
@@ -382,6 +382,7 @@ package android.app {
|
||||
method @Deprecated public boolean revokeRuntimePermission(String, String, android.os.UserHandle);
|
||||
method public void syncInputTransactions();
|
||||
method public void syncInputTransactions(boolean);
|
||||
method @Nullable public android.graphics.Bitmap takeScreenshot(@NonNull android.view.Window);
|
||||
field @NonNull public static final java.util.Set<java.lang.String> ALL_PERMISSIONS;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ import android.accessibilityservice.IAccessibilityServiceClient;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Rect;
|
||||
import android.view.InputEvent;
|
||||
import android.view.SurfaceControl;
|
||||
import android.view.WindowContentFrameStats;
|
||||
import android.view.WindowAnimationFrameStats;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
@@ -42,6 +43,7 @@ interface IUiAutomationConnection {
|
||||
void syncInputTransactions(boolean waitForAnimations);
|
||||
boolean setRotation(int rotation);
|
||||
Bitmap takeScreenshot(in Rect crop);
|
||||
Bitmap takeSurfaceControlScreenshot(in SurfaceControl surfaceControl);
|
||||
boolean clearWindowContentFrameStats(int windowId);
|
||||
WindowContentFrameStats getWindowContentFrameStats(int windowId);
|
||||
void clearWindowAnimationFrameStats();
|
||||
|
||||
@@ -50,6 +50,10 @@ import android.view.Display;
|
||||
import android.view.InputEvent;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.Surface;
|
||||
import android.view.SurfaceControl;
|
||||
import android.view.View;
|
||||
import android.view.ViewRootImpl;
|
||||
import android.view.Window;
|
||||
import android.view.WindowAnimationFrameStats;
|
||||
import android.view.WindowContentFrameStats;
|
||||
import android.view.accessibility.AccessibilityEvent;
|
||||
@@ -1012,7 +1016,7 @@ public final class UiAutomation {
|
||||
return null;
|
||||
}
|
||||
} catch (RemoteException re) {
|
||||
Log.e(LOG_TAG, "Error while taking screnshot!", re);
|
||||
Log.e(LOG_TAG, "Error while taking screenshot!", re);
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1022,6 +1026,51 @@ public final class UiAutomation {
|
||||
return screenShot;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to capture a screenshot of a Window. This can return null in the following cases:
|
||||
* 1. Window content hasn't been layed out.
|
||||
* 2. Window doesn't have a valid SurfaceControl
|
||||
* 3. An error occurred in SurfaceFlinger when trying to take the screenshot.
|
||||
*
|
||||
* @param window Window to take a screenshot of
|
||||
*
|
||||
* @return The screenshot bitmap on success, null otherwise.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@TestApi
|
||||
@Nullable
|
||||
public Bitmap takeScreenshot(@NonNull Window window) {
|
||||
if (window == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
View decorView = window.peekDecorView();
|
||||
if (decorView == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
ViewRootImpl viewRoot = decorView.getViewRootImpl();
|
||||
if (viewRoot == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
SurfaceControl sc = viewRoot.getSurfaceControl();
|
||||
if (!sc.isValid()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Apply a sync transaction to ensure SurfaceFlinger is flushed before capturing a
|
||||
// screenshot.
|
||||
new SurfaceControl.Transaction().apply(true);
|
||||
try {
|
||||
return mUiAutomationConnection.takeSurfaceControlScreenshot(sc);
|
||||
} catch (RemoteException re) {
|
||||
Log.e(LOG_TAG, "Error while taking screenshot!", re);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether this UiAutomation to run in a "monkey" mode. Applications can query whether
|
||||
* they are executed in a "monkey" mode, i.e. run by a test framework, and avoid doing
|
||||
|
||||
@@ -18,6 +18,7 @@ package android.app;
|
||||
|
||||
import android.accessibilityservice.AccessibilityServiceInfo;
|
||||
import android.accessibilityservice.IAccessibilityServiceClient;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.compat.annotation.UnsupportedAppUsage;
|
||||
import android.content.Context;
|
||||
@@ -206,6 +207,30 @@ public final class UiAutomationConnection extends IUiAutomationConnection.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Bitmap takeSurfaceControlScreenshot(@NonNull SurfaceControl surfaceControl) {
|
||||
synchronized (mLock) {
|
||||
throwIfCalledByNotTrustedUidLocked();
|
||||
throwIfShutdownLocked();
|
||||
throwIfNotConnectedLocked();
|
||||
}
|
||||
|
||||
SurfaceControl.ScreenshotHardwareBuffer captureBuffer;
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
captureBuffer = SurfaceControl.captureLayers(
|
||||
new SurfaceControl.LayerCaptureArgs.Builder(surfaceControl).build());
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
}
|
||||
|
||||
if (captureBuffer == null) {
|
||||
return null;
|
||||
}
|
||||
return captureBuffer.asBitmap();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean clearWindowContentFrameStats(int windowId) throws RemoteException {
|
||||
synchronized (mLock) {
|
||||
|
||||
Reference in New Issue
Block a user