Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 43d85880 authored by Zak Cohen's avatar Zak Cohen Committed by Android (Google) Code Review
Browse files

Merge "Screenshot helper - add method that allows the caller to supply bitmap."

parents fc6d7d29 ebd3b8b1
Loading
Loading
Loading
Loading
+37 −2
Original line number Diff line number Diff line
@@ -497,13 +497,48 @@ public interface WindowManager extends ViewManager {
     * Message for taking fullscreen screenshot
     * @hide
     */
    final int TAKE_SCREENSHOT_FULLSCREEN = 1;
    int TAKE_SCREENSHOT_FULLSCREEN = 1;

    /**
     * Message for taking screenshot of selected region.
     * @hide
     */
    final int TAKE_SCREENSHOT_SELECTED_REGION = 2;
    int TAKE_SCREENSHOT_SELECTED_REGION = 2;

    /**
     * Message for handling a screenshot flow with an image provided by the caller.
     * @hide
     */
    int TAKE_SCREENSHOT_PROVIDED_IMAGE = 3;

    /**
     * Parcel key for the screen shot bitmap sent with messages of type
     * {@link #TAKE_SCREENSHOT_PROVIDED_IMAGE}, type {@link android.graphics.Bitmap}
     * @hide
     */
    String PARCEL_KEY_SCREENSHOT_BITMAP = "screenshot_screen_bitmap";

    /**
     * Parcel key for the screen bounds of the image sent with messages of type
     * [@link {@link #TAKE_SCREENSHOT_PROVIDED_IMAGE}], type {@link Rect} in screen coordinates.
     * @hide
     */
    String PARCEL_KEY_SCREENSHOT_BOUNDS = "screenshot_screen_bounds";

    /**
     * Parcel key for the task id of the task that the screen shot was taken of, sent with messages
     * of type [@link {@link #TAKE_SCREENSHOT_PROVIDED_IMAGE}], type int.
     * @hide
     */
    String PARCEL_KEY_SCREENSHOT_TASK_ID = "screenshot_task_id";

    /**
     * Parcel key for the visible insets of the image sent with messages of type
     * [@link {@link #TAKE_SCREENSHOT_PROVIDED_IMAGE}], type {@link android.graphics.Insets} in
     * screen coordinates.
     * @hide
     */
    String PARCEL_KEY_SCREENSHOT_INSETS = "screenshot_insets";

    /**
     * @hide
+47 −4
Original line number Diff line number Diff line
@@ -6,7 +6,11 @@ import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.graphics.Bitmap;
import android.graphics.Insets;
import android.graphics.Rect;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
@@ -14,6 +18,7 @@ import android.os.Messenger;
import android.os.RemoteException;
import android.os.UserHandle;
import android.util.Log;
import android.view.WindowManager;

import java.util.function.Consumer;

@@ -38,9 +43,9 @@ public class ScreenshotHelper {
     * is recommended for general use.
     *
     * @param screenshotType     The type of screenshot, for example either
     *                           {@link android.view.WindowManager.TAKE_SCREENSHOT_FULLSCREEN}
     *                           {@link android.view.WindowManager#TAKE_SCREENSHOT_FULLSCREEN}
     *                           or
     *                           {@link android.view.WindowManager.TAKE_SCREENSHOT_SELECTED_REGION}
     *                           {@link android.view.WindowManager#TAKE_SCREENSHOT_SELECTED_REGION}
     * @param hasStatus          {@code true} if the status bar is currently showing. {@code false}
     *                           if
     *                           not.
@@ -65,9 +70,9 @@ public class ScreenshotHelper {
     * is recommended for general use.
     *
     * @param screenshotType     The type of screenshot, for example either
     *                           {@link android.view.WindowManager.TAKE_SCREENSHOT_FULLSCREEN}
     *                           {@link android.view.WindowManager#TAKE_SCREENSHOT_FULLSCREEN}
     *                           or
     *                           {@link android.view.WindowManager.TAKE_SCREENSHOT_SELECTED_REGION}
     *                           {@link android.view.WindowManager#TAKE_SCREENSHOT_SELECTED_REGION}
     * @param hasStatus          {@code true} if the status bar is currently showing. {@code false}
     *                           if
     *                           not.
@@ -84,6 +89,40 @@ public class ScreenshotHelper {
    public void takeScreenshot(final int screenshotType, final boolean hasStatus,
            final boolean hasNav, long timeoutMs, @NonNull Handler handler,
            @Nullable Consumer<Uri> completionConsumer) {
        takeScreenshot(screenshotType, hasStatus, hasNav, timeoutMs, handler, null,
                completionConsumer
        );
    }

    /**
     * Request that provided image be handled as if it was a screenshot.
     *
     * @param screenshot         The bitmap to treat as the screen shot.
     * @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 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 provideScreenshot(@NonNull Bitmap screenshot, @NonNull Rect boundsInScreen,
            @NonNull Insets insets, int taskId, @NonNull Handler handler,
            @Nullable Consumer<Uri> completionConsumer) {
        Bundle imageBundle = new Bundle();
        imageBundle.putParcelable(WindowManager.PARCEL_KEY_SCREENSHOT_BITMAP, screenshot);
        imageBundle.putParcelable(WindowManager.PARCEL_KEY_SCREENSHOT_BOUNDS, boundsInScreen);
        imageBundle.putParcelable(WindowManager.PARCEL_KEY_SCREENSHOT_INSETS, insets);
        imageBundle.putInt(WindowManager.PARCEL_KEY_SCREENSHOT_TASK_ID, taskId);

        takeScreenshot(
                WindowManager.TAKE_SCREENSHOT_PROVIDED_IMAGE,
                false, false, // ignored when image bundle is set
                SCREENSHOT_TIMEOUT_MS, handler, imageBundle, completionConsumer);
    }

    private void takeScreenshot(final int screenshotType, final boolean hasStatus,
            final boolean hasNav, long timeoutMs, @NonNull Handler handler,
            @Nullable Bundle providedImage, @Nullable Consumer<Uri> completionConsumer) {
        synchronized (mScreenshotLock) {
            if (mScreenshotConnection != null) {
                return;
@@ -139,6 +178,10 @@ public class ScreenshotHelper {
                        msg.arg1 = hasStatus ? 1 : 0;
                        msg.arg2 = hasNav ? 1 : 0;

                        if (screenshotType == WindowManager.TAKE_SCREENSHOT_PROVIDED_IMAGE) {
                            msg.setData(providedImage);
                        }

                        try {
                            messenger.send(msg);
                        } catch (RemoteException e) {
+10 −0
Original line number Diff line number Diff line
@@ -31,6 +31,9 @@ import static org.mockito.Mockito.mock;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Insets;
import android.graphics.Rect;
import android.os.Handler;
import android.os.Looper;

@@ -84,6 +87,13 @@ public final class ScreenshotHelperTest {
                null);
    }

    @Test
    public void testProvidedImageScreenshot() {
        mScreenshotHelper.provideScreenshot(
                Bitmap.createBitmap(10, 10, Bitmap.Config.ARGB_8888), new Rect(),
                Insets.of(0, 0, 0, 0), 1, mHandler, null);
    }

    @Test
    public void testScreenshotTimesOut() {
        long timeoutMs = 10;
+9 −0
Original line number Diff line number Diff line
@@ -16,12 +16,15 @@

package com.android.systemui.shared.recents;

import android.graphics.Bitmap;
import android.graphics.Insets;
import android.graphics.Rect;
import android.os.Bundle;
import android.view.MotionEvent;

/**
 * Temporary callbacks into SystemUI.
 * Next id = 22
 */
interface ISystemUiProxy {

@@ -114,4 +117,10 @@ interface ISystemUiProxy {
     * Sets the shelf height and visibility.
     */
    void setShelfHeight(boolean visible, int shelfHeight) = 20;

    /**
     * Handle the provided image as if it was a screenshot.
     */
     void handleImageAsScreenshot(in Bitmap screenImage, in Rect locationInScreen,
              in Insets visibleInsets, int taskId) = 21;
}
+12 −0
Original line number Diff line number Diff line
@@ -38,6 +38,8 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.graphics.Bitmap;
import android.graphics.Insets;
import android.graphics.Rect;
import android.graphics.Region;
import android.hardware.input.InputManager;
@@ -55,6 +57,7 @@ import android.view.MotionEvent;
import android.view.accessibility.AccessibilityManager;

import com.android.internal.policy.ScreenDecorationsUtils;
import com.android.internal.util.ScreenshotHelper;
import com.android.systemui.Dumpable;
import com.android.systemui.model.SysUiState;
import com.android.systemui.pip.PipUI;
@@ -115,6 +118,7 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis
    private final DeviceProvisionedController mDeviceProvisionedController;
    private final List<OverviewProxyListener> mConnectionCallbacks = new ArrayList<>();
    private final Intent mQuickStepIntent;
    private final ScreenshotHelper mScreenshotHelper;

    private Region mActiveNavBarRegion;

@@ -365,6 +369,13 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis
            }
        }

        @Override
        public void handleImageAsScreenshot(Bitmap screenImage, Rect locationInScreen,
                Insets visibleInsets, int taskId) {
            mScreenshotHelper.provideScreenshot(screenImage, locationInScreen, visibleInsets,
                    taskId, mHandler, null);
        }

        private boolean verifyCaller(String reason) {
            final int callerId = Binder.getCallingUserHandle().getIdentifier();
            if (callerId != mCurrentBoundedUserId) {
@@ -518,6 +529,7 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis

        // Listen for status bar state changes
        statusBarWinController.registerCallback(mStatusBarWindowCallback);
        mScreenshotHelper = new ScreenshotHelper(context);
    }

    public void notifyBackAction(boolean completed, int downX, int downY, boolean isButton,
Loading