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

Commit a6039455 authored by Shuming Hao's avatar Shuming Hao
Browse files

Launch split in vertical mode for foldables connected to external display.

When foldable pixel phone is connected to external display, the split selection in connected display should launch split pair in vertical mode. This CL updates the splitLayout to the new config when split select is initiated in external display, and fixes the `isLeftRightSplit` calculation for connected display, so that the split selection can launch in vertical mode as expected.

Bug: 438285797
Test: manual && atest WMShellUnitTests
Flag: com.android.window.flags.enable_non_default_display_split

Change-Id: I9a9458e3ba6802f0c476c64e60c7f9ecfa224e39
parent 193ac83c
Loading
Loading
Loading
Loading
+7 −5
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.wm.shell.common.split;

import static android.content.res.Configuration.SCREEN_HEIGHT_DP_UNDEFINED;
import static android.content.res.Configuration.SCREEN_WIDTH_DP_UNDEFINED;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.WindowManager.DOCKED_LEFT;
import static android.view.WindowManager.DOCKED_TOP;

@@ -252,7 +253,7 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
        mDimNonImeSide = res.getBoolean(R.bool.config_dimNonImeAttachedSide);
        mAllowLeftRightSplitInPortrait = SplitScreenUtils.allowLeftRightSplitInPortrait(res);
        mIsLeftRightSplit = SplitScreenUtils.isLeftRightSplit(mAllowLeftRightSplitInPortrait,
                configuration);
                configuration, DEFAULT_DISPLAY);
        statusBarHider.onLeftRightSplitUpdated(mIsLeftRightSplit);
        updateDividerConfig(mContext);

@@ -499,7 +500,7 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
    }

    /** Applies new configuration, returns {@code false} if there's no effect to the layout. */
    public boolean updateConfiguration(Configuration configuration) {
    public boolean updateConfiguration(Configuration configuration, int displayId) {
        // 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.
@@ -530,7 +531,7 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
        mUiMode = uiMode;
        mIsLargeScreen = configuration.smallestScreenWidthDp >= 600;
        mIsLeftRightSplit = SplitScreenUtils.isLeftRightSplit(mAllowLeftRightSplitInPortrait,
                configuration);
                configuration, displayId);
        mStatusBarHider.onLeftRightSplitUpdated(mIsLeftRightSplit);
        updateLayouts();
        updateDividerConfig(mContext);
@@ -555,11 +556,12 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
        // We only need new bounds here, other configuration should be update later.
        final boolean wasLeftRightSplit = SplitScreenUtils.isLeftRightSplit(
                mAllowLeftRightSplitInPortrait, mIsLargeScreen,
                mRootBounds.width() >= mRootBounds.height());
                mRootBounds.width() >= mRootBounds.height(), DEFAULT_DISPLAY);
        mTempRect.set(mRootBounds);
        mRootBounds.set(tmpRect);
        mIsLeftRightSplit = SplitScreenUtils.isLeftRightSplit(mAllowLeftRightSplitInPortrait,
                mIsLargeScreen, mRootBounds.width() >= mRootBounds.height());
                mIsLargeScreen, mRootBounds.width() >= mRootBounds.height(),
                DEFAULT_DISPLAY);
        mStatusBarHider.onLeftRightSplitUpdated(mIsLeftRightSplit);

        updateLayouts();
+40 −4
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.wm.shell.common.split;

import static android.view.Display.DEFAULT_DISPLAY;

