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

Commit f43ac720 authored by Massimo Carli's avatar Massimo Carli Committed by Android (Google) Code Review
Browse files

Merge "[25/n] Reduce LetterboxUiController-Reachability dependencies" into main

parents d1c47031 d621aacb
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -1988,8 +1988,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        // Don't move below setOrientation(info.screenOrientation) since it triggers
        // getOverrideOrientation that requires having mLetterboxUiController
        // initialised.
        mLetterboxUiController = new LetterboxUiController(mWmService, this);
        mAppCompatController = new AppCompatController(mWmService, this);
        mLetterboxUiController = new LetterboxUiController(mWmService, this);
        mResolveConfigHint = new TaskFragment.ConfigOverrideHint();
        if (mWmService.mFlags.mInsetsDecoupledConfiguration) {
            // When the stable configuration is the default behavior, override for the legacy apps
+33 −8
Original line number Diff line number Diff line
@@ -28,10 +28,9 @@ import static com.android.server.wm.AppCompatConfiguration.LETTERBOX_HORIZONTAL_
import static com.android.server.wm.AppCompatConfiguration.LETTERBOX_VERTICAL_REACHABILITY_POSITION_CENTER;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.graphics.Rect;

import com.android.internal.annotations.VisibleForTesting;

import java.util.function.Supplier;

/**
@@ -43,6 +42,8 @@ class AppCompatReachabilityPolicy {
    private final ActivityRecord mActivityRecord;
    @NonNull
    private final AppCompatConfiguration mAppCompatConfiguration;
    @Nullable
    private Supplier<Rect> mLetterboxInnerBoundsSupplier;

    AppCompatReachabilityPolicy(@NonNull ActivityRecord activityRecord,
            @NonNull AppCompatConfiguration appCompatConfiguration) {
@@ -50,15 +51,34 @@ class AppCompatReachabilityPolicy {
        mAppCompatConfiguration = appCompatConfiguration;
    }

    @VisibleForTesting
    void handleHorizontalDoubleTap(int x, @NonNull Supplier<Rect> innerFrameSupplier) {
    /**
     * To handle reachability a supplier for the current letterox inner bounds is required.
     * <p/>
     * @param letterboxInnerBoundsSupplier The supplier for the letterbox inner bounds.
     */
    void setLetterboxInnerBoundsSupplier(@Nullable Supplier<Rect> letterboxInnerBoundsSupplier) {
        mLetterboxInnerBoundsSupplier = letterboxInnerBoundsSupplier;
    }

    /**
     * Handles double tap events for reachability.
     * <p/>
     * @param x Double tap x coordinate.
     * @param y Double tap y coordinate.
     */
    void handleDoubleTap(int x, int y) {
        handleHorizontalDoubleTap(x);
        handleVerticalDoubleTap(y);
    }

    private void handleHorizontalDoubleTap(int x) {
        final AppCompatReachabilityOverrides reachabilityOverrides =
                mActivityRecord.mAppCompatController.getAppCompatReachabilityOverrides();
        if (!reachabilityOverrides.isHorizontalReachabilityEnabled()
                || mActivityRecord.isInTransition()) {
            return;
        }
        final Rect letterboxInnerFrame = innerFrameSupplier.get();
        final Rect letterboxInnerFrame = getLetterboxInnerFrame();
        if (letterboxInnerFrame.left <= x && letterboxInnerFrame.right >= x) {
            // Only react to clicks at the sides of the letterboxed app window.
            return;
@@ -97,15 +117,14 @@ class AppCompatReachabilityPolicy {
        mActivityRecord.recomputeConfiguration();
    }

    @VisibleForTesting
    void handleVerticalDoubleTap(int y, @NonNull Supplier<Rect> innerFrameSupplier) {
    private void handleVerticalDoubleTap(int y) {
        final AppCompatReachabilityOverrides reachabilityOverrides =
                mActivityRecord.mAppCompatController.getAppCompatReachabilityOverrides();
        if (!reachabilityOverrides.isVerticalReachabilityEnabled()
                || mActivityRecord.isInTransition()) {
            return;
        }
        final Rect letterboxInnerFrame = innerFrameSupplier.get();
        final Rect letterboxInnerFrame = getLetterboxInnerFrame();
        if (letterboxInnerFrame.top <= y && letterboxInnerFrame.bottom >= y) {
            // Only react to clicks at the top and bottom of the letterboxed app window.
            return;
@@ -150,4 +169,10 @@ class AppCompatReachabilityPolicy {
        mActivityRecord.mTaskSupervisor.getActivityMetricsLogger()
                .logLetterboxPositionChange(mActivityRecord, letterboxPositionChangeForLog);
    }

    @NonNull
    private Rect getLetterboxInnerFrame() {
        return mLetterboxInnerBoundsSupplier != null ? mLetterboxInnerBoundsSupplier.get()
                : new Rect();
    }
}
+27 −1
Original line number Diff line number Diff line
@@ -63,7 +63,7 @@ class AppCompatUtils {
    /**
     * Returns the aspect ratio of the given {@code rect}.
     */
    static float computeAspectRatio(Rect rect) {
    static float computeAspectRatio(@NonNull Rect rect) {
        final int width = rect.width();
        final int height = rect.height();
        if (width == 0 || height == 0) {
@@ -181,4 +181,30 @@ class AppCompatUtils {
        appCompatTaskInfo.cameraCompatTaskInfo.freeformCameraCompatMode = top.mAppCompatController
                .getAppCompatCameraOverrides().getFreeformCameraCompatMode();
    }

    /**
     * Returns a string representing the reason for letterboxing. This method assumes the activity
     * is letterboxed.
     * @param activityRecord The {@link ActivityRecord} for the letterboxed activity.
     * @param mainWin   The {@link WindowState} used to letterboxing.
     */
    @NonNull
    static String getLetterboxReasonString(@NonNull ActivityRecord activityRecord,
            @NonNull WindowState mainWin) {
        if (activityRecord.inSizeCompatMode()) {
            return "SIZE_COMPAT_MODE";
        }
        final AppCompatAspectRatioPolicy aspectRatioPolicy = activityRecord.mAppCompatController
                .getAppCompatAspectRatioPolicy();
        if (aspectRatioPolicy.isLetterboxedForFixedOrientationAndAspectRatio()) {
            return "FIXED_ORIENTATION";
        }
        if (mainWin.isLetterboxedForDisplayCutout()) {
            return "DISPLAY_CUTOUT";
        }
        if (aspectRatioPolicy.isLetterboxedForAspectRatioOnly()) {
            return "ASPECT_RATIO";
        }
        return "UNKNOWN_REASON";
    }
}
+8 −10
Original line number Diff line number Diff line
@@ -40,7 +40,6 @@ import com.android.server.UiThread;

import java.util.function.BooleanSupplier;
import java.util.function.DoubleSupplier;
import java.util.function.IntConsumer;
import java.util.function.IntSupplier;
import java.util.function.Supplier;

@@ -76,9 +75,8 @@ public class Letterbox {
    // for overlaping an app window and letterbox surfaces.
    private final LetterboxSurface mFullWindowSurface = new LetterboxSurface("fullWindow");
    private final LetterboxSurface[] mSurfaces = { mLeft, mTop, mRight, mBottom };
    // Reachability gestures.
    private final IntConsumer mDoubleTapCallbackX;
    private final IntConsumer mDoubleTapCallbackY;
    @NonNull
    private final AppCompatReachabilityPolicy mAppCompatReachabilityPolicy;

    /**
     * Constructs a Letterbox.
@@ -92,8 +90,7 @@ public class Letterbox {
            BooleanSupplier hasWallpaperBackgroundSupplier,
            IntSupplier blurRadiusSupplier,
            DoubleSupplier darkScrimAlphaSupplier,
            IntConsumer doubleTapCallbackX,
            IntConsumer doubleTapCallbackY,
            @NonNull AppCompatReachabilityPolicy appCompatReachabilityPolicy,
            Supplier<SurfaceControl> parentSurface) {
        mSurfaceControlFactory = surfaceControlFactory;
        mTransactionFactory = transactionFactory;
@@ -102,9 +99,10 @@ public class Letterbox {
        mHasWallpaperBackgroundSupplier = hasWallpaperBackgroundSupplier;
        mBlurRadiusSupplier = blurRadiusSupplier;
        mDarkScrimAlphaSupplier = darkScrimAlphaSupplier;
        mDoubleTapCallbackX = doubleTapCallbackX;
        mDoubleTapCallbackY = doubleTapCallbackY;
        mAppCompatReachabilityPolicy = appCompatReachabilityPolicy;
        mParentSurfaceSupplier = parentSurface;
        // TODO Remove after Letterbox refactoring.
        mAppCompatReachabilityPolicy.setLetterboxInnerBoundsSupplier(this::getInnerFrame);
    }

    /**
@@ -290,8 +288,8 @@ public class Letterbox {
                // This check prevents late events to be handled in case the Letterbox has been
                // already destroyed and so mOuter.isEmpty() is true.
                if (!mOuter.isEmpty() && e.getAction() == MotionEvent.ACTION_UP) {
                    mDoubleTapCallbackX.accept((int) e.getRawX());
                    mDoubleTapCallbackY.accept((int) e.getRawY());
                    mAppCompatReachabilityPolicy.handleDoubleTap((int) e.getRawX(),
                            (int) e.getRawY());
                    return true;
                }
                return false;
+37 −63
Original line number Diff line number Diff line
@@ -31,7 +31,6 @@ import static com.android.server.wm.AppCompatConfiguration.letterboxBackgroundTy
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManager.TaskDescription;
import android.content.res.Configuration;
import android.graphics.Color;
import android.graphics.Point;
import android.graphics.Rect;
@@ -63,6 +62,16 @@ final class LetterboxUiController {

    private final ActivityRecord mActivityRecord;

    // TODO(b/356385137): Remove these we added to make dependencies temporarily explicit.
    @NonNull
    private final AppCompatReachabilityOverrides mAppCompatReachabilityOverrides;
    @NonNull
    private final AppCompatReachabilityPolicy mAppCompatReachabilityPolicy;
    @NonNull
    private final TransparentPolicy mTransparentPolicy;
    @NonNull
    private final AppCompatOrientationOverrides mAppCompatOrientationOverrides;

    private boolean mShowWallpaperForLetterboxBackground;

    @Nullable
@@ -76,6 +85,15 @@ final class LetterboxUiController {
        // is created in its constructor. It shouldn't be used in this constructor but it's safe
        // to use it after since controller is only used in ActivityRecord.
        mActivityRecord = activityRecord;
        // TODO(b/356385137): Remove these we added to make dependencies temporarily explicit.
        mAppCompatReachabilityOverrides = mActivityRecord.mAppCompatController
                .getAppCompatReachabilityOverrides();
        mAppCompatReachabilityPolicy = mActivityRecord.mAppCompatController
                .getAppCompatReachabilityPolicy();
        mTransparentPolicy = mActivityRecord.mAppCompatController.getTransparentPolicy();
        mAppCompatOrientationOverrides = mActivityRecord.mAppCompatController
                .getAppCompatOrientationOverrides();

    }

    /** Cleans up {@link Letterbox} if it exists.*/
@@ -83,6 +101,8 @@ final class LetterboxUiController {
        if (mLetterbox != null) {
            mLetterbox.destroy();
            mLetterbox = null;
            // TODO Remove after Letterbox refactoring.
            mAppCompatReachabilityPolicy.setLetterboxInnerBoundsSupplier(null);
        }
    }

@@ -166,8 +186,7 @@ final class LetterboxUiController {
                        this::hasWallpaperBackgroundForLetterbox,
                        this::getLetterboxWallpaperBlurRadiusPx,
                        this::getLetterboxWallpaperDarkScrimAlpha,
                        this::handleHorizontalDoubleTap,
                        this::handleVerticalDoubleTap,
                        mAppCompatReachabilityPolicy,
                        this::getLetterboxParentSurface);
                mLetterbox.attachInput(w);
            }
@@ -203,12 +222,10 @@ final class LetterboxUiController {
            // For this reason we use ActivityRecord#getBounds() that the translucent activity
            // inherits from the first opaque activity beneath and also takes care of the scaling
            // in case of activities in size compat mode.
            final Rect innerFrame = mActivityRecord.mAppCompatController
                    .getTransparentPolicy().isRunning()
                    ? mActivityRecord.getBounds() : w.getFrame();
            final Rect innerFrame =
                    mTransparentPolicy.isRunning() ? mActivityRecord.getBounds() : w.getFrame();
            mLetterbox.layout(spaceToFill, innerFrame, mTmpPoint);
            if (mActivityRecord.mAppCompatController
                    .getAppCompatReachabilityOverrides().isDoubleTapEvent()) {
            if (mAppCompatReachabilityOverrides.isDoubleTapEvent()) {
                // We need to notify Shell that letterbox position has changed.
                mActivityRecord.getTask().dispatchTaskInfoChangedIfNeeded(true /* force */);
            }
@@ -243,36 +260,13 @@ final class LetterboxUiController {
                && mActivityRecord.fillsParent();
    }

    float getHorizontalPositionMultiplier(@NonNull Configuration parentConfiguration) {
        return mActivityRecord.mAppCompatController.getAppCompatReachabilityOverrides()
                .getHorizontalPositionMultiplier(parentConfiguration);
    }

    float getVerticalPositionMultiplier(@NonNull Configuration parentConfiguration) {
        return mActivityRecord.mAppCompatController.getAppCompatReachabilityOverrides()
                .getVerticalPositionMultiplier(parentConfiguration);
    }

    boolean isLetterboxEducationEnabled() {
        return mAppCompatConfiguration.getIsEducationEnabled();
    }

    @VisibleForTesting
    void handleHorizontalDoubleTap(int x) {
        mActivityRecord.mAppCompatController.getAppCompatReachabilityPolicy()
                .handleHorizontalDoubleTap(x, mLetterbox::getInnerFrame);
    }

    @VisibleForTesting
    void handleVerticalDoubleTap(int y) {
        mActivityRecord.mAppCompatController.getAppCompatReachabilityPolicy()
                .handleVerticalDoubleTap(y, mLetterbox::getInnerFrame);
    }

    @VisibleForTesting
    boolean shouldShowLetterboxUi(WindowState mainWindow) {
        if (mActivityRecord.mAppCompatController.getAppCompatOrientationOverrides()
                .getIsRelaunchingAfterRequestedOrientationChanged()) {
        if (mAppCompatOrientationOverrides.getIsRelaunchingAfterRequestedOrientationChanged()) {
            return mLastShouldShowLetterboxUi;
        }

@@ -361,8 +355,7 @@ final class LetterboxUiController {
        // corners because we assume the specific layout would. This is the case when the layout
        // of the translucent activity uses only a part of all the bounds because of the use of
        // LayoutParams.WRAP_CONTENT.
        if (mActivityRecord.mAppCompatController.getTransparentPolicy().isRunning()
                && (cropBounds.width() != mainWindow.mRequestedWidth
        if (mTransparentPolicy.isRunning() && (cropBounds.width() != mainWindow.mRequestedWidth
                || cropBounds.height() != mainWindow.mRequestedHeight)) {
            return null;
        }
@@ -505,7 +498,8 @@ final class LetterboxUiController {
            return;
        }

        pw.println(prefix + "  letterboxReason=" + getLetterboxReasonString(mainWin));
        pw.println(prefix + "  letterboxReason="
                + AppCompatUtils.getLetterboxReasonString(mActivityRecord, mainWin));
        pw.println(prefix + "  activityAspectRatio="
                + AppCompatUtils.computeAspectRatio(mActivityRecord.getBounds()));

@@ -515,10 +509,10 @@ final class LetterboxUiController {
        if (!shouldShowLetterboxUi) {
            return;
        }
        pw.println(prefix + "  isVerticalThinLetterboxed=" + mActivityRecord.mAppCompatController
                .getAppCompatReachabilityOverrides().isVerticalThinLetterboxed());
        pw.println(prefix + "  isHorizontalThinLetterboxed=" + mActivityRecord.mAppCompatController
                .getAppCompatReachabilityOverrides().isHorizontalThinLetterboxed());
        pw.println(prefix + "  isVerticalThinLetterboxed="
                + mAppCompatReachabilityOverrides.isVerticalThinLetterboxed());
        pw.println(prefix + "  isHorizontalThinLetterboxed="
                + mAppCompatReachabilityOverrides.isHorizontalThinLetterboxed());
        pw.println(prefix + "  letterboxBackgroundColor=" + Integer.toHexString(
                getLetterboxBackgroundColor().toArgb()));
        pw.println(prefix + "  letterboxBackgroundType="
@@ -542,9 +536,11 @@ final class LetterboxUiController {
        pw.println(prefix + "  isVerticalReachabilityEnabled="
                + reachabilityOverrides.isVerticalReachabilityEnabled());
        pw.println(prefix + "  letterboxHorizontalPositionMultiplier="
                + getHorizontalPositionMultiplier(mActivityRecord.getParent().getConfiguration()));
                + mAppCompatReachabilityOverrides.getHorizontalPositionMultiplier(mActivityRecord
                    .getParent().getConfiguration()));
        pw.println(prefix + "  letterboxVerticalPositionMultiplier="
                + getVerticalPositionMultiplier(mActivityRecord.getParent().getConfiguration()));
                + mAppCompatReachabilityOverrides.getVerticalPositionMultiplier(mActivityRecord
                    .getParent().getConfiguration()));
        pw.println(prefix + "  letterboxPositionForHorizontalReachability="
                + AppCompatConfiguration.letterboxHorizontalReachabilityPositionToString(
                mAppCompatConfiguration.getLetterboxPositionForHorizontalReachability(false)));
@@ -562,28 +558,6 @@ final class LetterboxUiController {
                .getIsDisplayAspectRatioEnabledForFixedOrientationLetterbox());
    }

    /**
     * Returns a string representing the reason for letterboxing. This method assumes the activity
     * is letterboxed.
     */
    private String getLetterboxReasonString(WindowState mainWin) {
        if (mActivityRecord.inSizeCompatMode()) {
            return "SIZE_COMPAT_MODE";
        }
        if (mActivityRecord.mAppCompatController.getAppCompatAspectRatioPolicy()
                .isLetterboxedForFixedOrientationAndAspectRatio()) {
            return "FIXED_ORIENTATION";
        }
        if (mainWin.isLetterboxedForDisplayCutout()) {
            return "DISPLAY_CUTOUT";
        }
        if (mActivityRecord.mAppCompatController.getAppCompatAspectRatioPolicy()
                .isLetterboxedForAspectRatioOnly()) {
            return "ASPECT_RATIO";
        }
        return "UNKNOWN_REASON";
    }

    @Nullable
    LetterboxDetails getLetterboxDetails() {
        final WindowState w = mActivityRecord.findMainWindow();
Loading