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

Commit 098c34c3 authored by Charles Chen's avatar Charles Chen
Browse files

Try to fix rounded corner overlay issue

Previously, the feature cannot exclude rounded corner layer because
it will be promoted to the top-most layer regardless of its window type.

1. Excludeds the rounded layer for a DisplayArea feature by default
because rounded corner should be anchored to its default position for most
features.
2. Increases the max layer because we may include/exclude
rounded corner layer unexpectedly by including/excluding window layer
TYPE_POINTER.
3. Fix ArrayIndexOutOfBoundsException when include/exclude TYPE_POINTER

Test: atest DisplayAreaPolicyBuilder#testFeatureNotThrowArrayIndexOutOfBoundsException
Test: manual - trigger hide notch + OHM
Bug: 172451212

Change-Id: I31794b665a8237e6dc8643a5a8d0e4f01c663621
parent c1cd3d6f
Loading
Loading
Loading
Loading
+36 −1
Original line number Diff line number Diff line
@@ -493,6 +493,32 @@ public interface WindowManagerPolicy extends WindowManagerPolicyConstants {
     * @return int An arbitrary integer used to order windows, with lower numbers below higher ones.
     */
    default int getWindowLayerFromTypeLw(int type, boolean canAddInternalSystemWindow) {
        return getWindowLayerFromTypeLw(type, canAddInternalSystemWindow,
                false /* roundedCornerOverlay */);
    }

    /**
     * Returns the layer assignment for the window type. Allows you to control how different
     * kinds of windows are ordered on-screen.
     *
     * @param type The type of window being assigned.
     * @param canAddInternalSystemWindow If the owner window associated with the type we are
     *        evaluating can add internal system windows. I.e they have
     *        {@link Manifest.permission#INTERNAL_SYSTEM_WINDOW}. If true, alert window
     *        types {@link android.view.WindowManager.LayoutParams#isSystemAlertWindowType(int)}
     *        can be assigned layers greater than the layer for
     *        {@link android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY} Else, their
     *        layers would be lesser.
     * @param roundedCornerOverlay {#code true} to indicate that the owner window is rounded corner
     *                             overlay.
     * @return int An arbitrary integer used to order windows, with lower numbers below higher ones.
     */
    default int getWindowLayerFromTypeLw(int type, boolean canAddInternalSystemWindow,
            boolean roundedCornerOverlay) {
        // Always put the rounded corner layer to the top most.
        if (roundedCornerOverlay && canAddInternalSystemWindow) {
            return getMaxWindowLayer();
        }
        if (type >= FIRST_APPLICATION_WINDOW && type <= LAST_APPLICATION_WINDOW) {
            return APPLICATION_LAYER;
        }
@@ -595,8 +621,17 @@ public interface WindowManagerPolicy extends WindowManagerPolicyConstants {
        }
    }

    // TODO(b/155340867): consider to remove the logic after using pure Surface for rounded corner
    //  overlay.
    /**
     * Returns the max window layer.
     * <p>Note that the max window layer should be higher that the maximum value which reported
     * by {@link #getWindowLayerFromTypeLw(int, boolean)} to contain rounded corner overlay.</p>
     *
     * @see WindowManager.LayoutParams#PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY
     */
    default int getMaxWindowLayer() {
        return 35;
        return 36;
    }

    /**
+14 −2
Original line number Diff line number Diff line
@@ -365,7 +365,7 @@ class DisplayAreaPolicyBuilder {
         */
        private void build(@Nullable List<HierarchyBuilder> displayAreaGroupHierarchyBuilders) {
            final WindowManagerPolicy policy = mRoot.mWmService.mPolicy;
            final int maxWindowLayerCount = policy.getMaxWindowLayer();
            final int maxWindowLayerCount = policy.getMaxWindowLayer() + 1;
            final DisplayArea.Tokens[] displayAreaForLayer =
                    new DisplayArea.Tokens[maxWindowLayerCount];
            final Map<Feature, List<DisplayArea<WindowContainer>>> featureAreas =
@@ -560,6 +560,7 @@ class DisplayAreaPolicyBuilder {
            private final int mId;
            private final boolean[] mLayers;
            private NewDisplayAreaSupplier mNewDisplayAreaSupplier = DisplayArea::new;
            private boolean mExcludeRoundedCorner = true;

            /**
             * Builds a new feature that applies to a set of window types as specified by the
@@ -578,7 +579,7 @@ class DisplayAreaPolicyBuilder {
                mPolicy = policy;
                mName = name;
                mId = id;
                mLayers = new boolean[mPolicy.getMaxWindowLayer()];
                mLayers = new boolean[mPolicy.getMaxWindowLayer() + 1];
            }

            /**
@@ -633,7 +634,18 @@ class DisplayAreaPolicyBuilder {
                return this;
            }

            // TODO(b/155340867): consider to remove the logic after using pure Surface for rounded
            // corner overlay.
            Builder setExcludeRoundedCornerOverlay(boolean excludeRoundedCorner) {
                mExcludeRoundedCorner = excludeRoundedCorner;
                return this;
            }

            Feature build() {
                if (mExcludeRoundedCorner) {
                    // Always put the rounded corner layer to the top most layer.
                    mLayers[mPolicy.getMaxWindowLayer()] = false;
                }
                return new Feature(mName, mId, mLayers.clone(), mNewDisplayAreaSupplier);
            }

+1 −5
Original line number Diff line number Diff line
@@ -115,15 +115,11 @@ class RootDisplayArea extends DisplayArea<DisplayArea> {
    @Nullable
    DisplayArea.Tokens findAreaForToken(int windowType, boolean ownerCanManageAppTokens,
            boolean roundedCornerOverlay) {
        // TODO(b/159767464): cover TYPE_INPUT_METHOD(_DIALOG) case here. mAreaForLayer doesn't
        // contain IME container.
        int windowLayerFromType = mWmService.mPolicy.getWindowLayerFromTypeLw(windowType,
                ownerCanManageAppTokens);
                ownerCanManageAppTokens, roundedCornerOverlay);
        if (windowLayerFromType == APPLICATION_LAYER) {
            throw new IllegalArgumentException(
                    "There shouldn't be WindowToken on APPLICATION_LAYER");
        } else if (roundedCornerOverlay) {
            windowLayerFromType = mAreaForLayer.length - 1;
        }
        return mAreaForLayer[windowLayerFromType];
    }
+3 −3
Original line number Diff line number Diff line
@@ -827,15 +827,15 @@ class WindowToken extends WindowContainer<WindowState> {
     * system bars, or in other words extend outside of the "Decor Frame"
     */
    boolean canLayerAboveSystemBars() {
        int layer = mWmService.mPolicy.getWindowLayerFromTypeLw(windowType,
                mOwnerCanManageAppTokens);
        int layer = getWindowLayerFromType();
        int navLayer = mWmService.mPolicy.getWindowLayerFromTypeLw(TYPE_NAVIGATION_BAR,
                mOwnerCanManageAppTokens);
        return mOwnerCanManageAppTokens && (layer > navLayer);
    }

    int getWindowLayerFromType() {
        return mWmService.mPolicy.getWindowLayerFromTypeLw(windowType, mOwnerCanManageAppTokens);
        return mWmService.mPolicy.getWindowLayerFromTypeLw(windowType, mOwnerCanManageAppTokens,
                mRoundedCornerOverlay);
    }

    int getOwnerUid() {
+10 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
import static android.view.WindowManager.LayoutParams.TYPE_POINTER;
import static android.view.WindowManager.LayoutParams.TYPE_PRESENTATION;
import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
@@ -667,6 +668,15 @@ public class DisplayAreaPolicyBuilderTest {
        assertThat(token2.isDescendantOf(mGroupRoot2)).isTrue();
    }

    @Test
    public void testFeatureNotThrowArrayIndexOutOfBoundsException() {
        final Feature feature1 = new Feature.Builder(mWms.mPolicy, "feature1",
                FEATURE_VENDOR_FIRST + 5)
                .all()
                .except(TYPE_POINTER)
                .build();
    }

    private static Resources resourcesWithProvider(String provider) {
        Resources mock = mock(Resources.class);
        when(mock.getString(