Merge "Code cleanup of ScreenshotRequest and usages" into tm-qpr-dev

This commit is contained in:
Mark Renouf
2022-08-01 19:07:53 +00:00
committed by Android (Google) Code Review
7 changed files with 95 additions and 134 deletions

View File

@@ -1,7 +1,6 @@
package com.android.internal.util;
import static android.content.Intent.ACTION_USER_SWITCHED;
import static android.view.WindowManager.ScreenshotSource.SCREENSHOT_OTHER;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -29,6 +28,10 @@ import android.os.RemoteException;
import android.os.UserHandle;
import android.util.Log;
import android.view.WindowManager;
import android.view.WindowManager.ScreenshotSource;
import android.view.WindowManager.ScreenshotType;
import com.android.internal.annotations.VisibleForTesting;
import java.util.Objects;
import java.util.function.Consumer;
@@ -42,24 +45,28 @@ public class ScreenshotHelper {
* Describes a screenshot request (to make it easier to pass data through to the handler).
*/
public static class ScreenshotRequest implements Parcelable {
private int mSource;
private boolean mHasStatusBar;
private boolean mHasNavBar;
private Bundle mBitmapBundle;
private Rect mBoundsInScreen;
private Insets mInsets;
private int mTaskId;
private int mUserId;
private ComponentName mTopComponent;
private final int mSource;
private final Bundle mBitmapBundle;
private final Rect mBoundsInScreen;
private final Insets mInsets;
private final int mTaskId;
private final int mUserId;
private final ComponentName mTopComponent;
ScreenshotRequest(int source, boolean hasStatus, boolean hasNav) {
@VisibleForTesting
public ScreenshotRequest(int source) {
mSource = source;
mHasStatusBar = hasStatus;
mHasNavBar = hasNav;
mBitmapBundle = null;
mBoundsInScreen = null;
mInsets = null;
mTaskId = -1;
mUserId = -1;
mTopComponent = null;
}
ScreenshotRequest(int source, Bundle bitmapBundle, Rect boundsInScreen, Insets insets,
int taskId, int userId, ComponentName topComponent) {
@VisibleForTesting
public ScreenshotRequest(int source, Bundle bitmapBundle, Rect boundsInScreen,
Insets insets, int taskId, int userId, ComponentName topComponent) {
mSource = source;
mBitmapBundle = bitmapBundle;
mBoundsInScreen = boundsInScreen;
@@ -71,16 +78,21 @@ public class ScreenshotHelper {
ScreenshotRequest(Parcel in) {
mSource = in.readInt();
mHasStatusBar = in.readBoolean();
mHasNavBar = in.readBoolean();
if (in.readInt() == 1) {
mBitmapBundle = in.readBundle(getClass().getClassLoader());
mBoundsInScreen = in.readParcelable(Rect.class.getClassLoader(), android.graphics.Rect.class);
mInsets = in.readParcelable(Insets.class.getClassLoader(), android.graphics.Insets.class);
mBoundsInScreen = in.readParcelable(Rect.class.getClassLoader(), Rect.class);
mInsets = in.readParcelable(Insets.class.getClassLoader(), Insets.class);
mTaskId = in.readInt();
mUserId = in.readInt();
mTopComponent = in.readParcelable(ComponentName.class.getClassLoader(), android.content.ComponentName.class);
mTopComponent = in.readParcelable(ComponentName.class.getClassLoader(),
ComponentName.class);
} else {
mBitmapBundle = null;
mBoundsInScreen = null;
mInsets = null;
mTaskId = -1;
mUserId = -1;
mTopComponent = null;
}
}
@@ -88,14 +100,6 @@ public class ScreenshotHelper {
return mSource;
}
public boolean getHasStatusBar() {
return mHasStatusBar;
}
public boolean getHasNavBar() {
return mHasNavBar;
}
public Bundle getBitmapBundle() {
return mBitmapBundle;
}
@@ -112,7 +116,6 @@ public class ScreenshotHelper {
return mTaskId;
}
public int getUserId() {
return mUserId;
}
@@ -129,8 +132,6 @@ public class ScreenshotHelper {
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(mSource);
dest.writeBoolean(mHasStatusBar);
dest.writeBoolean(mHasNavBar);
if (mBitmapBundle == null) {
dest.writeInt(0);
} else {
@@ -144,7 +145,8 @@ public class ScreenshotHelper {
}
}
public static final @NonNull Parcelable.Creator<ScreenshotRequest> CREATOR =
@NonNull
public static final Parcelable.Creator<ScreenshotRequest> CREATOR =
new Parcelable.Creator<ScreenshotRequest>() {
@Override
@@ -254,113 +256,71 @@ public class ScreenshotHelper {
/**
* Request a screenshot be taken.
*
* <p>
* Added to support reducing unit test duration; the method variant without a timeout argument
* is recommended for general use.
*
* @param screenshotType The type of screenshot, for example either
* {@link android.view.WindowManager#TAKE_SCREENSHOT_FULLSCREEN}
* or
* {@link android.view.WindowManager#TAKE_SCREENSHOT_SELECTED_REGION}
* @param hasStatus {@code true} if the status bar is currently showing. {@code false}
* if not.
* @param hasNav {@code true} if the navigation bar is currently showing. {@code
* false} if not.
* @param source The source of the screenshot request. One of
* {SCREENSHOT_GLOBAL_ACTIONS, SCREENSHOT_KEY_CHORD,
* SCREENSHOT_OVERVIEW, SCREENSHOT_OTHER}
* @param handler A handler used in case the screenshot times out
* @param completionConsumer Consumes `false` if a screenshot was not taken, and `true` if the
* screenshot was taken.
* @param screenshotType The type of screenshot, defined by {@link ScreenshotType}
* @param source The source of the screenshot request, defined by {@link ScreenshotSource}
* @param handler used to process messages received from the screenshot service
* @param completionConsumer receives the URI of the captured screenshot, once saved or
* null if no screenshot was saved
*/
public void takeScreenshot(final int screenshotType, final boolean hasStatus,
final boolean hasNav, int source, @NonNull Handler handler,
@Nullable Consumer<Uri> completionConsumer) {
ScreenshotRequest screenshotRequest = new ScreenshotRequest(source, hasStatus, hasNav);
takeScreenshot(screenshotType, SCREENSHOT_TIMEOUT_MS, handler, screenshotRequest,
public void takeScreenshot(@ScreenshotType int screenshotType, @ScreenshotSource int source,
@NonNull Handler handler, @Nullable Consumer<Uri> completionConsumer) {
ScreenshotRequest screenshotRequest = new ScreenshotRequest(source);
takeScreenshot(screenshotType, handler, screenshotRequest, SCREENSHOT_TIMEOUT_MS,
completionConsumer);
}
/**
* Request a screenshot be taken, with provided reason.
*
* @param screenshotType The type of screenshot, for example either
* {@link android.view.WindowManager#TAKE_SCREENSHOT_FULLSCREEN}
* or
* {@link android.view.WindowManager#TAKE_SCREENSHOT_SELECTED_REGION}
* @param hasStatus {@code true} if the status bar is currently showing. {@code false}
* if
* not.
* @param hasNav {@code true} if the navigation bar is currently showing. {@code
* false}
* if not.
* @param handler A handler used in case the screenshot times out
* @param completionConsumer Consumes `false` if a screenshot was not taken, and `true` if the
* screenshot was taken.
*/
public void takeScreenshot(final int screenshotType, final boolean hasStatus,
final boolean hasNav, @NonNull Handler handler,
@Nullable Consumer<Uri> completionConsumer) {
takeScreenshot(screenshotType, hasStatus, hasNav, SCREENSHOT_TIMEOUT_MS, handler,
completionConsumer);
}
/**
* Request a screenshot be taken with a specific timeout.
*
* Request a screenshot be taken.
* <p>
* Added to support reducing unit test duration; the method variant without a timeout argument
* is recommended for general use.
*
* @param screenshotType The type of screenshot, for example either
* {@link android.view.WindowManager#TAKE_SCREENSHOT_FULLSCREEN}
* or
* {@link android.view.WindowManager#TAKE_SCREENSHOT_SELECTED_REGION}
* @param hasStatus {@code true} if the status bar is currently showing. {@code false}
* if
* not.
* @param hasNav {@code true} if the navigation bar is currently showing. {@code
* false}
* if not.
* @param timeoutMs If the screenshot hasn't been completed within this time period,
* the screenshot attempt will be cancelled and `completionConsumer`
* will be run.
* @param handler A handler used in case the screenshot times out
* @param completionConsumer Consumes `false` if a screenshot was not taken, and `true` if the
* screenshot was taken.
* @param screenshotType The type of screenshot, defined by {@link ScreenshotType}
* @param source The source of the screenshot request, defined by {@link ScreenshotSource}
* @param handler used to process messages received from the screenshot service
* @param timeoutMs time limit for processing, intended only for testing
* @param completionConsumer receives the URI of the captured screenshot, once saved or
* null if no screenshot was saved
*/
public void takeScreenshot(final int screenshotType, final boolean hasStatus,
final boolean hasNav, long timeoutMs, @NonNull Handler handler,
@Nullable Consumer<Uri> completionConsumer) {
ScreenshotRequest screenshotRequest = new ScreenshotRequest(SCREENSHOT_OTHER, hasStatus,
hasNav);
takeScreenshot(screenshotType, timeoutMs, handler, screenshotRequest, completionConsumer);
@VisibleForTesting
public void takeScreenshot(@ScreenshotType int screenshotType, @ScreenshotSource int source,
@NonNull Handler handler, long timeoutMs, @Nullable Consumer<Uri> completionConsumer) {
ScreenshotRequest screenshotRequest = new ScreenshotRequest(source);
takeScreenshot(screenshotType, handler, screenshotRequest, timeoutMs, completionConsumer);
}
/**
* Request that provided image be handled as if it was a screenshot.
*
* @param screenshotBundle Bundle containing the buffer and color space of the screenshot.
* @param boundsInScreen The bounds in screen coordinates that the bitmap orginated from.
* @param insets The insets that the image was shown with, inside the screenbounds.
* @param taskId The taskId of the task that the screen shot was taken of.
* @param userId The userId of user running the task provided in taskId.
* @param topComponent The component name of the top component running in the task.
* @param handler A handler used in case the screenshot times out
* @param completionConsumer Consumes `false` if a screenshot was not taken, and `true` if the
* screenshot was taken.
* @param screenshotBundle Bundle containing the buffer and color space of the screenshot.
* @param boundsInScreen The bounds in screen coordinates that the bitmap originated from.
* @param insets The insets that the image was shown with, inside the screen bounds.
* @param taskId The taskId of the task that the screen shot was taken of.
* @param userId The userId of user running the task provided in taskId.
* @param topComponent The component name of the top component running in the task.
* @param source The source of the screenshot request, defined by {@link ScreenshotSource}
* @param handler A handler used in case the screenshot times out
* @param completionConsumer receives the URI of the captured screenshot, once saved or
* null if no screenshot was saved
*/
public void provideScreenshot(@NonNull Bundle screenshotBundle, @NonNull Rect boundsInScreen,
@NonNull Insets insets, int taskId, int userId, ComponentName topComponent, int source,
@NonNull Handler handler, @Nullable Consumer<Uri> completionConsumer) {
ScreenshotRequest screenshotRequest =
new ScreenshotRequest(source, screenshotBundle, boundsInScreen, insets, taskId,
userId, topComponent);
takeScreenshot(WindowManager.TAKE_SCREENSHOT_PROVIDED_IMAGE, SCREENSHOT_TIMEOUT_MS,
handler, screenshotRequest, completionConsumer);
@NonNull Insets insets, int taskId, int userId, ComponentName topComponent,
@ScreenshotSource int source, @NonNull Handler handler,
@Nullable Consumer<Uri> completionConsumer) {
ScreenshotRequest screenshotRequest = new ScreenshotRequest(source, screenshotBundle,
boundsInScreen, insets, taskId, userId, topComponent);
takeScreenshot(WindowManager.TAKE_SCREENSHOT_PROVIDED_IMAGE, handler, screenshotRequest,
SCREENSHOT_TIMEOUT_MS,
completionConsumer);
}
private void takeScreenshot(final int screenshotType, long timeoutMs, @NonNull Handler handler,
ScreenshotRequest screenshotRequest, @Nullable Consumer<Uri> completionConsumer) {
private void takeScreenshot(@ScreenshotType int screenshotType, @NonNull Handler handler,
ScreenshotRequest screenshotRequest, long timeoutMs,
@Nullable Consumer<Uri> completionConsumer) {
synchronized (mScreenshotLock) {
final Runnable mScreenshotTimeout = () -> {

View File

@@ -80,13 +80,14 @@ public final class ScreenshotHelperTest {
@Test
public void testFullscreenScreenshot() {
mScreenshotHelper.takeScreenshot(TAKE_SCREENSHOT_FULLSCREEN, false, false, mHandler, null);
mScreenshotHelper.takeScreenshot(TAKE_SCREENSHOT_FULLSCREEN,
WindowManager.ScreenshotSource.SCREENSHOT_OTHER, mHandler, null);
}
@Test
public void testSelectedRegionScreenshot() {
mScreenshotHelper.takeScreenshot(TAKE_SCREENSHOT_SELECTED_REGION, false, false, mHandler,
null);
mScreenshotHelper.takeScreenshot(TAKE_SCREENSHOT_SELECTED_REGION,
WindowManager.ScreenshotSource.SCREENSHOT_OTHER, mHandler, null);
}
@Test
@@ -101,8 +102,10 @@ public final class ScreenshotHelperTest {
long timeoutMs = 10;
CountDownLatch lock = new CountDownLatch(1);
mScreenshotHelper.takeScreenshot(TAKE_SCREENSHOT_FULLSCREEN, false, false, timeoutMs,
mScreenshotHelper.takeScreenshot(TAKE_SCREENSHOT_FULLSCREEN,
WindowManager.ScreenshotSource.SCREENSHOT_OTHER,
mHandler,
timeoutMs,
uri -> {
assertNull(uri);
lock.countDown();

View File

@@ -500,7 +500,7 @@ public class SystemActions extends CoreStartable {
private void handleTakeScreenshot() {
ScreenshotHelper screenshotHelper = new ScreenshotHelper(mContext);
screenshotHelper.takeScreenshot(WindowManager.TAKE_SCREENSHOT_FULLSCREEN, true, true,
screenshotHelper.takeScreenshot(WindowManager.TAKE_SCREENSHOT_FULLSCREEN,
SCREENSHOT_ACCESSIBILITY_ACTIONS, new Handler(Looper.getMainLooper()), null);
}

View File

@@ -947,7 +947,7 @@ public class GlobalActionsDialogLite implements DialogInterface.OnDismissListene
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
mScreenshotHelper.takeScreenshot(TAKE_SCREENSHOT_FULLSCREEN, true, true,
mScreenshotHelper.takeScreenshot(TAKE_SCREENSHOT_FULLSCREEN,
SCREENSHOT_GLOBAL_ACTIONS, mHandler, null);
mMetricsLogger.action(MetricsEvent.ACTION_SCREENSHOT_POWER_MENU);
mUiEventLogger.log(GlobalActionsEvent.GA_SCREENSHOT_PRESS);

View File

@@ -16,8 +16,6 @@
package com.android.server.accessibility;
import static android.view.WindowManager.ScreenshotSource.SCREENSHOT_ACCESSIBILITY_ACTIONS;
import android.accessibilityservice.AccessibilityService;
import android.app.PendingIntent;
import android.app.RemoteAction;
@@ -34,6 +32,7 @@ import android.util.Slog;
import android.view.InputDevice;
import android.view.KeyCharacterMap;
import android.view.KeyEvent;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
import com.android.internal.R;
@@ -392,8 +391,8 @@ public class SystemActionPerformer {
private boolean takeScreenshot() {
ScreenshotHelper screenshotHelper = (mScreenshotHelperSupplier != null)
? mScreenshotHelperSupplier.get() : new ScreenshotHelper(mContext);
screenshotHelper.takeScreenshot(android.view.WindowManager.TAKE_SCREENSHOT_FULLSCREEN,
true, true, SCREENSHOT_ACCESSIBILITY_ACTIONS,
screenshotHelper.takeScreenshot(WindowManager.TAKE_SCREENSHOT_FULLSCREEN,
WindowManager.ScreenshotSource.SCREENSHOT_ACCESSIBILITY_ACTIONS,
new Handler(Looper.getMainLooper()), null);
return true;
}

View File

@@ -2748,8 +2748,6 @@ public class DisplayPolicy {
public void takeScreenshot(int screenshotType, int source) {
if (mScreenshotHelper != null) {
mScreenshotHelper.takeScreenshot(screenshotType,
getStatusBar() != null && getStatusBar().isVisible(),
getNavigationBar() != null && getNavigationBar().isVisible(),
source, mHandler, null /* completionConsumer */);
}
}

View File

@@ -17,6 +17,7 @@
package com.android.server.accessibility;
import static android.view.WindowManager.ScreenshotSource.SCREENSHOT_ACCESSIBILITY_ACTIONS;
import static android.view.WindowManager.TAKE_SCREENSHOT_FULLSCREEN;
import static org.hamcrest.Matchers.hasItem;
import static org.hamcrest.Matchers.is;
@@ -27,7 +28,6 @@ import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.never;
@@ -301,8 +301,9 @@ public class SystemActionPerformerTest {
mSystemActionPerformer.performSystemAction(
AccessibilityService.GLOBAL_ACTION_TAKE_SCREENSHOT);
verify(mMockScreenshotHelper).takeScreenshot(
eq(android.view.WindowManager.TAKE_SCREENSHOT_FULLSCREEN), anyBoolean(),
anyBoolean(), eq(SCREENSHOT_ACCESSIBILITY_ACTIONS), any(Handler.class), any());
eq(TAKE_SCREENSHOT_FULLSCREEN),
eq(SCREENSHOT_ACCESSIBILITY_ACTIONS),
any(Handler.class), any());
}
// PendingIntent is a final class and cannot be mocked. So we are using this