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

Commit ac5d76fd authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Override app bounds related configuration fields for legacy app" into 24D1-dev

parents 0c3e06ec 77266cee
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -1518,6 +1518,16 @@ public class ActivityInfo extends ComponentInfo implements Parcelable {
    @EnabledSince(targetSdkVersion = Build.VERSION_CODES.S)
    private static final long CHECK_MIN_WIDTH_HEIGHT_FOR_MULTI_WINDOW = 197654537L;

    /**
     * The activity is targeting a SDK version that should receive the changed behavior of
     * configuration insets decouple.
     *
     * @hide
     */
    @ChangeId
    @EnabledSince(targetSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM)
    public static final long INSETS_DECOUPLED_CONFIGURATION_ENFORCED = 151861875L;

    /**
     * Optional set of a certificates identifying apps that are allowed to embed this activity. From
     * the "knownActivityEmbeddingCerts" attribute.
+94 −1
Original line number Diff line number Diff line
@@ -50,6 +50,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.app.WindowConfiguration.activityTypeToString;
import static android.app.WindowConfiguration.isFloating;
import static android.app.admin.DevicePolicyResources.Drawables.Source.PROFILE_SWITCH_ANIMATION;
import static android.app.admin.DevicePolicyResources.Drawables.Style.OUTLINE;
import static android.app.admin.DevicePolicyResources.Drawables.WORK_PROFILE_ICON;
@@ -75,6 +76,7 @@ import static android.content.pm.ActivityInfo.FLAG_NO_HISTORY;
import static android.content.pm.ActivityInfo.FLAG_SHOW_FOR_ALL_USERS;
import static android.content.pm.ActivityInfo.FLAG_STATE_NOT_NEEDED;
import static android.content.pm.ActivityInfo.FLAG_TURN_SCREEN_ON;
import static android.content.pm.ActivityInfo.INSETS_DECOUPLED_CONFIGURATION_ENFORCED;
import static android.content.pm.ActivityInfo.LAUNCH_MULTIPLE;
import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_INSTANCE;
import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TASK;
@@ -332,6 +334,7 @@ import android.service.contentcapture.ActivityEvent;
import android.service.dreams.DreamActivity;
import android.service.voice.IVoiceInteractionSession;
import android.util.ArraySet;
import android.util.DisplayMetrics;
import android.util.EventLog;
import android.util.Log;
import android.util.MergedConfiguration;
@@ -8483,6 +8486,9 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        // and back which can cause visible issues (see b/184078928).
        final int parentWindowingMode =
                newParentConfiguration.windowConfiguration.getWindowingMode();

        applySizeOverrideIfNeeded(newParentConfiguration, parentWindowingMode, resolvedConfig);

        final boolean isFixedOrientationLetterboxAllowed =
                parentWindowingMode == WINDOWING_MODE_MULTI_WINDOW
                        || parentWindowingMode == WINDOWING_MODE_FULLSCREEN
@@ -8581,6 +8587,87 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        logAppCompatState();
    }

    /**
     * If necessary, override configuration fields related to app bounds.
     * This will happen when the app is targeting SDK earlier than 35.
     * The insets and configuration has decoupled since SDK level 35, to make the system
     * compatible to existing apps, override the configuration with legacy metrics. In legacy
     * metrics, fields such as appBounds will exclude some of the system bar areas.
     * The override contains all potentially affected fields in Configuration, including
     * screenWidthDp, screenHeightDp, smallestScreenWidthDp, and orientation.
     * All overrides to those fields should be in this method.
     */
    private void applySizeOverrideIfNeeded(Configuration newParentConfiguration,
            int parentWindowingMode, Configuration inOutConfig) {
        if (mDisplayContent == null) {
            return;
        }
        final Rect fullBounds = newParentConfiguration.windowConfiguration.getAppBounds();
        int rotation = newParentConfiguration.windowConfiguration.getRotation();
        if (rotation == ROTATION_UNDEFINED && !isFixedRotationTransforming()) {
            rotation = mDisplayContent.getRotation();
        }
        if (!mWmService.mFlags.mInsetsDecoupledConfiguration
                || info.isChangeEnabled(INSETS_DECOUPLED_CONFIGURATION_ENFORCED)
                || getCompatDisplayInsets() != null
                || isFloating(parentWindowingMode) || fullBounds == null
                || fullBounds.isEmpty() || rotation == ROTATION_UNDEFINED) {
            // If the insets configuration decoupled logic is not enabled for the app, or the app
            // already has a compat override, or the context doesn't contain enough info to
            // calculate the override, skip the override.
            return;
        }

        // Override starts here.
        final Rect stableInsets = mDisplayContent.getDisplayPolicy().getDecorInsetsInfo(
                rotation, fullBounds.width(), fullBounds.height()).mLegacyConfigInsets;
        // This should be the only place override the configuration for ActivityRecord. Override
        // the value if not calculated yet.
        Rect outAppBounds = inOutConfig.windowConfiguration.getAppBounds();
        if (outAppBounds == null || outAppBounds.isEmpty()) {
            inOutConfig.windowConfiguration.setAppBounds(fullBounds);
            outAppBounds = inOutConfig.windowConfiguration.getAppBounds();
            outAppBounds.inset(stableInsets);
        }
        float density = inOutConfig.densityDpi;
        if (density == Configuration.DENSITY_DPI_UNDEFINED) {
            density = newParentConfiguration.densityDpi;
        }
        density *= DisplayMetrics.DENSITY_DEFAULT_SCALE;
        if (inOutConfig.screenWidthDp == Configuration.SCREEN_WIDTH_DP_UNDEFINED) {
            final int overrideScreenWidthDp = (int) (outAppBounds.width() / density + 0.5f);
            inOutConfig.screenWidthDp =
                    Math.min(overrideScreenWidthDp, newParentConfiguration.screenWidthDp);
        }
        if (inOutConfig.screenHeightDp == Configuration.SCREEN_HEIGHT_DP_UNDEFINED) {
            final int overrideScreenHeightDp =
                    (int) (outAppBounds.height() / density + 0.5f);
            inOutConfig.screenHeightDp =
                    Math.min(overrideScreenHeightDp, newParentConfiguration.screenHeightDp);
        }
        if (inOutConfig.smallestScreenWidthDp
                == Configuration.SMALLEST_SCREEN_WIDTH_DP_UNDEFINED
                && parentWindowingMode == WINDOWING_MODE_FULLSCREEN) {
            // For the case of PIP transition and multi-window environment, the
            // smallestScreenWidthDp is handled already. Override only if the app is in
            // fullscreen.
            final boolean rotated = (rotation == ROTATION_90 || rotation == ROTATION_270);
            DisplayInfo info = new DisplayInfo();
            mDisplayContent.getDisplay().getDisplayInfo(info);
            mDisplayContent.computeSizeRanges(info, rotated, info.logicalWidth,
                    info.logicalHeight, mDisplayContent.getDisplayMetrics().density,
                    inOutConfig, true /* legacyConfig */);
        }

        // It's possible that screen size will be considered in different orientation with or
        // without considering the system bar insets. Override orientation as well.
        if (inOutConfig.orientation == ORIENTATION_UNDEFINED) {
            inOutConfig.orientation =
                    (inOutConfig.screenWidthDp <= inOutConfig.screenHeightDp)
                            ? ORIENTATION_PORTRAIT : ORIENTATION_LANDSCAPE;
        }
    }

    /**
     * @return The orientation to use to understand if reachability is enabled.
     */
@@ -8834,6 +8921,11 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
        if (mDisplayContent == null) {
            return true;
        }
        if (mWmService.mFlags.mInsetsDecoupledConfiguration
                && info.isChangeEnabled(INSETS_DECOUPLED_CONFIGURATION_ENFORCED)) {
            // No insets should be considered any more.
            return true;
        }
        // Only need to make changes if activity sets an orientation
        final int requestedOrientation = getRequestedConfigurationOrientation();
        if (requestedOrientation == ORIENTATION_UNDEFINED) {
@@ -8848,7 +8940,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
                : mDisplayContent.getDisplayInfo();
        final Task task = getTask();
        task.calculateInsetFrames(mTmpBounds /* outNonDecorBounds */,
                outStableBounds /* outStableBounds */, parentBounds /* bounds */, di);
                outStableBounds /* outStableBounds */, parentBounds /* bounds */, di,
                true /* useLegacyInsetsForStableBounds */);
        final int orientationWithInsets = outStableBounds.height() >= outStableBounds.width()
                ? ORIENTATION_PORTRAIT : ORIENTATION_LANDSCAPE;
        // If orientation does not match the orientation with insets applied, then a
+34 −11
Original line number Diff line number Diff line
@@ -2301,7 +2301,8 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
            mDisplayInfo.flags &= ~Display.FLAG_SCALING_DISABLED;
        }

        computeSizeRanges(mDisplayInfo, rotated, dw, dh, mDisplayMetrics.density, outConfig);
        computeSizeRanges(mDisplayInfo, rotated, dw, dh, mDisplayMetrics.density, outConfig,
                false /* legacyConfig */);

        setDisplayInfoOverride();

