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

Commit a1adfd1d authored by Automerger Merge Worker's avatar Automerger Merge Worker Committed by Android (Google) Code Review
Browse files

Merge "Merge "Add screenshots logging" into rvc-dev am: 44cc1e27 am:...

Merge "Merge "Add screenshots logging" into rvc-dev am: 44cc1e27 am: e0efd49e" into rvc-d1-dev-plus-aosp
parents d721d28f 91b26818
Loading
Loading
Loading
Loading
+16 −25
Original line number Diff line number Diff line
@@ -514,33 +514,24 @@ public interface WindowManager extends ViewManager {
    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.
     * Enum listing the possible sources from which a screenshot was originated. Used for logging.
     *
     * @hide
     */
    String PARCEL_KEY_SCREENSHOT_INSETS = "screenshot_insets";
    @IntDef({ScreenshotSource.SCREENSHOT_GLOBAL_ACTIONS,
            ScreenshotSource.SCREENSHOT_KEY_CHORD,
            ScreenshotSource.SCREENSHOT_KEY_OTHER,
            ScreenshotSource.SCREENSHOT_OVERVIEW,
            ScreenshotSource.SCREENSHOT_ACCESSIBILITY_ACTIONS,
            ScreenshotSource.SCREENSHOT_OTHER})
    @interface ScreenshotSource {
        int SCREENSHOT_GLOBAL_ACTIONS = 0;
        int SCREENSHOT_KEY_CHORD = 1;
        int SCREENSHOT_KEY_OTHER = 2;
        int SCREENSHOT_OVERVIEW = 3;
        int SCREENSHOT_ACCESSIBILITY_ACTIONS = 4;
        int SCREENSHOT_OTHER = 5;
    }

    /**
     * @hide
+149 −28
Original line number Diff line number Diff line
package com.android.internal.util;

import static android.view.WindowManager.ScreenshotSource.SCREENSHOT_OTHER;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.ComponentName;
@@ -10,11 +12,12 @@ 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;
import android.os.Messenger;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.RemoteException;
import android.os.UserHandle;
import android.util.Log;
@@ -23,6 +26,109 @@ import android.view.WindowManager;
import java.util.function.Consumer;

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 Bitmap mBitmap;
        private Rect mBoundsInScreen;
        private Insets mInsets;
        private int mTaskId;

        ScreenshotRequest(int source, boolean hasStatus, boolean hasNav) {
            mSource = source;
            mHasStatusBar = hasStatus;
            mHasNavBar = hasNav;
        }

        ScreenshotRequest(
                int source, Bitmap bitmap, Rect boundsInScreen, Insets insets, int taskId) {
            mSource = source;
            mBitmap = bitmap;
            mBoundsInScreen = boundsInScreen;
            mInsets = insets;
            mTaskId = taskId;
        }

        ScreenshotRequest(Parcel in) {
            mSource = in.readInt();
            mHasStatusBar = in.readBoolean();
            mHasNavBar = in.readBoolean();
            if (in.readInt() == 1) {
                mBitmap = in.readParcelable(Bitmap.class.getClassLoader());
                mBoundsInScreen = in.readParcelable(Rect.class.getClassLoader());
                mInsets = in.readParcelable(Insets.class.getClassLoader());
                mTaskId = in.readInt();
            }
        }

        public int getSource() {
            return mSource;
        }

        public boolean getHasStatusBar() {
            return mHasStatusBar;
        }

        public boolean getHasNavBar() {
            return mHasNavBar;
        }

        public Bitmap getBitmap() {
            return mBitmap;
        }

        public Rect getBoundsInScreen() {
            return mBoundsInScreen;
        }

        public Insets getInsets() {
            return mInsets;
        }

        public int getTaskId() {
            return mTaskId;
        }

        @Override
        public int describeContents() {
            return 0;
        }

        @Override
        public void writeToParcel(Parcel dest, int flags) {
            dest.writeInt(mSource);
            dest.writeBoolean(mHasStatusBar);
            dest.writeBoolean(mHasNavBar);
            if (mBitmap == null) {
                dest.writeInt(0);
            } else {
                dest.writeInt(1);
                dest.writeParcelable(mBitmap, 0);
                dest.writeParcelable(mBoundsInScreen, 0);
                dest.writeParcelable(mInsets, 0);
                dest.writeInt(mTaskId);
            }
        }

        public static final @NonNull Parcelable.Creator<ScreenshotRequest> CREATOR =
                new Parcelable.Creator<ScreenshotRequest>() {

                    @Override
                    public ScreenshotRequest createFromParcel(Parcel source) {
                        return new ScreenshotRequest(source);
                    }

                    @Override
                    public ScreenshotRequest[] newArray(int size) {
                        return new ScreenshotRequest[size];
                    }
                };
    }
    private static final String TAG = "ScreenshotHelper";

    // Time until we give up on the screenshot & show an error instead.
@@ -36,8 +142,10 @@ public class ScreenshotHelper {
        mContext = context;
    }



    /**
     * Request a screenshot be taken with a specific timeout.
     * Request a screenshot be taken.
     *
     * Added to support reducing unit test duration; the method variant without a timeout argument
     * is recommended for general use.
@@ -47,6 +155,32 @@ public class ScreenshotHelper {
     *                           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.
     */
    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,
                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
@@ -64,7 +198,7 @@ public class ScreenshotHelper {
    }

    /**
     * Request a screenshot be taken.
     * Request a screenshot be taken with a specific timeout.
     *
     * Added to support reducing unit test duration; the method variant without a timeout argument
     * is recommended for general use.
@@ -89,9 +223,9 @@ 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
        );
        ScreenshotRequest screenshotRequest = new ScreenshotRequest(SCREENSHOT_OTHER, hasStatus,
                hasNav);
        takeScreenshot(screenshotType, timeoutMs, handler, screenshotRequest, completionConsumer);
    }

    /**
@@ -106,23 +240,16 @@ public class ScreenshotHelper {
     *                           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);
            @NonNull Insets insets, int taskId, int source,
            @NonNull Handler handler, @Nullable Consumer<Uri> completionConsumer) {
        ScreenshotRequest screenshotRequest =
                new ScreenshotRequest(source, screenshot, boundsInScreen, insets, taskId);
        takeScreenshot(WindowManager.TAKE_SCREENSHOT_PROVIDED_IMAGE, SCREENSHOT_TIMEOUT_MS,
                handler, screenshotRequest, 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) {
    private void takeScreenshot(final int screenshotType, long timeoutMs, @NonNull Handler handler,
            ScreenshotRequest screenshotRequest, @Nullable Consumer<Uri> completionConsumer) {
        synchronized (mScreenshotLock) {
            if (mScreenshotConnection != null) {
                return;
@@ -157,7 +284,7 @@ public class ScreenshotHelper {
                            return;
                        }
                        Messenger messenger = new Messenger(service);
                        Message msg = Message.obtain(null, screenshotType);
                        Message msg = Message.obtain(null, screenshotType, screenshotRequest);
                        final ServiceConnection myConn = this;
                        Handler h = new Handler(handler.getLooper()) {
                            @Override
@@ -175,12 +302,6 @@ public class ScreenshotHelper {
                            }
                        };
                        msg.replyTo = new Messenger(h);
                        msg.arg1 = hasStatus ? 1 : 0;
                        msg.arg2 = hasNav ? 1 : 0;

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

                        try {
                            messenger.send(msg);
+3 −1
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ import android.graphics.Insets;
import android.graphics.Rect;
import android.os.Handler;
import android.os.Looper;
import android.view.WindowManager;

import androidx.test.runner.AndroidJUnit4;

@@ -91,7 +92,8 @@ public final class ScreenshotHelperTest {
    public void testProvidedImageScreenshot() {
        mScreenshotHelper.provideScreenshot(
                Bitmap.createBitmap(10, 10, Bitmap.Config.ARGB_8888), new Rect(),
                Insets.of(0, 0, 0, 0), 1, mHandler, null);
                Insets.of(0, 0, 0, 0), 1,
                WindowManager.ScreenshotSource.SCREENSHOT_OTHER, mHandler, null);
    }

    @Test
+4 −2
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.systemui.accessibility;

import static android.view.WindowManager.ScreenshotSource.SCREENSHOT_GLOBAL_ACTIONS;

import android.accessibilityservice.AccessibilityService;
import android.app.PendingIntent;
import android.app.RemoteAction;
@@ -282,8 +284,8 @@ public class SystemActions extends SystemUI {

    private void handleTakeScreenshot() {
        ScreenshotHelper screenshotHelper = new ScreenshotHelper(mContext);
        screenshotHelper.takeScreenshot(WindowManager.TAKE_SCREENSHOT_FULLSCREEN,
                true, true, new Handler(Looper.getMainLooper()), null);
        screenshotHelper.takeScreenshot(WindowManager.TAKE_SCREENSHOT_FULLSCREEN, true, true,
                SCREENSHOT_GLOBAL_ACTIONS, new Handler(Looper.getMainLooper()), null);
    }

    private void handleAccessibilityMenu() {
+4 −1
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@ package com.android.systemui.globalactions;

import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
import static android.view.WindowManager.ScreenshotSource.SCREENSHOT_GLOBAL_ACTIONS;
import static android.view.WindowManager.TAKE_SCREENSHOT_FULLSCREEN;

import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_USER_REQUEST;
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_NOT_REQUIRED;
@@ -830,7 +832,8 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener,
            mHandler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    mScreenshotHelper.takeScreenshot(1, true, true, mHandler, null);
                    mScreenshotHelper.takeScreenshot(TAKE_SCREENSHOT_FULLSCREEN, true, true,
                            SCREENSHOT_GLOBAL_ACTIONS, mHandler, null);
                    mMetricsLogger.action(MetricsEvent.ACTION_SCREENSHOT_POWER_MENU);
                    mUiEventLogger.log(GlobalActionsEvent.GA_SCREENSHOT_PRESS);
                }
Loading