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

Commit aaaf1c47 authored by Yunfan Chen's avatar Yunfan Chen
Browse files

Do not override bounds when task override exists

This change fixes the issue that sometimes the non-decor insets are
accidentally deducted from override bounds even if the bounds doesn't
overlap with the insets.

A special handle is needed for split screen when the window is pushed
above by the IME. It is necessary to ensure the app receive the same
configuration before and after to make sure the activity won't relaunch
to ensure the IME can be shown correctly.

Bug: 358509380
Bug: 356050755
Test: WindowPolicyTests#testOptOutEdgeToEdgeAppBounds
Test: WindowPolicyTests#testOptOutEdgeToEdgeDisplayMetrics
Flag: EXEMPT bugfix
Change-Id: Ibebb43b29d76e5a9fa81334a6c678aa5f34678b2
parent 98beb550
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -8567,7 +8567,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
                resolvedConfig,
                mOptOutEdgeToEdge,
                hasFixedRotationTransform(),
                getCompatDisplayInsets() != null);
                getCompatDisplayInsets() != null,
                task);
        mResolveConfigHint.resetTmpOverrides();

        logAppCompatState();
+17 −12
Original line number Diff line number Diff line
@@ -195,12 +195,14 @@ public abstract class ConfigurationContainer<E extends ConfigurationContainer> {
     * screenWidthDp, screenHeightDp, smallestScreenWidthDp, and orientation.
     * All overrides to those fields should be in this method.
     *
     * Task is only needed for split-screen to apply an offset special handling.
     *
     * TODO: Consider integrate this with computeConfigByResolveHint()
     */
    static void applySizeOverrideIfNeeded(DisplayContent displayContent, ApplicationInfo appInfo,
            Configuration newParentConfiguration, Configuration inOutConfig,
            boolean optsOutEdgeToEdge, boolean hasFixedRotationTransform,
            boolean hasCompatDisplayInsets) {
            boolean hasCompatDisplayInsets, Task task) {
        if (displayContent == null) {
            return;
        }
@@ -223,13 +225,16 @@ public abstract class ConfigurationContainer<E extends ConfigurationContainer> {
        }
        if (!optsOutEdgeToEdge && (!useOverrideInsetsForConfig
                || hasCompatDisplayInsets
                || isFloating
                || 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;
        }
        if (isFloating) {
            // Floating window won't have any insets affect configuration. Skip the override.
            return;
        }
        // Make sure the orientation related fields will be updated by the override insets, because
        // fixed rotation has assigned the fields from display's configuration.
        if (hasFixedRotationTransform) {
@@ -255,17 +260,17 @@ public abstract class ConfigurationContainer<E extends ConfigurationContainer> {
            inOutConfig.windowConfiguration.setAppBounds(
                    newParentConfiguration.windowConfiguration.getBounds());
            outAppBounds = inOutConfig.windowConfiguration.getAppBounds();
            if (inOutConfig.windowConfiguration.getWindowingMode() == WINDOWING_MODE_FULLSCREEN) {
            if (task != null) {
                task = task.getCreatedByOrganizerTask();
                if (task != null && (task.mOffsetYForInsets != 0 || task.mOffsetXForInsets != 0)) {
                    outAppBounds.offset(task.mOffsetXForInsets, task.mOffsetYForInsets);
                }
            }
            final DisplayPolicy.DecorInsets.Info decor =
                    displayContent.getDisplayPolicy().getDecorInsetsInfo(rotation, dw, dh);
                if (outAppBounds.contains(decor.mOverrideNonDecorFrame)) {
                    outAppBounds.intersect(decor.mOverrideNonDecorFrame);
                }
            } else {
                // TODO(b/358509380): Handle other windowing mode like split screen and freeform
                //  cases correctly.
                outAppBounds.inset(displayContent.getDisplayPolicy()
                        .getDecorInsetsInfo(rotation, dw, dh).mOverrideNonDecorInsets);
            outAppBounds.intersectUnchecked(decor.mOverrideNonDecorFrame);
            if (task != null && (task.mOffsetYForInsets != 0 || task.mOffsetXForInsets != 0)) {
                outAppBounds.offset(-task.mOffsetXForInsets, -task.mOffsetYForInsets);
            }
        }
        float density = inOutConfig.densityDpi;
+11 −0
Original line number Diff line number Diff line
@@ -499,6 +499,13 @@ class Task extends TaskFragment {
     */
    boolean mIsTrimmableFromRecents;

    /**
     * Bounds offset should be applied when calculating compatible configuration for apps targeting
     * SDK level 34 or before.
     */
    int mOffsetXForInsets;
    int mOffsetYForInsets;

    private final AnimatingActivityRegistry mAnimatingActivityRegistry =
            new AnimatingActivityRegistry();

@@ -5874,6 +5881,10 @@ class Task extends TaskFragment {
        super.dumpInner(prefix, pw, dumpAll, dumpPackage);
        if (mCreatedByOrganizer) {
            pw.println(prefix + "  mCreatedByOrganizer=true");
            if (mOffsetXForInsets != 0 || mOffsetYForInsets != 0) {
                pw.println(prefix + "  mOffsetXForInsets=" + mOffsetXForInsets
                        + " mOffsetYForInsets=" + mOffsetYForInsets);
            }
        }
        if (mLastNonFullscreenBounds != null) {
            pw.print(prefix); pw.print("  mLastNonFullscreenBounds=");
+28 −0
Original line number Diff line number Diff line
@@ -18,9 +18,12 @@ package com.android.server.wm;

import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
import static android.app.ActivityManager.isStartResultSuccessful;
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.WINDOW_CONFIG_BOUNDS;
import static android.content.res.Configuration.SCREEN_HEIGHT_DP_UNDEFINED;
import static android.content.res.Configuration.SCREEN_WIDTH_DP_UNDEFINED;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.WindowManager.TRANSIT_CLOSE_PREPARE_BACK_NAVIGATION;
import static android.window.TaskFragmentOperation.OP_TYPE_CLEAR_ADJACENT_TASK_FRAGMENTS;
@@ -818,6 +821,31 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
                final Configuration c =
                        new Configuration(container.getRequestedOverrideConfiguration());
                c.setTo(change.getConfiguration(), configMask, windowMask);
                if (container.getWindowingMode() == WINDOWING_MODE_MULTI_WINDOW
                        && (change.getConfigSetMask() & ActivityInfo.CONFIG_SCREEN_SIZE) != 0) {
                    // Special handling for split screen window got offset. The insets calculation
                    // for configuration should be stable regardless of the offset. Set offset to
                    // the task level to be applied when calculate compat override for apps
                    // targeting SDK level 34 or before.
                    final Task task = container.asTask();
                    if (task != null) {
                        if (c.screenWidthDp != SCREEN_WIDTH_DP_UNDEFINED
                                && c.screenHeightDp != SCREEN_HEIGHT_DP_UNDEFINED) {
                            final Rect oldBounds = container.getRequestedOverrideBounds();
                            final Rect newBounds =
                                    change.getConfiguration().windowConfiguration.getBounds();
                            if (oldBounds.width() == newBounds.width()
                                    && oldBounds.height() == newBounds.height()) {
                                task.mOffsetXForInsets = oldBounds.left - newBounds.left;
                                task.mOffsetYForInsets = oldBounds.top - newBounds.top;
                            } else {
                                task.mOffsetXForInsets = task.mOffsetYForInsets = 0;
                            }
                        } else {
                            task.mOffsetXForInsets = task.mOffsetYForInsets = 0;
                        }
                    }
                }
                container.onRequestedOverrideConfigurationChanged(c);
            }
            effects |= TRANSACT_EFFECTS_CLIENT_CONFIG;
+2 −1
Original line number Diff line number Diff line
@@ -1689,7 +1689,8 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
                resolvedConfig,
                false /* optsOutEdgeToEdge */,
                false /* hasFixedRotationTransform */,
                false /* hasCompatDisplayInsets */);
                false /* hasCompatDisplayInsets */,
                null /* task */);
    }

    void dispatchConfiguration(@NonNull Configuration config) {
Loading