@@ -2437,7 +2438,8 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
        displayInfo.appHeight = appBounds.height();
        final DisplayCutout displayCutout = calculateDisplayCutoutForRotation(rotation);
        displayInfo.displayCutout = displayCutout.isEmpty() ? null : displayCutout;
        computeSizeRanges(displayInfo, rotated, dw, dh, mDisplayMetrics.density, outConfig);
        computeSizeRanges(displayInfo, rotated, dw, dh, mDisplayMetrics.density, outConfig,
                false /* legacyConfig */);
        return displayInfo;
    }

@@ -2601,8 +2603,21 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
        return curSize;
    }

    private void computeSizeRanges(DisplayInfo displayInfo, boolean rotated,
            int dw, int dh, float density, Configuration outConfig) {
    /**
     * Compute size range related fields of DisplayInfo and Configuration based on provided info.
     * The fields usually contain word such as smallest or largest.
     *
     * @param displayInfo In-out display info to compute the result.
     * @param rotated Whether the display is rotated.
     * @param dw Display Width in current rotation.
     * @param dh Display Height in current rotation.
     * @param density Display density.
     * @param outConfig The output configuration to
     * @param legacyConfig Whether we need to report the legacy result, which is excluding system
     *                     decorations.
     */
    void computeSizeRanges(DisplayInfo displayInfo, boolean rotated,
            int dw, int dh, float density, Configuration outConfig, boolean legacyConfig) {

        // We need to determine the smallest width that will occur under normal
        // operation.  To this, start with the base screen size and compute the
@@ -2620,10 +2635,10 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
        displayInfo.smallestNominalAppHeight = 1<<30;
        displayInfo.largestNominalAppWidth = 0;
        displayInfo.largestNominalAppHeight = 0;
        adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_0, unrotDw, unrotDh);
        adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_90, unrotDh, unrotDw);
        adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_180, unrotDw, unrotDh);
        adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_270, unrotDh, unrotDw);
        adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_0, unrotDw, unrotDh, legacyConfig);
        adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_90, unrotDh, unrotDw, legacyConfig);
        adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_180, unrotDw, unrotDh, legacyConfig);
        adjustDisplaySizeRanges(displayInfo, Surface.ROTATION_270, unrotDh, unrotDw, legacyConfig);

        if (outConfig == null) {
            return;
@@ -2632,11 +2647,19 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp
                (int) (displayInfo.smallestNominalAppWidth / density + 0.5f);
    }

    private void adjustDisplaySizeRanges(DisplayInfo displayInfo, int rotation, int dw, int dh) {
    private void adjustDisplaySizeRanges(DisplayInfo displayInfo, int rotation, int dw, int dh,
            boolean legacyConfig) {
        final DisplayPolicy.DecorInsets.Info info = mDisplayPolicy.getDecorInsetsInfo(
                rotation, dw, dh);
        final int w = info.mConfigFrame.width();
        final int h = info.mConfigFrame.height();
        final int w;
        final int h;
        if (!legacyConfig) {
            w = info.mConfigFrame.width();
            h = info.mConfigFrame.height();
        } else {
            w = info.mLegacyConfigFrame.width();
            h = info.mLegacyConfigFrame.height();
        }
        if (w < displayInfo.smallestNominalAppWidth) {
            displayInfo.smallestNominalAppWidth = w;
        }
+27 −3
Original line number Diff line number Diff line
@@ -1913,6 +1913,11 @@ public class DisplayPolicy {
             */
            final Rect mConfigInsets = new Rect();

            /**
             * Legacy value of mConfigInsets for app compatibility purpose.
             */
            final Rect mLegacyConfigInsets = new Rect();

            /** The display frame available after excluding {@link #mNonDecorInsets}. */
            final Rect mNonDecorFrame = new Rect();

@@ -1923,6 +1928,11 @@ public class DisplayPolicy {
             */
            final Rect mConfigFrame = new Rect();

            /**
             * Legacy value of mConfigFrame for app compatibility purpose.
             */
            final Rect mLegacyConfigFrame = new Rect();

            private boolean mNeedUpdate = true;

            InsetsState update(DisplayContent dc, int rotation, int w, int h) {
@@ -1933,15 +1943,26 @@ public class DisplayPolicy {
                final Rect displayFrame = insetsState.getDisplayFrame();
                final Insets decor = insetsState.calculateInsets(displayFrame,
                        dc.mWmService.mDecorTypes, true /* ignoreVisibility */);
                final Insets configInsets = insetsState.calculateInsets(displayFrame,
                        dc.mWmService.mConfigTypes, true /* ignoreVisibility */);
                final Insets configInsets = dc.mWmService.mConfigTypes == dc.mWmService.mDecorTypes
                        ? decor
                        : insetsState.calculateInsets(displayFrame, dc.mWmService.mConfigTypes,
                                true /* ignoreVisibility */);
                final Insets legacyConfigInsets = dc.mWmService.mConfigTypes
                        == dc.mWmService.mLegacyConfigTypes
                        ? configInsets
                        : insetsState.calculateInsets(displayFrame,
                                dc.mWmService.mLegacyConfigTypes, true /* ignoreVisibility */);
                mNonDecorInsets.set(decor.left, decor.top, decor.right, decor.bottom);
                mConfigInsets.set(configInsets.left, configInsets.top, configInsets.right,
                        configInsets.bottom);
                mLegacyConfigInsets.set(legacyConfigInsets.left, legacyConfigInsets.top,
                        legacyConfigInsets.right, legacyConfigInsets.bottom);
                mNonDecorFrame.set(displayFrame);
                mNonDecorFrame.inset(mNonDecorInsets);
                mConfigFrame.set(displayFrame);
                mConfigFrame.inset(mConfigInsets);
                mLegacyConfigFrame.set(displayFrame);
                mLegacyConfigFrame.inset(mLegacyConfigInsets);
                mNeedUpdate = false;
                return insetsState;
            }
@@ -1949,8 +1970,10 @@ public class DisplayPolicy {
            void set(Info other) {
                mNonDecorInsets.set(other.mNonDecorInsets);
                mConfigInsets.set(other.mConfigInsets);
                mLegacyConfigInsets.set(other.mLegacyConfigInsets);
                mNonDecorFrame.set(other.mNonDecorFrame);
                mConfigFrame.set(other.mConfigFrame);
                mLegacyConfigFrame.set(other.mLegacyConfigFrame);
                mNeedUpdate = false;
            }

@@ -2062,7 +2085,8 @@ public class DisplayPolicy {
        final DecorInsets.Info newInfo = mDecorInsets.mTmpInfo;
        final InsetsState newInsetsState = newInfo.update(mDisplayContent, rotation, dw, dh);
        final DecorInsets.Info currentInfo = getDecorInsetsInfo(rotation, dw, dh);
        if (newInfo.mConfigFrame.equals(currentInfo.mConfigFrame)) {
        if (newInfo.mConfigFrame.equals(currentInfo.mConfigFrame)
                && newInfo.mLegacyConfigFrame.equals(currentInfo.mLegacyConfigFrame)) {
            // Even if the config frame is not changed in current rotation, it may change the
            // insets in other rotations if the frame of insets source is changed.
            final InsetsState currentInsetsState = mDisplayContent.mDisplayFrames.mInsetsState;
+10 −3
Original line number Diff line number Diff line
@@ -2331,7 +2331,8 @@ class TaskFragment extends WindowContainer<WindowContainer> {
                // area, i.e. the screen area without the system bars.
                // The non decor inset are areas that could never be removed in Honeycomb. See
                // {@link WindowManagerPolicy#getNonDecorInsetsLw}.
                calculateInsetFrames(mTmpNonDecorBounds, mTmpStableBounds, mTmpFullBounds, di);
                calculateInsetFrames(mTmpNonDecorBounds, mTmpStableBounds, mTmpFullBounds, di,
                        false /* useLegacyInsetsForStableBounds */);
            } else {
                // Apply the given non-decor and stable insets to calculate the corresponding bounds
                // for screen size of configuration.
@@ -2429,9 +2430,11 @@ class TaskFragment extends WindowContainer<WindowContainer> {
     * @param outNonDecorBounds where to place bounds with non-decor insets applied.
     * @param outStableBounds where to place bounds with stable insets applied.
     * @param bounds the bounds to inset.
     * @param useLegacyInsetsForStableBounds {@code true} if we need to use the legacy insets frame
     *                for apps targeting U or before when calculating stable bounds.
     */
    void calculateInsetFrames(Rect outNonDecorBounds, Rect outStableBounds, Rect bounds,
            DisplayInfo displayInfo) {
            DisplayInfo displayInfo, boolean useLegacyInsetsForStableBounds) {
        outNonDecorBounds.set(bounds);
        outStableBounds.set(bounds);
        if (mDisplayContent == null) {
@@ -2443,7 +2446,11 @@ class TaskFragment extends WindowContainer<WindowContainer> {
        final DisplayPolicy.DecorInsets.Info info = policy.getDecorInsetsInfo(
                displayInfo.rotation, displayInfo.logicalWidth, displayInfo.logicalHeight);
        intersectWithInsetsIfFits(outNonDecorBounds, mTmpBounds, info.mNonDecorInsets);
        if (!useLegacyInsetsForStableBounds) {
            intersectWithInsetsIfFits(outStableBounds, mTmpBounds, info.mConfigInsets);
        } else {
            intersectWithInsetsIfFits(outStableBounds, mTmpBounds, info.mLegacyConfigInsets);
        }
    }

    /**
Loading