import static com.android.wm.shell.shared.split.SplitScreenConstants.CONTROLLED_ACTIVITY_TYPES;
import static com.android.wm.shell.shared.split.SplitScreenConstants.CONTROLLED_WINDOWING_MODES;
import static com.android.wm.shell.shared.split.SplitScreenConstants.SNAP_TO_2_10_90;
@@ -90,12 +92,13 @@ public class SplitScreenUtils {
     * Returns whether left/right split is supported in the given configuration.
     */
    public static boolean isLeftRightSplit(boolean allowLeftRightSplitInPortrait,
            Configuration config) {
            Configuration config, int displayId) {
        // Compare the max bounds sizes as on near-square devices, the insets may result in a
        // configuration in the other orientation
        final Rect maxBounds = config.windowConfiguration.getMaxBounds();
        final boolean isLandscape = maxBounds.width() >= maxBounds.height();
        return isLeftRightSplit(allowLeftRightSplitInPortrait, isLargeScreen(config), isLandscape);
        return isLeftRightSplit(allowLeftRightSplitInPortrait, isLargeScreen(config), isLandscape,
                displayId);
    }

    /**
@@ -103,9 +106,16 @@ public class SplitScreenUtils {
     * is useful for cases where we need to calculate this given last saved state.
     */
    public static boolean isLeftRightSplit(boolean allowLeftRightSplitInPortrait,
            boolean isLargeScreen, boolean isLandscape) {
            boolean isLargeScreen, boolean isLandscape, int displayId) {
        if (allowLeftRightSplitInPortrait && isLargeScreen) {
            if (displayId == DEFAULT_DISPLAY
                    || !DesktopExperienceFlags.ENABLE_NON_DEFAULT_DISPLAY_SPLIT.isTrue()) {
                return !isLandscape;
            } else {
                // If split is started in external display and the non_default_display_split_bugfix
                // is enabled, set isLeftRightSplit to true in landscape mode.
                return isLandscape;
            }
        } else {
            return isLandscape;
        }
@@ -185,4 +195,30 @@ public class SplitScreenUtils {
        final DisplayAreaInfo displayAreaInfo = rootTDAOrganizer.getDisplayAreaInfo(displayId);
        return displayAreaInfo != null ? displayAreaInfo.token : null;
    }

    /**
     * Retrieves DisplayAreaInfo for a given task and updates the SplitLayout's configuration.
     *
     * @param rootTDAOrganizer The RootTaskDisplayAreaOrganizer instance.
     * @param displayId The RunningTaskInfo displayId for which to get display information.
     * @param splitLayout The SplitLayout to update. Can be null.
     */
    public static void updateSplitLayoutConfig(
            @NonNull RootTaskDisplayAreaOrganizer rootTDAOrganizer,
            int displayId,
            @Nullable SplitLayout splitLayout) {
        if (!DesktopExperienceFlags.ENABLE_NON_DEFAULT_DISPLAY_SPLIT.isTrue()) {
            return;
        }

        DisplayAreaInfo displayAreaInfo = rootTDAOrganizer.getDisplayAreaInfo(displayId);
        if (displayAreaInfo == null) {
            return;
        }

        Configuration displayConfiguration = displayAreaInfo.configuration;
        if (splitLayout != null) {
            splitLayout.updateConfiguration(displayConfiguration, displayId);
        }
    }
}
+1 −1
Original line number Diff line number Diff line
@@ -223,7 +223,7 @@ public class DesktopModeVisualIndicator {
        boolean leftRightSplitInPortrait = SplitScreenUtils.allowLeftRightSplitInPortrait(
                context.getResources());
        return SplitScreenUtils.isLeftRightSplit(leftRightSplitInPortrait,
                /* isLargeScreen= */ true, landscape);
                /* isLargeScreen= */ true, landscape, taskInfo.displayId);
    }

    /** Start the fade out animation, running the callback on the main thread once it is done. */
+10 −2
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import static android.app.StatusBarManager.DISABLE_NONE;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
import static android.content.pm.ActivityInfo.CONFIG_ASSETS_PATHS;
import static android.content.pm.ActivityInfo.CONFIG_UI_MODE;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION;

