summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Tiger <tigerhuang@google.com> 2023-10-17 19:34:05 +0800
committer Tiger <tigerhuang@google.com> 2023-10-17 19:34:05 +0800
commitff98c45540a7c8aae707d49d76af228e5cb8335e (patch)
tree5e4ae8567d0c4e414550e85fb3efd76be183283c
parent279533e77ceb523f9e99002f68a929461ecebf18 (diff)
Don't create new leash if there is pending position
We might want the surface position to be changed when the surface is drawn after the buffer size is changed to prevent flicker. Creating a new leash might update the position earlier than expected, which could cause flicker. The CL defers updateControlForTarget to prevent creating a new leash until the pending position is applied. Fix: 303911439 Test: Toggle "Always show Taskbar" and make sure there is no flicker. Change-Id: I999cb464140da382fba939711273c3fa83a223a9
-rw-r--r--services/core/java/com/android/server/wm/InsetsSourceProvider.java44
-rw-r--r--services/core/java/com/android/server/wm/InsetsStateController.java6
2 files changed, 35 insertions, 15 deletions
diff --git a/services/core/java/com/android/server/wm/InsetsSourceProvider.java b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
index 02f5c217e5d8..cd114fcf9e21 100644
--- a/services/core/java/com/android/server/wm/InsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
@@ -68,6 +68,7 @@ class InsetsSourceProvider {
private final Rect mTmpRect = new Rect();
private final InsetsStateController mStateController;
private final InsetsSourceControl mFakeControl;
+ private final Consumer<Transaction> mSetLeashPositionConsumer;
private @Nullable InsetsSourceControl mControl;
private @Nullable InsetsControlTarget mControlTarget;
private @Nullable InsetsControlTarget mPendingControlTarget;
@@ -85,16 +86,7 @@ class InsetsSourceProvider {
private boolean mInsetsHintStale = true;
private @Flags int mFlagsFromFrameProvider;
private @Flags int mFlagsFromServer;
-
- private final Consumer<Transaction> mSetLeashPositionConsumer = t -> {
- if (mControl != null) {
- final SurfaceControl leash = mControl.getLeash();
- if (leash != null) {
- final Point position = mControl.getSurfacePosition();
- t.setPosition(leash, position.x, position.y);
- }
- }
- };
+ private boolean mHasPendingPosition;
/** The visibility override from the current controlling window. */
private boolean mClientVisible;
@@ -129,6 +121,21 @@ class InsetsSourceProvider {
source.getId(), source.getType(), null /* leash */, false /* initialVisible */,
new Point(), Insets.NONE);
mControllable = (InsetsPolicy.CONTROLLABLE_TYPES & source.getType()) != 0;
+ mSetLeashPositionConsumer = t -> {
+ if (mControl != null) {
+ final SurfaceControl leash = mControl.getLeash();
+ if (leash != null) {
+ final Point position = mControl.getSurfacePosition();
+ t.setPosition(leash, position.x, position.y);
+ }
+ }
+ if (mHasPendingPosition) {
+ mHasPendingPosition = false;
+ if (mPendingControlTarget != mControlTarget) {
+ mStateController.notifyControlTargetChanged(mPendingControlTarget, this);
+ }
+ }
+ };
}
InsetsSource getSource() {
@@ -185,9 +192,8 @@ class InsetsSourceProvider {
mWindowContainer.getInsetsSourceProviders().put(mSource.getId(), this);
if (mControllable) {
mWindowContainer.setControllableInsetProvider(this);
- if (mPendingControlTarget != null) {
+ if (mPendingControlTarget != mControlTarget) {
updateControlForTarget(mPendingControlTarget, true /* force */);
- mPendingControlTarget = null;
}
}
}
@@ -344,6 +350,7 @@ class InsetsSourceProvider {
changed = true;
if (windowState != null && windowState.getWindowFrames().didFrameSizeChange()
&& windowState.mWinAnimator.getShown() && mWindowContainer.okToDisplay()) {
+ mHasPendingPosition = true;
windowState.applyWithNextDraw(mSetLeashPositionConsumer);
} else {
Transaction t = mWindowContainer.getSyncTransaction();
@@ -465,18 +472,23 @@ class InsetsSourceProvider {
// to control the window for now.
return;
}
+ mPendingControlTarget = target;
if (mWindowContainer != null && mWindowContainer.getSurfaceControl() == null) {
// if window doesn't have a surface, set it null and return.
setWindowContainer(null, null, null);
}
if (mWindowContainer == null) {
- mPendingControlTarget = target;
return;
}
if (target == mControlTarget && !force) {
return;
}
+ if (mHasPendingPosition) {
+ // Don't create a new leash while having a pending position. Otherwise, the position
+ // will be changed earlier than expected, which can cause flicker.
+ return;
+ }
if (target == null) {
// Cancelling the animation will invoke onAnimationCancelled, resetting all the fields.
mWindowContainer.cancelAnimation();
@@ -618,6 +630,7 @@ class InsetsSourceProvider {
}
pw.print(prefix);
pw.print("mIsLeashReadyForDispatching="); pw.print(mIsLeashReadyForDispatching);
+ pw.print("mHasPendingPosition="); pw.print(mHasPendingPosition);
pw.println();
if (mWindowContainer != null) {
pw.print(prefix + "mWindowContainer=");
@@ -631,7 +644,7 @@ class InsetsSourceProvider {
pw.print(prefix + "mControlTarget=");
pw.println(mControlTarget);
}
- if (mPendingControlTarget != null) {
+ if (mPendingControlTarget != mControlTarget) {
pw.print(prefix + "mPendingControlTarget=");
pw.println(mPendingControlTarget);
}
@@ -652,7 +665,8 @@ class InsetsSourceProvider {
if (mControlTarget != null && mControlTarget.getWindow() != null) {
mControlTarget.getWindow().dumpDebug(proto, CONTROL_TARGET, logLevel);
}
- if (mPendingControlTarget != null && mPendingControlTarget.getWindow() != null) {
+ if (mPendingControlTarget != null && mPendingControlTarget != mControlTarget
+ && mPendingControlTarget.getWindow() != null) {
mPendingControlTarget.getWindow().dumpDebug(proto, PENDING_CONTROL_TARGET, logLevel);
}
if (mFakeControlTarget != null && mFakeControlTarget.getWindow() != null) {
diff --git a/services/core/java/com/android/server/wm/InsetsStateController.java b/services/core/java/com/android/server/wm/InsetsStateController.java
index 081ebe0e7cbd..c4d01291f558 100644
--- a/services/core/java/com/android/server/wm/InsetsStateController.java
+++ b/services/core/java/com/android/server/wm/InsetsStateController.java
@@ -278,6 +278,12 @@ class InsetsStateController {
notifyPendingInsetsControlChanged();
}
+ void notifyControlTargetChanged(@Nullable InsetsControlTarget target,
+ InsetsSourceProvider provider) {
+ onControlTargetChanged(provider, target, false /* fake */);
+ notifyPendingInsetsControlChanged();
+ }
+
void notifyControlRevoked(@NonNull InsetsControlTarget previousControlTarget,
InsetsSourceProvider provider) {
removeFromControlMaps(previousControlTarget, provider, false /* fake */);