diff --git a/core/java/com/android/internal/policy/DividerSnapAlgorithm.java b/core/java/com/android/internal/policy/DividerSnapAlgorithm.java index fbf690fa1457e..a8ad8102c6107 100644 --- a/core/java/com/android/internal/policy/DividerSnapAlgorithm.java +++ b/core/java/com/android/internal/policy/DividerSnapAlgorithm.java @@ -25,7 +25,6 @@ import android.content.res.Configuration; import android.content.res.Resources; import android.graphics.Rect; import android.hardware.display.DisplayManager; -import android.util.Log; import android.view.Display; import android.view.DisplayInfo; @@ -107,6 +106,12 @@ public class DividerSnapAlgorithm { DOCKED_INVALID, false); } + public DividerSnapAlgorithm(Resources res, int displayWidth, int displayHeight, int dividerSize, + boolean isHorizontalDivision, Rect insets, int dockSide) { + this(res, displayWidth, displayHeight, dividerSize, isHorizontalDivision, insets, + dockSide, false); + } + public DividerSnapAlgorithm(Resources res, int displayWidth, int displayHeight, int dividerSize, boolean isHorizontalDivision, Rect insets, int dockSide, boolean isMinimizedMode) { mMinFlingVelocityPxPerSecond = @@ -265,7 +270,11 @@ public class DividerSnapAlgorithm { ? mDisplayHeight : mDisplayWidth; int navBarSize = isHorizontalDivision ? mInsets.bottom : mInsets.right; - mTargets.add(new SnapTarget(-mDividerSize, -mDividerSize, SnapTarget.FLAG_DISMISS_START, + int startPos = -mDividerSize; + if (dockedSide == DOCKED_RIGHT) { + startPos += mInsets.left; + } + mTargets.add(new SnapTarget(startPos, startPos, SnapTarget.FLAG_DISMISS_START, 0.35f)); switch (mSnapMode) { case SNAP_MODE_16_9: diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java index 6d677ab74beeb..8d89314c2e210 100644 --- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java +++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java @@ -126,8 +126,10 @@ public class DividerView extends FrameLayout implements OnTouchListener, private SnapTarget mSnapTargetBeforeMinimized; private int mDividerInsets; + private final Display mDefaultDisplay; private int mDisplayWidth; private int mDisplayHeight; + private int mDisplayRotation; private int mDividerWindowWidth; private int mDividerSize; private int mTouchElevation; @@ -140,7 +142,7 @@ public class DividerView extends FrameLayout implements OnTouchListener, private final Rect mDockedInsetRect = new Rect(); private final Rect mOtherInsetRect = new Rect(); private final Rect mLastResizeRect = new Rect(); - private final Rect mDisplayRect = new Rect(); + private final Rect mTmpRect = new Rect(); private final WindowManagerProxy mWindowManagerProxy = WindowManagerProxy.getInstance(); private DividerWindowManager mWindowManager; private VelocityTracker mVelocityTracker; @@ -274,6 +276,9 @@ public class DividerView extends FrameLayout implements OnTouchListener, super(context, attrs, defStyleAttr, defStyleRes); mSfChoreographer = new SurfaceFlingerVsyncChoreographer(mHandler, context.getDisplay(), Choreographer.getInstance()); + final DisplayManager displayManager = + (DisplayManager) mContext.getSystemService(Context.DISPLAY_SERVICE); + mDefaultDisplay = displayManager.getDisplay(Display.DEFAULT_DISPLAY); } @Override @@ -373,7 +378,13 @@ public class DividerView extends FrameLayout implements OnTouchListener, if (mStableInsets.isEmpty()) { SystemServicesProxy.getInstance(mContext).getStableInsets(mStableInsets); } - repositionSnapTargetBeforeMinimized(); + + if (mState.mRatioPositionBeforeMinimized == 0) { + // Set the middle target as the initial state + mSnapTargetBeforeMinimized = mSnapAlgorithm.getMiddleTarget(); + } else { + repositionSnapTargetBeforeMinimized(); + } } public WindowManagerProxy getWindowManagerProxy() { @@ -403,6 +414,11 @@ public class DividerView extends FrameLayout implements OnTouchListener, mHandle.setTouching(true, animate); } mDockSide = mWindowManagerProxy.getDockSide(); + + // Update snap algorithm if rotation has occurred + if (mDisplayRotation != mDefaultDisplay.getRotation()) { + updateDisplayInfo(); + } initializeSnapAlgorithm(); mWindowManagerProxy.setResizing(true); if (touching) { @@ -453,7 +469,7 @@ public class DividerView extends FrameLayout implements OnTouchListener, private void initializeSnapAlgorithm() { if (mSnapAlgorithm == null) { mSnapAlgorithm = new DividerSnapAlgorithm(getContext().getResources(), mDisplayWidth, - mDisplayHeight, mDividerSize, isHorizontalDivision(), mStableInsets); + mDisplayHeight, mDividerSize, isHorizontalDivision(), mStableInsets, mDockSide); } if (mMinimizedSnapAlgorithm == null) { mMinimizedSnapAlgorithm = new DividerSnapAlgorithm(getContext().getResources(), @@ -620,7 +636,10 @@ public class DividerView extends FrameLayout implements OnTouchListener, } else { saveTarget = snapTarget; } - saveSnapTargetBeforeMinimized(saveTarget); + if (saveTarget.position != mSnapAlgorithm.getDismissEndTarget().position + && saveTarget.position != mSnapAlgorithm.getDismissStartTarget().position) { + saveSnapTargetBeforeMinimized(saveTarget); + } } }; Runnable notCancelledEndAction = () -> { @@ -764,6 +783,8 @@ public class DividerView extends FrameLayout implements OnTouchListener, initializeSnapAlgorithm(); if (mIsInMinimizeInteraction != minimized) { if (minimized) { + // Relayout to recalculate the divider shadow when minimizing + requestLayout(); mIsInMinimizeInteraction = true; resizeStack(mMinimizedSnapAlgorithm.getMiddleTarget()); } else { @@ -913,11 +934,9 @@ public class DividerView extends FrameLayout implements OnTouchListener, } private void updateDisplayInfo() { - final DisplayManager displayManager = - (DisplayManager) mContext.getSystemService(Context.DISPLAY_SERVICE); - Display display = displayManager.getDisplay(Display.DEFAULT_DISPLAY); + mDisplayRotation = mDefaultDisplay.getRotation(); final DisplayInfo info = new DisplayInfo(); - display.getDisplayInfo(info); + mDefaultDisplay.getDisplayInfo(info); mDisplayWidth = info.logicalWidth; mDisplayHeight = info.logicalHeight; mSnapAlgorithm = null; @@ -991,44 +1010,47 @@ public class DividerView extends FrameLayout implements OnTouchListener, if (mHomeStackResizable && mIsInMinimizeInteraction) { calculateBoundsForPosition(mSnapTargetBeforeMinimized.position, mDockSide, mDockedTaskRect); + calculateBoundsForPosition(mSnapTargetBeforeMinimized.position, + DockedDividerUtils.invertDockSide(mDockSide), mOtherTaskRect); // Move a right-docked-app to line up with the divider while dragging it if (mDockSide == DOCKED_RIGHT) { mDockedTaskRect.offset(Math.max(position, mStableInsets.left - mDividerSize) - mDockedTaskRect.left + mDividerSize, 0); + mOtherTaskRect.offset(mStableInsets.left, 0); } - calculateBoundsForPosition(mSnapTargetBeforeMinimized.position, - DockedDividerUtils.invertDockSide(mDockSide), mOtherTaskRect); mWindowManagerProxy.resizeDockedStack(mDockedRect, mDockedTaskRect, mDockedTaskRect, mOtherTaskRect, null); return; } if (mEntranceAnimationRunning && taskPosition != TASK_POSITION_SAME) { - if (mCurrentAnimator != null) { - calculateBoundsForPosition(taskPosition, mDockSide, mDockedTaskRect); - } else { - calculateBoundsForPosition(isHorizontalDivision() ? mDisplayHeight : mDisplayWidth, - mDockSide, mDockedTaskRect); - } + calculateBoundsForPosition(taskPosition, mDockSide, mDockedTaskRect); // Move a docked app if from the right in position with the divider up to insets if (mDockSide == DOCKED_RIGHT) { - mDockedTaskRect.offset(Math.max(position, - mStableInsets.left) - mDockedTaskRect.left, 0); + mDockedTaskRect.offset(Math.max(position, mStableInsets.left - mDividerSize) + - mDockedTaskRect.left + mDividerSize, 0); + mOtherTaskRect.offset(mStableInsets.left, 0); } calculateBoundsForPosition(taskPosition, DockedDividerUtils.invertDockSide(mDockSide), mOtherTaskRect); mWindowManagerProxy.resizeDockedStack(mDockedRect, mDockedTaskRect, null, mOtherTaskRect, null); } else if (mExitAnimationRunning && taskPosition != TASK_POSITION_SAME) { - calculateBoundsForPosition(taskPosition, - mDockSide, mDockedTaskRect); + calculateBoundsForPosition(taskPosition, mDockSide, mDockedTaskRect); + mDockedInsetRect.set(mDockedTaskRect); calculateBoundsForPosition(mExitStartPosition, DockedDividerUtils.invertDockSide(mDockSide), mOtherTaskRect); mOtherInsetRect.set(mOtherTaskRect); applyExitAnimationParallax(mOtherTaskRect, position); - mWindowManagerProxy.resizeDockedStack(mDockedRect, mDockedTaskRect, null, + + // Move a right-docked-app to line up with the divider while dragging it + if (mDockSide == DOCKED_RIGHT) { + mDockedTaskRect.offset(position - mStableInsets.left + mDividerSize, 0); + mOtherTaskRect.offset(mStableInsets.left, 0); + } + mWindowManagerProxy.resizeDockedStack(mDockedRect, mDockedTaskRect, mDockedInsetRect, mOtherTaskRect, mOtherInsetRect); } else if (taskPosition != TASK_POSITION_SAME) { calculateBoundsForPosition(position, DockedDividerUtils.invertDockSide(mDockSide), @@ -1040,17 +1062,17 @@ public class DividerView extends FrameLayout implements OnTouchListener, restrictDismissingTaskPosition(taskPosition, dockSideInverted, taskSnapTarget); calculateBoundsForPosition(taskPositionDocked, mDockSide, mDockedTaskRect); calculateBoundsForPosition(taskPositionOther, dockSideInverted, mOtherTaskRect); - mDisplayRect.set(0, 0, mDisplayWidth, mDisplayHeight); + mTmpRect.set(0, 0, mDisplayWidth, mDisplayHeight); alignTopLeft(mDockedRect, mDockedTaskRect); alignTopLeft(mOtherRect, mOtherTaskRect); mDockedInsetRect.set(mDockedTaskRect); mOtherInsetRect.set(mOtherTaskRect); if (dockSideTopLeft(mDockSide)) { - alignTopLeft(mDisplayRect, mDockedInsetRect); - alignBottomRight(mDisplayRect, mOtherInsetRect); + alignTopLeft(mTmpRect, mDockedInsetRect); + alignBottomRight(mTmpRect, mOtherInsetRect); } else { - alignBottomRight(mDisplayRect, mDockedInsetRect); - alignTopLeft(mDisplayRect, mOtherInsetRect); + alignBottomRight(mTmpRect, mDockedInsetRect); + alignTopLeft(mTmpRect, mOtherInsetRect); } applyDismissingParallax(mDockedTaskRect, mDockSide, taskSnapTarget, position, taskPositionDocked); @@ -1269,23 +1291,22 @@ public class DividerView extends FrameLayout implements OnTouchListener, startDragging(false /* animate */, false /* touching */); } updateDockSide(); - int position = DockedDividerUtils.calculatePositionForBounds(event.initialRect, - mDockSide, mDividerSize); mEntranceAnimationRunning = true; - resizeStack(position, mSnapAlgorithm.getMiddleTarget().position, + resizeStack(calculatePositionForInsetBounds(), mSnapAlgorithm.getMiddleTarget().position, mSnapAlgorithm.getMiddleTarget()); } public void onRecentsDrawn() { + updateDockSide(); + final int position = calculatePositionForInsetBounds(); if (mState.animateAfterRecentsDrawn) { mState.animateAfterRecentsDrawn = false; - updateDockSide(); mHandler.post(() -> { // Delay switching resizing mode because this might cause jank in recents animation // that's longer than this animation. - stopDragging(getCurrentPosition(), mSnapAlgorithm.getMiddleTarget(), + stopDragging(position, getSnapAlgorithm().getMiddleTarget(), mLongPressEntraceAnimDuration, Interpolators.FAST_OUT_SLOW_IN, 200 /* endDelay */); }); @@ -1294,7 +1315,7 @@ public class DividerView extends FrameLayout implements OnTouchListener, mState.growAfterRecentsDrawn = false; updateDockSide(); EventBus.getDefault().send(new RecentsGrowingEvent()); - stopDragging(getCurrentPosition(), mSnapAlgorithm.getMiddleTarget(), 336, + stopDragging(position, getSnapAlgorithm().getMiddleTarget(), 336, Interpolators.FAST_OUT_SLOW_IN); } } @@ -1315,4 +1336,10 @@ public class DividerView extends FrameLayout implements OnTouchListener, 0 /* endDelay */, Interpolators.FAST_OUT_SLOW_IN); } } + + private int calculatePositionForInsetBounds() { + mTmpRect.set(0, 0, mDisplayWidth, mDisplayHeight); + mTmpRect.inset(mStableInsets); + return DockedDividerUtils.calculatePositionForBounds(mTmpRect, mDockSide, mDividerSize); + } } diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java index a85df03e97f68..87d3696482335 100644 --- a/services/core/java/com/android/server/am/ActivityStack.java +++ b/services/core/java/com/android/server/am/ActivityStack.java @@ -639,6 +639,9 @@ class ActivityStack extends ConfigurationContai // so that the divider matches and remove this logic. // TODO: This is currently only called when entering split-screen while in another // task, and from the tests + // TODO (b/78247419): Check if launcher and overview are same then move home stack + // instead of recents stack. Then fix the rotation animation from fullscreen to + // minimized mode final ActivityStack recentStack = display.getOrCreateStack( WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_RECENTS, true /* onTop */);