@@ -168,8 +169,12 @@ public class DragLayout extends LinearLayout
        // near-square devices may report the same orietation with insets taken into account
        mAllowLeftRightSplitInPortrait = SplitScreenUtils.allowLeftRightSplitInPortrait(
                context.getResources());
        int displayId = (mSession != null && mSession.runningTaskInfo != null)
                ? mSession.runningTaskInfo.displayId
                : DEFAULT_DISPLAY;

        mIsLeftRightSplit = SplitScreenUtils.isLeftRightSplit(mAllowLeftRightSplitInPortrait,
                getResources().getConfiguration());
                getResources().getConfiguration(), displayId);
        setOrientation(mIsLeftRightSplit ? LinearLayout.HORIZONTAL : LinearLayout.VERTICAL);
        updateContainerMargins(mIsLeftRightSplit);
    }
@@ -267,8 +272,11 @@ public class DragLayout extends LinearLayout
    }

    public void onConfigChanged(Configuration newConfig) {
        int displayId = (mSession != null && mSession.runningTaskInfo != null)
                ? mSession.runningTaskInfo.displayId
                : DEFAULT_DISPLAY;
        boolean isLeftRightSplit = SplitScreenUtils.isLeftRightSplit(mAllowLeftRightSplitInPortrait,
                newConfig);
                newConfig, displayId);
        if (isLeftRightSplit != mIsLeftRightSplit) {
            mIsLeftRightSplit = isLeftRightSplit;
            setOrientation(mIsLeftRightSplit ? LinearLayout.HORIZONTAL : LinearLayout.VERTICAL);
+5 −3
Original line number Diff line number Diff line
@@ -45,9 +45,10 @@ import static com.android.wm.shell.Flags.splitDisableChildTaskBounds;
import static com.android.wm.shell.common.split.SplitLayout.PARALLAX_ALIGN_CENTER;
import static com.android.wm.shell.common.split.SplitLayout.PARALLAX_FLEX_HYBRID;
import static com.android.wm.shell.common.split.SplitLayout.RESTING_DIM_LAYER;
import static com.android.wm.shell.common.split.SplitScreenUtils.getNewParentTokenForStage;
import static com.android.wm.shell.common.split.SplitScreenUtils.reverseSplitPosition;
import static com.android.wm.shell.common.split.SplitScreenUtils.splitFailureMessage;
import static com.android.wm.shell.common.split.SplitScreenUtils.getNewParentTokenForStage;
import static com.android.wm.shell.common.split.SplitScreenUtils.updateSplitLayoutConfig;
import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN;
import static com.android.wm.shell.shared.TransitionUtil.isClosingType;
import static com.android.wm.shell.shared.TransitionUtil.isOpeningMode;
@@ -1027,6 +1028,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
            final RunningTaskInfo taskInfo = mTaskOrganizer.getRunningTaskInfo(taskId);

            if (taskInfo != null) {
                updateSplitLayoutConfig(mRootTDAOrganizer, taskInfo.displayId, mSplitLayout);
                prepareMovingSplitScreenRoot(wct, taskInfo.displayId);
            }
        }
@@ -2521,7 +2523,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
        mSplitMultiDisplayHelper.setDisplayRootTaskInfo(taskInfo.displayId, taskInfo);

        if (mSplitLayout != null
                && mSplitLayout.updateConfiguration(taskInfo.configuration)
                && mSplitLayout.updateConfiguration(taskInfo.configuration, taskInfo.displayId)
                && isSplitActive()) {
            ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "onTaskInfoChanged: task=%d updating",
                    taskInfo.taskId);
@@ -3089,7 +3091,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
                displayId, fromRotation, toRotation,
                newDisplayAreaInfo != null ? newDisplayAreaInfo.configuration : null);
        if (newDisplayAreaInfo != null) {
            mSplitLayout.updateConfiguration(newDisplayAreaInfo.configuration);
            mSplitLayout.updateConfiguration(newDisplayAreaInfo.configuration, displayId);
        } else {
            mSplitLayout.rotateTo(toRotation);
        }
Loading