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

Commit 27aef4f9 authored by Tiger's avatar Tiger
Browse files

Force layoutInDisplayCutoutMode to be always for edge-to-edge

If a window is forced to go edge-to-edge and fills the display, its
layoutInDisplayCutoutMode will be forced to be
LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS.

Bug: 309578419
Flag: com.android.window.flags.enforce_edge_to_edge
Test: PhoneWindowTest
Change-Id: I3e994a18d442d18868671c8a84f813fdc3344e3e
parent 869e636a
Loading
Loading
Loading
Loading
+23 −2
Original line number Diff line number Diff line
@@ -84,6 +84,7 @@ import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_EDGE_TO_EDGE_ENFORCED;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FIT_INSETS_CONTROLLED;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DECOR_VIEW_VISIBILITY;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_INSET_PARENT_FRAME_BY_IME;
@@ -105,12 +106,12 @@ import static android.view.accessibility.Flags.fixMergedContentChangeEventV2;
import static android.view.accessibility.Flags.forceInvertColor;
import static android.view.accessibility.Flags.reduceWindowContentChangedEventThrottle;
import static android.view.flags.Flags.sensitiveContentAppProtection;
import static android.view.flags.Flags.toolkitFrameRateFunctionEnablingReadOnly;
import static android.view.flags.Flags.toolkitFrameRateTypingReadOnly;
import static android.view.flags.Flags.toolkitFrameRateVelocityMappingReadOnly;
import static android.view.flags.Flags.toolkitFrameRateViewEnablingReadOnly;
import static android.view.flags.Flags.toolkitMetricsForFrameRateDecision;
import static android.view.flags.Flags.toolkitSetFrameRateReadOnly;
import static android.view.flags.Flags.toolkitFrameRateFunctionEnablingReadOnly;
import static android.view.flags.Flags.toolkitFrameRateViewEnablingReadOnly;
import static android.view.inputmethod.InputMethodEditorTraceProto.InputMethodClientsTraceProto.ClientSideProto.IME_FOCUS_CONTROLLER;
import static android.view.inputmethod.InputMethodEditorTraceProto.InputMethodClientsTraceProto.ClientSideProto.INSETS_CONTROLLER;
@@ -1441,6 +1442,7 @@ public final class ViewRootImpl implements ViewParent,
                // Keep track of the actual window flags supplied by the client.
                mClientWindowLayoutFlags = attrs.flags;
                adjustLayoutInDisplayCutoutMode(attrs);
                setAccessibilityFocus(null, null);
                if (view instanceof RootViewSurfaceTaker) {
@@ -2043,6 +2045,9 @@ public final class ViewRootImpl implements ViewParent,
            final int appearance = mWindowAttributes.insetsFlags.appearance;
            final int behavior = mWindowAttributes.insetsFlags.behavior;
            // Calling this before copying prevents redundant LAYOUT_CHANGED.
            final int layoutInDisplayCutoutModeFromCaller = adjustLayoutInDisplayCutoutMode(attrs);
            final int changes = mWindowAttributes.copyFrom(attrs);
            if ((changes & WindowManager.LayoutParams.TRANSLUCENT_FLAGS_CHANGED) != 0) {
                // Recompute system ui visibility.
@@ -2059,6 +2064,9 @@ public final class ViewRootImpl implements ViewParent,
                mWindowAttributes.packageName = mBasePackageName;
            }
            // Restore the layoutInDisplayCutoutMode of the caller;
            attrs.layoutInDisplayCutoutMode = layoutInDisplayCutoutModeFromCaller;
            // Restore preserved flags.
            mWindowAttributes.systemUiVisibility = systemUiVisibility;
            mWindowAttributes.subtreeSystemUiVisibility = subtreeSystemUiVisibility;
@@ -2101,6 +2109,19 @@ public final class ViewRootImpl implements ViewParent,
        }
    }
    private int adjustLayoutInDisplayCutoutMode(WindowManager.LayoutParams attrs) {
        final int originalMode = attrs.layoutInDisplayCutoutMode;
        if ((attrs.privateFlags & PRIVATE_FLAG_EDGE_TO_EDGE_ENFORCED) != 0
                && attrs.isFullscreen()
                && attrs.getFitInsetsTypes() == 0
                && attrs.getFitInsetsSides() == 0) {
            if (originalMode != LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS) {
                attrs.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
            }
        }
        return originalMode;
    }
    void handleAppVisibility(boolean visible) {
        if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
            Trace.instant(Trace.TRACE_TAG_VIEW, TextUtils.formatSimple(
+0 −3
Original line number Diff line number Diff line
@@ -2488,9 +2488,6 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
            setFlags(FLAG_LAYOUT_IN_SCREEN|FLAG_LAYOUT_INSET_DECOR, flagsToUpdate);
            params.setFitInsetsSides(0);
            params.setFitInsetsTypes(0);
            if (mEdgeToEdgeEnforced) {
                params.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
            }
        }

        if (a.getBoolean(R.styleable.Window_windowNoTitle, false)) {
+9 −8
Original line number Diff line number Diff line
@@ -2300,7 +2300,7 @@
             ensure that the status bar has enough contrast with the contents of this app, and set
             an appropriate effective bar background accordingly.
             See: {@link android.R.attr#enforceStatusBarContrast}
             <p>If the app targets
             <p>If the window belongs to an app targeting
             {@link android.os.Build.VERSION_CODES#VANILLA_ICE_CREAM VANILLA_ICE_CREAM} or above,
             this attribute is ignored.
             @deprecated Draw proper background behind
@@ -2320,7 +2320,7 @@
             ensure that the navigation bar has enough contrast with the contents of this app, and
             set an appropriate effective bar background accordingly.
             See: {@link android.R.attr#enforceNavigationBarContrast}
             <p>If the app targets
             <p>If the window belongs to an app targeting
             {@link android.os.Build.VERSION_CODES#VANILLA_ICE_CREAM VANILLA_ICE_CREAM} or above,
             this attribute is ignored.
             @deprecated Draw proper background behind
@@ -2335,7 +2335,7 @@
             have been requested to be translucent with
             {@link android.R.attr#windowTranslucentNavigation}.
             Corresponds to {@link android.view.Window#setNavigationBarDividerColor(int)}.
             <p>If the app targets
             <p>If the window belongs to an app targeting
             {@link android.os.Build.VERSION_CODES#VANILLA_ICE_CREAM VANILLA_ICE_CREAM} or above,
             this attribute is ignored.
             @deprecated Draw proper background behind
@@ -2431,7 +2431,9 @@
        <!-- Controls how the window is laid out if there is a {@code DisplayCutout}.
        <p>
        Defaults to {@code default}.
        Defaults to {@code default}. But if the window fills the screen, and it belongs to an app
        targeting {@link android.os.Build.VERSION_CODES#VANILLA_ICE_CREAM VANILLA_ICE_CREAM} or
        above, the behavior will be the same as specifying {@code always} regardless.
        <p>
        See also
        {@link android.view.WindowManager.LayoutParams#layoutInDisplayCutoutMode
@@ -2528,8 +2530,8 @@
        <!-- Flag indicating whether this window would opt-out the edge-to-edge enforcement.
             <p>If this is false, the edge-to-edge enforcement will be applied to the window if its
             app targets
             <p>If this is false, the edge-to-edge enforcement will be applied to the window if it
             belongs to an app targeting
             {@link android.os.Build.VERSION_CODES#VANILLA_ICE_CREAM VANILLA_ICE_CREAM} or above.
             The affected behaviors are:
             <ul>
@@ -2537,9 +2539,8 @@
                 through the {@link android.view.WindowInsets} to the content view, as if calling
                 {@link android.view.Window#setDecorFitsSystemWindows(boolean)} with false.
                 <li>{@link android.view.WindowManager.LayoutParams#layoutInDisplayCutoutMode} of
                 the non-floating windows will be set to {@link
                 the fill-screen windows will behave as specifying {@link
                 android.view.WindowManager.LayoutParams#LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS}.
                 Changing it to other values will cause {@link lang.IllegalArgumentException}.
                 <li>The framework will set {@link android.R.attr#statusBarColor},
                 {@link android.R.attr#navigationBarColor}, and
                 {@link android.R.attr#navigationBarDividerColor} to transparent.
+2 −9
Original line number Diff line number Diff line
@@ -20,7 +20,6 @@ import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_M
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_EDGE_TO_EDGE_ENFORCED;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
import static android.view.flags.Flags.FLAG_TOOLKIT_SET_FRAME_RATE_READ_ONLY;

@@ -82,15 +81,9 @@ public final class PhoneWindowTest {
        createPhoneWindowWithTheme(R.style.LayoutInDisplayCutoutModeUnset);
        installDecor();

        if ((mPhoneWindow.getAttributes().privateFlags & PRIVATE_FLAG_EDGE_TO_EDGE_ENFORCED) != 0
                && !mPhoneWindow.isFloating()) {
            assertThat(mPhoneWindow.getAttributes().layoutInDisplayCutoutMode,
                    is(LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS));
        } else {
        assertThat(mPhoneWindow.getAttributes().layoutInDisplayCutoutMode,
                is(LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT));
    }
    }

    @Test
    public void layoutInDisplayCutoutMode_default() throws Exception {
+0 −14
Original line number Diff line number Diff line
@@ -41,7 +41,6 @@ import static android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACK
import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_CONSUME_IME_INSETS;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_EDGE_TO_EDGE_ENFORCED;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IMMERSIVE_CONFIRMATION_WINDOW;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_INTERCEPT_GLOBAL_DRAG_AND_DROP;
@@ -986,19 +985,6 @@ public class DisplayPolicy {
                                + " to fit insets. fitInsetsTypes=" + WindowInsets.Type.toString(
                                        attrs.getFitInsetsTypes()));
                    }
                    if ((attrs.privateFlags & PRIVATE_FLAG_EDGE_TO_EDGE_ENFORCED) != 0
                            && attrs.layoutInDisplayCutoutMode
                                    != LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS) {
                        // A non-translucent main window of the app enforced to go edge-to-edge
                        // isn't allowed to fit display cutout, or it will cause software bezels.
                        throw new IllegalArgumentException("Illegal attributes: Main window of "
                                + win.mActivityRecord.getName() + " that isn't translucent and"
                                + " targets SDK level " + win.mActivityRecord.mTargetSdk
                                + " (>= 35) trying to specify layoutInDisplayCutoutMode as '"
                                + WindowManager.LayoutParams.layoutInDisplayCutoutModeToString(
                                        attrs.layoutInDisplayCutoutMode)
                                + "' instead of 'always'");
                    }
                }
                break;
        }