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

Commit 76522e99 authored by Tony Huang's avatar Tony Huang
Browse files

Fix divider display issue

onDisplayAreaInfoChanged might callback many times in one action
such like fold to unfold, it might cause some issues because we
don't use lastet config resources to set SplitLayout.

Another bug is we cannot get divider leash immediately after we
init it because leash is built after attachToParentSurface.

Fix both bug by always do whole SplitLayout setting if any cared
configs changed. And add a callback after divider leash build,
show the leash on this callback to ensure we got null leash.

Fix: 198581512
Fix: 197296095
Test: manual
Test: pass existing tests
Change-Id: I06a4093927d6469a85b2104b36c16d6e16519a51
parent eeb927bd
Loading
Loading
Loading
Loading
+15 −4
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@ import com.android.wm.shell.common.DisplayImeController;
import com.android.wm.shell.common.SurfaceUtils;
import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.common.split.SplitLayout;
import com.android.wm.shell.common.split.SplitWindowManager;

import java.io.PrintWriter;

@@ -70,6 +71,19 @@ class AppPair implements ShellTaskOrganizer.TaskListener, SplitLayout.SplitLayou
    private final DisplayImeController mDisplayImeController;
    private SplitLayout mSplitLayout;

    private final SplitWindowManager.ParentContainerCallbacks mParentContainerCallbacks =
            new SplitWindowManager.ParentContainerCallbacks() {
        @Override
        public void attachToParentSurface(SurfaceControl.Builder b) {
            b.setParent(mRootTaskLeash);
        }

        @Override
        public void onLeashReady(SurfaceControl leash) {
            mSyncQueue.runInSync(t -> t.show(leash));
        }
    };

    AppPair(AppPairsController controller) {
        mController = controller;
        mSyncQueue = controller.getSyncTransactionQueue();
@@ -110,8 +124,7 @@ class AppPair implements ShellTaskOrganizer.TaskListener, SplitLayout.SplitLayou
        mSplitLayout = new SplitLayout(TAG + "SplitDivider",
                mDisplayController.getDisplayContext(mRootTaskInfo.displayId),
                mRootTaskInfo.configuration, this /* layoutChangeListener */,
                b -> b.setParent(mRootTaskLeash), mDisplayImeController,
                mController.getTaskOrganizer());
                mParentContainerCallbacks, mDisplayImeController, mController.getTaskOrganizer());

        final WindowContainerToken token1 = task1.token;
        final WindowContainerToken token2 = task2.token;
