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

Commit 4e7e789b authored by Kazuki Takise's avatar Kazuki Takise
Browse files

Make sure mFlags is synced properly in WindowConfiguration

The previous logic doesn't have the logic to distinguish "off" and
"undefined" for mFlags. This CL solves this issue by introducing
a variable dedicated to always on top. See b/110383970 for more
background.

Bug: 110383970
Test: atest WindowConfigurationTests
Test: go/wm-smoke
Change-Id: Ia4fe8f43e5f6d65d68b1257951b1770a49af35bc
parent 148d00ac
Loading
Loading
Loading
Loading
+45 −33
Original line number Diff line number Diff line
@@ -59,11 +59,6 @@ public class WindowConfiguration implements Parcelable, Comparable<WindowConfigu
    /** The current windowing mode of the configuration. */
    private @WindowingMode int mWindowingMode;

    private int mFlags;

    /** Indicates that this window should always be on top of the other windows. */
    private static final int PFLAG_ALWAYS_ON_TOP = 1 << 0;

    /** Windowing mode is currently not defined. */
    public static final int WINDOWING_MODE_UNDEFINED = 0;
    /** Occupies the full area of the screen or the parent container. */
@@ -129,6 +124,24 @@ public class WindowConfiguration implements Parcelable, Comparable<WindowConfigu
    })
    public @interface ActivityType {}

    /** The current always on top status of the configuration. */
    private @AlwaysOnTop int mAlwaysOnTop;

    /** Always on top is currently not defined. */
    private static final int ALWAYS_ON_TOP_UNDEFINED = 0;
    /** Always on top is currently on for this configuration. */
    private static final int ALWAYS_ON_TOP_ON = 1;
    /** Always on top is currently off for this configuration. */
    private static final int ALWAYS_ON_TOP_OFF = 2;

    /** @hide */
    @IntDef(prefix = { "ALWAYS_ON_TOP_" }, value = {
            ALWAYS_ON_TOP_UNDEFINED,
            ALWAYS_ON_TOP_ON,
            ALWAYS_ON_TOP_OFF,
    })
    private @interface AlwaysOnTop {}

    /** Bit that indicates that the {@link #mBounds} changed.
     * @hide */
    public static final int WINDOW_CONFIG_BOUNDS = 1 << 0;
@@ -141,16 +154,16 @@ public class WindowConfiguration implements Parcelable, Comparable<WindowConfigu
    /** Bit that indicates that the {@link #mActivityType} changed.
     * @hide */
    public static final int WINDOW_CONFIG_ACTIVITY_TYPE = 1 << 3;
    /** Bit that indicates that the {@link #mFlags} changed.
    /** Bit that indicates that the {@link #mAlwaysOnTop} changed.
     * @hide */
    public static final int WINDOW_CONFIG_FLAGS = 1 << 4;
    public static final int WINDOW_CONFIG_ALWAYS_ON_TOP = 1 << 4;
    /** @hide */
    @IntDef(flag = true, prefix = { "WINDOW_CONFIG_" }, value = {
            WINDOW_CONFIG_BOUNDS,
            WINDOW_CONFIG_APP_BOUNDS,
            WINDOW_CONFIG_WINDOWING_MODE,
            WINDOW_CONFIG_ACTIVITY_TYPE,
            WINDOW_CONFIG_FLAGS
            WINDOW_CONFIG_ALWAYS_ON_TOP,
    })
    public @interface WindowConfig {}

@@ -176,7 +189,7 @@ public class WindowConfiguration implements Parcelable, Comparable<WindowConfigu
        dest.writeParcelable(mAppBounds, flags);
        dest.writeInt(mWindowingMode);
        dest.writeInt(mActivityType);
        dest.writeInt(mFlags);
        dest.writeInt(mAlwaysOnTop);
    }

    private void readFromParcel(Parcel source) {
@@ -184,7 +197,7 @@ public class WindowConfiguration implements Parcelable, Comparable<WindowConfigu
        mAppBounds = source.readParcelable(Rect.class.getClassLoader());
        mWindowingMode = source.readInt();
        mActivityType = source.readInt();
        mFlags = source.readInt();
        mAlwaysOnTop = source.readInt();
    }

    @Override
