From fa6f73429d0604af526254b68a6ff4bef923563a Mon Sep 17 00:00:00 2001 From: Tiger Huang Date: Mon, 31 May 2021 18:02:09 +0800 Subject: Update the surface position of each control in insets animation If the surface position is changed during the insets animation, the surface position of the controls in the animation should be updated. Otherwise, the cached position in the animation will overwrite the newly-updated leash position. Fix: 177925500 Test: Steps in the bug. Test: 1. Open Window Insets Tests -> Window Insets Controller. 2. Click on the [IME INVISIBLE] button. 3. Click on the [STATUS BARS VISIBLE] button during IME animation. See if the position of IME (Gborad) is correct. Change-Id: I7441426a41019996651220e86ca90dd416ef9498 --- core/java/android/view/InsetsAnimationControlImpl.java | 14 ++++++++++++++ .../android/view/InsetsAnimationControlRunner.java | 8 ++++++++ .../view/InsetsAnimationThreadControlRunner.java | 18 +++++++++++++++++- core/java/android/view/InsetsController.java | 6 ++++++ 4 files changed, 45 insertions(+), 1 deletion(-) diff --git a/core/java/android/view/InsetsAnimationControlImpl.java b/core/java/android/view/InsetsAnimationControlImpl.java index b3caac07aa61..17b3020001d4 100644 --- a/core/java/android/view/InsetsAnimationControlImpl.java +++ b/core/java/android/view/InsetsAnimationControlImpl.java @@ -44,6 +44,7 @@ import android.annotation.Nullable; import android.content.res.CompatibilityInfo; import android.graphics.Insets; import android.graphics.Matrix; +import android.graphics.Point; import android.graphics.Rect; import android.util.ArraySet; import android.util.Log; @@ -203,6 +204,19 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll mControllingTypes &= ~types; } + @Override + public void updateSurfacePosition(SparseArray controls) { + for (int i = controls.size() - 1; i >= 0; i--) { + final InsetsSourceControl control = controls.valueAt(i); + final InsetsSourceControl c = mControls.get(control.getType()); + if (c == null) { + continue; + } + final Point position = control.getSurfacePosition(); + c.setSurfacePosition(position.x, position.y); + } + } + @Override public @AnimationType int getAnimationType() { return mAnimationType; diff --git a/core/java/android/view/InsetsAnimationControlRunner.java b/core/java/android/view/InsetsAnimationControlRunner.java index 7787af5e133b..1cb00e3ae7af 100644 --- a/core/java/android/view/InsetsAnimationControlRunner.java +++ b/core/java/android/view/InsetsAnimationControlRunner.java @@ -16,6 +16,7 @@ package android.view; +import android.util.SparseArray; import android.util.proto.ProtoOutputStream; import android.view.InsetsController.AnimationType; import android.view.InsetsState.InternalInsetsType; @@ -44,6 +45,13 @@ public interface InsetsAnimationControlRunner { */ void notifyControlRevoked(@InsetsType int types); + /** + * Updates the surface positions of the controls owned by this runner if there is any. + * + * @param controls An array of {@link InsetsSourceControl} that the caller newly receives. + */ + void updateSurfacePosition(SparseArray controls); + /** * Cancels the animation. */ diff --git a/core/java/android/view/InsetsAnimationThreadControlRunner.java b/core/java/android/view/InsetsAnimationThreadControlRunner.java index c6ebc9e52e84..691e638f3669 100644 --- a/core/java/android/view/InsetsAnimationThreadControlRunner.java +++ b/core/java/android/view/InsetsAnimationThreadControlRunner.java @@ -62,7 +62,12 @@ public class InsetsAnimationThreadControlRunner implements InsetsAnimationContro @Override public void scheduleApplyChangeInsets(InsetsAnimationControlRunner runner) { - mControl.applyChangeInsets(null /* outState */); + synchronized (mControl) { + // This reads the surface position on the animation thread, but the surface position + // would be updated on the UI thread, so we need this critical section. + // See: updateSurfacePosition. + mControl.applyChangeInsets(null /* outState */); + } } @Override @@ -148,10 +153,21 @@ public class InsetsAnimationThreadControlRunner implements InsetsAnimationContro } @Override + @UiThread public void notifyControlRevoked(@InsetsType int types) { mControl.notifyControlRevoked(types); } + @Override + @UiThread + public void updateSurfacePosition(SparseArray controls) { + synchronized (mControl) { + // This is called from the UI thread, however, the surface position will be used on the + // animation thread, so we need this critical section. See: scheduleApplyChangeInsets. + mControl.updateSurfacePosition(controls); + } + } + @Override @UiThread public void cancel() { diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java index d339c0471125..8080883c2b3e 100644 --- a/core/java/android/view/InsetsController.java +++ b/core/java/android/view/InsetsController.java @@ -829,7 +829,13 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation requestedStateStale = requestedVisibilityChanged || imeRequestedVisible; } + } + if (mTmpControlArray.size() > 0) { + // Update surface positions for animations. + for (int i = mRunningAnimations.size() - 1; i >= 0; i--) { + mRunningAnimations.get(i).runner.updateSurfacePosition(mTmpControlArray); + } } mTmpControlArray.clear(); -- cgit v1.2.3-59-g8ed1b