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

Commit baba7831 authored by Chong Zhang's avatar Chong Zhang
Browse files

Animate IME adjustment for docked stack through the divider

This makes sure the top stack crop, divider position and bottom stack
surface position moves together with the IME window. Currently the
bottom stack and divider are moving together but top stack crop is
changed immediately.

bug: 27779495
Change-Id: I653ad9093621b218d9c11b0bb2efdddb1d33763e
parent a17893b0
Loading
Loading
Loading
Loading
+49 −11
Original line number Diff line number Diff line
@@ -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;
    void setAdjustedForIme(boolean adjusted, boolean animate) {
        if (mAdjustedForIme != adjusted) {
            mAnimatingForIme = animate;
            mAdjustedForIme = adjusted;
        }

    boolean isAdjustingForIme() {
        return mAdjustingForIme;
    }

    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<TaskStack> 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;
+54 −7
Original line number Diff line number Diff line
@@ -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();
    }

    /**
     * Resets the adjustment after it got adjusted for the IME.
     * 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.
     */
    void resetAdjustedForIme() {
    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(boolean adjustBoundsNow) {
        if (adjustBoundsNow) {
            mImeWin = null;
        if (updateAdjustedBounds()) {
            getDisplayContent().mDividerControllerLocked.setAdjustingForIme(true);
            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;
+5 −2
Original line number Diff line number Diff line
@@ -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<TaskStack> stacks = displayContent.getStacks();
@@ -7391,12 +7392,14 @@ public class WindowManagerService extends IWindowManager.Stub
                    stack.setAdjustedForIme(imeWin);
                }
            }
            displayContent.mDividerControllerLocked.setAdjustedForIme(true, true);
        } else {
            final ArrayList<TaskStack> 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);
        }
    }

+4 −8
Original line number Diff line number Diff line
@@ -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,