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

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

Merge "[18/n] Extract applyAspectRatio logic" into main

parents 59893908 17816c28
Loading
Loading
Loading
Loading
+28 −52
Original line number Diff line number Diff line
@@ -817,23 +817,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
    // naturally.
    private boolean mInSizeCompatModeForBounds = false;

    // Bounds populated in resolveFixedOrientationConfiguration when this activity is letterboxed
    // for fixed orientation. If not null, they are used as parent container in
    // resolveSizeCompatModeConfiguration and in a constructor of CompatDisplayInsets. If
    // letterboxed due to fixed orientation then aspect ratio restrictions are also respected.
    // This happens when an activity has fixed orientation which doesn't match orientation of the
    // parent because a display is ignoring orientation request or fixed to user rotation.
    // See WindowManagerService#getIgnoreOrientationRequest and
    // WindowManagerService#getFixedToUserRotation for more context.
    @Nullable
    private Rect mLetterboxBoundsForFixedOrientationAndAspectRatio;

    // Bounds populated in resolveAspectRatioRestriction when this activity is letterboxed for
    // aspect ratio. If not null, they are used as parent container in
    // resolveSizeCompatModeConfiguration and in a constructor of CompatDisplayInsets.
    @Nullable
    private Rect mLetterboxBoundsForAspectRatio;

    // Whether the activity is eligible to be letterboxed for fixed orientation with respect to its
    // requested orientation, even when it's letterbox for another reason (e.g., size compat mode)
    // and therefore #isLetterboxedForFixedOrientationAndAspectRatio returns false.
