From fae5d6e315fdfa1bd6aaee4b6d64251cbf1d6a0c Mon Sep 17 00:00:00 2001 From: Wale Ogunwale Date: Tue, 10 Mar 2020 13:46:27 +0000 Subject: [PATCH 1/2] Revert "Don't apply ime adjustments/dims if split is not active" Revert submission 10602670 Reason for revert: Breaks WM pre-submit Reverted Changes: I68f1b47e0:Some clean-up of divider code in preparation for b... Ifcac72f0f:Don't apply ime adjustments/dims if split is not a... Bug: 151053107 Change-Id: Ie599188debabc3e58ad37141edaba7fab7f7d8eb --- .../systemui/stackdivider/Divider.java | 36 ++++++++----------- .../systemui/stackdivider/DividerView.java | 14 +------- 2 files changed, 15 insertions(+), 35 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java b/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java index 04d53627d0c67..ce45b03585118 100644 --- a/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java +++ b/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java @@ -148,8 +148,6 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks, * regardless of what has focus. */ private boolean mTargetShown = false; - private float mTargetPrimaryDim = 0.f; - private float mTargetSecondaryDim = 0.f; // The following are the current (most recent) states set during animation /** {@code true} if the secondary split has IME focus. */ @@ -188,12 +186,8 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks, @Override public void onImeStartPositioning(int displayId, int hiddenTop, int shownTop, boolean imeShouldShow, SurfaceControl.Transaction t) { - if (!inSplitMode()) { - return; - } - final boolean splitIsVisible = !mView.isHidden(); mSecondaryHasFocus = getSecondaryHasFocus(displayId); - mTargetAdjusted = splitIsVisible && imeShouldShow && mSecondaryHasFocus + mTargetAdjusted = imeShouldShow && mSecondaryHasFocus && !mSplitLayout.mDisplayLayout.isLandscape(); mHiddenTop = hiddenTop; mShownTop = shownTop; @@ -201,10 +195,6 @@ 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 (mAnimation != null || (mImeWasShown && imeShouldShow && mTargetAdjusted != mAdjusted)) { // We need to animate adjustment independently of the IME position, so @@ -212,11 +202,7 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks, // different split's editor has gained focus while the IME is still visible. startAsyncAnimation(); } - if (splitIsVisible) { - // If split is hidden, we don't want to trigger any relayouts that would cause the - // divider to show again. - updateImeAdjustState(); - } + updateImeAdjustState(); } private void updateImeAdjustState() { @@ -259,7 +245,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) { // Not synchronized with IME anymore, so return. return; } @@ -271,7 +257,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) { // Not synchronized with IME anymore, so return. return; } @@ -287,10 +273,14 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks, mSplitLayout.mAdjustedSecondary); } final float invProg = 1.f - progress; + final float targetPrimaryDim = + (mSecondaryHasFocus && mTargetShown) ? ADJUSTED_NONFOCUS_DIM : 0.f; + final float targetSecondaryDim = + (!mSecondaryHasFocus && mTargetShown) ? ADJUSTED_NONFOCUS_DIM : 0.f; mView.setResizeDimLayer(t, true /* primary */, - mLastPrimaryDim * invProg + progress * mTargetPrimaryDim); + mLastPrimaryDim * invProg + progress * targetPrimaryDim); mView.setResizeDimLayer(t, false /* primary */, - mLastSecondaryDim * invProg + progress * mTargetSecondaryDim); + mLastSecondaryDim * invProg + progress * targetSecondaryDim); } private void onEnd(boolean cancelled, SurfaceControl.Transaction t) { @@ -299,8 +289,10 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks, mAdjusted = mTargetAdjusted; mImeWasShown = mTargetShown; mLastAdjustTop = mAdjusted ? mShownTop : mHiddenTop; - mLastPrimaryDim = mTargetPrimaryDim; - mLastSecondaryDim = mTargetSecondaryDim; + mLastPrimaryDim = + (mSecondaryHasFocus && mTargetShown) ? ADJUSTED_NONFOCUS_DIM : 0.f; + mLastSecondaryDim = + (!mSecondaryHasFocus && mTargetShown) ? ADJUSTED_NONFOCUS_DIM : 0.f; } } diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java index 4114bb9d055da..477cbb7c7ad07 100644 --- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java +++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java @@ -165,10 +165,6 @@ public class DividerView extends FrameLayout implements OnTouchListener, // The view is removed or in the process of been removed from the system. private boolean mRemoved; - // Whether the surface for this view has been hidden regardless of actual visibility. This is - // used interact with keyguard. - private boolean mSurfaceHidden = false; - private final Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { @@ -418,10 +414,6 @@ public class DividerView extends FrameLayout implements OnTouchListener, /** Unlike setVisible, this directly hides the surface without changing view visibility. */ void setHidden(boolean hidden) { - if (mSurfaceHidden == hidden) { - return; - } - mSurfaceHidden = hidden; post(() -> { final SurfaceControl sc = getWindowSurfaceControl(); if (sc == null) { @@ -438,10 +430,6 @@ public class DividerView extends FrameLayout implements OnTouchListener, }); } - boolean isHidden() { - return mSurfaceHidden; - } - public boolean startDragging(boolean animate, boolean touching) { cancelFlingAnimation(); if (touching) { @@ -1083,7 +1071,7 @@ public class DividerView extends FrameLayout implements OnTouchListener, void setResizeDimLayer(Transaction t, boolean primary, float alpha) { SurfaceControl dim = primary ? mTiles.mPrimaryDim : mTiles.mSecondaryDim; - if (alpha <= 0.001f) { + if (alpha <= 0.f) { t.hide(dim); } else { t.setAlpha(dim, alpha); From 91ac7d79c515fea486e2fbc33383f981363ae118 Mon Sep 17 00:00:00 2001 From: Wale Ogunwale Date: Tue, 10 Mar 2020 13:46:27 +0000 Subject: [PATCH 2/2] Revert "Some clean-up of divider code in preparation for bugfixes" Revert submission 10602670 Reason for revert: Breaks WM pre-submit Reverted Changes: I68f1b47e0:Some clean-up of divider code in preparation for b... Ifcac72f0f:Don't apply ime adjustments/dims if split is not a... Bug: 150781668 Change-Id: I8a497b395f25865b476590c3c0cb98133b94ac8e --- .../systemui/stackdivider/Divider.java | 495 +++++++++--------- .../stackdivider/DividerWindowManager.java | 3 - .../stackdivider/WindowManagerProxy.java | 21 +- 3 files changed, 275 insertions(+), 244 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java b/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java index ce45b03585118..c6eecf260dac1 100644 --- a/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java +++ b/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java @@ -129,213 +129,217 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks, } }; - private class DividerImeController implements DisplayImeController.ImePositionProcessor { - /** - * These are the y positions of the top of the IME surface when it is hidden and when it is - * shown respectively. These are NOT necessarily the top of the visible IME itself. - */ - private int mHiddenTop = 0; - private int mShownTop = 0; + private DisplayImeController.ImePositionProcessor mImePositionProcessor = + new DisplayImeController.ImePositionProcessor() { + /** + * These are the y positions of the top of the IME surface when it is hidden and + * when it is shown respectively. These are NOT necessarily the top of the visible + * IME itself. + */ + private int mHiddenTop = 0; + private int mShownTop = 0; - // The following are target states (what we are curretly animating towards). - /** - * {@code true} if, at the end of the animation, the split task positions should be - * adjusted by height of the IME. This happens when the secondary split is the IME target. - */ - private boolean mTargetAdjusted = false; - /** - * {@code true} if, at the end of the animation, the IME should be shown/visible - * regardless of what has focus. - */ - private boolean mTargetShown = false; + // The following are target states (what we are curretly animating towards). + /** + * {@code true} if, at the end of the animation, the split task positions should be + * adjusted by height of the IME. This happens when the secondary split is the IME + * target. + */ + private boolean mTargetAdjusted = false; + /** + * {@code true} if, at the end of the animation, the IME should be shown/visible + * regardless of what has focus. + */ + private boolean mTargetShown = false; - // The following are the current (most recent) states set during animation - /** {@code true} if the secondary split has IME focus. */ - private boolean mSecondaryHasFocus = false; - /** The dimming currently applied to the primary/secondary splits. */ - private float mLastPrimaryDim = 0.f; - private float mLastSecondaryDim = 0.f; - /** The most recent y position of the top of the IME surface */ - private int mLastAdjustTop = -1; + // The following are the current (most recent) states set during animation + /** + * {@code true} if the secondary split has IME focus. + */ + private boolean mSecondaryHasFocus = false; + /** The dimming currently applied to the primary/secondary splits. */ + private float mLastPrimaryDim = 0.f; + private float mLastSecondaryDim = 0.f; + /** The most recent y position of the top of the IME surface */ + private int mLastAdjustTop = -1; - // The following are states reached last time an animation fully completed. - /** {@code true} if the IME was shown/visible by the last-completed animation. */ - private boolean mImeWasShown = false; - /** {@code true} if the split positions were adjusted by the last-completed animation. */ - private boolean mAdjusted = false; + // The following are states reached last time an animation fully completed. + /** {@code true} if the IME was shown/visible by the last-completed animation. */ + private boolean mImeWasShown = false; + /** + * {@code true} if the split positions were adjusted by the last-completed + * animation. + */ + private boolean mAdjusted = false; - /** - * When some aspect of split-screen needs to animate independent from the IME, - * this will be non-null and control split animation. - */ - @Nullable - private ValueAnimator mAnimation = null; + /** + * When some aspect of split-screen needs to animate independent from the IME, + * this will be non-null and control split animation. + */ + @Nullable + private ValueAnimator mAnimation = null; - private boolean getSecondaryHasFocus(int displayId) { - try { - IWindowContainer imeSplit = ActivityTaskManager.getTaskOrganizerController() - .getImeTarget(displayId); - return imeSplit != null - && (imeSplit.asBinder() == mSplits.mSecondary.token.asBinder()); - } catch (RemoteException e) { - Slog.w(TAG, "Failed to get IME target", e); - } - return false; - } - - @Override - public void onImeStartPositioning(int displayId, int hiddenTop, int shownTop, - boolean imeShouldShow, SurfaceControl.Transaction t) { - mSecondaryHasFocus = getSecondaryHasFocus(displayId); - mTargetAdjusted = imeShouldShow && mSecondaryHasFocus - && !mSplitLayout.mDisplayLayout.isLandscape(); - mHiddenTop = hiddenTop; - mShownTop = shownTop; - mTargetShown = imeShouldShow; - if (mLastAdjustTop < 0) { - mLastAdjustTop = imeShouldShow ? hiddenTop : shownTop; - } - if (mAnimation != null || (mImeWasShown && imeShouldShow - && mTargetAdjusted != mAdjusted)) { - // We need to animate adjustment independently of the IME position, so - // start our own animation to drive adjustment. This happens when a - // different split's editor has gained focus while the IME is still visible. - startAsyncAnimation(); - } - updateImeAdjustState(); - } - - private void updateImeAdjustState() { - // Reposition the server's secondary split position so that it evaluates - // insets properly. - WindowContainerTransaction wct = new WindowContainerTransaction(); - if (mTargetAdjusted) { - mSplitLayout.updateAdjustedBounds(mShownTop, mHiddenTop, mShownTop); - wct.setBounds(mSplits.mSecondary.token, mSplitLayout.mAdjustedSecondary); - // "Freeze" the configuration size so that the app doesn't get a config - // or relaunch. This is required because normally nav-bar contributes - // to configuration bounds (via nondecorframe). - Rect adjustAppBounds = new Rect(mSplits.mSecondary.configuration - .windowConfiguration.getAppBounds()); - adjustAppBounds.offset(0, mSplitLayout.mAdjustedSecondary.top - - mSplitLayout.mSecondary.top); - wct.setAppBounds(mSplits.mSecondary.token, adjustAppBounds); - wct.setScreenSizeDp(mSplits.mSecondary.token, - mSplits.mSecondary.configuration.screenWidthDp, - mSplits.mSecondary.configuration.screenHeightDp); - } else { - wct.setBounds(mSplits.mSecondary.token, mSplitLayout.mSecondary); - wct.setAppBounds(mSplits.mSecondary.token, null); - wct.setScreenSizeDp(mSplits.mSecondary.token, - SCREEN_WIDTH_DP_UNDEFINED, SCREEN_HEIGHT_DP_UNDEFINED); - } - try { - ActivityTaskManager.getTaskOrganizerController() - .applyContainerTransaction(wct, null /* organizer */); - } catch (RemoteException e) { - } - - // Update all the adjusted-for-ime states - mView.setAdjustedForIme(mTargetShown, mTargetShown - ? DisplayImeController.ANIMATION_DURATION_SHOW_MS - : DisplayImeController.ANIMATION_DURATION_HIDE_MS); - setAdjustedForIme(mTargetShown); - } - - @Override - public void onImePositionChanged(int displayId, int imeTop, - SurfaceControl.Transaction t) { - if (mAnimation != null) { - // Not synchronized with IME anymore, so return. - return; - } - final float fraction = ((float) imeTop - mHiddenTop) / (mShownTop - mHiddenTop); - final float progress = mTargetShown ? fraction : 1.f - fraction; - onProgress(progress, t); - } - - @Override - public void onImeEndPositioning(int displayId, boolean cancelled, - SurfaceControl.Transaction t) { - if (mAnimation != null) { - // Not synchronized with IME anymore, so return. - return; - } - onEnd(cancelled, t); - } - - private void onProgress(float progress, SurfaceControl.Transaction t) { - if (mTargetAdjusted != mAdjusted) { - final float fraction = mTargetAdjusted ? progress : 1.f - progress; - mLastAdjustTop = (int) (fraction * mShownTop + (1.f - fraction) * mHiddenTop); - mSplitLayout.updateAdjustedBounds(mLastAdjustTop, mHiddenTop, mShownTop); - mView.resizeSplitSurfaces(t, mSplitLayout.mAdjustedPrimary, - mSplitLayout.mAdjustedSecondary); - } - final float invProg = 1.f - progress; - final float targetPrimaryDim = - (mSecondaryHasFocus && mTargetShown) ? ADJUSTED_NONFOCUS_DIM : 0.f; - final float targetSecondaryDim = - (!mSecondaryHasFocus && mTargetShown) ? ADJUSTED_NONFOCUS_DIM : 0.f; - mView.setResizeDimLayer(t, true /* primary */, - mLastPrimaryDim * invProg + progress * targetPrimaryDim); - mView.setResizeDimLayer(t, false /* primary */, - mLastSecondaryDim * invProg + progress * targetSecondaryDim); - } - - private void onEnd(boolean cancelled, SurfaceControl.Transaction t) { - if (!cancelled) { - onProgress(1.f, t); - mAdjusted = mTargetAdjusted; - mImeWasShown = mTargetShown; - mLastAdjustTop = mAdjusted ? mShownTop : mHiddenTop; - mLastPrimaryDim = - (mSecondaryHasFocus && mTargetShown) ? ADJUSTED_NONFOCUS_DIM : 0.f; - mLastSecondaryDim = - (!mSecondaryHasFocus && mTargetShown) ? ADJUSTED_NONFOCUS_DIM : 0.f; - } - } - - private void startAsyncAnimation() { - if (mAnimation != null) { - mAnimation.cancel(); - } - mAnimation = ValueAnimator.ofFloat(0.f, 1.f); - mAnimation.setDuration(DisplayImeController.ANIMATION_DURATION_SHOW_MS); - if (mTargetAdjusted != mAdjusted) { - final float fraction = - ((float) mLastAdjustTop - mHiddenTop) / (mShownTop - mHiddenTop); - final float progress = mTargetAdjusted ? fraction : 1.f - fraction; - mAnimation.setCurrentFraction(progress); - } - - mAnimation.addUpdateListener(animation -> { - SurfaceControl.Transaction t = mTransactionPool.acquire(); - float value = (float) animation.getAnimatedValue(); - onProgress(value, t); - t.apply(); - mTransactionPool.release(t); - }); - mAnimation.setInterpolator(DisplayImeController.INTERPOLATOR); - mAnimation.addListener(new AnimatorListenerAdapter() { - private boolean mCancel = false; - @Override - public void onAnimationCancel(Animator animation) { - mCancel = true; + private boolean getSecondaryHasFocus(int displayId) { + try { + IWindowContainer imeSplit = ActivityTaskManager.getTaskOrganizerController() + .getImeTarget(displayId); + return imeSplit != null + && (imeSplit.asBinder() == mSplits.mSecondary.token.asBinder()); + } catch (RemoteException e) { + Slog.w(TAG, "Failed to get IME target", e); + } + return false; } + @Override - public void onAnimationEnd(Animator animation) { - SurfaceControl.Transaction t = mTransactionPool.acquire(); - onEnd(mCancel, t); - t.apply(); - mTransactionPool.release(t); - mAnimation = null; + public void onImeStartPositioning(int displayId, int hiddenTop, int shownTop, + boolean imeShouldShow, SurfaceControl.Transaction t) { + mSecondaryHasFocus = getSecondaryHasFocus(displayId); + mTargetAdjusted = imeShouldShow && mSecondaryHasFocus + && !mSplitLayout.mDisplayLayout.isLandscape(); + mHiddenTop = hiddenTop; + mShownTop = shownTop; + mTargetShown = imeShouldShow; + if (mLastAdjustTop < 0) { + mLastAdjustTop = imeShouldShow ? hiddenTop : shownTop; + } + if (mAnimation != null || (mImeWasShown && imeShouldShow + && mTargetAdjusted != mAdjusted)) { + // We need to animate adjustment independently of the IME position, so + // start our own animation to drive adjustment. This happens when a + // different split's editor has gained focus while the IME is still visible. + startAsyncAnimation(); + } + // Reposition the server's secondary split position so that it evaluates + // insets properly. + WindowContainerTransaction wct = new WindowContainerTransaction(); + if (mTargetAdjusted) { + mSplitLayout.updateAdjustedBounds(mShownTop, mHiddenTop, mShownTop); + wct.setBounds(mSplits.mSecondary.token, mSplitLayout.mAdjustedSecondary); + // "Freeze" the configuration size so that the app doesn't get a config + // or relaunch. This is required because normally nav-bar contributes + // to configuration bounds (via nondecorframe). + Rect adjustAppBounds = new Rect(mSplits.mSecondary.configuration + .windowConfiguration.getAppBounds()); + adjustAppBounds.offset(0, mSplitLayout.mAdjustedSecondary.top + - mSplitLayout.mSecondary.top); + wct.setAppBounds(mSplits.mSecondary.token, adjustAppBounds); + wct.setScreenSizeDp(mSplits.mSecondary.token, + mSplits.mSecondary.configuration.screenWidthDp, + mSplits.mSecondary.configuration.screenHeightDp); + } else { + wct.setBounds(mSplits.mSecondary.token, mSplitLayout.mSecondary); + wct.setAppBounds(mSplits.mSecondary.token, null); + wct.setScreenSizeDp(mSplits.mSecondary.token, + SCREEN_WIDTH_DP_UNDEFINED, SCREEN_HEIGHT_DP_UNDEFINED); + } + try { + ActivityTaskManager.getTaskOrganizerController() + .applyContainerTransaction(wct, null /* organizer */); + } catch (RemoteException e) { + } + + // Update all the adjusted-for-ime states + mView.setAdjustedForIme(mTargetShown, mTargetShown + ? DisplayImeController.ANIMATION_DURATION_SHOW_MS + : DisplayImeController.ANIMATION_DURATION_HIDE_MS); + setAdjustedForIme(mTargetShown); } - }); - mAnimation.start(); - } - } - private final DividerImeController mImePositionProcessor = new DividerImeController(); + + @Override + public void onImePositionChanged(int displayId, int imeTop, + SurfaceControl.Transaction t) { + if (mAnimation != null) { + // Not synchronized with IME anymore, so return. + return; + } + final float fraction = ((float) imeTop - mHiddenTop) / (mShownTop - mHiddenTop); + final float progress = mTargetShown ? fraction : 1.f - fraction; + onProgress(progress, t); + } + + @Override + public void onImeEndPositioning(int displayId, boolean cancelled, + SurfaceControl.Transaction t) { + if (mAnimation != null) { + // Not synchronized with IME anymore, so return. + return; + } + onEnd(cancelled, t); + } + + private void onProgress(float progress, SurfaceControl.Transaction t) { + if (mTargetAdjusted != mAdjusted) { + final float fraction = mTargetAdjusted ? progress : 1.f - progress; + mLastAdjustTop = + (int) (fraction * mShownTop + (1.f - fraction) * mHiddenTop); + mSplitLayout.updateAdjustedBounds(mLastAdjustTop, mHiddenTop, mShownTop); + mView.resizeSplitSurfaces(t, mSplitLayout.mAdjustedPrimary, + mSplitLayout.mAdjustedSecondary); + } + final float invProg = 1.f - progress; + final float targetPrimaryDim = (mSecondaryHasFocus && mTargetShown) + ? ADJUSTED_NONFOCUS_DIM : 0.f; + final float targetSecondaryDim = (!mSecondaryHasFocus && mTargetShown) + ? ADJUSTED_NONFOCUS_DIM : 0.f; + mView.setResizeDimLayer(t, true /* primary */, + mLastPrimaryDim * invProg + progress * targetPrimaryDim); + mView.setResizeDimLayer(t, false /* primary */, + mLastSecondaryDim * invProg + progress * targetSecondaryDim); + } + + private void onEnd(boolean cancelled, SurfaceControl.Transaction t) { + if (!cancelled) { + onProgress(1.f, t); + mAdjusted = mTargetAdjusted; + mImeWasShown = mTargetShown; + mLastAdjustTop = mAdjusted ? mShownTop : mHiddenTop; + mLastPrimaryDim = + (mSecondaryHasFocus && mTargetShown) ? ADJUSTED_NONFOCUS_DIM : 0.f; + mLastSecondaryDim = + (!mSecondaryHasFocus && mTargetShown) ? ADJUSTED_NONFOCUS_DIM : 0.f; + } + } + + private void startAsyncAnimation() { + if (mAnimation != null) { + mAnimation.cancel(); + } + mAnimation = ValueAnimator.ofFloat(0.f, 1.f); + mAnimation.setDuration(DisplayImeController.ANIMATION_DURATION_SHOW_MS); + if (mTargetAdjusted != mAdjusted) { + final float fraction = + ((float) mLastAdjustTop - mHiddenTop) / (mShownTop - mHiddenTop); + final float progress = mTargetAdjusted ? fraction : 1.f - fraction; + mAnimation.setCurrentFraction(progress); + } + + mAnimation.addUpdateListener(animation -> { + SurfaceControl.Transaction t = mTransactionPool.acquire(); + float value = (float) animation.getAnimatedValue(); + onProgress(value, t); + t.apply(); + mTransactionPool.release(t); + }); + mAnimation.setInterpolator(DisplayImeController.INTERPOLATOR); + mAnimation.addListener(new AnimatorListenerAdapter() { + private boolean mCancel = false; + @Override + public void onAnimationCancel(Animator animation) { + mCancel = true; + } + @Override + public void onAnimationEnd(Animator animation) { + SurfaceControl.Transaction t = mTransactionPool.acquire(); + onEnd(mCancel, t); + t.apply(); + mTransactionPool.release(t); + mAnimation = null; + } + }); + mAnimation.start(); + } + }; public Divider(Context context, Optional> recentsOptionalLazy, DisplayController displayController, SystemWindows systemWindows, @@ -509,43 +513,42 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks, } } + private void setHomeStackResizable(boolean resizable) { + if (mHomeStackResizable == resizable) { + return; + } + mHomeStackResizable = resizable; + if (!inSplitMode()) { + return; + } + WindowManagerProxy.applyHomeTasksMinimized(mSplitLayout, mSplits.mSecondary.token); + } + + private void updateMinimizedDockedStack(final boolean minimized, final long animDuration, + final boolean isHomeStackResizable) { + setHomeStackResizable(isHomeStackResizable); + if (animDuration > 0) { + mView.setMinimizedDockStack(minimized, animDuration, isHomeStackResizable); + } else { + mView.setMinimizedDockStack(minimized, isHomeStackResizable); + } + updateTouchable(); + } + /** Switch to minimized state if appropriate */ public void setMinimized(final boolean minimized) { mHandler.post(() -> { - WindowContainerTransaction wct = new WindowContainerTransaction(); - if (setHomeMinimized(minimized, mHomeStackResizable, wct)) { - WindowManagerProxy.applyContainerTransaction(wct); + if (!inSplitMode()) { + return; + } + if (mMinimized == minimized) { + return; } - }); - } - - private boolean setHomeMinimized(final boolean minimized, boolean homeStackResizable, - WindowContainerTransaction wct) { - boolean transact = false; - - // Update minimized state - if (mMinimized != minimized) { mMinimized = minimized; - wct.setFocusable(mSplits.mPrimary.token, !mMinimized); - transact = true; - } - - // Update home-stack resizability - if (mHomeStackResizable != homeStackResizable) { - mHomeStackResizable = homeStackResizable; - if (inSplitMode()) { - WindowManagerProxy.applyHomeTasksMinimized( - mSplitLayout, mSplits.mSecondary.token, wct); - transact = true; - } - } - - // Sync state to DividerView if it exists. - if (mView != null) { - mView.setMinimizedDockStack(minimized, getAnimDuration(), homeStackResizable); - } - updateTouchable(); - return transact; + WindowManagerProxy.applyPrimaryFocusable(mSplits, !mMinimized); + mView.setMinimizedDockStack(minimized, getAnimDuration(), mHomeStackResizable); + updateTouchable(); + }); } void setAdjustedForIme(boolean adjustedForIme) { @@ -643,30 +646,46 @@ public class Divider extends SystemUI implements DividerView.DividerCallbacks, } void ensureMinimizedSplit() { - WindowContainerTransaction wct = new WindowContainerTransaction(); - if (setHomeMinimized(true, mSplits.mSecondary.isResizable(), wct)) { - WindowManagerProxy.applyContainerTransaction(wct); - } + final boolean wasMinimized = mMinimized; + mMinimized = true; + setHomeStackResizable(mSplits.mSecondary.isResizable()); + WindowManagerProxy.applyPrimaryFocusable(mSplits, false /* focusable */); if (!inSplitMode()) { // Wasn't in split-mode yet, so enter now. if (DEBUG) { Log.d(TAG, " entering split mode with minimized=true"); } updateVisibility(true /* visible */); + } else if (!wasMinimized) { + if (DEBUG) { + Log.d(TAG, " in split mode, but minimizing "); + } + // Was already in split-mode, update just minimized state. + updateMinimizedDockedStack(mMinimized, getAnimDuration(), + mHomeStackResizable); } } void ensureNormalSplit() { - WindowContainerTransaction wct = new WindowContainerTransaction(); - if (setHomeMinimized(false /* minimized */, mHomeStackResizable, wct)) { - WindowManagerProxy.applyContainerTransaction(wct); + if (mMinimized) { + WindowManagerProxy.applyPrimaryFocusable(mSplits, true /* focusable */); } if (!inSplitMode()) { // Wasn't in split-mode, so enter now. if (DEBUG) { Log.d(TAG, " enter split mode unminimized "); } + mMinimized = false; updateVisibility(true /* visible */); } + if (mMinimized) { + // Was in minimized state, so leave that. + if (DEBUG) { + Log.d(TAG, " in split mode already, but unminimizing "); + } + mMinimized = false; + updateMinimizedDockedStack(mMinimized, getAnimDuration(), + mHomeStackResizable); + } } } diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerWindowManager.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerWindowManager.java index 729df3887915c..3020a25dfa474 100644 --- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerWindowManager.java +++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerWindowManager.java @@ -88,9 +88,6 @@ public class DividerWindowManager { } public void setTouchable(boolean touchable) { - if (mView == null) { - return; - } boolean changed = false; if (!touchable && (mLp.flags & FLAG_NOT_TOUCHABLE) == 0) { mLp.flags |= FLAG_NOT_TOUCHABLE; diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java b/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java index fea57a320d04c..167c33abac6e3 100644 --- a/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java +++ b/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java @@ -21,7 +21,6 @@ import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.view.Display.DEFAULT_DISPLAY; -import android.annotation.NonNull; import android.app.ActivityManager; import android.app.ActivityTaskManager; import android.graphics.Rect; @@ -138,13 +137,17 @@ public class WindowManagerProxy { return resizable; } + static void applyHomeTasksMinimized(SplitDisplayLayout layout, IWindowContainer parent) { + applyHomeTasksMinimized(layout, parent, null /* transaction */); + } + /** * Assign a fixed override-bounds to home tasks that reflect their geometry while the primary * split is minimized. This actually "sticks out" of the secondary split area, but when in * minimized mode, the secondary split gets a 'negative' crop to expose it. */ static boolean applyHomeTasksMinimized(SplitDisplayLayout layout, IWindowContainer parent, - @NonNull WindowContainerTransaction wct) { + WindowContainerTransaction t) { // Resize the home/recents stacks to the larger minimized-state size final Rect homeBounds; final ArrayList homeStacks = new ArrayList<>(); @@ -155,9 +158,19 @@ public class WindowManagerProxy { homeBounds = new Rect(0, 0, layout.mDisplayLayout.width(), layout.mDisplayLayout.height()); } + WindowContainerTransaction wct = t != null ? t : new WindowContainerTransaction(); for (int i = homeStacks.size() - 1; i >= 0; --i) { wct.setBounds(homeStacks.get(i), homeBounds); } + if (t != null) { + return isHomeResizable; + } + try { + ActivityTaskManager.getTaskOrganizerController().applyContainerTransaction(wct, + null /* organizer */); + } catch (RemoteException e) { + Log.e(TAG, "Failed to resize home stacks ", e); + } return isHomeResizable; } @@ -288,8 +301,10 @@ public class WindowManagerProxy { } } - static void applyContainerTransaction(WindowContainerTransaction wct) { + static void applyPrimaryFocusable(SplitScreenTaskOrganizer splits, boolean focusable) { try { + WindowContainerTransaction wct = new WindowContainerTransaction(); + wct.setFocusable(splits.mPrimary.token, focusable); ActivityTaskManager.getTaskOrganizerController().applyContainerTransaction(wct, null /* organizer */); } catch (RemoteException e) {