diff --git a/services/core/java/com/android/server/wm/DockedStackDividerController.java b/services/core/java/com/android/server/wm/DockedStackDividerController.java index 6741aba35f3c3..68ea4df0c0b0d 100644 --- a/services/core/java/com/android/server/wm/DockedStackDividerController.java +++ b/services/core/java/com/android/server/wm/DockedStackDividerController.java @@ -41,6 +41,8 @@ import android.view.animation.Interpolator; import com.android.server.wm.DimLayer.DimLayerUser; +import java.util.ArrayList; + /** * Keeps information about the docked stack divider. */ @@ -87,7 +89,7 @@ public class DockedStackDividerController implements DimLayerUser { private final DimLayer mDimLayer; private boolean mMinimizedDock; - private boolean mAnimating; + private boolean mAnimatingForMinimizedDockedStack; private boolean mAnimationStarted; private long mAnimationStartTime; private float mAnimationStart; @@ -96,7 +98,8 @@ public class DockedStackDividerController implements DimLayerUser { private final Interpolator mMinimizedDockInterpolator; private float mMaximizeMeetFraction; private final Rect mTouchRegion = new Rect(); - private boolean mAdjustingForIme; + private boolean mAnimatingForIme; + private boolean mAdjustedForIme; DockedStackDividerController(WindowManagerService service, DisplayContent displayContent) { mService = service; @@ -174,12 +177,11 @@ public class DockedStackDividerController implements DimLayerUser { return mLastVisibility; } - void setAdjustingForIme(boolean adjusting) { - mAdjustingForIme = adjusting; - } - - boolean isAdjustingForIme() { - return mAdjustingForIme; + void setAdjustedForIme(boolean adjusted, boolean animate) { + if (mAdjustedForIme != adjusted) { + mAnimatingForIme = animate; + mAdjustedForIme = adjusted; + } } void positionDockedStackedDivider(Rect frame) { @@ -342,6 +344,7 @@ public class DockedStackDividerController implements DimLayerUser { } mMinimizedDock = minimizedDock; + mAnimatingForIme = false; if (minimizedDock) { if (animate) { startAdjustAnimation(0f, 1f); @@ -358,7 +361,7 @@ public class DockedStackDividerController implements DimLayerUser { } private void startAdjustAnimation(float from, float to) { - mAnimating = true; + mAnimatingForMinimizedDockedStack = true; mAnimationStarted = false; mAnimationStart = from; mAnimationTarget = to; @@ -380,10 +383,45 @@ public class DockedStackDividerController implements DimLayerUser { } public boolean animate(long now) { - if (!mAnimating) { + if (mAnimatingForMinimizedDockedStack) { + return animateForMinimizedDockedStack(now); + } else if (mAnimatingForIme) { + return animateForIme(); + } else { return false; } + } + private boolean animateForIme() { + boolean updated = false; + boolean animating = false; + + final ArrayList stacks = mDisplayContent.getStacks(); + for (int i = stacks.size() - 1; i >= 0; --i) { + final TaskStack stack = stacks.get(i); + if (stack != null && stack.isAdjustedForIme()) { + updated |= stack.updateAdjustForIme(); + animating |= stack.isAnimatingForIme(); + } + } + + if (updated) { + mService.mWindowPlacerLocked.performSurfacePlacement(); + } + + if (!animating) { + mAnimatingForIme = false; + for (int i = stacks.size() - 1; i >= 0; --i) { + final TaskStack stack = stacks.get(i); + if (stack != null) { + stack.clearImeGoingAway(); + } + } + } + return animating; + } + + private boolean animateForMinimizedDockedStack(long now) { final TaskStack stack = mDisplayContent.getDockedStackVisibleForUserLocked(); if (!mAnimationStarted) { mAnimationStarted = true; @@ -406,7 +444,7 @@ public class DockedStackDividerController implements DimLayerUser { } } if (t >= 1.0f) { - mAnimating = false; + mAnimatingForMinimizedDockedStack = false; return false; } else { return true; diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java index 8d67771e0bff1..0bf7102ddeb87 100644 --- a/services/core/java/com/android/server/wm/TaskStack.java +++ b/services/core/java/com/android/server/wm/TaskStack.java @@ -55,6 +55,11 @@ public class TaskStack implements DimLayer.DimLayerUser, // If the stack should be resized to fullscreen. private static final boolean FULLSCREEN = true; + // When we have a top-bottom split screen, we shift the bottom stack up to accommodate + // the IME window. The static flag below controls whether to run animation when the + // IME window goes away. + private static final boolean ANIMATE_IME_GOING_AWAY = false; + /** Unique identifier */ final int mStackId; @@ -107,6 +112,7 @@ public class TaskStack implements DimLayer.DimLayerUser, private final Rect mLastContentBounds = new Rect(); private final Rect mTmpAdjustedBounds = new Rect(); private boolean mAdjustedForIme; + private boolean mImeGoingAway; private WindowState mImeWin; private float mMinimizeAmount; private final int mDockedStackMinimizeThickness; @@ -796,19 +802,54 @@ public class TaskStack implements DimLayer.DimLayerUser, void setAdjustedForIme(WindowState imeWin) { mAdjustedForIme = true; mImeWin = imeWin; - if (updateAdjustedBounds()) { - getDisplayContent().mDividerControllerLocked.setAdjustingForIme(true); + mImeGoingAway = false; + } + + boolean isAdjustedForIme() { + return mAdjustedForIme || mImeGoingAway; + } + void clearImeGoingAway() { + mImeGoingAway = false; + } + + boolean isAnimatingForIme() { + return mImeWin != null && mImeWin.isAnimatingLw(); + } + + /** + * Update the stack's bounds (crop or position) according to the IME window's + * current position. When IME window is animated, the bottom stack is animated + * together to track the IME window's current position, and the top stack is + * cropped as necessary. + * + * @return true if a traversal should be performed after the adjustment. + */ + boolean updateAdjustForIme() { + boolean stopped = false; + if (mImeGoingAway && (!ANIMATE_IME_GOING_AWAY || !isAnimatingForIme())) { + mImeWin = null; + mAdjustedForIme = false; + stopped = true; } + // Make sure to run a traversal when the animation stops so that the stack + // is moved to its final position. + return updateAdjustedBounds() || stopped; } /** * Resets the adjustment after it got adjusted for the IME. + * @param adjustBoundsNow if true, reset and update the bounds immediately and forget about + * animations; otherwise, set flag and animates the window away together + * with IME window. */ - void resetAdjustedForIme() { - mAdjustedForIme = false; - mImeWin = null; - if (updateAdjustedBounds()) { - getDisplayContent().mDividerControllerLocked.setAdjustingForIme(true); + void resetAdjustedForIme(boolean adjustBoundsNow) { + if (adjustBoundsNow) { + mImeWin = null; + mAdjustedForIme = false; + mImeGoingAway = false; + updateAdjustedBounds(); + } else { + mImeGoingAway |= mAdjustedForIme; } } @@ -843,6 +884,12 @@ public class TaskStack implements DimLayer.DimLayerUser, getDisplayContent().getContentRect(displayContentRect); contentBounds.set(displayContentRect); int imeTop = Math.max(imeWin.getDisplayFrameLw().top, contentBounds.top); + + // if IME window is animating, get its actual vertical shown position (but no smaller than + // the final target vertical position) + if (imeWin.isAnimatingLw()) { + imeTop = Math.max(imeTop, imeWin.getShownPositionLw().y); + } imeTop += imeWin.getGivenContentInsetsLw().top; if (contentBounds.bottom > imeTop) { contentBounds.bottom = imeTop; diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 5d13b3b38c842..6d350b038ca2c 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -7380,8 +7380,9 @@ public class WindowManagerService extends IWindowManager.Stub final WindowState imeWin = mInputMethodWindow; final TaskStack focusedStack = mCurrentFocus != null ? mCurrentFocus.getStack() : null; + final boolean dockVisible = isStackVisibleLocked(DOCKED_STACK_ID); if (imeWin != null && imeWin.isVisibleLw() && imeWin.isDisplayedLw() - && isStackVisibleLocked(DOCKED_STACK_ID) + && dockVisible && focusedStack != null && focusedStack.getDockSide() == DOCKED_BOTTOM){ final ArrayList stacks = displayContent.getStacks(); @@ -7391,12 +7392,14 @@ public class WindowManagerService extends IWindowManager.Stub stack.setAdjustedForIme(imeWin); } } + displayContent.mDividerControllerLocked.setAdjustedForIme(true, true); } else { final ArrayList stacks = displayContent.getStacks(); for (int i = stacks.size() - 1; i >= 0; --i) { final TaskStack stack = stacks.get(i); - stack.resetAdjustedForIme(); + stack.resetAdjustedForIme(!dockVisible); } + displayContent.mDividerControllerLocked.setAdjustedForIme(false, dockVisible); } } diff --git a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java index 3b0081d6376f3..3e5ddbce5a7b3 100644 --- a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java +++ b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java @@ -693,16 +693,14 @@ class WindowSurfacePlacer { // currently animating... let's do something. final int left = w.mFrame.left; final int top = w.mFrame.top; - final boolean adjustedForMinimizedDockedStack = w.getTask() != null && - w.getTask().mStack.isAdjustedForMinimizedDockedStack(); + final boolean adjustedForMinimizedDockOrIme = task != null + && (task.mStack.isAdjustedForMinimizedDockedStack() + || task.mStack.isAdjustedForIme()); if ((w.mAttrs.privateFlags & PRIVATE_FLAG_NO_MOVE_ANIMATION) == 0 - && !w.isDragResizing() && !adjustedForMinimizedDockedStack + && !w.isDragResizing() && !adjustedForMinimizedDockOrIme && (task == null || !w.getTask().mStack.getFreezeMovementAnimations()) && !w.mWinAnimator.mLastHidden) { winAnimator.setMoveAnimation(left, top); - } else if (w.mAttrs.type == TYPE_DOCK_DIVIDER && - displayContent.getDockedDividerController().isAdjustingForIme()) { - winAnimator.setMoveAnimation(left, top); } //TODO (multidisplay): Accessibility supported only for the default display. @@ -819,8 +817,6 @@ class WindowSurfacePlacer { mService.updateResizingWindows(w); } - displayContent.getDockedDividerController().setAdjustingForIme(false); - mService.mDisplayManagerInternal.setDisplayProperties(displayId, mDisplayHasContent, mPreferredRefreshRate,