@@ -8464,10 +8447,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
                    fullConfig.windowConfiguration.getRotation());
        }

        final Rect letterboxedContainerBounds =
                mLetterboxBoundsForFixedOrientationAndAspectRatio != null
                        ? mLetterboxBoundsForFixedOrientationAndAspectRatio
                        : mLetterboxBoundsForAspectRatio;
        final Rect letterboxedContainerBounds = mAppCompatController
                .getAppCompatAspectRatioPolicy().getLetterboxedContainerBounds();

        // The role of CompatDisplayInsets is like the override bounds.
        mCompatDisplayInsets =
                new CompatDisplayInsets(
@@ -8543,8 +8525,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A

        mAppCompatController.getAppCompatAspectRatioPolicy().reset();
        mIsEligibleForFixedOrientationLetterbox = false;
        mLetterboxBoundsForFixedOrientationAndAspectRatio = null;
        mLetterboxBoundsForAspectRatio = null;
        mResolveConfigHint.resolveTmpOverrides(mDisplayContent, newParentConfiguration,
                isFixedRotationTransforming());

@@ -8577,7 +8557,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        // If activity in fullscreen mode is letterboxed because of fixed orientation then bounds
        // are already calculated in resolveFixedOrientationConfiguration.
        // Don't apply aspect ratio if app is overridden to fullscreen by device user/manufacturer.
        if (Flags.immersiveAppRepositioning() && !isLetterboxedForFixedOrientationAndAspectRatio()
        if (Flags.immersiveAppRepositioning()
                && !mAppCompatController.getAppCompatAspectRatioPolicy()
                    .isLetterboxedForFixedOrientationAndAspectRatio()
                && !mAppCompatController.getAppCompatAspectRatioOverrides()
                    .hasFullscreenOverride()) {
            resolveAspectRatioRestriction(newParentConfiguration);
@@ -8599,7 +8581,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        // are already calculated in resolveFixedOrientationConfiguration, or if in size compat
        // mode, it should already be calculated in resolveSizeCompatModeConfiguration.
        // Don't apply aspect ratio if app is overridden to fullscreen by device user/manufacturer.
        if (!Flags.immersiveAppRepositioning() && !isLetterboxedForFixedOrientationAndAspectRatio()
        if (!Flags.immersiveAppRepositioning()
                && !mAppCompatController.getAppCompatAspectRatioPolicy()
                    .isLetterboxedForFixedOrientationAndAspectRatio()
                && !mInSizeCompatModeForBounds
                && !mAppCompatController.getAppCompatAspectRatioOverrides()
                    .hasFullscreenOverride()) {
@@ -8619,7 +8603,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
                // Fixed orientation letterboxing is possible on both large screen devices
                // with ignoreOrientationRequest enabled and on phones in split screen even with
                // ignoreOrientationRequest disabled.
                && (mLetterboxBoundsForFixedOrientationAndAspectRatio != null
                && (mAppCompatController.getAppCompatAspectRatioPolicy()
                    .isLetterboxedForFixedOrientationAndAspectRatio()
                        // Limiting check for aspect ratio letterboxing to devices with enabled
                        // ignoreOrientationRequest. This avoids affecting phones where apps may
                        // not expect the change of smallestScreenWidthDp after rotation which is
@@ -8744,11 +8729,13 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        // letterboxed for fixed orientation. Aspect ratio restrictions are also applied if
        // present. But this doesn't return true when the activity is letterboxed only because
        // of aspect ratio restrictions.
        if (isLetterboxedForFixedOrientationAndAspectRatio()) {
        if (mAppCompatController.getAppCompatAspectRatioPolicy()
                .isLetterboxedForFixedOrientationAndAspectRatio()) {
            return APP_COMPAT_STATE_CHANGED__STATE__LETTERBOXED_FOR_FIXED_ORIENTATION;
        }
        // Letterbox for limited aspect ratio.
        if (isLetterboxedForAspectRatioOnly()) {
        if (mAppCompatController.getAppCompatAspectRatioPolicy()
                .isLetterboxedForAspectRatioOnly()) {
            return APP_COMPAT_STATE_CHANGED__STATE__LETTERBOXED_FOR_ASPECT_RATIO;
        }

@@ -8898,22 +8885,6 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        return inTransitionSelfOrParent();
    }

    /**
     * Whether this activity is letterboxed for fixed orientation. If letterboxed due to fixed
     * orientation then aspect ratio restrictions are also already respected.
     *
     * <p>This happens when an activity has fixed orientation which doesn't match orientation of the
     * parent because a display setting 'ignoreOrientationRequest' is set to true. See {@link
     * WindowManagerService#getIgnoreOrientationRequest} for more context.
     */
    boolean isLetterboxedForFixedOrientationAndAspectRatio() {
        return mLetterboxBoundsForFixedOrientationAndAspectRatio != null;
    }

    boolean isLetterboxedForAspectRatioOnly() {
        return mLetterboxBoundsForAspectRatio != null;
    }

    /**
     * Whether this activity is eligible for letterbox eduction.
     *
@@ -8946,7 +8917,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
     * @param parentBounds are the new parent bounds passed down to the activity and should be used
     *                     to compute the stable bounds.
     * @param outStableBounds will store the stable bounds, which are the bounds with insets
     *                        applied, if orientation is not respected when insets are applied.
     *                        applied, if orientation is not respected when insets are applied.g
     *                        Stable bounds should be used to compute letterboxed bounds if
     *                        orientation is not respected when insets are applied.
     * @param outNonDecorBounds will store the non decor bounds, which are the bounds with non
@@ -9100,7 +9071,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        resolvedBounds.set(containingBounds);

        mAppCompatController.getAppCompatAspectRatioPolicy()
                .applyAspectRatio(newParentConfig, parentBounds, resolvedBounds,
                .applyDesiredAspectRatio(newParentConfig, parentBounds, resolvedBounds,
                        containingBoundsWithInsets, containingBounds);

        if (compatDisplayInsets != null) {
@@ -9129,7 +9100,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        // for comparison with size compat app bounds in {@link resolveSizeCompatModeConfiguration}.
        mResolveConfigHint.mTmpCompatInsets = compatDisplayInsets;
        computeConfigByResolveHint(getResolvedOverrideConfiguration(), newParentConfig);
        mLetterboxBoundsForFixedOrientationAndAspectRatio = new Rect(resolvedBounds);
        mAppCompatController.getAppCompatAspectRatioPolicy()
                .setLetterboxBoundsForFixedOrientationAndAspectRatio(new Rect(resolvedBounds));
    }

    /**
@@ -9147,7 +9119,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        // restricted size (resolved bounds may be the requested override bounds).
        mTmpBounds.setEmpty();
        mAppCompatController.getAppCompatAspectRatioPolicy()
                .applyAspectRatio(mTmpBounds, parentAppBounds, parentBounds);
                .applyAspectRatioForLetterbox(mTmpBounds, parentAppBounds, parentBounds);
        // If the out bounds is not empty, it means the activity cannot fill parent's app bounds,
        // then they should be aligned later in #updateResolvedBoundsPosition()
        if (!mTmpBounds.isEmpty()) {
@@ -9158,7 +9130,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
            // restrict, the bounds should be the requested override bounds.
            mResolveConfigHint.mTmpOverrideDisplayInfo = getFixedRotationTransformDisplayInfo();
            computeConfigByResolveHint(resolvedConfig, newParentConfiguration);
            mLetterboxBoundsForAspectRatio = new Rect(resolvedBounds);
            mAppCompatController.getAppCompatAspectRatioPolicy()
                    .setLetterboxBoundsForAspectRatio(new Rect(resolvedBounds));
        }
    }

@@ -9176,8 +9149,10 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        // activity will be displayed within them even if it is in size compat mode. They should be
        // saved here before resolved bounds are overridden below.
        final boolean useResolvedBounds = Flags.immersiveAppRepositioning()
                ? mAppCompatController.getAppCompatAspectRatioPolicy().isAspectRatioApplied()
                : isLetterboxedForFixedOrientationAndAspectRatio();
                ? mAppCompatController.getAppCompatAspectRatioPolicy()
                    .isAspectRatioApplied()
                : mAppCompatController.getAppCompatAspectRatioPolicy()
                    .isLetterboxedForFixedOrientationAndAspectRatio();
        final Rect containerBounds = useResolvedBounds
                ? new Rect(resolvedBounds)
                : newParentConfiguration.windowConfiguration.getBounds();
@@ -9222,7 +9197,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        // The size of floating task is fixed (only swap), so the aspect ratio is already correct.
        if (!compatDisplayInsets.mIsFloating) {
            mAppCompatController.getAppCompatAspectRatioPolicy()
                    .applyAspectRatio(resolvedBounds, containingAppBounds, containingBounds);
                    .applyAspectRatioForLetterbox(resolvedBounds, containingAppBounds,
                            containingBounds);
        }

        // Use resolvedBounds to compute other override configurations such as appBounds. The bounds
+87 −24
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ import static com.android.server.wm.LetterboxConfiguration.DEFAULT_LETTERBOX_ASP
import static com.android.server.wm.LetterboxConfiguration.MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.WindowConfiguration;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
@@ -48,23 +49,17 @@ class AppCompatAspectRatioPolicy {
    @NonNull
    private final TransparentPolicy mTransparentPolicy;
    @NonNull
    private final AppCompatOrientationPolicy mAppCompatOrientationPolicy;
    @NonNull
    private final AppCompatOverrides mAppCompatOverrides;
    @NonNull
    private final AspectRatioState mAspectRatioState;


    private final AppCompatAspectRatioState mAppCompatAspectRatioState;

    AppCompatAspectRatioPolicy(@NonNull ActivityRecord activityRecord,
            @NonNull TransparentPolicy transparentPolicy,
            @NonNull AppCompatOrientationPolicy orientationPolicy,
            @NonNull AppCompatOverrides appCompatOverrides) {
        mActivityRecord = activityRecord;
        mTransparentPolicy = transparentPolicy;
        mAppCompatOrientationPolicy = orientationPolicy;
        mAppCompatOverrides = appCompatOverrides;
        mAspectRatioState = new AspectRatioState();
        mAppCompatAspectRatioState = new AppCompatAspectRatioState();
    }

    /**
@@ -72,41 +67,43 @@ class AppCompatAspectRatioPolicy {
     * resolved.
     */
    void reset() {
        mAspectRatioState.mIsAspectRatioApplied = false;
        mAppCompatAspectRatioState.reset();
    }

    void applyAspectRatio(@NonNull Configuration newParentConfig, @NonNull Rect parentBounds,
            @NonNull Rect resolvedBounds, @NonNull Rect containingBoundsWithInsets,
            @NonNull Rect containingBounds) {
    float getDesiredAspectRatio(@NonNull Configuration newParentConfig,
            @NonNull Rect parentBounds) {
        final float letterboxAspectRatioOverride =
                mAppCompatOverrides.getAppCompatAspectRatioOverrides()
                        .getFixedOrientationLetterboxAspectRatio(newParentConfig);

        // Aspect ratio as suggested by the system. Apps requested mix/max aspect ratio will
        // be respected in #applyAspectRatio.
        final float desiredAspectRatio;
        if (isDefaultMultiWindowLetterboxAspectRatioDesired(newParentConfig)) {
            desiredAspectRatio = DEFAULT_LETTERBOX_ASPECT_RATIO_FOR_MULTI_WINDOW;
            return DEFAULT_LETTERBOX_ASPECT_RATIO_FOR_MULTI_WINDOW;
        } else if (letterboxAspectRatioOverride > MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO) {
            desiredAspectRatio = letterboxAspectRatioOverride;
        } else {
            desiredAspectRatio = AppCompatUtils.computeAspectRatio(parentBounds);
            return letterboxAspectRatioOverride;
        }
        mAspectRatioState.mIsAspectRatioApplied = applyAspectRatio(resolvedBounds,
        return AppCompatUtils.computeAspectRatio(parentBounds);
    }

    void applyDesiredAspectRatio(@NonNull Configuration newParentConfig, @NonNull Rect parentBounds,
            @NonNull Rect resolvedBounds, @NonNull Rect containingBoundsWithInsets,
            @NonNull Rect containingBounds) {
        final float desiredAspectRatio = getDesiredAspectRatio(newParentConfig, parentBounds);
        mAppCompatAspectRatioState.mIsAspectRatioApplied = applyAspectRatio(resolvedBounds,
                containingBoundsWithInsets, containingBounds, desiredAspectRatio);
    }

    void applyAspectRatio(Rect outBounds, Rect containingAppBounds,
    void applyAspectRatioForLetterbox(Rect outBounds, Rect containingAppBounds,
            Rect containingBounds) {
        mAspectRatioState.mIsAspectRatioApplied = applyAspectRatio(outBounds, containingAppBounds,
                containingBounds, 0 /* desiredAspectRatio */);
        mAppCompatAspectRatioState.mIsAspectRatioApplied = applyAspectRatio(outBounds,
                containingAppBounds, containingBounds, 0 /* desiredAspectRatio */);
    }

    /**
     * @return {@code true} when an app compat aspect ratio has been applied.
     */
    boolean isAspectRatioApplied() {
        return mAspectRatioState.mIsAspectRatioApplied;
        return mAppCompatAspectRatioState.mIsAspectRatioApplied;
    }

    /**
@@ -173,6 +170,35 @@ class AppCompatAspectRatioPolicy {
        return mActivityRecord.info.getMaxAspectRatio();
    }

    @Nullable
    Rect getLetterboxedContainerBounds() {
        return mAppCompatAspectRatioState.getLetterboxedContainerBounds();
    }

    /**
     * Whether this activity is letterboxed for fixed orientation. If letterboxed due to fixed
     * orientation then aspect ratio restrictions are also already respected.
     *
     * <p>This happens when an activity has fixed orientation which doesn't match orientation of the
     * parent because a display setting 'ignoreOrientationRequest' is set to true. See {@link
     * WindowManagerService#getIgnoreOrientationRequest} for more context.
     */
    boolean isLetterboxedForFixedOrientationAndAspectRatio() {
        return mAppCompatAspectRatioState.isLetterboxedForFixedOrientationAndAspectRatio();
    }

    boolean isLetterboxedForAspectRatioOnly() {
        return mAppCompatAspectRatioState.isLetterboxedForAspectRatioOnly();
    }

    void setLetterboxBoundsForFixedOrientationAndAspectRatio(@NonNull Rect bounds) {
        mAppCompatAspectRatioState.mLetterboxBoundsForFixedOrientationAndAspectRatio = bounds;
    }

    void setLetterboxBoundsForAspectRatio(@NonNull Rect bounds) {
        mAppCompatAspectRatioState.mLetterboxBoundsForAspectRatio = bounds;
    }

    private boolean isParentFullscreenPortrait() {
        final WindowContainer<?> parent = mActivityRecord.getParent();
        return parent != null
@@ -308,9 +334,46 @@ class AppCompatAspectRatioPolicy {
                && !dc.getIgnoreOrientationRequest();
    }

    private static class AspectRatioState {
    private static class AppCompatAspectRatioState {
        // Whether the aspect ratio restrictions applied to the activity bounds
        // in applyAspectRatio().
        private boolean mIsAspectRatioApplied = false;

        // Bounds populated in resolveAspectRatioRestriction when this activity is letterboxed for
        // aspect ratio. If not null, they are used as parent container in
        // resolveSizeCompatModeConfiguration and in a constructor of CompatDisplayInsets.
        @Nullable
        private Rect mLetterboxBoundsForAspectRatio;
        // Bounds populated in resolveFixedOrientationConfiguration when this activity is
        // letterboxed for fixed orientation. If not null, they are used as parent container in
        // resolveSizeCompatModeConfiguration and in a constructor of CompatDisplayInsets. If
        // letterboxed due to fixed orientation then aspect ratio restrictions are also respected.
        // This happens when an activity has fixed orientation which doesn't match orientation of
        // the parent because a display is ignoring orientation request or fixed to user rotation.
        // See WindowManagerService#getIgnoreOrientationRequest and
        // WindowManagerService#getFixedToUserRotation for more context.
        @Nullable
        private Rect mLetterboxBoundsForFixedOrientationAndAspectRatio;

        @Nullable
        Rect getLetterboxedContainerBounds() {
            return mLetterboxBoundsForFixedOrientationAndAspectRatio != null
                    ? mLetterboxBoundsForFixedOrientationAndAspectRatio
                    : mLetterboxBoundsForAspectRatio;
        }

        void reset() {
            mIsAspectRatioApplied = false;
            mLetterboxBoundsForFixedOrientationAndAspectRatio = null;
            mLetterboxBoundsForAspectRatio = null;
        }

        boolean isLetterboxedForFixedOrientationAndAspectRatio() {
            return mLetterboxBoundsForFixedOrientationAndAspectRatio != null;
        }

        boolean isLetterboxedForAspectRatioOnly() {
            return mLetterboxBoundsForAspectRatio != null;
        }
    }
}
+1 −1
Original line number Diff line number Diff line
@@ -49,7 +49,7 @@ class AppCompatController {
                wmService.mLetterboxConfiguration, optPropBuilder);
        mOrientationPolicy = new AppCompatOrientationPolicy(activityRecord, mAppCompatOverrides);
        mAppCompatAspectRatioPolicy = new AppCompatAspectRatioPolicy(activityRecord,
                mTransparentPolicy, mOrientationPolicy, mAppCompatOverrides);
                mTransparentPolicy, mAppCompatOverrides);
    }

    @NonNull
+2 −2
Original line number Diff line number Diff line
@@ -50,7 +50,6 @@ class AppCompatOrientationOverrides {
    private final ActivityRecord mActivityRecord;
    @NonNull
    private final AppCompatCameraOverrides mAppCompatCameraOverrides;

    @NonNull
    private final OptPropFactory.OptProp mIgnoreRequestedOrientationOptProp;
    @NonNull
@@ -109,7 +108,8 @@ class AppCompatOrientationOverrides {
        mOrientationOverridesState.updateOrientationRequestLoopState();

        return mOrientationOverridesState.shouldIgnoreRequestInLoop()
                && !mActivityRecord.isLetterboxedForFixedOrientationAndAspectRatio();
                && !mActivityRecord.mAppCompatController.getAppCompatAspectRatioPolicy()
                    .isLetterboxedForFixedOrientationAndAspectRatio();
    }

    /**
+4 −2
Original line number Diff line number Diff line
@@ -956,13 +956,15 @@ final class LetterboxUiController {
        if (mActivityRecord.inSizeCompatMode()) {
            return "SIZE_COMPAT_MODE";
        }
        if (mActivityRecord.isLetterboxedForFixedOrientationAndAspectRatio()) {
        if (mActivityRecord.mAppCompatController.getAppCompatAspectRatioPolicy()
                .isLetterboxedForFixedOrientationAndAspectRatio()) {
            return "FIXED_ORIENTATION";
        }
        if (mainWin.isLetterboxedForDisplayCutout()) {
            return "DISPLAY_CUTOUT";
        }
        if (mActivityRecord.isLetterboxedForAspectRatioOnly()) {
        if (mActivityRecord.mAppCompatController.getAppCompatAspectRatioPolicy()
                .isLetterboxedForAspectRatioOnly()) {
            return "ASPECT_RATIO";
        }
        return "UNKNOWN_REASON";
Loading