diff options
| author | 2022-09-14 17:52:20 +0000 | |
|---|---|---|
| committer | 2022-09-19 21:03:44 +0000 | |
| commit | 62f6fe2294dfd866beb62fdf401f27d0c7966baa (patch) | |
| tree | ea7ee1dee7a449be4e6377e9d78cd4b84996fd1d | |
| parent | 66f5377be9fd4fbabb2179fdde8d7f30b150ce58 (diff) | |
Move PiP swiftly in response to IME with keep clear areas flag enabled.
If the keep clear algorithm is enabled, PiP window will avoid the
keep clear areas and move away from occluding keyboard.
When IME is shown, we trigger the movement right away, for a smoother
experience.
If there is another animation ongoing, we delay moving PiP again, so
that it's more smooth overall.
Finally, we always apply gravity bottom with keep clear areas flag on,
so that it goes back down after IME dismiss.
Test: manually, http://recall/-/blXo3gy66k4fDYh7gFkrpe
Bug: 183746978
Change-Id: I32c52e4b6dd3c083b2168fda6a8b3b13facdac69
4 files changed, 60 insertions, 16 deletions
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java index f170e774739f..1a52d8c395ba 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java @@ -324,6 +324,19 @@ public class PipTaskOrganizer implements ShellTaskOrganizer.TaskListener, return mPipTransitionController; } + /** + * Returns true if the PiP window is currently being animated. + */ + public boolean isAnimating() { + // TODO(b/183746978) move this to PipAnimationController, and inject that in PipController + PipAnimationController.PipTransitionAnimator animator = + mPipAnimationController.getCurrentAnimator(); + if (animator != null && animator.isRunning()) { + return true; + } + return false; + } + public Rect getCurrentOrAnimatingBounds() { PipAnimationController.PipTransitionAnimator animator = mPipAnimationController.getCurrentAnimator(); diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipKeepClearAlgorithm.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipKeepClearAlgorithm.java index 6dd02e46d657..84071e08d472 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipKeepClearAlgorithm.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PhonePipKeepClearAlgorithm.java @@ -54,13 +54,8 @@ public class PhonePipKeepClearAlgorithm implements PipKeepClearAlgorithm { ? pipBoundsAlgorithm.getEntryDestinationBoundsIgnoringKeepClearAreas() : pipBoundsState.getBounds(); float snapFraction = pipBoundsAlgorithm.getSnapFraction(startingBounds); - int verticalGravity; + int verticalGravity = Gravity.BOTTOM; int horizontalGravity; - if (snapFraction < 1.5f || snapFraction >= 3.5f) { - verticalGravity = Gravity.NO_GRAVITY; - } else { - verticalGravity = Gravity.BOTTOM; - } if (snapFraction >= 0.5f && snapFraction < 2.5f) { horizontalGravity = Gravity.RIGHT; } else { diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java index 3d879b685706..bc8191d2af46 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java @@ -149,7 +149,42 @@ public class PipController implements PipTransitionController.PipTransitionCallb private final Rect mTmpInsetBounds = new Rect(); private final int mEnterAnimationDuration; - private final Runnable mMovePipInResponseToKeepClearAreasChangeCallback; + private final Runnable mMovePipInResponseToKeepClearAreasChangeCallback = + this::onKeepClearAreasChangedCallback; + + private void onKeepClearAreasChangedCallback() { + if (!mEnablePipKeepClearAlgorithm) { + // early bail out if the keep clear areas feature is disabled + return; + } + // if there is another animation ongoing, wait for it to finish and try again + if (mPipTaskOrganizer.isAnimating()) { + mMainExecutor.removeCallbacks( + mMovePipInResponseToKeepClearAreasChangeCallback); + mMainExecutor.executeDelayed( + mMovePipInResponseToKeepClearAreasChangeCallback, + PIP_KEEP_CLEAR_AREAS_DELAY); + return; + } + updatePipPositionForKeepClearAreas(); + } + + private void updatePipPositionForKeepClearAreas() { + if (!mEnablePipKeepClearAlgorithm) { + // early bail out if the keep clear areas feature is disabled + return; + } + // only move if already in pip, other transitions account for keep clear areas + if (mPipTransitionState.hasEnteredPip()) { + Rect destBounds = mPipKeepClearAlgorithm.adjust(mPipBoundsState, + mPipBoundsAlgorithm); + // only move if the bounds are actually different + if (destBounds != mPipBoundsState.getBounds()) { + mPipTaskOrganizer.scheduleAnimateResizePip(destBounds, + mEnterAnimationDuration, null); + } + } + } private boolean mIsInFixedRotation; private PipAnimationListener mPinnedStackAnimationRecentsCallback; @@ -302,6 +337,9 @@ public class PipController implements PipTransitionController.PipTransitionCallb public void onImeVisibilityChanged(boolean imeVisible, int imeHeight) { mPipBoundsState.setImeVisibility(imeVisible, imeHeight); mTouchHandler.onImeVisibilityChanged(imeVisible, imeHeight); + if (imeVisible) { + updatePipPositionForKeepClearAreas(); + } } @Override @@ -414,15 +452,6 @@ public class PipController implements PipTransitionController.PipTransitionCallb mEnterAnimationDuration = mContext.getResources() .getInteger(R.integer.config_pipEnterAnimationDuration); - mMovePipInResponseToKeepClearAreasChangeCallback = () -> { - // only move if already in pip, other transitions account for keep clear areas - if (mPipTransitionState.hasEnteredPip()) { - Rect destBounds = mPipKeepClearAlgorithm.adjust(mPipBoundsState, - mPipBoundsAlgorithm); - mPipTaskOrganizer.scheduleAnimateResizePip(destBounds, - mEnterAnimationDuration, null); - } - }; mPipParamsChangedForwarder = pipParamsChangedForwarder; mDisplayInsetsController = displayInsetsController; diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java index 84d9217e6fb3..1f3f31e025a0 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java @@ -34,6 +34,7 @@ import android.content.res.Resources; import android.graphics.Point; import android.graphics.PointF; import android.graphics.Rect; +import android.os.SystemProperties; import android.provider.DeviceConfig; import android.util.Size; import android.view.DisplayCutout; @@ -70,6 +71,9 @@ public class PipTouchHandler { private static final String TAG = "PipTouchHandler"; private static final float DEFAULT_STASH_VELOCITY_THRESHOLD = 18000.f; + private static final boolean ENABLE_PIP_KEEP_CLEAR_ALGORITHM = + SystemProperties.getBoolean("persist.wm.debug.enable_pip_keep_clear_algorithm", false); + // Allow PIP to resize to a slightly bigger state upon touch private boolean mEnableResize; private final Context mContext; @@ -426,6 +430,9 @@ public class PipTouchHandler { if (mTouchState.isUserInteracting()) { // Defer the update of the current movement bounds until after the user finishes // touching the screen + } else if (ENABLE_PIP_KEEP_CLEAR_ALGORITHM) { + // Ignore moving PiP if keep clear algorithm is enabled, since IME and shelf height + // now are accounted for in the keep clear algorithm calculations } else { final boolean isExpanded = mMenuState == MENU_STATE_FULL && willResizeMenu(); final Rect toMovementBounds = new Rect(); |