diff options
| author | 2024-02-22 16:35:40 +0000 | |
|---|---|---|
| committer | 2024-04-18 13:45:46 +0000 | |
| commit | 08c01f0dbeb6f73b839edcfc02cc8eb7da63903b (patch) | |
| tree | 135f188826e060adad84bed32eba1424f08e504e | |
| parent | 2fe6f1737c7dafdb2f982a8c30fbba9db5f49ed1 (diff) | |
Unregister IME callback in onBackInvoked immediately
By removing the IME callback in onBackInvoked immediately, a new back gesture that starts during the IME hide animation can already dispatch to a new back callback. Currently, back gestures that start during the (predictive back) IME hide animation are simply ignored. This CL fixes that.
Bug: 322836622
Flag: ACONFIG android.view.inputmethod.predictive_back_ime DISABLED
Test: separate CL
Change-Id: Iab628e23982915b5c5f17896436157794e90b649
| -rw-r--r-- | core/java/android/view/ImeBackAnimationController.java | 22 | ||||
| -rw-r--r-- | core/java/android/view/ImeInsetsSourceConsumer.java | 3 | ||||
| -rw-r--r-- | core/java/android/view/InsetsController.java | 15 |
3 files changed, 37 insertions, 3 deletions
diff --git a/core/java/android/view/ImeBackAnimationController.java b/core/java/android/view/ImeBackAnimationController.java index 665fac18be99..911f7b2d4ff6 100644 --- a/core/java/android/view/ImeBackAnimationController.java +++ b/core/java/android/view/ImeBackAnimationController.java @@ -31,9 +31,12 @@ import android.util.Log; import android.view.animation.BackGestureInterpolator; import android.view.animation.Interpolator; import android.view.animation.PathInterpolator; +import android.view.inputmethod.ImeTracker; import android.window.BackEvent; import android.window.OnBackAnimationCallback; +import com.android.internal.inputmethod.SoftInputShowHideReason; + /** * Controller for IME predictive back animation * @@ -192,6 +195,24 @@ public class ImeBackAnimationController implements OnBackAnimationCallback { mPostCommitAnimator.setDuration( triggerBack ? POST_COMMIT_DURATION_MS : POST_COMMIT_CANCEL_DURATION_MS); mPostCommitAnimator.start(); + if (triggerBack) { + mInsetsController.setPredictiveBackImeHideAnimInProgress(true); + notifyHideIme(); + } + } + + private void notifyHideIme() { + ImeTracker.Token statsToken = ImeTracker.forLogging().onStart(ImeTracker.TYPE_HIDE, + ImeTracker.ORIGIN_CLIENT, + SoftInputShowHideReason.HIDE_SOFT_INPUT_REQUEST_HIDE_WITH_CONTROL, true); + // This notifies the IME that it is being hidden. In response, the IME will unregister the + // animation callback, such that new back gestures happening during the post-commit phase of + // the hide animation can already dispatch to a new callback. + // Note that the IME will call hide() in InsetsController. InsetsController will not animate + // that hide request if it sees that ImeBackAnimationController is already animating + // the IME away + mInsetsController.getHost().getInputMethodManager() + .notifyImeHidden(mInsetsController.getHost().getWindowToken(), statsToken); } private void reset() { @@ -200,6 +221,7 @@ public class ImeBackAnimationController implements OnBackAnimationCallback { mLastProgress = 0f; mTriggerBack = false; mIsPreCommitAnimationInProgress = false; + mInsetsController.setPredictiveBackImeHideAnimInProgress(false); } private void resetPostCommitAnimator() { diff --git a/core/java/android/view/ImeInsetsSourceConsumer.java b/core/java/android/view/ImeInsetsSourceConsumer.java index 6caf4d6ff992..3def604e6739 100644 --- a/core/java/android/view/ImeInsetsSourceConsumer.java +++ b/core/java/android/view/ImeInsetsSourceConsumer.java @@ -243,7 +243,8 @@ public final class ImeInsetsSourceConsumer extends InsetsSourceConsumer { * {@link InputMethodManager#showSoftInput(View, int)} is called. */ public void onShowRequested() { - if (mAnimationState == ANIMATION_STATE_HIDE) { + if (mAnimationState == ANIMATION_STATE_HIDE + || mController.isPredictiveBackImeHideAnimInProgress()) { mHasPendingRequest = true; } } diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java index 1f6cecafd68f..8c00fbb5023e 100644 --- a/core/java/android/view/InsetsController.java +++ b/core/java/android/view/InsetsController.java @@ -651,6 +651,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation private @Appearance int mAppearanceControlled; private @Appearance int mAppearanceFromResource; private boolean mBehaviorControlled; + private boolean mIsPredictiveBackImeHideAnimInProgress; private final Runnable mPendingControlTimeout = this::abortPendingImeControlRequest; private final ArrayList<OnControllableInsetsChangedListener> mControllableInsetsChangedListeners @@ -1027,6 +1028,14 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation reportRequestedVisibleTypes(); } + void setPredictiveBackImeHideAnimInProgress(boolean isInProgress) { + mIsPredictiveBackImeHideAnimInProgress = isInProgress; + } + + boolean isPredictiveBackImeHideAnimInProgress() { + return mIsPredictiveBackImeHideAnimInProgress; + } + @Override public void show(@InsetsType int types) { show(types, false /* fromIme */, null /* statsToken */); @@ -1090,7 +1099,8 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation } continue; } - if (fromIme && animationType == ANIMATION_TYPE_USER) { + if (fromIme && animationType == ANIMATION_TYPE_USER + && !mIsPredictiveBackImeHideAnimInProgress) { // App is already controlling the IME, don't cancel it. if (isIme) { ImeTracker.forLogging().onFailed( @@ -1186,7 +1196,8 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation } } if (!requestedVisible && animationType == ANIMATION_TYPE_NONE - || animationType == ANIMATION_TYPE_HIDE) { + || animationType == ANIMATION_TYPE_HIDE || (animationType + == ANIMATION_TYPE_USER && mIsPredictiveBackImeHideAnimInProgress)) { // no-op: already hidden or animating out (because window visibility is // applied before starting animation). if (isImeAnimation) { |