Merge "Let insets can still be controlled if its window bounds is moved" into sc-dev

This commit is contained in:
Tiger Huang
2021-03-18 15:27:57 +00:00
committed by Android (Google) Code Review
14 changed files with 212 additions and 81 deletions

View File

@@ -20,6 +20,7 @@ import android.annotation.Nullable;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.pm.ApplicationInfo;
import android.graphics.Canvas;
import android.graphics.Insets;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.Region;
@@ -28,6 +29,7 @@ import android.os.Build.VERSION_CODES;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.DisplayMetrics;
import android.view.InsetsSourceControl;
import android.view.InsetsState;
import android.view.MotionEvent;
import android.view.WindowManager;
@@ -423,12 +425,37 @@ public class CompatibilityInfo implements Parcelable {
}
/**
* Translate an InsetsState in screen coordinates into the app window's coordinates.
* Translate an {@link InsetsState} in screen coordinates into the app window's coordinates.
*/
public void translateInsetsStateInScreenToAppWindow(InsetsState state) {
state.scale(applicationInvertedScale);
}
/**
* Translate {@link InsetsSourceControl}s in screen coordinates into the app window's
* coordinates.
*/
public void translateSourceControlsInScreenToAppWindow(InsetsSourceControl[] controls) {
if (controls == null) {
return;
}
final float scale = applicationInvertedScale;
if (scale == 1f) {
return;
}
for (InsetsSourceControl control : controls) {
if (control == null) {
continue;
}
final Insets hint = control.getInsetsHint();
control.setInsetsHint(
(int) (scale * hint.left),
(int) (scale * hint.top),
(int) (scale * hint.right),
(int) (scale * hint.bottom));
}
}
/**
* Translate a Point in screen coordinates into the app window's coordinates.
*/

View File

