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
This commit is contained in:
Tiger Huang
2021-05-31 18:02:09 +08:00
parent ad1cfd0db8
commit fa6f73429d
4 changed files with 45 additions and 1 deletions

View File

@@ -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<InsetsSourceControl> 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;

View File

@@ -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<InsetsSourceControl> controls);
/**
* Cancels the animation.
*/

View File

@@ -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<InsetsSourceControl> 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() {

View File

@@ -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();