Merge "Let the client know the initial visibility of an InsetsSourceControl" into tm-qpr-dev
diff --git a/core/java/android/view/InsetsSourceConsumer.java b/core/java/android/view/InsetsSourceConsumer.java
index b17e199..d63c25a 100644
--- a/core/java/android/view/InsetsSourceConsumer.java
+++ b/core/java/android/view/InsetsSourceConsumer.java
@@ -25,7 +25,6 @@
import static android.view.InsetsSourceConsumerProto.PENDING_FRAME;
import static android.view.InsetsSourceConsumerProto.PENDING_VISIBLE_FRAME;
import static android.view.InsetsSourceConsumerProto.SOURCE_CONTROL;
-import static android.view.InsetsSourceControl.INVALID_HINTS;
import static android.view.InsetsState.ITYPE_IME;
import static android.view.InsetsState.getDefaultVisibility;
import static android.view.InsetsState.toPublicType;
@@ -34,7 +33,6 @@
import android.annotation.IntDef;
import android.annotation.Nullable;
-import android.graphics.Insets;
import android.graphics.Rect;
import android.util.ArraySet;
import android.util.Log;
@@ -94,13 +92,6 @@
private Rect mPendingVisibleFrame;
/**
- * Indicates if we have the pending animation. When we have the control, we need to play the
- * animation if the requested visibility is different from the current state. But if we haven't
- * had a leash yet, we will set this flag, and play the animation once we get the leash.
- */
- private boolean mIsAnimationPending;
-
- /**
* @param type The {@link InternalInsetsType} of the consumed insets.
* @param state The current {@link InsetsState} of the consumed insets.
* @param transactionSupplier The source of new {@link Transaction} instances. The supplier
@@ -138,7 +129,6 @@
}
return false;
}
- SurfaceControl oldLeash = mSourceControl != null ? mSourceControl.getLeash() : null;
final InsetsSourceControl lastControl = mSourceControl;
mSourceControl = control;
@@ -163,27 +153,21 @@
// For updateCompatSysUiVisibility
applyLocalVisibilityOverride();
} else {
- // We are gaining control, and need to run an animation since previous state
- // didn't match
final boolean requestedVisible = isRequestedVisibleAwaitingControl();
- final boolean fakeControl = INVALID_HINTS.equals(control.getInsetsHint());
- final boolean needsAnimation = requestedVisible != mState.getSource(mType).isVisible()
- && !fakeControl;
- if (control.getLeash() != null && (needsAnimation || mIsAnimationPending)) {
- if (DEBUG) Log.d(TAG, String.format("Gaining control in %s, requestedVisible: %b",
+ final SurfaceControl oldLeash = lastControl != null ? lastControl.getLeash() : null;
+ final SurfaceControl newLeash = control.getLeash();
+ if (newLeash != null && (oldLeash == null || !newLeash.isSameSurface(oldLeash))
+ && requestedVisible != control.isInitiallyVisible()) {
+ // We are gaining leash, and need to run an animation since previous state
+ // didn't match.
+ if (DEBUG) Log.d(TAG, String.format("Gaining leash in %s, requestedVisible: %b",
mController.getHost().getRootViewTitle(), requestedVisible));
if (requestedVisible) {
showTypes[0] |= toPublicType(getType());
} else {
hideTypes[0] |= toPublicType(getType());
}
- mIsAnimationPending = false;
} else {
- if (needsAnimation) {
- // We need animation but we haven't had a leash yet. Set this flag that when we
- // get the leash we can play the deferred animation.
- mIsAnimationPending = true;
- }
// We are gaining control, but don't need to run an animation.
// However make sure that the leash visibility is still up to date.
if (applyLocalVisibilityOverride()) {
@@ -195,7 +179,7 @@
applyRequestedVisibilityToControl();
// Remove the surface that owned by last control when it lost.
- if (!requestedVisible && !mIsAnimationPending && lastControl == null) {
+ if (!requestedVisible && lastControl == null) {
removeSurface();
}
}
@@ -406,16 +390,6 @@
protected void setRequestedVisible(boolean requestedVisible) {
if (mRequestedVisible != requestedVisible) {
mRequestedVisible = requestedVisible;
-
- // We need an animation later if the leash of a real control (which has an insets hint)
- // is not ready. The !mIsAnimationPending check is in case that the requested visibility
- // is changed twice before playing the animation -- we don't need an animation in this
- // case.
- mIsAnimationPending = !mIsAnimationPending
- && mSourceControl != null
- && mSourceControl.getLeash() == null
- && !Insets.NONE.equals(mSourceControl.getInsetsHint());
-
mController.onRequestedVisibilityChanged(this);
if (DEBUG) Log.d(TAG, "setRequestedVisible: " + requestedVisible);
}
diff --git a/core/java/android/view/InsetsSourceControl.java b/core/java/android/view/InsetsSourceControl.java
index 2cf827d..5f1cbba 100644
--- a/core/java/android/view/InsetsSourceControl.java
+++ b/core/java/android/view/InsetsSourceControl.java
@@ -31,6 +31,7 @@
import android.view.InsetsState.InternalInsetsType;
import java.io.PrintWriter;
+import java.util.Objects;
import java.util.function.Consumer;
/**
@@ -39,10 +40,9 @@
*/
public class InsetsSourceControl implements Parcelable {
- public static final Insets INVALID_HINTS = Insets.of(-1, -1, -1, -1);
-
private final @InternalInsetsType int mType;
private final @Nullable SurfaceControl mLeash;
+ private final boolean mInitiallyVisible;
private final Point mSurfacePosition;
// This is used while playing an insets animation regardless of the relative frame. This would
@@ -53,9 +53,10 @@
private int mParcelableFlags;
public InsetsSourceControl(@InternalInsetsType int type, @Nullable SurfaceControl leash,
- Point surfacePosition, Insets insetsHint) {
+ boolean initiallyVisible, Point surfacePosition, Insets insetsHint) {
mType = type;
mLeash = leash;
+ mInitiallyVisible = initiallyVisible;
mSurfacePosition = surfacePosition;
mInsetsHint = insetsHint;
}
@@ -67,6 +68,7 @@
} else {
mLeash = null;
}
+ mInitiallyVisible = other.mInitiallyVisible;
mSurfacePosition = new Point(other.mSurfacePosition);
mInsetsHint = other.mInsetsHint;
mSkipAnimationOnce = other.getAndClearSkipAnimationOnce();
@@ -75,6 +77,7 @@
public InsetsSourceControl(Parcel in) {
mType = in.readInt();
mLeash = in.readTypedObject(SurfaceControl.CREATOR);
+ mInitiallyVisible = in.readBoolean();
mSurfacePosition = in.readTypedObject(Point.CREATOR);
mInsetsHint = in.readTypedObject(Insets.CREATOR);
mSkipAnimationOnce = in.readBoolean();
@@ -94,6 +97,10 @@
return mLeash;
}
+ public boolean isInitiallyVisible() {
+ return mInitiallyVisible;
+ }
+
public boolean setSurfacePosition(int left, int top) {
if (mSurfacePosition.equals(left, top)) {
return false;
@@ -148,6 +155,7 @@
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(mType);
dest.writeTypedObject(mLeash, mParcelableFlags);
+ dest.writeBoolean(mInitiallyVisible);
dest.writeTypedObject(mSurfacePosition, mParcelableFlags);
dest.writeTypedObject(mInsetsHint, mParcelableFlags);
dest.writeBoolean(mSkipAnimationOnce);
@@ -172,6 +180,7 @@
return mType == that.mType
&& ((mLeash == thatLeash)
|| (mLeash != null && thatLeash != null && mLeash.isSameSurface(thatLeash)))
+ && mInitiallyVisible == that.mInitiallyVisible
&& mSurfacePosition.equals(that.mSurfacePosition)
&& mInsetsHint.equals(that.mInsetsHint)
&& mSkipAnimationOnce == that.mSkipAnimationOnce;
@@ -179,12 +188,8 @@
@Override
public int hashCode() {
- int result = mType;
- result = 31 * result + (mLeash != null ? mLeash.hashCode() : 0);
- result = 31 * result + mSurfacePosition.hashCode();
- result = 31 * result + mInsetsHint.hashCode();
- result = 31 * result + (mSkipAnimationOnce ? 1 : 0);
- return result;
+ return Objects.hash(mType, mLeash, mInitiallyVisible, mSurfacePosition, mInsetsHint,
+ mSkipAnimationOnce);
}
@Override
@@ -200,6 +205,7 @@
pw.print(prefix);
pw.print("InsetsSourceControl type="); pw.print(InsetsState.typeToString(mType));
pw.print(" mLeash="); pw.print(mLeash);
+ pw.print(" mInitiallyVisible="); pw.print(mInitiallyVisible);
pw.print(" mSurfacePosition="); pw.print(mSurfacePosition);
pw.print(" mInsetsHint="); pw.print(mInsetsHint);
pw.print(" mSkipAnimationOnce="); pw.print(mSkipAnimationOnce);
diff --git a/core/tests/coretests/src/android/view/ImeInsetsSourceConsumerTest.java b/core/tests/coretests/src/android/view/ImeInsetsSourceConsumerTest.java
index 34a1fd8..44bb062 100644
--- a/core/tests/coretests/src/android/view/ImeInsetsSourceConsumerTest.java
+++ b/core/tests/coretests/src/android/view/ImeInsetsSourceConsumerTest.java
@@ -92,7 +92,7 @@
@Test
public void testImeVisibility() {
final InsetsSourceControl ime =
- new InsetsSourceControl(ITYPE_IME, mLeash, new Point(), Insets.NONE);
+ new InsetsSourceControl(ITYPE_IME, mLeash, false, new Point(), Insets.NONE);
mController.onControlsChanged(new InsetsSourceControl[] { ime });
InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
@@ -121,7 +121,7 @@
// set control and verify visibility is applied.
InsetsSourceControl control =
- new InsetsSourceControl(ITYPE_IME, mLeash, new Point(), Insets.NONE);
+ new InsetsSourceControl(ITYPE_IME, mLeash, false, new Point(), Insets.NONE);
mController.onControlsChanged(new InsetsSourceControl[] { control });
// IME show animation should be triggered when control becomes available.
verify(mController).applyAnimation(
@@ -158,7 +158,7 @@
// set control and verify visibility is applied.
InsetsSourceControl control = Mockito.spy(
- new InsetsSourceControl(ITYPE_IME, mLeash, new Point(), Insets.NONE));
+ new InsetsSourceControl(ITYPE_IME, mLeash, false, new Point(), Insets.NONE));
// Simulate IME source control set this flag when the target has starting window.
control.setSkipAnimationOnce(true);
diff --git a/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java b/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java
index 4f1da1b2..d0f7fe04 100644
--- a/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java
+++ b/core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java
@@ -95,12 +95,13 @@
() -> mMockTransaction, mMockController);
topConsumer.setControl(
new InsetsSourceControl(
- ITYPE_STATUS_BAR, mTopLeash, new Point(0, 0), Insets.of(0, 100, 0, 0)),
+ ITYPE_STATUS_BAR, mTopLeash, true, new Point(0, 0),
+ Insets.of(0, 100, 0, 0)),
new int[1], new int[1]);
InsetsSourceConsumer navConsumer = new InsetsSourceConsumer(ITYPE_NAVIGATION_BAR,
mInsetsState, () -> mMockTransaction, mMockController);
- navConsumer.setControl(new InsetsSourceControl(ITYPE_NAVIGATION_BAR, mNavLeash,
+ navConsumer.setControl(new InsetsSourceControl(ITYPE_NAVIGATION_BAR, mNavLeash, true,
new Point(400, 0), Insets.of(0, 0, 100, 0)), new int[1], new int[1]);
navConsumer.hide();
diff --git a/core/tests/coretests/src/android/view/InsetsControllerTest.java b/core/tests/coretests/src/android/view/InsetsControllerTest.java
index dcb1835..ed6a649 100644
--- a/core/tests/coretests/src/android/view/InsetsControllerTest.java
+++ b/core/tests/coretests/src/android/view/InsetsControllerTest.java
@@ -223,7 +223,7 @@
InsetsSourceControl control =
new InsetsSourceControl(
- ITYPE_STATUS_BAR, mLeash, new Point(), Insets.of(0, 10, 0, 0));
+ ITYPE_STATUS_BAR, mLeash, true, new Point(), Insets.of(0, 10, 0, 0));
mController.onControlsChanged(new InsetsSourceControl[]{control});
mController.controlWindowInsetsAnimation(0, 0 /* durationMs */,
new LinearInterpolator(),
@@ -926,7 +926,8 @@
// Simulate binder behavior by copying SurfaceControl. Otherwise, InsetsController will
// attempt to release mLeash directly.
SurfaceControl copy = new SurfaceControl(mLeash, "InsetsControllerTest.createControl");
- return new InsetsSourceControl(type, copy, new Point(), Insets.NONE);
+ return new InsetsSourceControl(type, copy, InsetsState.getDefaultVisibility(type),
+ new Point(), Insets.NONE);
}
private InsetsSourceControl[] createSingletonControl(@InternalInsetsType int type) {
diff --git a/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java b/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java
index b3aa7e8..2054b4f 100644
--- a/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java
+++ b/core/tests/coretests/src/android/view/InsetsSourceConsumerTest.java
@@ -110,7 +110,8 @@
instrumentation.waitForIdleSync();
mConsumer.setControl(
- new InsetsSourceControl(ITYPE_STATUS_BAR, mLeash, new Point(), Insets.NONE),
+ new InsetsSourceControl(ITYPE_STATUS_BAR, mLeash, true /* initialVisible */,
+ new Point(), Insets.NONE),
new int[1], new int[1]);
}
@@ -180,7 +181,8 @@
verifyZeroInteractions(mMockTransaction);
int[] hideTypes = new int[1];
mConsumer.setControl(
- new InsetsSourceControl(ITYPE_STATUS_BAR, mLeash, new Point(), Insets.NONE),
+ new InsetsSourceControl(ITYPE_STATUS_BAR, mLeash, true /* initialVisible */,
+ new Point(), Insets.NONE),
new int[1], hideTypes);
assertEquals(statusBars(), hideTypes[0]);
assertFalse(mRemoveSurfaceCalled);
@@ -191,14 +193,14 @@
public void testRestore_noAnimation() {
InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
mConsumer.hide();
- mController.onStateChanged(mState);
mConsumer.setControl(null, new int[1], new int[1]);
reset(mMockTransaction);
verifyZeroInteractions(mMockTransaction);
mRemoveSurfaceCalled = false;
int[] hideTypes = new int[1];
mConsumer.setControl(
- new InsetsSourceControl(ITYPE_STATUS_BAR, mLeash, new Point(), Insets.NONE),
+ new InsetsSourceControl(ITYPE_STATUS_BAR, mLeash, false /* initialVisible */,
+ new Point(), Insets.NONE),
new int[1], hideTypes);
assertTrue(mRemoveSurfaceCalled);
assertEquals(0, hideTypes[0]);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayImeControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayImeControllerTest.java
index 587782c..5b691f2 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayImeControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayImeControllerTest.java
@@ -122,7 +122,7 @@
private InsetsSourceControl[] insetsSourceControl() {
return new InsetsSourceControl[]{
new InsetsSourceControl(
- ITYPE_IME, mock(SurfaceControl.class), new Point(0, 0), Insets.NONE)
+ ITYPE_IME, mock(SurfaceControl.class), false, new Point(0, 0), Insets.NONE)
};
}
diff --git a/services/core/java/com/android/server/wm/InsetsSourceProvider.java b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
index 86a73c9..bf4b65d 100644
--- a/services/core/java/com/android/server/wm/InsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
@@ -125,7 +125,8 @@
mDisplayContent = displayContent;
mStateController = stateController;
mFakeControl = new InsetsSourceControl(
- source.getType(), null /* leash */, new Point(), InsetsSourceControl.INVALID_HINTS);
+ source.getType(), null /* leash */, false /* initialVisible */, new Point(),
+ Insets.NONE);
mControllable = InsetsPolicy.isInsetsTypeControllable(source.getType());
}
@@ -468,7 +469,8 @@
final SurfaceControl leash = mAdapter.mCapturedLeash;
mControlTarget = target;
updateVisibility();
- mControl = new InsetsSourceControl(mSource.getType(), leash, surfacePosition, mInsetsHint);
+ mControl = new InsetsSourceControl(mSource.getType(), leash, mClientVisible,
+ surfacePosition, mInsetsHint);
ProtoLog.d(WM_DEBUG_WINDOW_INSETS,
"InsetsSource Control %s for target %s", mControl, mControlTarget);
@@ -553,7 +555,8 @@
// to the client in case that the client applies its transaction sooner than ours
// that we could unexpectedly overwrite the surface state.
return new InsetsSourceControl(mControl.getType(), null /* leash */,
- mControl.getSurfacePosition(), mControl.getInsetsHint());
+ mControl.isInitiallyVisible(), mControl.getSurfacePosition(),
+ mControl.getInsetsHint());
}
return mControl;
}