diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java b/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java index ea5ec05030675..63bd076924fa8 100644 --- a/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java +++ b/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java @@ -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); diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java index 4114bb9d055da..0d6403d94515f 100644 --- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java +++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java @@ -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 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;