@@ -218,8 +231,6 @@ class AppPair implements ShellTaskOrganizer.TaskListener, SplitLayout.SplitLayou
                if (mSplitLayout.updateConfiguration(mRootTaskInfo.configuration)) {
                    onLayoutChanged(mSplitLayout);
                }
                // updateConfiguration re-inits the dividerbar, so show it now
                mSyncQueue.runInSync(t -> t.show(mSplitLayout.getDividerLeash()));
            }
        } else if (taskInfo.taskId == getTaskId1()) {
            mTaskInfo1 = taskInfo;
+10 −13
Original line number Diff line number Diff line
@@ -125,8 +125,8 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
        mRotation = configuration.windowConfiguration.getRotation();
        mSplitLayoutHandler = splitLayoutHandler;
        mDisplayImeController = displayImeController;
        mSplitWindowManager = new SplitWindowManager(
                windowName, mContext, configuration, parentContainerCallbacks);
        mSplitWindowManager = new SplitWindowManager(windowName, mContext, configuration,
                parentContainerCallbacks);
        mTaskOrganizer = taskOrganizer;
        mImePositionProcessor = new ImePositionProcessor(mContext.getDisplayId());
        mDismissingParallaxPolicy = new DismissingParallaxPolicy();
@@ -181,22 +181,19 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
    public boolean updateConfiguration(Configuration configuration) {
        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.
        // Make sure to render the divider bar with proper resources that matching the screen
        // orientation.
        final int rotation = configuration.windowConfiguration.getRotation();
        final Rect rootBounds = configuration.windowConfiguration.getBounds();
        if (rotation != mRotation || !mRootBounds.equals(rootBounds)) {
        final int orientation = configuration.orientation;
        if (rotation != mRotation || !mRootBounds.equals(rootBounds)
                || orientation != mOrientation) {
            mContext = mContext.createConfigurationContext(configuration);
            mSplitWindowManager.setConfiguration(configuration);
            mOrientation = orientation;
            mTempRect.set(mRootBounds);
            mRootBounds.set(rootBounds);
            mDividerSnapAlgorithm = getSnapAlgorithm(mContext, mRootBounds);
+2 −0
Original line number Diff line number Diff line
@@ -64,6 +64,7 @@ public final class SplitWindowManager extends WindowlessWindowManager {

    public interface ParentContainerCallbacks {
        void attachToParentSurface(SurfaceControl.Builder b);
        void onLeashReady(SurfaceControl leash);
    }

    public SplitWindowManager(String windowName, Context context, Configuration config,
@@ -100,6 +101,7 @@ public final class SplitWindowManager extends WindowlessWindowManager {
                .setCallsite("SplitWindowManager#attachToParentSurface");
        mParentContainerCallbacks.attachToParentSurface(builder);
        mLeash = builder.build();
        mParentContainerCallbacks.onLeashReady(mLeash);
        b.setParent(mLeash);
    }

+15 −4
Original line number Diff line number Diff line
@@ -90,6 +90,7 @@ import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.common.TransactionPool;
import com.android.wm.shell.common.split.SplitLayout;
import com.android.wm.shell.common.split.SplitLayout.SplitPosition;
import com.android.wm.shell.common.split.SplitWindowManager;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
import com.android.wm.shell.transition.Transitions;

@@ -163,6 +164,19 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,
        mDismissTop = NO_DISMISS;
    };

    private final SplitWindowManager.ParentContainerCallbacks mParentContainerCallbacks =
            new SplitWindowManager.ParentContainerCallbacks() {
        @Override
        public void attachToParentSurface(SurfaceControl.Builder b) {
            mRootTDAOrganizer.attachToDisplayArea(mDisplayId, b);
        }

        @Override
        public void onLeashReady(SurfaceControl leash) {
            mSyncQueue.runInSync(t -> applyDividerVisibility(t));
        }
    };

    StageCoordinator(Context context, int displayId, SyncTransactionQueue syncQueue,
            RootTaskDisplayAreaOrganizer rootTDAOrganizer, ShellTaskOrganizer taskOrganizer,
            DisplayImeController displayImeController,
@@ -726,7 +740,6 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,
        } else {
            t.hide(dividerLeash);
        }

    }

    private void onStageHasChildrenChanged(StageListenerImpl stageListener) {
@@ -852,8 +865,7 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,
        mDisplayAreaInfo = displayAreaInfo;
        if (mSplitLayout == null) {
            mSplitLayout = new SplitLayout(TAG + "SplitDivider", mContext,
                    mDisplayAreaInfo.configuration, this,
                    b -> mRootTDAOrganizer.attachToDisplayArea(mDisplayId, b),
                    mDisplayAreaInfo.configuration, this, mParentContainerCallbacks,
                    mDisplayImeController, mTaskOrganizer);
            mDisplayInsetsController.addInsetsChangedListener(mDisplayId, mSplitLayout);
        }
@@ -871,7 +883,6 @@ class StageCoordinator implements SplitLayout.SplitLayoutHandler,
                && mSplitLayout.updateConfiguration(mDisplayAreaInfo.configuration)
                && mMainStage.isActive()) {
            onLayoutChanged(mSplitLayout);
            mSyncQueue.runInSync(t -> applyDividerVisibility(t));
        }
    }

+2 −3
Original line number Diff line number Diff line
@@ -29,7 +29,6 @@ import static org.mockito.Mockito.verify;

import android.content.res.Configuration;
import android.graphics.Rect;
import android.view.SurfaceControl;

import androidx.test.annotation.UiThreadTest;
import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -53,7 +52,7 @@ import org.mockito.MockitoAnnotations;
@RunWith(AndroidJUnit4.class)
public class SplitLayoutTests extends ShellTestCase {
    @Mock SplitLayout.SplitLayoutHandler mSplitLayoutHandler;
    @Mock SurfaceControl mRootLeash;
    @Mock SplitWindowManager.ParentContainerCallbacks mCallbacks;
    @Mock DisplayImeController mDisplayImeController;
    @Mock ShellTaskOrganizer mTaskOrganizer;
    @Captor ArgumentCaptor<Runnable> mRunnableCaptor;
@@ -67,7 +66,7 @@ public class SplitLayoutTests extends ShellTestCase {
                mContext,
                getConfiguration(),
                mSplitLayoutHandler,
                b -> b.setParent(mRootLeash),
                mCallbacks,
                mDisplayImeController,
                mTaskOrganizer));
    }
Loading