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:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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]);
|
||||
|
||||
@@ -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)
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user