Add app movement for IME predictive back and adjustPan
Bug: 322836622
Flag: ACONFIG android.view.inputmethod.predictive_back_ime DISABLED
Test: separate CL
Change-Id: I671e99c14372f000fdd58b9e5a7d016ae451d70c
diff --git a/core/java/android/view/ImeBackAnimationController.java b/core/java/android/view/ImeBackAnimationController.java
index 911f7b2..ed049b5 100644
--- a/core/java/android/view/ImeBackAnimationController.java
+++ b/core/java/android/view/ImeBackAnimationController.java
@@ -18,6 +18,7 @@
import static android.view.InsetsController.ANIMATION_TYPE_USER;
import static android.view.WindowInsets.Type.ime;
+import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN;
import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
import static android.view.WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST;
@@ -60,6 +61,7 @@
private float mLastProgress = 0f;
private boolean mTriggerBack = false;
private boolean mIsPreCommitAnimationInProgress = false;
+ private int mStartRootScrollY = 0;
public ImeBackAnimationController(ViewRootImpl viewRoot) {
mInsetsController = viewRoot.getInsetsController();
@@ -96,6 +98,7 @@
public void onReady(@NonNull WindowInsetsAnimationController controller,
@WindowInsets.Type.InsetsType int types) {
mWindowInsetsAnimationController = controller;
+ if (isAdjustPan()) mStartRootScrollY = mViewRoot.mScrollY;
if (mIsPreCommitAnimationInProgress) {
setPreCommitProgress(mLastProgress);
} else {
@@ -146,6 +149,10 @@
float imeHeight = shownY - hiddenY;
float interpolatedProgress = BACK_GESTURE.getInterpolation(progress);
int newY = (int) (imeHeight - interpolatedProgress * (imeHeight * PEEK_FRACTION));
+ if (mStartRootScrollY != 0) {
+ mViewRoot.setScrollY(
+ (int) (mStartRootScrollY * (1 - interpolatedProgress * PEEK_FRACTION)));
+ }
mWindowInsetsAnimationController.setInsetsAndAlpha(Insets.of(0, 0, 0, newY), 1f,
progress);
}
@@ -199,6 +206,19 @@
mInsetsController.setPredictiveBackImeHideAnimInProgress(true);
notifyHideIme();
}
+ if (mStartRootScrollY != 0) {
+ // RootView is panned, ensure that it is scrolled back to the intended scroll position
+ if (triggerBack) {
+ // requesting ime as invisible
+ mInsetsController.setRequestedVisibleTypes(0, ime());
+ // changes the animation state and notifies RootView of changed insets, which
+ // causes it to reset its scrollY to 0f (animated)
+ mInsetsController.onAnimationStateChanged(ime(), /*running*/ true);
+ } else {
+ // This causes RootView to update its scroll back to the panned position
+ mInsetsController.getHost().notifyInsetsChanged();
+ }
+ }
}
private void notifyHideIme() {
@@ -222,6 +242,7 @@
mTriggerBack = false;
mIsPreCommitAnimationInProgress = false;
mInsetsController.setPredictiveBackImeHideAnimInProgress(false);
+ mStartRootScrollY = 0;
}
private void resetPostCommitAnimator() {
@@ -236,6 +257,11 @@
== SOFT_INPUT_ADJUST_RESIZE;
}
+ private boolean isAdjustPan() {
+ return (mViewRoot.mWindowAttributes.softInputMode & SOFT_INPUT_MASK_ADJUST)
+ == SOFT_INPUT_ADJUST_PAN;
+ }
+
private boolean isHideAnimationInProgress() {
return mPostCommitAnimator != null && mTriggerBack;
}
diff --git a/core/java/android/view/ImeInsetsSourceConsumer.java b/core/java/android/view/ImeInsetsSourceConsumer.java
index 3def604..62dbc39 100644
--- a/core/java/android/view/ImeInsetsSourceConsumer.java
+++ b/core/java/android/view/ImeInsetsSourceConsumer.java
@@ -66,7 +66,12 @@
"ImeInsetsSourceConsumer#onAnimationFinished",
mController.getHost().getInputMethodManager(), null /* icProto */);
}
- final boolean insetsChanged = super.onAnimationStateChanged(running);
+ boolean insetsChanged = super.onAnimationStateChanged(running);
+ if (running && !isShowRequested() && mController.isPredictiveBackImeHideAnimInProgress()) {
+ // IME predictive back animation switched from pre-commit to post-commit.
+ insetsChanged |= applyLocalVisibilityOverride();
+ }
+
if (!isShowRequested()) {
mIsRequestedVisibleAwaitingLeash = false;
if (!running && !mHasPendingRequest) {
diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java
index 8c00fbb..6c90011 100644
--- a/core/java/android/view/InsetsController.java
+++ b/core/java/android/view/InsetsController.java
@@ -1620,7 +1620,7 @@
onAnimationStateChanged(removedTypes, false /* running */);
}
- private void onAnimationStateChanged(@InsetsType int types, boolean running) {
+ void onAnimationStateChanged(@InsetsType int types, boolean running) {
boolean insetsChanged = false;
for (int i = mSourceConsumers.size() - 1; i >= 0; i--) {
final InsetsSourceConsumer consumer = mSourceConsumers.valueAt(i);
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index cd0602c..00840cc 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -5881,6 +5881,13 @@
return handled;
}
+ void setScrollY(int scrollY) {
+ if (mScroller != null) {
+ mScroller.abortAnimation();
+ }
+ mScrollY = scrollY;
+ }
+
/**
* @hide
*/