From 8fab62792e461cf97f3aba5fba4b431793eb4579 Mon Sep 17 00:00:00 2001 From: Tiger <tigerhuang@google.com> Date: Fri, 17 May 2024 23:18:58 +0800 Subject: [PATCH] Update the leash position when gaining a new control If there is an animation playing, the leash position will be updated after calling InsetsAnimationControlRunner#updateSurfacePosition in the next animation frame or the end of animation. However, if there is no animation playing. The client wouldn't update the leash position if the surface position of the insets source window is changed at the server side. This is fine in most of time because the server will update the leash position. But if the client is playing the animation while the server is updating the leash position, and then the client finishes the animation right before receiving the new control, the position can be overwritten by the client animation. This CL updates the leash position when the client gains a new control if there is no leash-animation playing, like we did to the visibility. Bug: 337018949 Flag: NA Test: Turn screen off while the device is unfolded, fold the device, and then turn screen on. See if the taskbar position is expected. Change-Id: I5ba0c33ca4542d27bb4dee4ce849f34721f20b14 --- core/java/android/view/InsetsController.java | 6 ++--- .../android/view/InsetsSourceConsumer.java | 27 ++++++++++++------- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java index f1cb4103f008..b54063b6f66e 100644 --- a/core/java/android/view/InsetsController.java +++ b/core/java/android/view/InsetsController.java @@ -303,7 +303,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation } /** Not running an animation. */ - @VisibleForTesting + @VisibleForTesting(visibility = PACKAGE) public static final int ANIMATION_TYPE_NONE = -1; /** Running animation will show insets */ @@ -317,7 +317,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation public static final int ANIMATION_TYPE_USER = 2; /** Running animation will resize insets */ - @VisibleForTesting + @VisibleForTesting(visibility = PACKAGE) public static final int ANIMATION_TYPE_RESIZE = 3; @Retention(RetentionPolicy.SOURCE) @@ -1709,7 +1709,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation mImeSourceConsumer.onWindowFocusLost(); } - @VisibleForTesting + @VisibleForTesting(visibility = PACKAGE) public @AnimationType int getAnimationType(@InsetsType int type) { for (int i = mRunningAnimations.size() - 1; i >= 0; i--) { InsetsAnimationControlRunner control = mRunningAnimations.get(i).runner; diff --git a/core/java/android/view/InsetsSourceConsumer.java b/core/java/android/view/InsetsSourceConsumer.java index fdb2a6ee1791..6c670f5d6934 100644 --- a/core/java/android/view/InsetsSourceConsumer.java +++ b/core/java/android/view/InsetsSourceConsumer.java @@ -17,6 +17,7 @@ package android.view; import static android.view.InsetsController.ANIMATION_TYPE_NONE; +import static android.view.InsetsController.ANIMATION_TYPE_RESIZE; import static android.view.InsetsController.AnimationType; import static android.view.InsetsController.DEBUG; import static android.view.InsetsSourceConsumerProto.ANIMATION_STATE; @@ -31,6 +32,7 @@ import static com.android.internal.annotations.VisibleForTesting.Visibility.PACK import android.annotation.IntDef; import android.annotation.Nullable; +import android.graphics.Point; import android.graphics.Rect; import android.util.Log; import android.util.proto.ProtoOutputStream; @@ -179,10 +181,11 @@ public class InsetsSourceConsumer { mController.notifyVisibilityChanged(); } - // If we have a new leash, make sure visibility is up-to-date, even though we - // didn't want to run an animation above. - if (mController.getAnimationType(mType) == ANIMATION_TYPE_NONE) { - applyRequestedVisibilityToControl(); + // If there is no animation controlling the leash, make sure the visibility and the + // position is up-to-date. + final int animType = mController.getAnimationType(mType); + if (animType == ANIMATION_TYPE_NONE || animType == ANIMATION_TYPE_RESIZE) { + applyRequestedVisibilityAndPositionToControl(); } // Remove the surface that owned by last control when it lost. @@ -371,21 +374,27 @@ public class InsetsSourceConsumer { if (DEBUG) Log.d(TAG, "updateSource: " + newSource); } - private void applyRequestedVisibilityToControl() { - if (mSourceControl == null || mSourceControl.getLeash() == null) { + private void applyRequestedVisibilityAndPositionToControl() { + if (mSourceControl == null) { + return; + } + final SurfaceControl leash = mSourceControl.getLeash(); + if (leash == null) { return; } final boolean requestedVisible = (mController.getRequestedVisibleTypes() & mType) != 0; + final Point surfacePosition = mSourceControl.getSurfacePosition(); try (Transaction t = mTransactionSupplier.get()) { if (DEBUG) Log.d(TAG, "applyRequestedVisibilityToControl: " + requestedVisible); if (requestedVisible) { - t.show(mSourceControl.getLeash()); + t.show(leash); } else { - t.hide(mSourceControl.getLeash()); + t.hide(leash); } // Ensure the alpha value is aligned with the actual requested visibility. - t.setAlpha(mSourceControl.getLeash(), requestedVisible ? 1 : 0); + t.setAlpha(leash, requestedVisible ? 1 : 0); + t.setPosition(leash, surfacePosition.x, surfacePosition.y); t.apply(); } onPerceptible(requestedVisible); -- GitLab