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

Commit 16ec9faa authored by Jerry Chang's avatar Jerry Chang
Browse files

Prevent rendering divider bar into wrong orientation

The display area's bounds and orientation changed might be callbacked
seperatedly when the device's folded state changed, causing the
SplitLayout rendered divider bar into wrong orientation. This makes sure
to update divider bar and split layout correspondingly when the
orientation, rotation and root bounds chagned.

Fix: 189101216
Test: atest WMShellUnitTests
Change-Id: Ie5d7132e4122b82d9b5b404a40f97cca3095ce2c
parent d86db44b
Loading
Loading
Loading
Loading
+30 −14
Original line number Diff line number Diff line
@@ -92,12 +92,16 @@ public final class SplitLayout {
    private DividerSnapAlgorithm mDividerSnapAlgorithm;
    private int mDividePosition;
    private boolean mInitialized = false;
    private int mOrientation;
    private int mRotation;

    public SplitLayout(String windowName, Context context, Configuration configuration,
            SplitLayoutHandler splitLayoutHandler,
            SplitWindowManager.ParentContainerCallbacks parentContainerCallbacks,
            DisplayImeController displayImeController, ShellTaskOrganizer taskOrganizer) {
        mContext = context.createConfigurationContext(configuration);
        mOrientation = configuration.orientation;
        mRotation = configuration.windowConfiguration.getRotation();
        mSplitLayoutHandler = splitLayoutHandler;
        mDisplayImeController = displayImeController;
        mSplitWindowManager = new SplitWindowManager(
@@ -144,27 +148,39 @@ public final class SplitLayout {

    /** Applies new configuration, returns {@code false} if there's no effect to the layout. */
    public boolean updateConfiguration(Configuration configuration) {
        final Rect rootBounds = configuration.windowConfiguration.getBounds();
        if (mRootBounds.equals(rootBounds)) {
            return false;
        }
        boolean affectsLayout = false;

        // Make sure to render the divider bar with proper resources that matching the screen
        // orientation.
        final int orientation = configuration.orientation;
        if (orientation != mOrientation) {
            mOrientation = orientation;
            mContext = mContext.createConfigurationContext(configuration);
            mSplitWindowManager.setConfiguration(configuration);
            affectsLayout = true;
        }

        // Update the split bounds when necessary. Besides root bounds changed, split bounds need to
        // be updated when the rotation changed to cover the case that users rotated the screen 180
        // degrees.
        final int rotation = configuration.windowConfiguration.getRotation();
        final Rect rootBounds = configuration.windowConfiguration.getBounds();
        if (rotation != mRotation || !mRootBounds.equals(rootBounds)) {
            mRootBounds.set(rootBounds);
            mDividerSnapAlgorithm = getSnapAlgorithm(mContext, mRootBounds);
            resetDividerPosition();

        // Don't inflate divider bar if it is not initialized.
        if (!mInitialized) {
            return false;
            affectsLayout = true;
        }

        if (mInitialized && affectsLayout) {
            release();
            init();
            return true;
        }

        return false;
    }

    /** Updates recording bounds of divider window and both of the splits. */
    private void updateBounds(int position) {
        mDividerBounds.set(mRootBounds);
+21 −6
Original line number Diff line number Diff line
@@ -61,7 +61,7 @@ public class SplitLayoutTests extends ShellTestCase {
        mSplitLayout = new SplitLayout(
                "TestSplitLayout",
                mContext,
                getConfiguration(false),
                getConfiguration(),
                mSplitLayoutHandler,
                b -> b.setParent(mRootLeash),
                mDisplayImeController,
@@ -71,9 +71,23 @@ public class SplitLayoutTests extends ShellTestCase {
    @Test
    @UiThreadTest
    public void testUpdateConfiguration() {
        final Configuration config = getConfiguration();
        mSplitLayout.init();
        assertThat(mSplitLayout.updateConfiguration(getConfiguration(false))).isFalse();
        assertThat(mSplitLayout.updateConfiguration(getConfiguration(true))).isTrue();

        // Verify it returns true if new config won't affect split layout.
        assertThat(mSplitLayout.updateConfiguration(config)).isFalse();

        // Verify updateConfiguration returns true if the orientation changed.
        config.orientation = ORIENTATION_LANDSCAPE;
        assertThat(mSplitLayout.updateConfiguration(config)).isTrue();

        // Verify updateConfiguration returns true if it rotated.
        config.windowConfiguration.setRotation(1);
        assertThat(mSplitLayout.updateConfiguration(config)).isTrue();

        // Verify updateConfiguration returns true if the root bounds changed.
        config.windowConfiguration.setBounds(new Rect(0, 0, 2160, 1080));
        assertThat(mSplitLayout.updateConfiguration(config)).isTrue();
    }

    @Test
@@ -108,12 +122,13 @@ public class SplitLayoutTests extends ShellTestCase {
        verify(mSplitLayoutHandler).onSnappedToDismiss(eq(true));
    }

    private static Configuration getConfiguration(boolean isLandscape) {
    private static Configuration getConfiguration() {
        final Configuration configuration = new Configuration();
        configuration.unset();
        configuration.orientation = isLandscape ? ORIENTATION_LANDSCAPE : ORIENTATION_PORTRAIT;
        configuration.orientation = ORIENTATION_PORTRAIT;
        configuration.windowConfiguration.setRotation(0);
        configuration.windowConfiguration.setBounds(
                new Rect(0, 0, isLandscape ? 2160 : 1080, isLandscape ? 1080 : 2160));
                new Rect(0, 0, 1080, 2160));
        return configuration;
    }