@@ -232,9 +245,7 @@ public class WindowConfiguration implements Parcelable, Comparable<WindowConfigu
        setAppBounds(rect.left, rect.top, rect.right, rect.bottom);
    }

    private void setFlags(int flags) {
        mFlags = flags;
    }


    /**
     * Sets whether this window should be always on top.
@@ -242,11 +253,11 @@ public class WindowConfiguration implements Parcelable, Comparable<WindowConfigu
     * @hide
     */
    public void setAlwaysOnTop(boolean alwaysOnTop) {
        if (alwaysOnTop) {
            mFlags |= PFLAG_ALWAYS_ON_TOP;
        } else {
            mFlags &= ~PFLAG_ALWAYS_ON_TOP;
        mAlwaysOnTop = alwaysOnTop ? ALWAYS_ON_TOP_ON : ALWAYS_ON_TOP_OFF;
    }

    private void setAlwaysOnTop(@AlwaysOnTop int alwaysOnTop) {
        mAlwaysOnTop = alwaysOnTop;
    }

    /**
@@ -308,7 +319,7 @@ public class WindowConfiguration implements Parcelable, Comparable<WindowConfigu
        setAppBounds(other.mAppBounds);
        setWindowingMode(other.mWindowingMode);
        setActivityType(other.mActivityType);
        setFlags(other.mFlags);
        setAlwaysOnTop(other.mAlwaysOnTop);
    }

    /** Set this object to completely undefined.
@@ -323,7 +334,7 @@ public class WindowConfiguration implements Parcelable, Comparable<WindowConfigu
        setBounds(null);
        setWindowingMode(WINDOWING_MODE_UNDEFINED);
        setActivityType(ACTIVITY_TYPE_UNDEFINED);
        setFlags(0);
        setAlwaysOnTop(ALWAYS_ON_TOP_UNDEFINED);
    }

    /**
@@ -341,10 +352,6 @@ public class WindowConfiguration implements Parcelable, Comparable<WindowConfigu
            changed |= WINDOW_CONFIG_BOUNDS;
            setBounds(delta.mBounds);
        }
        if (delta.mFlags != mFlags) {
            changed |= WINDOW_CONFIG_FLAGS;
            setFlags(delta.mFlags);
        }
        if (delta.mAppBounds != null && !delta.mAppBounds.equals(mAppBounds)) {
            changed |= WINDOW_CONFIG_APP_BOUNDS;
            setAppBounds(delta.mAppBounds);
@@ -359,6 +366,11 @@ public class WindowConfiguration implements Parcelable, Comparable<WindowConfigu
            changed |= WINDOW_CONFIG_ACTIVITY_TYPE;
            setActivityType(delta.mActivityType);
        }
        if (delta.mAlwaysOnTop != ALWAYS_ON_TOP_UNDEFINED
                && mAlwaysOnTop != delta.mAlwaysOnTop) {
            changed |= WINDOW_CONFIG_ALWAYS_ON_TOP;
            setAlwaysOnTop(delta.mAlwaysOnTop);
        }
        return changed;
    }

@@ -380,10 +392,6 @@ public class WindowConfiguration implements Parcelable, Comparable<WindowConfigu
            changes |= WINDOW_CONFIG_BOUNDS;
        }

        if (mFlags != other.mFlags) {
            changes |= WINDOW_CONFIG_FLAGS;
        }

        // Make sure that one of the values is not null and that they are not equal.
        if ((compareUndefined || other.mAppBounds != null)
                && mAppBounds != other.mAppBounds
@@ -401,6 +409,11 @@ public class WindowConfiguration implements Parcelable, Comparable<WindowConfigu
            changes |= WINDOW_CONFIG_ACTIVITY_TYPE;
        }

        if ((compareUndefined || other.mAlwaysOnTop != ALWAYS_ON_TOP_UNDEFINED)
                && mAlwaysOnTop != other.mAlwaysOnTop) {
            changes |= WINDOW_CONFIG_ALWAYS_ON_TOP;
        }

        return changes;
    }

@@ -435,8 +448,7 @@ public class WindowConfiguration implements Parcelable, Comparable<WindowConfigu
        if (n != 0) return n;
        n = mActivityType - that.mActivityType;
        if (n != 0) return n;

        n = mFlags - that.mFlags;
        n = mAlwaysOnTop - that.mAlwaysOnTop;
        if (n != 0) return n;

        // if (n != 0) return n;
@@ -465,7 +477,7 @@ public class WindowConfiguration implements Parcelable, Comparable<WindowConfigu

        result = 31 * result + mWindowingMode;
        result = 31 * result + mActivityType;
        result = 31 * result + mFlags;
        result = 31 * result + mAlwaysOnTop;
        return result;
    }

@@ -476,7 +488,7 @@ public class WindowConfiguration implements Parcelable, Comparable<WindowConfigu
                + " mAppBounds=" + mAppBounds
                + " mWindowingMode=" + windowingModeToString(mWindowingMode)
                + " mActivityType=" + activityTypeToString(mActivityType)
                + " mFlags=0x" + Integer.toHexString(mFlags)
                + " mAlwaysOnTop=" + activityTypeToString(mAlwaysOnTop)
                + "}";
    }

@@ -563,7 +575,7 @@ public class WindowConfiguration implements Parcelable, Comparable<WindowConfigu
     * @hide
     */
    public boolean isAlwaysOnTop() {
        return mWindowingMode == WINDOWING_MODE_PINNED || (mFlags & PFLAG_ALWAYS_ON_TOP) != 0;
        return mWindowingMode == WINDOWING_MODE_PINNED || mAlwaysOnTop == ALWAYS_ON_TOP_ON;
    }

    /**
+3 −0
Original line number Diff line number Diff line
@@ -385,9 +385,12 @@ public class DisplayContentTests extends WindowTestsBase {
    @Test
    public void testAlwaysOnTopStackLocation() {
        final TaskStack alwaysOnTopStack = createTaskStackOnDisplay(mDisplayContent);
        final Task task = createTaskInStack(alwaysOnTopStack, 0 /* userId */);
        alwaysOnTopStack.setAlwaysOnTop(true);
        mDisplayContent.positionStackAt(POSITION_TOP, alwaysOnTopStack);
        assertTrue(alwaysOnTopStack.isAlwaysOnTop());
        // Ensure always on top state is synced to the children of the stack.
        assertTrue(alwaysOnTopStack.getTopChild().isAlwaysOnTop());
        assertEquals(alwaysOnTopStack, mDisplayContent.getTopStack());

        final TaskStack pinnedStack = createStackControllerOnStackOnDisplay(
+12 −0
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.WINDOW_CONFIG_ALWAYS_ON_TOP;
import static android.app.WindowConfiguration.WINDOW_CONFIG_APP_BOUNDS;
import static android.app.WindowConfiguration.WINDOW_CONFIG_WINDOWING_MODE;
import static android.content.pm.ActivityInfo.CONFIG_WINDOW_CONFIGURATION;
@@ -81,6 +82,11 @@ public class WindowConfigurationTests extends WindowTestsBase {
        assertEquals(WINDOW_CONFIG_APP_BOUNDS | WINDOW_CONFIG_WINDOWING_MODE,
                winConfig1.diff(winConfig2, false /* compareUndefined */));

        winConfig2.setAlwaysOnTop(true);
        assertEquals(WINDOW_CONFIG_APP_BOUNDS | WINDOW_CONFIG_WINDOWING_MODE
                | WINDOW_CONFIG_ALWAYS_ON_TOP,
                winConfig1.diff(winConfig2, false /* compareUndefined */));

        assertEquals(0, config1.diff(config3));
        assertEquals(0, config1.diffPublicOnly(config3));
        assertEquals(0, winConfig1.diff(winConfig3, false /* compareUndefined */));
@@ -108,6 +114,12 @@ public class WindowConfigurationTests extends WindowTestsBase {
        assertNotEquals(winConfig1.compareTo(winConfig2), 0);
        winConfig2.setWindowingMode(winConfig1.getWindowingMode());

        // Different always on top state
        winConfig2.setAlwaysOnTop(true);
        assertNotEquals(config1.compareTo(config2), 0);
        assertNotEquals(winConfig1.compareTo(winConfig2), 0);
        winConfig2.setAlwaysOnTop(winConfig1.isAlwaysOnTop());

        // Different bounds
        winConfig2.setAppBounds(0, 2, 3, 4);
        assertNotEquals(config1.compareTo(config2), 0);