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

Commit 8b5a69a1 authored by Massimo Carli's avatar Massimo Carli
Browse files

[3/n] Reduce LetterboxUiController-TransparentPolicy dependency

ActivityRecord depends on the TransparentPolicy directly removing all the
unnecessary interactions with LetterboxUiController.

Bug: 337346942
Flag: EXEMPT refactor
Test: atest WmTests:LetterboxUiControllerTest
Test: atest WmTests:SizeCompatTests

Change-Id: Ibdd4814c0127488111ba7a33e19983b19db0639c
parent 256fc91c
Loading
Loading
Loading
Loading
+23 −17
Original line number Diff line number Diff line
@@ -802,6 +802,11 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
    final LetterboxUiController mLetterboxUiController;
    /**
     * The policy for transparent activities
     */
    final TransparentPolicy mTransparentPolicy;
    /**
     * The scale to fit at least one side of the activity to its parent. If the activity uses
     * 1920x1080, and the actually size on the screen is 960x540, then the scale is 0.5.
@@ -1698,7 +1703,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
            if (isState(RESUMED)) {
                newParent.setResumedActivity(this, "onParentChanged");
            }
            mLetterboxUiController.updateInheritedLetterbox();
            mTransparentPolicy.start();
        }
        if (rootTask != null && rootTask.topRunningActivity() == this) {
@@ -2136,6 +2141,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        // Don't move below setOrientation(info.screenOrientation) since it triggers
        // getOverrideOrientation that requires having mLetterboxUiController
        // initialised.
        mTransparentPolicy = new TransparentPolicy(this, mWmService.mLetterboxConfiguration);
        mLetterboxUiController = new LetterboxUiController(mWmService, this);
        mCameraCompatControlEnabled = mWmService.mContext.getResources()
                .getBoolean(R.bool.config_isCameraCompatControlForStretchedIssuesEnabled);
@@ -8080,13 +8086,13 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
    @Configuration.Orientation
    int getRequestedConfigurationOrientation(boolean forDisplay,
            @ActivityInfo.ScreenOrientation int requestedOrientation) {
        if (mLetterboxUiController.hasInheritedOrientation()) {
        if (mTransparentPolicy.hasInheritedOrientation()) {
            final RootDisplayArea root = getRootDisplayArea();
            if (forDisplay && root != null && root.isOrientationDifferentFromDisplay()) {
                return reverseConfigurationOrientation(
                        mLetterboxUiController.getInheritedOrientation());
                        mTransparentPolicy.getInheritedOrientation());
            } else {
                return mLetterboxUiController.getInheritedOrientation();
                return mTransparentPolicy.getInheritedOrientation();
            }
        }
        if (task != null && requestedOrientation == SCREEN_ORIENTATION_BEHIND) {
@@ -8302,8 +8308,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
    @Nullable
    CompatDisplayInsets getCompatDisplayInsets() {
        if (mLetterboxUiController.hasInheritedLetterboxBehavior()) {
            return mLetterboxUiController.getInheritedCompatDisplayInsets();
        if (mTransparentPolicy.isRunning()) {
            return mTransparentPolicy.getInheritedCompatDisplayInsets();
        }
        return mCompatDisplayInsets;
    }
@@ -8466,7 +8472,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        }
        mSizeCompatBounds = null;
        mCompatDisplayInsets = null;
        mLetterboxUiController.clearInheritedCompatDisplayInsets();
        mTransparentPolicy.clearInheritedCompatDisplayInsets();
    }
    @VisibleForTesting
@@ -8784,8 +8790,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
            return APP_COMPAT_STATE_CHANGED__STATE__NOT_VISIBLE;
        }
        // TODO(b/256564921): Investigate if we need new metrics for translucent activities
        if (mLetterboxUiController.hasInheritedLetterboxBehavior()) {
            return mLetterboxUiController.getInheritedAppCompatState();
        if (mTransparentPolicy.isRunning()) {
            return mTransparentPolicy.getInheritedAppCompatState();
        }
        if (mInSizeCompatModeForBounds) {
            return APP_COMPAT_STATE_CHANGED__STATE__LETTERBOXED_FOR_SIZE_COMPAT_MODE;
@@ -8938,7 +8944,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        // We check if the current activity is transparent. In that case we need to
        // recomputeConfiguration of the first opaque activity beneath, to allow a
        // proper computation of the new bounds.
        if (!mLetterboxUiController.applyOnOpaqueActivityBelow(
        if (!mTransparentPolicy.applyOnOpaqueActivityBelow(
                ActivityRecord::recomputeConfiguration)) {
            onRequestedOverrideConfigurationChanged(getRequestedOverrideConfiguration());
        }
@@ -9411,7 +9417,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
    void updateSizeCompatScale(Rect resolvedAppBounds, Rect containerAppBounds) {
        // Only allow to scale down.
        mSizeCompatScale = mLetterboxUiController.findOpaqueNotFinishingActivityBelow()
        mSizeCompatScale = mTransparentPolicy.findOpaqueNotFinishingActivityBelow()
                .map(activityRecord -> activityRecord.mSizeCompatScale)
                .orElseGet(() -> {
                    final int contentW = resolvedAppBounds.width();
@@ -9424,7 +9430,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
    }
    private boolean isInSizeCompatModeForBounds(final Rect appBounds, final Rect containerBounds) {
        if (mLetterboxUiController.hasInheritedLetterboxBehavior()) {
        if (mTransparentPolicy.isRunning()) {
            // To avoid wrong app behaviour, we decided to disable SCM when a translucent activity
            // is letterboxed.
            return false;
@@ -9487,7 +9493,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
    public Rect getBounds() {
        // TODO(b/268458693): Refactor configuration inheritance in case of translucent activities
        final Rect superBounds = super.getBounds();
        return mLetterboxUiController.findOpaqueNotFinishingActivityBelow()
        return mTransparentPolicy.findOpaqueNotFinishingActivityBelow()
                .map(ActivityRecord::getBounds)
                .orElseGet(() -> {
                    if (mSizeCompatBounds != null) {
@@ -9851,8 +9857,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
     * Returns the min aspect ratio of this activity.
     */
    float getMinAspectRatio() {
        if (mLetterboxUiController.hasInheritedLetterboxBehavior()) {
            return mLetterboxUiController.getInheritedMinAspectRatio();
        if (mTransparentPolicy.isRunning()) {
            return mTransparentPolicy.getInheritedMinAspectRatio();
        }
        if (info.applicationInfo == null) {
            return info.getMinAspectRatio();
@@ -9902,8 +9908,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
    }
    float getMaxAspectRatio() {
        if (mLetterboxUiController.hasInheritedLetterboxBehavior()) {
            return mLetterboxUiController.getInheritedMaxAspectRatio();
        if (mTransparentPolicy.isRunning()) {
            return mTransparentPolicy.getInheritedMaxAspectRatio();
        }
        return info.getMaxAspectRatio();
    }
+11 −108
Original line number Diff line number Diff line
@@ -129,10 +129,7 @@ import com.android.server.wm.utils.OptPropFactory.OptProp;
import com.android.window.flags.Flags;

import java.io.PrintWriter;
import java.util.Optional;
import java.util.function.BooleanSupplier;
import java.util.function.Consumer;
import java.util.function.Predicate;

/** Controls behaviour of the letterbox UI for {@link mActivityRecord}. */
// TODO(b/185262487): Improve test coverage of this class. Parts of it are tested in
@@ -228,10 +225,6 @@ final class LetterboxUiController {
    @NonNull
    private final OptProp mFakeFocusOptProp;

    // TODO(b/336807329) Eventually eemove this dependency when refactoring Reachability.
    @NonNull
    private final TransparentPolicy mTransparentPolicy;

    private boolean mIsRelaunchingAfterRequestedOrientationChanged;

    private boolean mLastShouldShowLetterboxUi;
@@ -245,24 +238,6 @@ final class LetterboxUiController {
        // to use it after since controller is only used in ActivityRecord.
        mActivityRecord = activityRecord;

        mTransparentPolicy = new TransparentPolicy(activityRecord, mLetterboxConfiguration,
                new Predicate<ActivityRecord>() {
                    @Override
                    public boolean test(ActivityRecord opaqueActivity) {
                        if (opaqueActivity == null || opaqueActivity.isEmbedded()) {
                            // We skip letterboxing if the translucent activity doesn't have any
                            // opaque activities beneath or the activity below is embedded which
                            // never has letterbox.
                            mActivityRecord.recomputeConfiguration();
                            return true;
                        }
                        if (mActivityRecord.getTask() == null || mActivityRecord.fillsParent()
                                || mActivityRecord.hasCompatDisplayInsetsWithoutInheritance()) {
                            return true;
                        }
                        return false;
                    }
                });
        PackageManager packageManager = wmService.mContext.getPackageManager();

        final OptPropFactory optPropBuilder = new OptPropFactory(packageManager,
@@ -340,7 +315,7 @@ final class LetterboxUiController {
            mLetterbox.destroy();
            mLetterbox = null;
        }
        mTransparentPolicy.stop();
        mActivityRecord.mTransparentPolicy.stop();
    }

    void onMovedToDisplay(int displayId) {
@@ -349,11 +324,6 @@ final class LetterboxUiController {
        }
    }

    @NonNull
    TransparentPolicy getTransparentPolicy() {
        return mTransparentPolicy;
    }

    /**
     * Whether should ignore app requested orientation in response to an app
     * calling {@link android.app.Activity#setRequestedOrientation}.
@@ -854,7 +824,7 @@ 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 = hasInheritedLetterboxBehavior()
            final Rect innerFrame = mActivityRecord.mTransparentPolicy.isRunning()
                    ? mActivityRecord.getBounds() : w.getFrame();
            mLetterbox.layout(spaceToFill, innerFrame, mTmpPoint);
            if (mDoubleTapEvent) {
@@ -1320,10 +1290,9 @@ final class LetterboxUiController {
        }
        // Use screen resolved bounds which uses resolved bounds or size compat bounds
        // as activity bounds can sometimes be empty
        final Rect opaqueActivityBounds = hasInheritedLetterboxBehavior()
                ? getTransparentPolicy().getTransparentPolicyState()
                    .mFirstOpaqueActivity.getScreenResolvedBounds()
                : mActivityRecord.getScreenResolvedBounds();
        final Rect opaqueActivityBounds = mActivityRecord.mTransparentPolicy
                .getFirstOpaqueActivity().map(ActivityRecord::getScreenResolvedBounds)
                .orElse(mActivityRecord.getScreenResolvedBounds());
        return mLetterboxConfiguration.getIsHorizontalReachabilityEnabled()
                && parentConfiguration.windowConfiguration.getWindowingMode()
                        == WINDOWING_MODE_FULLSCREEN
@@ -1358,11 +1327,10 @@ final class LetterboxUiController {
            return false;
        }
        // Use screen resolved bounds which uses resolved bounds or size compat bounds
        // as activity bounds can sometimes be empty
        final Rect opaqueActivityBounds = hasInheritedLetterboxBehavior()
                ? getTransparentPolicy().getTransparentPolicyState()
                    .mFirstOpaqueActivity.getScreenResolvedBounds()
                : mActivityRecord.getScreenResolvedBounds();
        // as activity bounds can sometimes be empty.
        final Rect opaqueActivityBounds = mActivityRecord.mTransparentPolicy
                .getFirstOpaqueActivity().map(ActivityRecord::getScreenResolvedBounds)
                .orElse(mActivityRecord.getScreenResolvedBounds());
        return mLetterboxConfiguration.getIsVerticalReachabilityEnabled()
                && parentConfiguration.windowConfiguration.getWindowingMode()
                        == WINDOWING_MODE_FULLSCREEN
@@ -1469,7 +1437,8 @@ 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 (hasInheritedLetterboxBehavior() && (cropBounds.width() != mainWindow.mRequestedWidth
        if (mActivityRecord.mTransparentPolicy.isRunning()
                && (cropBounds.width() != mainWindow.mRequestedWidth
                || cropBounds.height() != mainWindow.mRequestedHeight)) {
            return null;
        }
@@ -1773,72 +1742,6 @@ final class LetterboxUiController {
        );
    }

    /**
     * Handles translucent activities letterboxing inheriting constraints from the
     * first opaque activity beneath.
     */
    void updateInheritedLetterbox() {
        mTransparentPolicy.start();
    }

    /**
     * @return {@code true} if the current activity is translucent with an opaque activity
     * beneath. In this case it will inherit bounds, orientation and aspect ratios from
     * the first opaque activity beneath.
     */
    boolean hasInheritedLetterboxBehavior() {
        return mTransparentPolicy.hasInheritedLetterboxBehavior();
    }

    /**
     * @return {@code true} if the current activity is translucent with an opaque activity
     * beneath and needs to inherit its orientation.
     */
    boolean hasInheritedOrientation() {
        return mTransparentPolicy.hasInheritedOrientation();
    }

    float getInheritedMinAspectRatio() {
        return mTransparentPolicy.getInheritedMinAspectRatio();
    }

    float getInheritedMaxAspectRatio() {
        return mTransparentPolicy.getInheritedMaxAspectRatio();
    }

    int getInheritedAppCompatState() {
        return mTransparentPolicy.getInheritedAppCompatState();
    }

    @Configuration.Orientation
    int getInheritedOrientation() {
        return mTransparentPolicy.getInheritedOrientation();
    }

    ActivityRecord.CompatDisplayInsets getInheritedCompatDisplayInsets() {
        return mTransparentPolicy.getInheritedCompatDisplayInsets();
    }

    void clearInheritedCompatDisplayInsets() {
        mTransparentPolicy.clearInheritedCompatDisplayInsets();
    }

    /**
     * In case of translucent activities, it consumes the {@link ActivityRecord} of the first opaque
     * activity beneath using the given consumer and returns {@code true}.
     */
    boolean applyOnOpaqueActivityBelow(@NonNull Consumer<ActivityRecord> consumer) {
        return mTransparentPolicy.applyOnOpaqueActivityBelow(consumer);
    }

    /**
     * @return The first not finishing opaque activity beneath the current translucent activity
     * if it exists and the strategy is enabled.
     */
    Optional<ActivityRecord> findOpaqueNotFinishingActivityBelow() {
        return mTransparentPolicy.findOpaqueNotFinishingActivityBelow();
    }

    @NonNull
    private static BooleanSupplier asLazy(@NonNull BooleanSupplier supplier) {
        return new BooleanSupplier() {
+57 −50
Original line number Diff line number Diff line
@@ -40,6 +40,11 @@ import java.util.function.Predicate;

/**
 * Encapsulate logic about translucent activities.
 * <p/>
 * An activity is defined as translucent if {@link ActivityRecord#fillsParent()} returns
 * {@code false}. When the policy is running for a letterboxed activity, a transparent activity
 * will inherit constraints about bounds, aspect ratios and orientation from the first not finishing
 * activity below.
 */
class TransparentPolicy {

@@ -50,30 +55,28 @@ class TransparentPolicy {
    private static final Predicate<ActivityRecord> FIRST_OPAQUE_NOT_FINISHING_ACTIVITY_PREDICATE =
            ActivityRecord::occludesParent;

    // The predicate to check to skip the policy
    @NonNull
    private final Predicate<ActivityRecord> mSkipLetterboxPredicate;

    // The ActivityRecord this policy relates to.
    @NonNull
    private final ActivityRecord mActivityRecord;

    // If transparent activity policy is enabled.
    @NonNull
    private final BooleanSupplier mIsTranslucentLetterboxingEnabledSupplier;

    // The list of observers for the destroy event of candidate opaque activities
    // when dealing with translucent activities.
    @NonNull
    private final List<TransparentPolicy> mDestroyListeners = new ArrayList<>();

    // THe current state for the possible transparent activity
    // The current state for the possible transparent activity
    @NonNull
    private final TransparentPolicyState mTransparentPolicyState;

    TransparentPolicy(@NonNull ActivityRecord activityRecord,
            @NonNull LetterboxConfiguration letterboxConfiguration,
            @NonNull Predicate<ActivityRecord> skipLetterboxPredicate) {
            @NonNull LetterboxConfiguration letterboxConfiguration) {
        mActivityRecord = activityRecord;
        mIsTranslucentLetterboxingEnabledSupplier = () -> letterboxConfiguration
                .isTranslucentLetterboxingEnabled();
        mSkipLetterboxPredicate = skipLetterboxPredicate;
        mIsTranslucentLetterboxingEnabledSupplier =
                letterboxConfiguration::isTranslucentLetterboxingEnabled;
        mTransparentPolicyState = new TransparentPolicyState(activityRecord);
    }

@@ -98,7 +101,7 @@ class TransparentPolicy {
                true /* traverseTopToBottom */);
        // We check if we need for some reason to skip the policy gievn the specific first
        // opaque activity
        if (mSkipLetterboxPredicate.test(firstOpaqueActivity)) {
        if (shouldSkipTransparentPolicy(firstOpaqueActivity)) {
            return;
        }
        mTransparentPolicyState.start(firstOpaqueActivity);
@@ -112,7 +115,12 @@ class TransparentPolicy {
        mTransparentPolicyState.reset();
    }

    boolean hasInheritedLetterboxBehavior() {
    /**
     * @return {@code true} if the current activity is translucent with an opaque activity
     * beneath and the related policy is running. In this case it will inherit bounds, orientation
     * and aspect ratios from the first opaque activity beneath.
     */
    boolean isRunning() {
        return mTransparentPolicyState.isRunning();
    }

@@ -121,35 +129,33 @@ class TransparentPolicy {
     * beneath and needs to inherit its orientation.
     */
    boolean hasInheritedOrientation() {
        // To force a different orientation, the transparent one needs to have an explicit one
        // otherwise the existing one is fine and the actual orientation will depend on the
        // bounds.
        // To avoid wrong behaviour, we're not forcing orientation for activities with not
        // fixed orientation (e.g. permission dialogs).
        return hasInheritedLetterboxBehavior()
        // To avoid wrong behaviour (e.g. permission dialogs not centered or with wrong size),
        // transparent activities inherit orientation from the first opaque activity below only if
        // they explicitly define an orientation different from SCREEN_ORIENTATION_UNSPECIFIED.
        return isRunning()
                && mActivityRecord.getOverrideOrientation()
                != SCREEN_ORIENTATION_UNSPECIFIED;
    }

    float getInheritedMinAspectRatio() {
        return mTransparentPolicyState.getInheritedMinAspectRatio();
        return mTransparentPolicyState.mInheritedMinAspectRatio;
    }

    float getInheritedMaxAspectRatio() {
        return mTransparentPolicyState.getInheritedMaxAspectRatio();
        return mTransparentPolicyState.mInheritedMaxAspectRatio;
    }

    int getInheritedAppCompatState() {
        return mTransparentPolicyState.getInheritedAppCompatState();
        return mTransparentPolicyState.mInheritedAppCompatState;
    }

    @Configuration.Orientation
    int getInheritedOrientation() {
        return mTransparentPolicyState.getInheritedOrientation();
        return mTransparentPolicyState.mInheritedOrientation;
    }

    ActivityRecord.CompatDisplayInsets getInheritedCompatDisplayInsets() {
        return mTransparentPolicyState.getInheritedCompatDisplayInsets();
        return mTransparentPolicyState.mInheritedCompatDisplayInsets;
    }

    void clearInheritedCompatDisplayInsets() {
@@ -168,6 +174,12 @@ class TransparentPolicy {
        return mTransparentPolicyState.applyOnOpaqueActivityBelow(consumer);
    }

    @NonNull
    Optional<ActivityRecord> getFirstOpaqueActivity() {
        return isRunning() ? Optional.of(mTransparentPolicyState.mFirstOpaqueActivity)
                : Optional.empty();
    }

    /**
     * @return The first not finishing opaque activity beneath the current translucent activity
     * if it exists and the strategy is enabled.
@@ -176,6 +188,22 @@ class TransparentPolicy {
        return mTransparentPolicyState.findOpaqueNotFinishingActivityBelow();
    }

    // We evaluate the case when the policy should not be applied.
    private boolean shouldSkipTransparentPolicy(@Nullable ActivityRecord opaqueActivity) {
        if (opaqueActivity == null || opaqueActivity.isEmbedded()) {
            // We skip letterboxing if the translucent activity doesn't have any
            // opaque activities beneath or the activity below is embedded which
            // never has letterbox.
            mActivityRecord.recomputeConfiguration();
            return true;
        }
        if (mActivityRecord.getTask() == null || mActivityRecord.fillsParent()
                || mActivityRecord.hasCompatDisplayInsetsWithoutInheritance()) {
            return true;
        }
        return false;
    }

    /** Resets the screen size related fields so they can be resolved by requested bounds later. */
    private static void resetTranslucentOverrideConfig(Configuration config) {
        // The values for the following properties will be defined during the configuration
@@ -212,10 +240,11 @@ class TransparentPolicy {
        private int mInheritedAppCompatState = APP_COMPAT_STATE_CHANGED__STATE__UNKNOWN;

        // The CompatDisplayInsets of the opaque activity beneath the translucent one.
        @Nullable
        private ActivityRecord.CompatDisplayInsets mInheritedCompatDisplayInsets;

        @Nullable
        ActivityRecord mFirstOpaqueActivity;
        private ActivityRecord mFirstOpaqueActivity;

        /*
         * WindowContainerListener responsible to make translucent activities inherit
@@ -231,9 +260,8 @@ class TransparentPolicy {

        private void start(@NonNull ActivityRecord firstOpaqueActivity) {
            mFirstOpaqueActivity = firstOpaqueActivity;
            mFirstOpaqueActivity.mLetterboxUiController.getTransparentPolicy()
                    .mDestroyListeners.add(mActivityRecord.mLetterboxUiController
                            .getTransparentPolicy());
            mFirstOpaqueActivity.mTransparentPolicy
                    .mDestroyListeners.add(mActivityRecord.mTransparentPolicy);
            inheritFromOpaque(firstOpaqueActivity);
            final WindowContainer<?> parent = mActivityRecord.getParent();
            mLetterboxConfigListener = WindowContainer.overrideConfigurationPropagation(
@@ -284,9 +312,8 @@ class TransparentPolicy {
            mInheritedAppCompatState = APP_COMPAT_STATE_CHANGED__STATE__UNKNOWN;
            mInheritedCompatDisplayInsets = null;
            if (mFirstOpaqueActivity != null) {
                mFirstOpaqueActivity.mLetterboxUiController.getTransparentPolicy()
                        .mDestroyListeners.remove(mActivityRecord.mLetterboxUiController
                                .getTransparentPolicy());
                mFirstOpaqueActivity.mTransparentPolicy
                        .mDestroyListeners.remove(mActivityRecord.mTransparentPolicy);
            }
            mFirstOpaqueActivity = null;
        }
@@ -295,26 +322,6 @@ class TransparentPolicy {
            return mLetterboxConfigListener != null;
        }

        private int getInheritedOrientation() {
            return mInheritedOrientation;
        }

        private float getInheritedMinAspectRatio() {
            return mInheritedMinAspectRatio;
        }

        private float getInheritedMaxAspectRatio() {
            return mInheritedMaxAspectRatio;
        }

        private int getInheritedAppCompatState() {
            return mInheritedAppCompatState;
        }

        private ActivityRecord.CompatDisplayInsets getInheritedCompatDisplayInsets() {
            return mInheritedCompatDisplayInsets;
        }

        private void clearInheritedCompatDisplayInsets() {
            mInheritedCompatDisplayInsets = null;
        }
+4 −3
Original line number Diff line number Diff line
@@ -77,6 +77,7 @@ import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.annotation.Nullable;
import android.compat.testing.PlatformCompatChangeRule;
@@ -110,7 +111,7 @@ import org.junit.rules.TestRule;
import org.junit.runner.RunWith;

/**
 * Test class for {@link LetterboxUiControllerTest}.
 * Test class for {@link LetterboxUiController}.
 *
 * Build/Install/Run:
 * atest WmTests:LetterboxUiControllerTest
@@ -521,8 +522,8 @@ public class LetterboxUiControllerTest extends WindowTestsBase {
        final Rect opaqueBounds = new Rect(0, 0, 500, 300);
        doReturn(opaqueBounds).when(mActivity).getBounds();
        // Activity is translucent
        spyOn(mActivity.mLetterboxUiController);
        doReturn(true).when(mActivity.mLetterboxUiController).hasInheritedLetterboxBehavior();
        spyOn(mActivity.mTransparentPolicy);
        when(mActivity.mTransparentPolicy.isRunning()).thenReturn(true);

        // Makes requested sizes different
        mainWindow.mRequestedWidth = opaqueBounds.width() - 1;
+19 −21

File changed.

Preview size limit exceeded, changes collapsed.