Merge "Let the client know the initial visibility of an InsetsSourceControl" into tm-qpr-dev am: b4a6c4bf46 am: 8210f8087d

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/19379426

Change-Id: Ifbf0e17c23469ed03c414e626de46e8536a8bb52
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Tiger Huang
2022-07-29 00:01:17 +00:00
committed by Automerger Merge Worker
8 changed files with 45 additions and 58 deletions

View File

@@ -25,7 +25,6 @@ import static android.view.InsetsSourceConsumerProto.IS_REQUESTED_VISIBLE;
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 static com.android.internal.annotations.VisibleForTesting.Visibility.PACK
import android.annotation.IntDef;
import android.annotation.Nullable;
import android.graphics.Insets;
import android.graphics.Rect;
import android.util.ArraySet;
import android.util.Log;
@@ -93,13 +91,6 @@ public class InsetsSourceConsumer {
private Rect mPendingFrame;
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.
@@ -138,7 +129,6 @@ public class InsetsSourceConsumer {
}
return false;
}
SurfaceControl oldLeash = mSourceControl != null ? mSourceControl.getLeash() : null;
final InsetsSourceControl lastControl = mSourceControl;
mSourceControl = control;
@@ -163,27 +153,21 @@ public class InsetsSourceConsumer {
// 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 @@ public class InsetsSourceConsumer {
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 @@ public class InsetsSourceConsumer {
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);
}

View File

@@ -31,6 +31,7 @@ import android.util.proto.ProtoOutputStream;
import android.view.InsetsState.InternalInsetsType;
import java.io.PrintWriter;
import java.util.Objects;
import java.util.function.Consumer;
/**
@@ -39,10 +40,9 @@ import java.util.function.Consumer;
*/
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 @@ public class InsetsSourceControl implements Parcelable {
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 @@ public class InsetsSourceControl implements Parcelable {
} else {
mLeash = null;
}
mInitiallyVisible = other.mInitiallyVisible;
mSurfacePosition = new Point(other.mSurfacePosition);
mInsetsHint = other.mInsetsHint;
mSkipAnimationOnce = other.getAndClearSkipAnimationOnce();
@@ -75,6 +77,7 @@ public class InsetsSourceControl implements Parcelable {
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 @@ public class InsetsSourceControl implements Parcelable {
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 class InsetsSourceControl implements Parcelable {
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 @@ public class InsetsSourceControl implements Parcelable {
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 @@ public class InsetsSourceControl implements Parcelable {
@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 @@ public class InsetsSourceControl implements Parcelable {
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);

View File

@@ -92,7 +92,7 @@ public class ImeInsetsSourceConsumerTest {
@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 @@ public class ImeInsetsSourceConsumerTest {
// 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 @@ public class ImeInsetsSourceConsumerTest {
// 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);

View File

@@ -95,12 +95,13 @@ public class InsetsAnimationControlImplTest {
() -> 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();

View File

@@ -223,7 +223,7 @@ public class InsetsControllerTest {
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 @@ public class InsetsControllerTest {
// 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) {

View File

@@ -110,7 +110,8 @@ public class InsetsSourceConsumerTest {
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 @@ public class InsetsSourceConsumerTest {
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 class InsetsSourceConsumerTest {
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]);

View File

@@ -122,7 +122,7 @@ public class DisplayImeControllerTest extends ShellTestCase {
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)
};
}

View File

@@ -125,7 +125,8 @@ abstract class InsetsSourceProvider {
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 @@ abstract class InsetsSourceProvider {
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 @@ abstract class InsetsSourceProvider {
// 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;
}