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

Commit c0eec05e authored by Evan Rosky's avatar Evan Rosky
Browse files

Fix up interractions between Adjust for IME and minimize

These aren't compatible at the moment, but at the very least
prevent them from running at the same time so that switching between
secondary adjusted to recents works.

This works by augmenting the divider's ime handling with a paused
state. When paused, it will keep track of ime changes, but it won't
apply them to the divider until it's resumed.

Despite this, the interraction is still quite glitchy, but at least
it ends up in the right end-states. A full fix for this will require
a significant rewrite of the whole DividerView's bounds handling.

Bug: 150781668
Test: Open 2 apps in splits. show IME in secondary, then swipe-up
      to recents. While not perfect, it should work.
Change-Id: I4e7a6b9ed04b38edb83655b2326de4448124b904
parent a8375cc9
Loading
Loading
Loading
Loading
+57 −8
Original line number Diff line number Diff line
@@ -173,6 +173,9 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks,
        @Nullable
        private ValueAnimator mAnimation = null;

        private boolean mPaused = true;
        private boolean mPausedTargetAdjusted = false;

        private boolean getSecondaryHasFocus(int displayId) {
            try {
                IWindowContainer imeSplit = ActivityTaskManager.getTaskOrganizerController()
@@ -185,6 +188,14 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks,
            return false;
        }

        private void updateDimTargets() {
            final boolean splitIsVisible = !mView.isHidden();
            mTargetPrimaryDim = (mSecondaryHasFocus && mTargetShown && splitIsVisible)
                    ? ADJUSTED_NONFOCUS_DIM : 0.f;
            mTargetSecondaryDim = (!mSecondaryHasFocus && mTargetShown && splitIsVisible)
                    ? ADJUSTED_NONFOCUS_DIM : 0.f;
        }

        @Override
        public void onImeStartPositioning(int displayId, int hiddenTop, int shownTop,
                boolean imeShouldShow, SurfaceControl.Transaction t) {
@@ -193,7 +204,7 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks,
            }
            final boolean splitIsVisible = !mView.isHidden();
            mSecondaryHasFocus = getSecondaryHasFocus(displayId);
            mTargetAdjusted = splitIsVisible && imeShouldShow && mSecondaryHasFocus
            final boolean targetAdjusted = splitIsVisible && imeShouldShow && mSecondaryHasFocus
                    && !mSplitLayout.mDisplayLayout.isLandscape();
            mHiddenTop = hiddenTop;
            mShownTop = shownTop;
@@ -201,10 +212,12 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks,
            if (mLastAdjustTop < 0) {
                mLastAdjustTop = imeShouldShow ? hiddenTop : shownTop;
            }
            mTargetPrimaryDim = (mSecondaryHasFocus && mTargetShown && splitIsVisible)
                    ? ADJUSTED_NONFOCUS_DIM : 0.f;
            mTargetSecondaryDim = (!mSecondaryHasFocus && mTargetShown && splitIsVisible)
                    ? ADJUSTED_NONFOCUS_DIM : 0.f;
            if (mPaused) {
                mPausedTargetAdjusted = targetAdjusted;
                return;
            }
            mTargetAdjusted = targetAdjusted;
            updateDimTargets();
            if (mAnimation != null || (mImeWasShown && imeShouldShow
                    && mTargetAdjusted != mAdjusted)) {
                // We need to animate adjustment independently of the IME position, so
@@ -259,7 +272,7 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks,
        @Override
        public void onImePositionChanged(int displayId, int imeTop,
                SurfaceControl.Transaction t) {
            if (mAnimation != null || !inSplitMode()) {
            if (mAnimation != null || !inSplitMode() || mPaused) {
                // Not synchronized with IME anymore, so return.
                return;
            }
@@ -271,7 +284,7 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks,
        @Override
        public void onImeEndPositioning(int displayId, boolean cancelled,
                SurfaceControl.Transaction t) {
            if (mAnimation != null || !inSplitMode()) {
            if (mAnimation != null || !inSplitMode() || mPaused) {
                // Not synchronized with IME anymore, so return.
                return;
            }
@@ -279,7 +292,7 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks,
        }

        private void onProgress(float progress, SurfaceControl.Transaction t) {
            if (mTargetAdjusted != mAdjusted) {
            if (mTargetAdjusted != mAdjusted && !mPaused) {
                final float fraction = mTargetAdjusted ? progress : 1.f - progress;
                mLastAdjustTop = (int) (fraction * mShownTop + (1.f - fraction) * mHiddenTop);
                mSplitLayout.updateAdjustedBounds(mLastAdjustTop, mHiddenTop, mShownTop);
@@ -342,6 +355,32 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks,
            });
            mAnimation.start();
        }

        /** Completely aborts/resets adjustment state */
        public void pause(int displayId) {
            mHandler.post(() -> {
                mPaused = true;
                mPausedTargetAdjusted = mTargetAdjusted;
                mTargetAdjusted = false;
                mTargetPrimaryDim = mTargetSecondaryDim = 0.f;
                updateImeAdjustState();
                startAsyncAnimation();
            });
        }

        public void resume(int displayId) {
            mHandler.post(() -> {
                mPaused = false;
                mTargetAdjusted = mPausedTargetAdjusted;
                updateDimTargets();
                if (mTargetAdjusted && mView != null) {
                    // End unminimize animations since they conflict with adjustment animations.
                    mView.finishAnimations();
                }
                updateImeAdjustState();
                startAsyncAnimation();
            });
        }
    }
    private final DividerImeController mImePositionProcessor = new DividerImeController();

@@ -544,7 +583,17 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks,

        // Sync state to DividerView if it exists.
        if (mView != null) {
            final int displayId = mView.getDisplay() != null
                    ? mView.getDisplay().getDisplayId() : DEFAULT_DISPLAY;
            // pause ime here (before updateMinimizedDockedStack)
            if (mMinimized) {
                mImePositionProcessor.pause(displayId);
            }
            mView.setMinimizedDockStack(minimized, getAnimDuration(), homeStackResizable);
            if (!mMinimized) {
                // afterwards so it can end any animations started in view
                mImePositionProcessor.resume(displayId);
            }
        }
        updateTouchable();
        WindowManagerProxy.applyContainerTransaction(wct);
+22 −18
Original line number Diff line number Diff line
@@ -67,6 +67,8 @@ import com.android.systemui.R;
import com.android.systemui.shared.system.WindowManagerWrapper;
import com.android.systemui.statusbar.FlingAnimationUtils;

import java.util.function.Consumer;

/**
 * Docked stack divider.
 */
@@ -634,16 +636,20 @@ public class DividerView extends FrameLayout implements OnTouchListener,
                        ? TASK_POSITION_SAME
                        : snapTarget.taskPosition,
                snapTarget));
        Runnable endAction = () -> {
        Consumer<Boolean> endAction = cancelled -> {
            final boolean wasMinimizeInteraction = mIsInMinimizeInteraction;
            // Reset minimized divider position after unminimized state animation finishes.
            if (!cancelled && !mDockedStackMinimized && mIsInMinimizeInteraction) {
                mIsInMinimizeInteraction = false;
            }
            boolean dismissed = commitSnapFlags(snapTarget);
            mWindowManagerProxy.setResizing(false);
            updateDockSide();
            mCurrentAnimator = null;
            mEntranceAnimationRunning = false;
            mExitAnimationRunning = false;
            if (!dismissed) {
                WindowManagerProxy.applyResizeSplits((mIsInMinimizeInteraction
                        ? mSnapTargetBeforeMinimized : snapTarget).position, mSplitLayout);
            if (!dismissed && !wasMinimizeInteraction) {
                WindowManagerProxy.applyResizeSplits(snapTarget.position, mSplitLayout);
            }
            if (mCallback != null) {
                mCallback.onDraggingEnd();
@@ -667,12 +673,6 @@ public class DividerView extends FrameLayout implements OnTouchListener,
                }
            }
        };
        Runnable notCancelledEndAction = () -> {
            // Reset minimized divider position after unminimized state animation finishes
            if (!mDockedStackMinimized && mIsInMinimizeInteraction) {
                mIsInMinimizeInteraction = false;
            }
        };
        anim.addListener(new AnimatorListenerAdapter() {

            private boolean mCancelled;
@@ -694,15 +694,10 @@ public class DividerView extends FrameLayout implements OnTouchListener,
                    delay = mSfChoreographer.getSurfaceFlingerOffsetMs();
                }
                if (delay == 0) {
                    if (!mCancelled) {
                        notCancelledEndAction.run();
                    }
                    endAction.run();
                    endAction.accept(mCancelled);
                } else {
                    if (!mCancelled) {
                        mHandler.postDelayed(notCancelledEndAction, delay);
                    }
                    mHandler.postDelayed(endAction, delay);
                    final Boolean cancelled = mCancelled;
                    mHandler.postDelayed(() -> endAction.accept(cancelled), delay);
                }
            }
        });
@@ -946,6 +941,15 @@ public class DividerView extends FrameLayout implements OnTouchListener,
                .start();
    }

    // Needed to end any currently playing animations when they might compete with other anims
    // (specifically, IME adjust animation immediately after leaving minimized). Someday maybe
    // these can be unified, but not today.
    void finishAnimations() {
        if (mCurrentAnimator != null) {
            mCurrentAnimator.end();
        }
    }

    public void setAdjustedForIme(boolean adjustedForIme, long animDuration) {
        if (mAdjustedForIme == adjustedForIme) {
            return;