Loading core/java/android/view/InsetsAnimationControlImpl.java +25 −8 Original line number Diff line number Diff line Loading @@ -16,13 +16,14 @@ package android.view; 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; import static android.view.InsetsState.ITYPE_IME; import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE; Loading Loading @@ -74,6 +75,8 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll private final @InsetsType int mTypes; private final InsetsAnimationControlCallbacks mController; private final WindowInsetsAnimation mAnimation; /** @see WindowInsetsAnimationController#hasZeroInsetsIme */ private final boolean mHasZeroInsetsIme; private Insets mCurrentInsets; private Insets mPendingInsets; private float mPendingFraction; Loading Loading @@ -102,6 +105,12 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll 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); } buildTypeSourcesMap(mTypeSideMap, mSideSourceMap, mControls); mAnimation = new WindowInsetsAnimation(mTypes, interpolator, Loading @@ -112,6 +121,11 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll new Bounds(mHiddenInsets, mShownInsets)); } @Override public boolean hasZeroInsetsIme() { return mHasZeroInsetsIme; } @Override public Insets getHiddenStateInsets() { return mHiddenInsets; Loading Loading @@ -182,8 +196,6 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll params, state, mPendingAlpha); updateLeashesForSide(ISIDE_BOTTOM, offset.bottom, mShownInsets.bottom, mPendingInsets.bottom, params, state, mPendingAlpha); updateLeashesForSide(ISIDE_FLOATING, 0 /* offset */, 0 /* inset */, 0 /* maxInset */, params, state, mPendingAlpha); mController.applySurfaceParams(params.toArray(new SurfaceParams[params.size()])); mCurrentInsets = mPendingInsets; Loading Loading @@ -290,6 +302,9 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll if (insets == null) { insets = getCurrentInsets(); } if (hasZeroInsetsIme()) { return insets; } return Insets.max(Insets.min(insets, mShownInsets), mHiddenInsets); } Loading @@ -313,17 +328,19 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll mTmpFrame.set(source.getFrame()); addTranslationToMatrix(side, offset, mTmpMatrix, mTmpFrame); state.getSource(source.getType()).setVisible(side == ISIDE_FLOATING || inset != 0); final boolean visible = mHasZeroInsetsIme && side == ISIDE_BOTTOM ? (mAnimationType == ANIMATION_TYPE_SHOW ? true : !mFinished) : inset != 0; state.getSource(source.getType()).setVisible(visible); state.getSource(source.getType()).setFrame(mTmpFrame); // If the system is controlling the insets source, the leash can be null. if (leash != null) { SurfaceParams params = new SurfaceParams.Builder(leash) .withAlpha(side == ISIDE_FLOATING ? 1 : alpha) .withAlpha(alpha) .withMatrix(mTmpMatrix) .withVisibility(side == ISIDE_FLOATING ? mShownOnFinish : inset != 0 /* visible */) .withVisibility(visible) .build(); surfaceParams.add(params); } Loading core/java/android/view/InsetsController.java +20 −4 Original line number Diff line number Diff line Loading @@ -162,6 +162,9 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation */ @Nullable String getRootViewTitle(); /** @see ViewRootImpl#dipToPx */ int dipToPx(int dips); } private static final String TAG = "InsetsController"; Loading Loading @@ -254,6 +257,9 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation public static class InternalAnimationControlListener implements WindowInsetsAnimationControlListener { /** The amount IME will move up/down when animating in floating mode. */ protected static final int FLOATING_IME_BOTTOM_INSET = -80; private WindowInsetsAnimationController mController; private ValueAnimator mAnimator; private final boolean mShow; Loading @@ -261,6 +267,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation private final @InsetsType int mRequestedTypes; private final long mDurationMs; private final boolean mDisable; private final int mFloatingImeBottomInset; private ThreadLocal<AnimationHandler> mSfAnimationHandlerThreadLocal = new ThreadLocal<AnimationHandler>() { Loading @@ -273,12 +280,13 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation }; public InternalAnimationControlListener(boolean show, boolean hasAnimationCallbacks, int requestedTypes, boolean disable) { int requestedTypes, boolean disable, int floatingImeBottomInset) { mShow = show; mHasAnimationCallbacks = hasAnimationCallbacks; mRequestedTypes = requestedTypes; mDurationMs = calculateDurationMs(); mDisable = disable; mFloatingImeBottomInset = floatingImeBottomInset; } @Override Loading @@ -293,12 +301,19 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation mAnimator = ValueAnimator.ofFloat(0f, 1f); mAnimator.setDuration(mDurationMs); mAnimator.setInterpolator(new LinearInterpolator()); Insets hiddenInsets = controller.getHiddenStateInsets(); // IME with zero insets is a special case: it will animate-in from offscreen and end // with final insets of zero and vice-versa. hiddenInsets = controller.hasZeroInsetsIme() ? Insets.of(hiddenInsets.left, hiddenInsets.top, hiddenInsets.right, mFloatingImeBottomInset) : hiddenInsets; Insets start = mShow ? controller.getHiddenStateInsets() ? hiddenInsets : controller.getShownStateInsets(); Insets end = mShow ? controller.getShownStateInsets() : controller.getHiddenStateInsets(); : hiddenInsets; Interpolator insetsInterpolator = getInterpolator(); Interpolator alphaInterpolator = getAlphaInterpolator(); mAnimator.addUpdateListener(animation -> { Loading Loading @@ -1173,7 +1188,8 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation boolean hasAnimationCallbacks = mHost.hasAnimationCallbacks(); final InternalAnimationControlListener listener = new InternalAnimationControlListener( show, hasAnimationCallbacks, types, mAnimationsDisabled); show, hasAnimationCallbacks, types, 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. Loading core/java/android/view/ViewRootImpl.java +1 −1 Original line number Diff line number Diff line Loading @@ -2315,7 +2315,7 @@ public final class ViewRootImpl implements ViewParent, || lp.type == TYPE_VOLUME_OVERLAY; } private int dipToPx(int dip) { int dipToPx(int dip) { final DisplayMetrics displayMetrics = mContext.getResources().getDisplayMetrics(); return (int) (displayMetrics.density * dip + 0.5f); } Loading core/java/android/view/ViewRootInsetsControllerHost.java +8 −0 Original line number Diff line number Diff line Loading @@ -228,4 +228,12 @@ public class ViewRootInsetsControllerHost implements InsetsController.Host { } return mViewRoot.getTitle().toString(); } @Override public int dipToPx(int dips) { if (mViewRoot != null) { return mViewRoot.dipToPx(dips); } return 0; } } core/java/android/view/WindowInsetsAnimationController.java +7 −0 Original line number Diff line number Diff line Loading @@ -181,4 +181,11 @@ public interface WindowInsetsAnimationController { * @return {@code true} if the instance is cancelled, {@code false} otherwise. */ boolean isCancelled(); /** * @hide * @return {@code true} when controller controls IME and IME has no insets (floating, * fullscreen or non-overlapping). */ boolean hasZeroInsetsIme(); } Loading
core/java/android/view/InsetsAnimationControlImpl.java +25 −8 Original line number Diff line number Diff line Loading @@ -16,13 +16,14 @@ package android.view; 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; import static android.view.InsetsState.ITYPE_IME; import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE; Loading Loading @@ -74,6 +75,8 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll private final @InsetsType int mTypes; private final InsetsAnimationControlCallbacks mController; private final WindowInsetsAnimation mAnimation; /** @see WindowInsetsAnimationController#hasZeroInsetsIme */ private final boolean mHasZeroInsetsIme; private Insets mCurrentInsets; private Insets mPendingInsets; private float mPendingFraction; Loading Loading @@ -102,6 +105,12 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll 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); } buildTypeSourcesMap(mTypeSideMap, mSideSourceMap, mControls); mAnimation = new WindowInsetsAnimation(mTypes, interpolator, Loading @@ -112,6 +121,11 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll new Bounds(mHiddenInsets, mShownInsets)); } @Override public boolean hasZeroInsetsIme() { return mHasZeroInsetsIme; } @Override public Insets getHiddenStateInsets() { return mHiddenInsets; Loading Loading @@ -182,8 +196,6 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll params, state, mPendingAlpha); updateLeashesForSide(ISIDE_BOTTOM, offset.bottom, mShownInsets.bottom, mPendingInsets.bottom, params, state, mPendingAlpha); updateLeashesForSide(ISIDE_FLOATING, 0 /* offset */, 0 /* inset */, 0 /* maxInset */, params, state, mPendingAlpha); mController.applySurfaceParams(params.toArray(new SurfaceParams[params.size()])); mCurrentInsets = mPendingInsets; Loading Loading @@ -290,6 +302,9 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll if (insets == null) { insets = getCurrentInsets(); } if (hasZeroInsetsIme()) { return insets; } return Insets.max(Insets.min(insets, mShownInsets), mHiddenInsets); } Loading @@ -313,17 +328,19 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll mTmpFrame.set(source.getFrame()); addTranslationToMatrix(side, offset, mTmpMatrix, mTmpFrame); state.getSource(source.getType()).setVisible(side == ISIDE_FLOATING || inset != 0); final boolean visible = mHasZeroInsetsIme && side == ISIDE_BOTTOM ? (mAnimationType == ANIMATION_TYPE_SHOW ? true : !mFinished) : inset != 0; state.getSource(source.getType()).setVisible(visible); state.getSource(source.getType()).setFrame(mTmpFrame); // If the system is controlling the insets source, the leash can be null. if (leash != null) { SurfaceParams params = new SurfaceParams.Builder(leash) .withAlpha(side == ISIDE_FLOATING ? 1 : alpha) .withAlpha(alpha) .withMatrix(mTmpMatrix) .withVisibility(side == ISIDE_FLOATING ? mShownOnFinish : inset != 0 /* visible */) .withVisibility(visible) .build(); surfaceParams.add(params); } Loading
core/java/android/view/InsetsController.java +20 −4 Original line number Diff line number Diff line Loading @@ -162,6 +162,9 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation */ @Nullable String getRootViewTitle(); /** @see ViewRootImpl#dipToPx */ int dipToPx(int dips); } private static final String TAG = "InsetsController"; Loading Loading @@ -254,6 +257,9 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation public static class InternalAnimationControlListener implements WindowInsetsAnimationControlListener { /** The amount IME will move up/down when animating in floating mode. */ protected static final int FLOATING_IME_BOTTOM_INSET = -80; private WindowInsetsAnimationController mController; private ValueAnimator mAnimator; private final boolean mShow; Loading @@ -261,6 +267,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation private final @InsetsType int mRequestedTypes; private final long mDurationMs; private final boolean mDisable; private final int mFloatingImeBottomInset; private ThreadLocal<AnimationHandler> mSfAnimationHandlerThreadLocal = new ThreadLocal<AnimationHandler>() { Loading @@ -273,12 +280,13 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation }; public InternalAnimationControlListener(boolean show, boolean hasAnimationCallbacks, int requestedTypes, boolean disable) { int requestedTypes, boolean disable, int floatingImeBottomInset) { mShow = show; mHasAnimationCallbacks = hasAnimationCallbacks; mRequestedTypes = requestedTypes; mDurationMs = calculateDurationMs(); mDisable = disable; mFloatingImeBottomInset = floatingImeBottomInset; } @Override Loading @@ -293,12 +301,19 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation mAnimator = ValueAnimator.ofFloat(0f, 1f); mAnimator.setDuration(mDurationMs); mAnimator.setInterpolator(new LinearInterpolator()); Insets hiddenInsets = controller.getHiddenStateInsets(); // IME with zero insets is a special case: it will animate-in from offscreen and end // with final insets of zero and vice-versa. hiddenInsets = controller.hasZeroInsetsIme() ? Insets.of(hiddenInsets.left, hiddenInsets.top, hiddenInsets.right, mFloatingImeBottomInset) : hiddenInsets; Insets start = mShow ? controller.getHiddenStateInsets() ? hiddenInsets : controller.getShownStateInsets(); Insets end = mShow ? controller.getShownStateInsets() : controller.getHiddenStateInsets(); : hiddenInsets; Interpolator insetsInterpolator = getInterpolator(); Interpolator alphaInterpolator = getAlphaInterpolator(); mAnimator.addUpdateListener(animation -> { Loading Loading @@ -1173,7 +1188,8 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation boolean hasAnimationCallbacks = mHost.hasAnimationCallbacks(); final InternalAnimationControlListener listener = new InternalAnimationControlListener( show, hasAnimationCallbacks, types, mAnimationsDisabled); show, hasAnimationCallbacks, types, 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. Loading
core/java/android/view/ViewRootImpl.java +1 −1 Original line number Diff line number Diff line Loading @@ -2315,7 +2315,7 @@ public final class ViewRootImpl implements ViewParent, || lp.type == TYPE_VOLUME_OVERLAY; } private int dipToPx(int dip) { int dipToPx(int dip) { final DisplayMetrics displayMetrics = mContext.getResources().getDisplayMetrics(); return (int) (displayMetrics.density * dip + 0.5f); } Loading
core/java/android/view/ViewRootInsetsControllerHost.java +8 −0 Original line number Diff line number Diff line Loading @@ -228,4 +228,12 @@ public class ViewRootInsetsControllerHost implements InsetsController.Host { } return mViewRoot.getTitle().toString(); } @Override public int dipToPx(int dips) { if (mViewRoot != null) { return mViewRoot.dipToPx(dips); } return 0; } }
core/java/android/view/WindowInsetsAnimationController.java +7 −0 Original line number Diff line number Diff line Loading @@ -181,4 +181,11 @@ public interface WindowInsetsAnimationController { * @return {@code true} if the instance is cancelled, {@code false} otherwise. */ boolean isCancelled(); /** * @hide * @return {@code true} when controller controls IME and IME has no insets (floating, * fullscreen or non-overlapping). */ boolean hasZeroInsetsIme(); }