Fixes splitscreen when executed from fullscreen app
Fixes splitscreen from the right for launching splitscreen from fullscreen app including pixel launcher and 3rd party launchers. With 3rd party launchers, the experience is the same as Android O. With pixel launcher since launcher and recents are merged, it will split to minimized mode. When pixel launcher is used, the recents stack is ignored. Fixes: 73250406 Fixes: 78247419 Test: use split screen; invoke command with supportapp.apk in b/78247419 adb shell am broadcast -a launcher-acc --ei cmd 1 Change-Id: I70b0551c517465b3a059ff7d0641c27f71e8114e
This commit is contained in:
@@ -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:
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -639,6 +639,9 @@ class ActivityStack<T extends StackWindowController> 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 */);
|
||||
|
||||
Reference in New Issue
Block a user