Merge "Let insets can still be controlled if its window bounds is moved" into sc-dev
This commit is contained in:
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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 });
|
||||
|
||||
@@ -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<>();
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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]);
|
||||
|
||||
@@ -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)
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user