@@ -29,6 +29,7 @@ import static android.view.InsetsController.ANIMATION_TYPE_SHOW;
import static android.view.InsetsController.AnimationType;
import static android.view.InsetsController.DEBUG;
import static android.view.InsetsState.ISIDE_BOTTOM;
import static android.view.InsetsState.ISIDE_FLOATING;
import static android.view.InsetsState.ISIDE_LEFT;
import static android.view.InsetsState.ISIDE_RIGHT;
import static android.view.InsetsState.ISIDE_TOP;
@@ -74,8 +75,7 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll
private final WindowInsetsAnimationControlListener mListener;
private final SparseArray<InsetsSourceControl> mControls;
private final SparseIntArray mTypeSideMap = new SparseIntArray();
private final SparseSetArray<InsetsSourceControl> mSideSourceMap = new SparseSetArray<>();
private final SparseSetArray<InsetsSourceControl> mSideControlsMap = new SparseSetArray<>();
/** @see WindowInsetsAnimationController#getHiddenStateInsets */
private final Insets mHiddenInsets;
@@ -104,8 +104,8 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll
private Boolean mPerceptible;
@VisibleForTesting
public InsetsAnimationControlImpl(SparseArray<InsetsSourceControl> controls, Rect frame,
InsetsState state, WindowInsetsAnimationControlListener listener,
public InsetsAnimationControlImpl(SparseArray<InsetsSourceControl> controls,
@Nullable Rect frame, InsetsState state, WindowInsetsAnimationControlListener listener,
@InsetsType int types,
InsetsAnimationControlCallbacks controller, long durationMs, Interpolator interpolator,
@AnimationType int animationType, CompatibilityInfo.Translator translator) {
@@ -114,19 +114,30 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll
mTypes = types;
mController = controller;
mInitialInsetsState = new InsetsState(state, true /* copySources */);
mCurrentInsets = getInsetsFromState(mInitialInsetsState, frame, null /* typeSideMap */);
mPendingInsets = mCurrentInsets;
mHiddenInsets = calculateInsets(mInitialInsetsState, frame, controls, false /* shown */,
null /* typeSideMap */);
mShownInsets = calculateInsets(mInitialInsetsState, frame, controls, true /* shown */,
mTypeSideMap);
mHasZeroInsetsIme = mShownInsets.bottom == 0 && controlsInternalType(ITYPE_IME);
if (mHasZeroInsetsIme) {
// IME has shownInsets of ZERO, and can't map to a side by default.
// Map zero insets IME to bottom, making it a special case of bottom insets.
mTypeSideMap.put(ITYPE_IME, ISIDE_BOTTOM);
if (frame != null) {
final SparseIntArray typeSideMap = new SparseIntArray();
mCurrentInsets = getInsetsFromState(mInitialInsetsState, frame, null /* typeSideMap */);
mHiddenInsets = calculateInsets(mInitialInsetsState, frame, controls, false /* shown */,
null /* typeSideMap */);
mShownInsets = calculateInsets(mInitialInsetsState, frame, controls, true /* shown */,
typeSideMap);
mHasZeroInsetsIme = mShownInsets.bottom == 0 && controlsInternalType(ITYPE_IME);
if (mHasZeroInsetsIme) {
// IME has shownInsets of ZERO, and can't map to a side by default.
// Map zero insets IME to bottom, making it a special case of bottom insets.
typeSideMap.put(ITYPE_IME, ISIDE_BOTTOM);
}
buildSideControlsMap(typeSideMap, mSideControlsMap, controls);
} else {
// Passing a null frame indicates the caller wants to play the insets animation anyway,
// no matter the source provides insets to the frame or not.
mCurrentInsets = calculateInsets(mInitialInsetsState, controls, true /* shown */);
mHiddenInsets = calculateInsets(null, controls, false /* shown */);
mShownInsets = calculateInsets(null, controls, true /* shown */);
mHasZeroInsetsIme = mShownInsets.bottom == 0 && controlsInternalType(ITYPE_IME);
buildSideControlsMap(mSideControlsMap, controls);
}
buildTypeSourcesMap(mTypeSideMap, mSideSourceMap, mControls);
mPendingInsets = mCurrentInsets;
mAnimation = new WindowInsetsAnimation(mTypes, interpolator,
durationMs);
@@ -312,25 +323,10 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll
proto.end(token);
}
WindowInsetsAnimationControlListener getListener() {
return mListener;
}
SparseArray<InsetsSourceControl> getControls() {
return mControls;
}
private Insets calculateInsets(InsetsState state, Rect frame,
SparseArray<InsetsSourceControl> controls, boolean shown,
@Nullable @InternalInsetsSide SparseIntArray typeSideMap) {
for (int i = controls.size() - 1; i >= 0; i--) {
// control may be null if it got revoked.
if (controls.valueAt(i) == null) continue;
state.getSource(controls.valueAt(i).getType()).setVisible(shown);
}
return getInsetsFromState(state, frame, typeSideMap);
}
private Insets getInsetsFromState(InsetsState state, Rect frame,
@Nullable @InternalInsetsSide SparseIntArray typeSideMap) {
return state.calculateInsets(frame, null /* ignoringVisibilityState */,
@@ -340,6 +336,41 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll
WINDOWING_MODE_UNDEFINED, typeSideMap).getInsets(mTypes);
}
/** Computes the insets relative to the given frame. */
private Insets calculateInsets(InsetsState state, Rect frame,
SparseArray<InsetsSourceControl> controls, boolean shown,
@Nullable @InternalInsetsSide SparseIntArray typeSideMap) {
for (int i = controls.size() - 1; i >= 0; i--) {
final InsetsSourceControl control = controls.valueAt(i);
if (control == null) {
// control may be null if it got revoked.
continue;
}
state.getSource(control.getType()).setVisible(shown);
}
return getInsetsFromState(state, frame, typeSideMap);
}
/** Computes the insets from the insets hints of controls. */
private Insets calculateInsets(InsetsState state, SparseArray<InsetsSourceControl> controls,
boolean shownOrCurrent) {
Insets insets = Insets.NONE;
if (!shownOrCurrent) {
return insets;
}
for (int i = controls.size() - 1; i >= 0; i--) {
final InsetsSourceControl control = controls.valueAt(i);
if (control == null) {
// control may be null if it got revoked.
continue;
}
if (state == null || state.getSource(control.getType()).isVisible()) {
insets = Insets.max(insets, control.getInsetsHint());
}
}
return insets;
}
private Insets sanitize(Insets insets) {
if (insets == null) {
insets = getCurrentInsets();
@@ -356,13 +387,13 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll
private void updateLeashesForSide(@InternalInsetsSide int side, int offset, int inset,
ArrayList<SurfaceParams> surfaceParams, @Nullable InsetsState outState, float alpha) {
ArraySet<InsetsSourceControl> items = mSideSourceMap.get(side);
if (items == null) {
final ArraySet<InsetsSourceControl> controls = mSideControlsMap.get(side);
if (controls == null) {
return;
}
// TODO: Implement behavior when inset spans over multiple types
for (int i = items.size() - 1; i >= 0; i--) {
final InsetsSourceControl control = items.valueAt(i);
for (int i = controls.size() - 1; i >= 0; i--) {
final InsetsSourceControl control = controls.valueAt(i);
final InsetsSource source = mInitialInsetsState.getSource(control.getType());
final SurfaceControl leash = control.getLeash();
@@ -371,7 +402,7 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll
addTranslationToMatrix(side, offset, mTmpMatrix, mTmpFrame);
final boolean visible = mHasZeroInsetsIme && side == ISIDE_BOTTOM
? (mAnimationType == ANIMATION_TYPE_SHOW ? true : !mFinished)
? (mAnimationType == ANIMATION_TYPE_SHOW || !mFinished)
: inset != 0;
if (outState != null) {
@@ -391,32 +422,32 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll
}
}
private void addTranslationToMatrix(@InternalInsetsSide int side, int inset, Matrix m,
private void addTranslationToMatrix(@InternalInsetsSide int side, int offset, Matrix m,
Rect frame) {
final float surfaceOffset = mTranslator != null
? mTranslator.translateLengthInAppWindowToScreen(inset) : inset;
? mTranslator.translateLengthInAppWindowToScreen(offset) : offset;
switch (side) {
case ISIDE_LEFT:
m.postTranslate(-surfaceOffset, 0);
frame.offset(-inset, 0);
frame.offset(-offset, 0);
break;
case ISIDE_TOP:
m.postTranslate(0, -surfaceOffset);
frame.offset(0, -inset);
frame.offset(0, -offset);
break;
case ISIDE_RIGHT:
m.postTranslate(surfaceOffset, 0);
frame.offset(inset, 0);
frame.offset(offset, 0);
break;
case ISIDE_BOTTOM:
m.postTranslate(0, surfaceOffset);
frame.offset(0, inset);
frame.offset(0, offset);
break;
}
}
private static void buildTypeSourcesMap(SparseIntArray typeSideMap,
SparseSetArray<InsetsSourceControl> sideSourcesMap,
private static void buildSideControlsMap(SparseIntArray typeSideMap,
SparseSetArray<InsetsSourceControl> sideControlsMap,
SparseArray<InsetsSourceControl> controls) {
for (int i = typeSideMap.size() - 1; i >= 0; i--) {
final int type = typeSideMap.keyAt(i);
@@ -427,7 +458,24 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll
// there can be some null controllers.
continue;
}
sideSourcesMap.add(side, control);
sideControlsMap.add(side, control);
}
}
private static void buildSideControlsMap(
SparseSetArray<InsetsSourceControl> sideControlsMap,
SparseArray<InsetsSourceControl> controls) {
for (int i = controls.size() - 1; i >= 0; i--) {
final InsetsSourceControl control = controls.valueAt(i);
if (control == null) {
// control may be null if it got revoked.
continue;
}
@InternalInsetsSide int side = InsetsState.getInsetSide(control.getInsetsHint());
if (side == ISIDE_FLOATING && control.getType() == ITYPE_IME) {
side = ISIDE_BOTTOM;
}
sideControlsMap.add(side, control);
}
}
}

View File

@@ -19,6 +19,7 @@ package android.view;
import static android.view.InsetsController.DEBUG;
import static android.view.SyncRtSurfaceTransactionApplier.applyParams;
import android.annotation.Nullable;
import android.annotation.UiThread;
import android.content.res.CompatibilityInfo;
import android.graphics.Rect;
@@ -100,8 +101,8 @@ public class InsetsAnimationThreadControlRunner implements InsetsAnimationContro
};
@UiThread
public InsetsAnimationThreadControlRunner(SparseArray<InsetsSourceControl> controls, Rect frame,
InsetsState state, WindowInsetsAnimationControlListener listener,
public InsetsAnimationThreadControlRunner(SparseArray<InsetsSourceControl> controls,
@Nullable Rect frame, InsetsState state, WindowInsetsAnimationControlListener listener,
@InsetsType int types,
InsetsAnimationControlCallbacks controller, long durationMs, Interpolator interpolator,
@AnimationType int animationType, CompatibilityInfo.Translator translator,

View File

@@ -837,9 +837,12 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
PendingControlRequest pendingRequest = mPendingImeControlRequest;
mPendingImeControlRequest = null;
mHandler.removeCallbacks(mPendingControlTimeout);
// We are about to playing the default animation. Passing a null frame indicates the
// controlled types should be animated regardless of the frame.
controlAnimationUnchecked(
pendingRequest.types, pendingRequest.cancellationSignal,
pendingRequest.listener, mFrame,
pendingRequest.listener, null /* frame */,
true /* fromIme */, pendingRequest.durationMs, pendingRequest.interpolator,
pendingRequest.animationType,
pendingRequest.layoutInsetsDuringAnimation,
@@ -934,7 +937,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
private void controlAnimationUnchecked(@InsetsType int types,
@Nullable CancellationSignal cancellationSignal,
WindowInsetsAnimationControlListener listener, Rect frame, boolean fromIme,
WindowInsetsAnimationControlListener listener, @Nullable Rect frame, boolean fromIme,
long durationMs, Interpolator interpolator,
@AnimationType int animationType,
@LayoutInsetsDuringAnimation int layoutInsetsDuringAnimation,
@@ -1358,10 +1361,10 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation
show, hasAnimationCallbacks, types, skipAnim || mAnimationsDisabled,
mHost.dipToPx(InternalAnimationControlListener.FLOATING_IME_BOTTOM_INSET));
// Show/hide animations always need to be relative to the display frame, in order that shown
// and hidden state insets are correct.
// We are about to playing the default animation (show/hide). Passing a null frame indicates
// the controlled types should be animated regardless of the frame.
controlAnimationUnchecked(
types, null /* cancellationSignal */, listener, mState.getDisplayFrame(), fromIme,
types, null /* cancellationSignal */, listener, null /* frame */, fromIme,
listener.getDurationMs(), listener.getInterpolator(),
show ? ANIMATION_TYPE_SHOW : ANIMATION_TYPE_HIDE,
show ? LAYOUT_INSETS_DURING_ANIMATION_SHOWN : LAYOUT_INSETS_DURING_ANIMATION_HIDDEN,

View File

@@ -23,6 +23,7 @@ import static android.view.InsetsSourceControlProto.POSITION;
import static android.view.InsetsSourceControlProto.TYPE;
import android.annotation.Nullable;
import android.graphics.Insets;
import android.graphics.Point;
import android.os.Parcel;
import android.os.Parcelable;
@@ -41,13 +42,19 @@ public class InsetsSourceControl implements Parcelable {
private final @InternalInsetsType int mType;
private final @Nullable SurfaceControl mLeash;
private final Point mSurfacePosition;
// This is used while playing an insets animation regardless of the relative frame. This would
// be the insets received by the bounds of its source window.
private Insets mInsetsHint;
private boolean mSkipAnimationOnce;
public InsetsSourceControl(@InternalInsetsType int type, @Nullable SurfaceControl leash,
Point surfacePosition) {
Point surfacePosition, Insets insetsHint) {
mType = type;
mLeash = leash;
mSurfacePosition = surfacePosition;
mInsetsHint = insetsHint;
}
public InsetsSourceControl(InsetsSourceControl other) {
@@ -58,9 +65,18 @@ public class InsetsSourceControl implements Parcelable {
mLeash = null;
}
mSurfacePosition = new Point(other.mSurfacePosition);
mInsetsHint = other.mInsetsHint;
mSkipAnimationOnce = other.getAndClearSkipAnimationOnce();
}
public InsetsSourceControl(Parcel in) {
mType = in.readInt();
mLeash = in.readTypedObject(SurfaceControl.CREATOR);
mSurfacePosition = in.readTypedObject(Point.CREATOR);
mInsetsHint = in.readTypedObject(Insets.CREATOR);
mSkipAnimationOnce = in.readBoolean();
}
public int getType() {
return mType;
}
@@ -75,13 +91,6 @@ public class InsetsSourceControl implements Parcelable {
return mLeash;
}
public InsetsSourceControl(Parcel in) {
mType = in.readInt();
mLeash = in.readTypedObject(SurfaceControl.CREATOR);
mSurfacePosition = in.readTypedObject(Point.CREATOR);
mSkipAnimationOnce = in.readBoolean();
}
public boolean setSurfacePosition(int left, int top) {
if (mSurfacePosition.equals(left, top)) {
return false;
@@ -90,14 +99,26 @@ public class InsetsSourceControl implements Parcelable {
return true;
}
public void setSkipAnimationOnce(boolean skipAnimation) {
mSkipAnimationOnce = skipAnimation;
}
public Point getSurfacePosition() {
return mSurfacePosition;
}
public void setInsetsHint(Insets insets) {
mInsetsHint = insets;
}
public void setInsetsHint(int left, int top, int right, int bottom) {
mInsetsHint = Insets.of(left, top, right, bottom);
}
public Insets getInsetsHint() {
return mInsetsHint;
}
public void setSkipAnimationOnce(boolean skipAnimation) {
mSkipAnimationOnce = skipAnimation;
}
/**
* Get the state whether the current control needs to skip animation or not.
*
@@ -121,6 +142,7 @@ public class InsetsSourceControl implements Parcelable {
dest.writeInt(mType);
dest.writeTypedObject(mLeash, 0 /* parcelableFlags */);
dest.writeTypedObject(mSurfacePosition, 0 /* parcelableFlags */);
dest.writeTypedObject(mInsetsHint, 0 /* parcelableFlags */);
dest.writeBoolean(mSkipAnimationOnce);
}
@@ -135,6 +157,7 @@ public class InsetsSourceControl implements Parcelable {
pw.print("InsetsSourceControl type="); pw.print(InsetsState.typeToString(mType));
pw.print(" mLeash="); pw.print(mLeash);
pw.print(" mSurfacePosition="); pw.print(mSurfacePosition);
pw.print(" mInsetsHint="); pw.print(mInsetsHint);
pw.print(" mSkipAnimationOnce="); pw.print(mSkipAnimationOnce);
pw.println();
}

View File

@@ -400,7 +400,7 @@ public class InsetsState implements Parcelable {
* Retrieves the side for a certain {@code insets}. It is required that only one field l/t/r/b
* is set in order that this method returns a meaningful result.
*/
private @InternalInsetsSide int getInsetSide(Insets insets) {
static @InternalInsetsSide int getInsetSide(Insets insets) {
if (Insets.NONE.equals(insets)) {
return ISIDE_FLOATING;
}

View File

@@ -1100,6 +1100,7 @@ public final class ViewRootImpl implements ViewParent,
mTempControls);
if (mTranslator != null) {
mTranslator.translateInsetsStateInScreenToAppWindow(mTempInsets);
mTranslator.translateSourceControlsInScreenToAppWindow(mTempControls);
}
} catch (RemoteException e) {
mAdded = false;
@@ -7699,6 +7700,7 @@ public final class ViewRootImpl implements ViewParent,
if (mTranslator != null) {
mTranslator.translateRectInScreenToAppWindow(mTmpFrames.frame);
mTranslator.translateInsetsStateInScreenToAppWindow(mTempInsets);
mTranslator.translateSourceControlsInScreenToAppWindow(mTempControls);
}
setFrame(mTmpFrames.frame);
mInsetsController.onStateChanged(mTempInsets);
@@ -8158,6 +8160,7 @@ public final class ViewRootImpl implements ViewParent,
}
if (mTranslator != null) {
mTranslator.translateInsetsStateInScreenToAppWindow(insetsState);
mTranslator.translateSourceControlsInScreenToAppWindow(activeControls);
}
if (insetsState != null && insetsState.getSource(ITYPE_IME).isVisible()) {
ImeTracing.getInstance().triggerClientDump("ViewRootImpl#dispatchInsetsControlChanged",

View File

@@ -91,7 +91,8 @@ public class ImeInsetsSourceConsumerTest {
@Test
public void testImeVisibility() {
final InsetsSourceControl ime = new InsetsSourceControl(ITYPE_IME, mLeash, new Point());
final InsetsSourceControl ime =
new InsetsSourceControl(ITYPE_IME, mLeash, new Point(), Insets.NONE);
mController.onControlsChanged(new InsetsSourceControl[] { ime });
InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
@@ -119,7 +120,8 @@ public class ImeInsetsSourceConsumerTest {
mImeConsumer.applyImeVisibility(true /* setVisible */);
// set control and verify visibility is applied.
InsetsSourceControl control = new InsetsSourceControl(ITYPE_IME, mLeash, new Point());
InsetsSourceControl control =
new InsetsSourceControl(ITYPE_IME, mLeash, new Point(), Insets.NONE);
mController.onControlsChanged(new InsetsSourceControl[] { control });
// IME show animation should be triggered when control becomes available.
verify(mController).applyAnimation(
@@ -138,7 +140,7 @@ public class ImeInsetsSourceConsumerTest {
// set control and verify visibility is applied.
InsetsSourceControl control = Mockito.spy(
new InsetsSourceControl(ITYPE_IME, mLeash, new Point()));
new InsetsSourceControl(ITYPE_IME, mLeash, new Point(), Insets.NONE));
// Simulate IME source control set this flag when the target has starting window.
control.setSkipAnimationOnce(true);
mController.onControlsChanged(new InsetsSourceControl[] { control });

View File

@@ -94,13 +94,14 @@ public class InsetsAnimationControlImplTest {
InsetsSourceConsumer topConsumer = new InsetsSourceConsumer(ITYPE_STATUS_BAR, mInsetsState,
() -> mMockTransaction, mMockController);
topConsumer.setControl(
new InsetsSourceControl(ITYPE_STATUS_BAR, mTopLeash, new Point(0, 0)),
new InsetsSourceControl(
ITYPE_STATUS_BAR, mTopLeash, 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,
new Point(400, 0)), new int[1], new int[1]);
new Point(400, 0), Insets.of(0, 0, 100, 0)), new int[1], new int[1]);
navConsumer.hide();
SparseArray<InsetsSourceControl> controls = new SparseArray<>();

View File

@@ -213,7 +213,8 @@ public class InsetsControllerTest {
mController.onFrameChanged(new Rect(0, 0, 100, 100));
mController.getState().setDisplayFrame(new Rect(0, 0, 200, 200));
InsetsSourceControl control =
new InsetsSourceControl(ITYPE_STATUS_BAR, mLeash, new Point());
new InsetsSourceControl(
ITYPE_STATUS_BAR, mLeash, new Point(), Insets.of(0, 10, 0, 0));
mController.onControlsChanged(new InsetsSourceControl[] { control });
WindowInsetsAnimationControlListener controlListener =
mock(WindowInsetsAnimationControlListener.class);
@@ -814,7 +815,7 @@ 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());
return new InsetsSourceControl(type, copy, new Point(), Insets.NONE);
}
private InsetsSourceControl[] createSingletonControl(@InternalInsetsType int type) {

View File

@@ -34,6 +34,7 @@ import static org.mockito.Mockito.verifyZeroInteractions;
import android.app.Instrumentation;
import android.content.Context;
import android.graphics.Insets;
import android.graphics.Point;
import android.graphics.Rect;
import android.platform.test.annotations.Presubmit;
@@ -108,7 +109,8 @@ public class InsetsSourceConsumerTest {
});
instrumentation.waitForIdleSync();
mConsumer.setControl(new InsetsSourceControl(ITYPE_STATUS_BAR, mLeash, new Point()),
mConsumer.setControl(
new InsetsSourceControl(ITYPE_STATUS_BAR, mLeash, new Point(), Insets.NONE),
new int[1], new int[1]);
}
@@ -177,7 +179,8 @@ public class InsetsSourceConsumerTest {
mConsumer.hide();
verifyZeroInteractions(mMockTransaction);
int[] hideTypes = new int[1];
mConsumer.setControl(new InsetsSourceControl(ITYPE_STATUS_BAR, mLeash, new Point()),
mConsumer.setControl(
new InsetsSourceControl(ITYPE_STATUS_BAR, mLeash, new Point(), Insets.NONE),
new int[1], hideTypes);
assertEquals(statusBars(), hideTypes[0]);
assertFalse(mRemoveSurfaceCalled);
@@ -194,7 +197,8 @@ public class InsetsSourceConsumerTest {
verifyZeroInteractions(mMockTransaction);
mRemoveSurfaceCalled = false;
int[] hideTypes = new int[1];
mConsumer.setControl(new InsetsSourceControl(ITYPE_STATUS_BAR, mLeash, new Point()),
mConsumer.setControl(
new InsetsSourceControl(ITYPE_STATUS_BAR, mLeash, new Point(), Insets.NONE),
new int[1], hideTypes);
assertTrue(mRemoveSurfaceCalled);
assertEquals(0, hideTypes[0]);

View File

@@ -29,6 +29,7 @@ import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
import android.graphics.Insets;
import android.graphics.Point;
import android.view.InsetsSource;
import android.view.InsetsSourceControl;
@@ -119,7 +120,8 @@ public class DisplayImeControllerTest {
private InsetsSourceControl[] insetsSourceControl() {
return new InsetsSourceControl[]{
new InsetsSourceControl(ITYPE_IME, mock(SurfaceControl.class), new Point(0, 0))
new InsetsSourceControl(
ITYPE_IME, mock(SurfaceControl.class), new Point(0, 0), Insets.NONE)
};
}

View File

@@ -492,8 +492,11 @@ class InsetsPolicy {
mAnimatingShown = show;
final InsetsState state = getInsetsForWindow(mFocusedWin);
// We are about to playing the default animation. Passing a null frame indicates
// the controlled types should be animated regardless of the frame.
mAnimationControl = new InsetsAnimationControlImpl(controls,
state.getDisplayFrame(), state, mListener, typesReady, this,
null /* frame */, state, mListener, typesReady, this,
mListener.getDurationMs(), InsetsController.SYSTEM_BARS_INTERPOLATOR,
show ? ANIMATION_TYPE_SHOW : ANIMATION_TYPE_HIDE, null /* translator */);
SurfaceAnimationThread.getHandler().post(

View File

@@ -43,6 +43,7 @@ import static com.android.server.wm.WindowManagerService.H.LAYOUT_AND_ASSIGN_WIN
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.graphics.Insets;
import android.graphics.Point;
import android.graphics.Rect;
import android.util.proto.ProtoOutputStream;
@@ -102,7 +103,8 @@ class InsetsSourceProvider {
mSource = source;
mDisplayContent = displayContent;
mStateController = stateController;
mFakeControl = new InsetsSourceControl(source.getType(), null /* leash */, new Point());
mFakeControl = new InsetsSourceControl(
source.getType(), null /* leash */, new Point(), Insets.NONE);
switch (source.getType()) {
case ITYPE_STATUS_BAR:
@@ -246,8 +248,10 @@ class InsetsSourceProvider {
setServerVisible(mWin.wouldBeVisibleIfPolicyIgnored() && mWin.isVisibleByPolicy());
updateSourceFrame();
if (mControl != null) {
boolean changed = false;
final Point position = getWindowFrameSurfacePosition();
if (mControl.setSurfacePosition(position.x, position.y) && mControlTarget != null) {
changed = true;
if (!mWin.getWindowFrames().didFrameSizeChange()) {
updateLeashPosition(-1 /* frameNumber */);
} else if (mWin.mInRelayout) {
@@ -255,6 +259,14 @@ class InsetsSourceProvider {
} else {
mWin.mPendingPositionChanged = this;
}
}
final Insets insetsHint = mSource.calculateInsets(
mWin.getBounds(), true /* ignoreVisibility */);
if (!insetsHint.equals(mControl.getInsetsHint())) {
changed = true;
mControl.setInsetsHint(insetsHint);
}
if (changed) {
mStateController.notifyControlChanged(mControlTarget);
}
}
@@ -343,7 +355,8 @@ class InsetsSourceProvider {
final SurfaceControl leash = mAdapter.mCapturedLeash;
mControlTarget = target;
updateVisibility();
mControl = new InsetsSourceControl(mSource.getType(), leash, surfacePosition);
mControl = new InsetsSourceControl(mSource.getType(), leash, surfacePosition,
mSource.calculateInsets(mWin.getBounds(), true /* ignoreVisibility */));
ProtoLog.d(WM_DEBUG_IME,
"InsetsSource Control %s for target %s", mControl, mControlTarget);
}
@@ -418,7 +431,7 @@ 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.getSurfacePosition(), mControl.getInsetsHint());
}
return mControl;
}