Loading libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerSnapAlgorithm.java +26 −23 Original line number Diff line number Diff line Loading @@ -19,6 +19,14 @@ package com.android.wm.shell.common.split; import static android.view.WindowManager.DOCKED_INVALID; import static android.view.WindowManager.DOCKED_LEFT; import static android.view.WindowManager.DOCKED_RIGHT; import static com.android.wm.shell.common.split.SplitScreenConstants.SNAP_TO_30_70; import static com.android.wm.shell.common.split.SplitScreenConstants.SNAP_TO_50_50; import static com.android.wm.shell.common.split.SplitScreenConstants.SNAP_TO_70_30; import static com.android.wm.shell.common.split.SplitScreenConstants.SNAP_TO_END_AND_DISMISS; import static com.android.wm.shell.common.split.SplitScreenConstants.SNAP_TO_MINIMIZE; import static com.android.wm.shell.common.split.SplitScreenConstants.SNAP_TO_NONE; import static com.android.wm.shell.common.split.SplitScreenConstants.SNAP_TO_START_AND_DISMISS; import static com.android.wm.shell.common.split.SplitScreenConstants.SnapPosition; import android.content.Context; import android.content.res.Configuration; Loading Loading @@ -263,7 +271,7 @@ public class DividerSnapAlgorithm { private SnapTarget snap(int position, boolean hardDismiss) { if (shouldApplyFreeSnapMode(position)) { return new SnapTarget(position, position, SnapTarget.FLAG_NONE); return new SnapTarget(position, position, SNAP_TO_NONE); } int minIndex = -1; float minDistance = Float.MAX_VALUE; Loading Loading @@ -291,8 +299,7 @@ public class DividerSnapAlgorithm { if (dockedSide == DOCKED_RIGHT) { startPos += mInsets.left; } mTargets.add(new SnapTarget(startPos, startPos, SnapTarget.FLAG_DISMISS_START, 0.35f)); mTargets.add(new SnapTarget(startPos, startPos, SNAP_TO_START_AND_DISMISS, 0.35f)); switch (mSnapMode) { case SNAP_MODE_16_9: addRatio16_9Targets(isHorizontalDivision, dividerMax); Loading @@ -307,15 +314,15 @@ public class DividerSnapAlgorithm { addMinimizedTarget(isHorizontalDivision, dockedSide); break; } mTargets.add(new SnapTarget(dividerMax, dividerMax, SnapTarget.FLAG_DISMISS_END, 0.35f)); mTargets.add(new SnapTarget(dividerMax, dividerMax, SNAP_TO_END_AND_DISMISS, 0.35f)); } private void addNonDismissingTargets(boolean isHorizontalDivision, int topPosition, int bottomPosition, int dividerMax) { maybeAddTarget(topPosition, topPosition - getStartInset()); maybeAddTarget(topPosition, topPosition - getStartInset(), SNAP_TO_30_70); addMiddleTarget(isHorizontalDivision); maybeAddTarget(bottomPosition, dividerMax - getEndInset() - (bottomPosition + mDividerSize)); dividerMax - getEndInset() - (bottomPosition + mDividerSize), SNAP_TO_70_30); } private void addFixedDivisionTargets(boolean isHorizontalDivision, int dividerMax) { Loading Loading @@ -349,16 +356,16 @@ public class DividerSnapAlgorithm { * Adds a target at {@param position} but only if the area with size of {@param smallerSize} * meets the minimal size requirement. */ private void maybeAddTarget(int position, int smallerSize) { private void maybeAddTarget(int position, int smallerSize, @SnapPosition int snapTo) { if (smallerSize >= mMinimalSizeResizableTask) { mTargets.add(new SnapTarget(position, position, SnapTarget.FLAG_NONE)); mTargets.add(new SnapTarget(position, position, snapTo)); } } private void addMiddleTarget(boolean isHorizontalDivision) { int position = DockedDividerUtils.calculateMiddlePosition(isHorizontalDivision, mInsets, mDisplayWidth, mDisplayHeight, mDividerSize); mTargets.add(new SnapTarget(position, position, SnapTarget.FLAG_NONE)); mTargets.add(new SnapTarget(position, position, SNAP_TO_50_50)); } private void addMinimizedTarget(boolean isHorizontalDivision, int dockedSide) { Loading @@ -372,7 +379,7 @@ public class DividerSnapAlgorithm { position = mDisplayWidth - position - mInsets.right - mDividerSize; } } mTargets.add(new SnapTarget(position, position, SnapTarget.FLAG_NONE)); mTargets.add(new SnapTarget(position, position, SNAP_TO_MINIMIZE)); } public SnapTarget getMiddleTarget() { Loading Loading @@ -435,14 +442,6 @@ public class DividerSnapAlgorithm { * Represents a snap target for the divider. */ public static class SnapTarget { public static final int FLAG_NONE = 0; /** If the divider reaches this value, the left/top task should be dismissed. */ public static final int FLAG_DISMISS_START = 1; /** If the divider reaches this value, the right/bottom task should be dismissed */ public static final int FLAG_DISMISS_END = 2; /** Position of this snap target. The right/bottom edge of the top/left task snaps here. */ public final int position; Loading @@ -452,7 +451,10 @@ public class DividerSnapAlgorithm { */ public final int taskPosition; public final int flag; /** * An int describing the placement of the divider in this snap target. */ public final @SnapPosition int snapTo; public boolean isMiddleTarget; Loading @@ -462,14 +464,15 @@ public class DividerSnapAlgorithm { */ private final float distanceMultiplier; public SnapTarget(int position, int taskPosition, int flag) { this(position, taskPosition, flag, 1f); public SnapTarget(int position, int taskPosition, @SnapPosition int snapTo) { this(position, taskPosition, snapTo, 1f); } public SnapTarget(int position, int taskPosition, int flag, float distanceMultiplier) { public SnapTarget(int position, int taskPosition, @SnapPosition int snapTo, float distanceMultiplier) { this.position = position; this.taskPosition = taskPosition; this.flag = flag; this.snapTo = snapTo; this.distanceMultiplier = distanceMultiplier; } } Loading libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java +5 −6 Original line number Diff line number Diff line Loading @@ -23,13 +23,12 @@ import static android.view.WindowManager.DOCKED_INVALID; import static android.view.WindowManager.DOCKED_LEFT; import static android.view.WindowManager.DOCKED_RIGHT; import static android.view.WindowManager.DOCKED_TOP; import static com.android.internal.jank.InteractionJankMonitor.CUJ_SPLIT_SCREEN_DOUBLE_TAP_DIVIDER; import static com.android.internal.jank.InteractionJankMonitor.CUJ_SPLIT_SCREEN_RESIZE; import static com.android.wm.shell.common.split.DividerSnapAlgorithm.SnapTarget.FLAG_DISMISS_END; import static com.android.wm.shell.common.split.DividerSnapAlgorithm.SnapTarget.FLAG_DISMISS_START; import static com.android.wm.shell.animation.Interpolators.DIM_INTERPOLATOR; import static com.android.wm.shell.animation.Interpolators.SLOWDOWN_INTERPOLATOR; import static com.android.wm.shell.common.split.SplitScreenConstants.SNAP_TO_END_AND_DISMISS; import static com.android.wm.shell.common.split.SplitScreenConstants.SNAP_TO_START_AND_DISMISS; import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT; import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT; import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_UNDEFINED; Loading Loading @@ -511,13 +510,13 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange * target indicates dismissing split. */ public void snapToTarget(int currentPosition, DividerSnapAlgorithm.SnapTarget snapTarget) { switch (snapTarget.flag) { case FLAG_DISMISS_START: switch (snapTarget.snapTo) { case SNAP_TO_START_AND_DISMISS: flingDividePosition(currentPosition, snapTarget.position, FLING_RESIZE_DURATION, () -> mSplitLayoutHandler.onSnappedToDismiss(false /* bottomOrRight */, EXIT_REASON_DRAG_DIVIDER)); break; case FLAG_DISMISS_END: case SNAP_TO_END_AND_DISMISS: flingDividePosition(currentPosition, snapTarget.position, FLING_RESIZE_DURATION, () -> mSplitLayoutHandler.onSnappedToDismiss(true /* bottomOrRight */, EXIT_REASON_DRAG_DIVIDER)); Loading libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitScreenConstants.java +32 −0 Original line number Diff line number Diff line Loading @@ -57,6 +57,38 @@ public class SplitScreenConstants { public @interface SplitPosition { } /** The divider doesn't snap to any target and is freely placeable. */ public static final int SNAP_TO_NONE = 0; /** A snap target positioned near the screen edge for a minimized task */ public static final int SNAP_TO_MINIMIZE = 1; /** If the divider reaches this value, the left/top task should be dismissed. */ public static final int SNAP_TO_START_AND_DISMISS = 2; /** A snap target in the first half of the screen, where the split is roughly 30-70. */ public static final int SNAP_TO_30_70 = 3; /** The 50-50 snap target */ public static final int SNAP_TO_50_50 = 4; /** A snap target in the latter half of the screen, where the split is roughly 70-30. */ public static final int SNAP_TO_70_30 = 5; /** If the divider reaches this value, the right/bottom task should be dismissed. */ public static final int SNAP_TO_END_AND_DISMISS = 6; @IntDef(prefix = { "SNAP_TO_" }, value = { SNAP_TO_NONE, SNAP_TO_MINIMIZE, SNAP_TO_START_AND_DISMISS, SNAP_TO_30_70, SNAP_TO_50_50, SNAP_TO_70_30, SNAP_TO_END_AND_DISMISS }) public @interface SnapPosition {} public static final int[] CONTROLLED_ACTIVITY_TYPES = {ACTIVITY_TYPE_STANDARD}; public static final int[] CONTROLLED_WINDOWING_MODES = {WINDOWING_MODE_FULLSCREEN, WINDOWING_MODE_UNDEFINED}; Loading libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/SplitLayoutTests.java +4 −4 Original line number Diff line number Diff line Loading @@ -18,9 +18,9 @@ package com.android.wm.shell.common.split; import static android.content.res.Configuration.ORIENTATION_LANDSCAPE; import static android.content.res.Configuration.ORIENTATION_PORTRAIT; import static com.android.wm.shell.common.split.SplitScreenConstants.SNAP_TO_END_AND_DISMISS; import static com.android.wm.shell.common.split.SplitScreenConstants.SNAP_TO_START_AND_DISMISS; import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; Loading Loading @@ -146,7 +146,7 @@ public class SplitLayoutTests extends ShellTestCase { public void testSnapToDismissStart() { // verify it callbacks properly when the snap target indicates dismissing split. DividerSnapAlgorithm.SnapTarget snapTarget = getSnapTarget(0 /* position */, DividerSnapAlgorithm.SnapTarget.FLAG_DISMISS_START); SNAP_TO_START_AND_DISMISS); mSplitLayout.snapToTarget(mSplitLayout.getDividePosition(), snapTarget); waitDividerFlingFinished(); Loading @@ -158,7 +158,7 @@ public class SplitLayoutTests extends ShellTestCase { public void testSnapToDismissEnd() { // verify it callbacks properly when the snap target indicates dismissing split. DividerSnapAlgorithm.SnapTarget snapTarget = getSnapTarget(0 /* position */, DividerSnapAlgorithm.SnapTarget.FLAG_DISMISS_END); SNAP_TO_END_AND_DISMISS); mSplitLayout.snapToTarget(mSplitLayout.getDividePosition(), snapTarget); waitDividerFlingFinished(); Loading Loading
libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerSnapAlgorithm.java +26 −23 Original line number Diff line number Diff line Loading @@ -19,6 +19,14 @@ package com.android.wm.shell.common.split; import static android.view.WindowManager.DOCKED_INVALID; import static android.view.WindowManager.DOCKED_LEFT; import static android.view.WindowManager.DOCKED_RIGHT; import static com.android.wm.shell.common.split.SplitScreenConstants.SNAP_TO_30_70; import static com.android.wm.shell.common.split.SplitScreenConstants.SNAP_TO_50_50; import static com.android.wm.shell.common.split.SplitScreenConstants.SNAP_TO_70_30; import static com.android.wm.shell.common.split.SplitScreenConstants.SNAP_TO_END_AND_DISMISS; import static com.android.wm.shell.common.split.SplitScreenConstants.SNAP_TO_MINIMIZE; import static com.android.wm.shell.common.split.SplitScreenConstants.SNAP_TO_NONE; import static com.android.wm.shell.common.split.SplitScreenConstants.SNAP_TO_START_AND_DISMISS; import static com.android.wm.shell.common.split.SplitScreenConstants.SnapPosition; import android.content.Context; import android.content.res.Configuration; Loading Loading @@ -263,7 +271,7 @@ public class DividerSnapAlgorithm { private SnapTarget snap(int position, boolean hardDismiss) { if (shouldApplyFreeSnapMode(position)) { return new SnapTarget(position, position, SnapTarget.FLAG_NONE); return new SnapTarget(position, position, SNAP_TO_NONE); } int minIndex = -1; float minDistance = Float.MAX_VALUE; Loading Loading @@ -291,8 +299,7 @@ public class DividerSnapAlgorithm { if (dockedSide == DOCKED_RIGHT) { startPos += mInsets.left; } mTargets.add(new SnapTarget(startPos, startPos, SnapTarget.FLAG_DISMISS_START, 0.35f)); mTargets.add(new SnapTarget(startPos, startPos, SNAP_TO_START_AND_DISMISS, 0.35f)); switch (mSnapMode) { case SNAP_MODE_16_9: addRatio16_9Targets(isHorizontalDivision, dividerMax); Loading @@ -307,15 +314,15 @@ public class DividerSnapAlgorithm { addMinimizedTarget(isHorizontalDivision, dockedSide); break; } mTargets.add(new SnapTarget(dividerMax, dividerMax, SnapTarget.FLAG_DISMISS_END, 0.35f)); mTargets.add(new SnapTarget(dividerMax, dividerMax, SNAP_TO_END_AND_DISMISS, 0.35f)); } private void addNonDismissingTargets(boolean isHorizontalDivision, int topPosition, int bottomPosition, int dividerMax) { maybeAddTarget(topPosition, topPosition - getStartInset()); maybeAddTarget(topPosition, topPosition - getStartInset(), SNAP_TO_30_70); addMiddleTarget(isHorizontalDivision); maybeAddTarget(bottomPosition, dividerMax - getEndInset() - (bottomPosition + mDividerSize)); dividerMax - getEndInset() - (bottomPosition + mDividerSize), SNAP_TO_70_30); } private void addFixedDivisionTargets(boolean isHorizontalDivision, int dividerMax) { Loading Loading @@ -349,16 +356,16 @@ public class DividerSnapAlgorithm { * Adds a target at {@param position} but only if the area with size of {@param smallerSize} * meets the minimal size requirement. */ private void maybeAddTarget(int position, int smallerSize) { private void maybeAddTarget(int position, int smallerSize, @SnapPosition int snapTo) { if (smallerSize >= mMinimalSizeResizableTask) { mTargets.add(new SnapTarget(position, position, SnapTarget.FLAG_NONE)); mTargets.add(new SnapTarget(position, position, snapTo)); } } private void addMiddleTarget(boolean isHorizontalDivision) { int position = DockedDividerUtils.calculateMiddlePosition(isHorizontalDivision, mInsets, mDisplayWidth, mDisplayHeight, mDividerSize); mTargets.add(new SnapTarget(position, position, SnapTarget.FLAG_NONE)); mTargets.add(new SnapTarget(position, position, SNAP_TO_50_50)); } private void addMinimizedTarget(boolean isHorizontalDivision, int dockedSide) { Loading @@ -372,7 +379,7 @@ public class DividerSnapAlgorithm { position = mDisplayWidth - position - mInsets.right - mDividerSize; } } mTargets.add(new SnapTarget(position, position, SnapTarget.FLAG_NONE)); mTargets.add(new SnapTarget(position, position, SNAP_TO_MINIMIZE)); } public SnapTarget getMiddleTarget() { Loading Loading @@ -435,14 +442,6 @@ public class DividerSnapAlgorithm { * Represents a snap target for the divider. */ public static class SnapTarget { public static final int FLAG_NONE = 0; /** If the divider reaches this value, the left/top task should be dismissed. */ public static final int FLAG_DISMISS_START = 1; /** If the divider reaches this value, the right/bottom task should be dismissed */ public static final int FLAG_DISMISS_END = 2; /** Position of this snap target. The right/bottom edge of the top/left task snaps here. */ public final int position; Loading @@ -452,7 +451,10 @@ public class DividerSnapAlgorithm { */ public final int taskPosition; public final int flag; /** * An int describing the placement of the divider in this snap target. */ public final @SnapPosition int snapTo; public boolean isMiddleTarget; Loading @@ -462,14 +464,15 @@ public class DividerSnapAlgorithm { */ private final float distanceMultiplier; public SnapTarget(int position, int taskPosition, int flag) { this(position, taskPosition, flag, 1f); public SnapTarget(int position, int taskPosition, @SnapPosition int snapTo) { this(position, taskPosition, snapTo, 1f); } public SnapTarget(int position, int taskPosition, int flag, float distanceMultiplier) { public SnapTarget(int position, int taskPosition, @SnapPosition int snapTo, float distanceMultiplier) { this.position = position; this.taskPosition = taskPosition; this.flag = flag; this.snapTo = snapTo; this.distanceMultiplier = distanceMultiplier; } } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java +5 −6 Original line number Diff line number Diff line Loading @@ -23,13 +23,12 @@ import static android.view.WindowManager.DOCKED_INVALID; import static android.view.WindowManager.DOCKED_LEFT; import static android.view.WindowManager.DOCKED_RIGHT; import static android.view.WindowManager.DOCKED_TOP; import static com.android.internal.jank.InteractionJankMonitor.CUJ_SPLIT_SCREEN_DOUBLE_TAP_DIVIDER; import static com.android.internal.jank.InteractionJankMonitor.CUJ_SPLIT_SCREEN_RESIZE; import static com.android.wm.shell.common.split.DividerSnapAlgorithm.SnapTarget.FLAG_DISMISS_END; import static com.android.wm.shell.common.split.DividerSnapAlgorithm.SnapTarget.FLAG_DISMISS_START; import static com.android.wm.shell.animation.Interpolators.DIM_INTERPOLATOR; import static com.android.wm.shell.animation.Interpolators.SLOWDOWN_INTERPOLATOR; import static com.android.wm.shell.common.split.SplitScreenConstants.SNAP_TO_END_AND_DISMISS; import static com.android.wm.shell.common.split.SplitScreenConstants.SNAP_TO_START_AND_DISMISS; import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT; import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT; import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_UNDEFINED; Loading Loading @@ -511,13 +510,13 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange * target indicates dismissing split. */ public void snapToTarget(int currentPosition, DividerSnapAlgorithm.SnapTarget snapTarget) { switch (snapTarget.flag) { case FLAG_DISMISS_START: switch (snapTarget.snapTo) { case SNAP_TO_START_AND_DISMISS: flingDividePosition(currentPosition, snapTarget.position, FLING_RESIZE_DURATION, () -> mSplitLayoutHandler.onSnappedToDismiss(false /* bottomOrRight */, EXIT_REASON_DRAG_DIVIDER)); break; case FLAG_DISMISS_END: case SNAP_TO_END_AND_DISMISS: flingDividePosition(currentPosition, snapTarget.position, FLING_RESIZE_DURATION, () -> mSplitLayoutHandler.onSnappedToDismiss(true /* bottomOrRight */, EXIT_REASON_DRAG_DIVIDER)); Loading
libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitScreenConstants.java +32 −0 Original line number Diff line number Diff line Loading @@ -57,6 +57,38 @@ public class SplitScreenConstants { public @interface SplitPosition { } /** The divider doesn't snap to any target and is freely placeable. */ public static final int SNAP_TO_NONE = 0; /** A snap target positioned near the screen edge for a minimized task */ public static final int SNAP_TO_MINIMIZE = 1; /** If the divider reaches this value, the left/top task should be dismissed. */ public static final int SNAP_TO_START_AND_DISMISS = 2; /** A snap target in the first half of the screen, where the split is roughly 30-70. */ public static final int SNAP_TO_30_70 = 3; /** The 50-50 snap target */ public static final int SNAP_TO_50_50 = 4; /** A snap target in the latter half of the screen, where the split is roughly 70-30. */ public static final int SNAP_TO_70_30 = 5; /** If the divider reaches this value, the right/bottom task should be dismissed. */ public static final int SNAP_TO_END_AND_DISMISS = 6; @IntDef(prefix = { "SNAP_TO_" }, value = { SNAP_TO_NONE, SNAP_TO_MINIMIZE, SNAP_TO_START_AND_DISMISS, SNAP_TO_30_70, SNAP_TO_50_50, SNAP_TO_70_30, SNAP_TO_END_AND_DISMISS }) public @interface SnapPosition {} public static final int[] CONTROLLED_ACTIVITY_TYPES = {ACTIVITY_TYPE_STANDARD}; public static final int[] CONTROLLED_WINDOWING_MODES = {WINDOWING_MODE_FULLSCREEN, WINDOWING_MODE_UNDEFINED}; Loading
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/SplitLayoutTests.java +4 −4 Original line number Diff line number Diff line Loading @@ -18,9 +18,9 @@ package com.android.wm.shell.common.split; import static android.content.res.Configuration.ORIENTATION_LANDSCAPE; import static android.content.res.Configuration.ORIENTATION_PORTRAIT; import static com.android.wm.shell.common.split.SplitScreenConstants.SNAP_TO_END_AND_DISMISS; import static com.android.wm.shell.common.split.SplitScreenConstants.SNAP_TO_START_AND_DISMISS; import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; Loading Loading @@ -146,7 +146,7 @@ public class SplitLayoutTests extends ShellTestCase { public void testSnapToDismissStart() { // verify it callbacks properly when the snap target indicates dismissing split. DividerSnapAlgorithm.SnapTarget snapTarget = getSnapTarget(0 /* position */, DividerSnapAlgorithm.SnapTarget.FLAG_DISMISS_START); SNAP_TO_START_AND_DISMISS); mSplitLayout.snapToTarget(mSplitLayout.getDividePosition(), snapTarget); waitDividerFlingFinished(); Loading @@ -158,7 +158,7 @@ public class SplitLayoutTests extends ShellTestCase { public void testSnapToDismissEnd() { // verify it callbacks properly when the snap target indicates dismissing split. DividerSnapAlgorithm.SnapTarget snapTarget = getSnapTarget(0 /* position */, DividerSnapAlgorithm.SnapTarget.FLAG_DISMISS_END); SNAP_TO_END_AND_DISMISS); mSplitLayout.snapToTarget(mSplitLayout.getDividePosition(), snapTarget); waitDividerFlingFinished(); Loading