Loading core/java/android/view/InsetsAnimationControlImpl.java +1 −5 Original line number Diff line number Diff line Loading @@ -68,7 +68,6 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll private final @InsetsType int mTypes; private final InsetsAnimationControlCallbacks mController; private final WindowInsetsAnimation mAnimation; private final boolean mFade; private Insets mCurrentInsets; private Insets mPendingInsets; private float mPendingFraction; Loading @@ -83,11 +82,10 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll InsetsState state, WindowInsetsAnimationControlListener listener, @InsetsType int types, InsetsAnimationControlCallbacks controller, long durationMs, Interpolator interpolator, boolean fade, @AnimationType int animationType) { @AnimationType int animationType) { mControls = controls; mListener = listener; mTypes = types; mFade = fade; mController = controller; mInitialInsetsState = new InsetsState(state, true /* copySources */); mCurrentInsets = getInsetsFromState(mInitialInsetsState, frame, null /* typeSideMap */); Loading Loading @@ -299,8 +297,6 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll // If the system is controlling the insets source, the leash can be null. if (leash != null) { // TODO: use a better interpolation for fade. alpha = mFade ? ((float) inset / maxInset * 0.3f + 0.7f) : alpha; SurfaceParams params = new SurfaceParams.Builder(leash) .withAlpha(side == ISIDE_FLOATING ? 1 : alpha) .withMatrix(mTmpMatrix) Loading core/java/android/view/InsetsAnimationThreadControlRunner.java +2 −2 Original line number Diff line number Diff line Loading @@ -88,11 +88,11 @@ public class InsetsAnimationThreadControlRunner implements InsetsAnimationContro InsetsState state, WindowInsetsAnimationControlListener listener, @InsetsType int types, InsetsAnimationControlCallbacks controller, long durationMs, Interpolator interpolator, boolean fade, @AnimationType int animationType, Handler mainThreadHandler) { @AnimationType int animationType, Handler mainThreadHandler) { mMainThreadHandler = mainThreadHandler; mOuterCallbacks = controller; mControl = new InsetsAnimationControlImpl(copyControls(controls), frame, state, listener, types, mCallbacks, durationMs, interpolator, fade, animationType); types, mCallbacks, durationMs, interpolator, animationType); InsetsAnimationThread.getHandler().post(() -> listener.onReady(mControl, types)); } Loading core/java/android/view/InsetsController.java +108 −60 Original line number Diff line number Diff line Loading @@ -27,7 +27,9 @@ import android.animation.AnimationHandler; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ObjectAnimator; import android.animation.PropertyValuesHolder; import android.animation.TypeEvaluator; import android.animation.ValueAnimator; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; Loading @@ -36,6 +38,7 @@ import android.graphics.Rect; import android.os.CancellationSignal; import android.os.Handler; import android.os.RemoteException; import android.renderscript.Sampler.Value; import android.util.ArraySet; import android.util.Log; import android.util.Pair; Loading @@ -50,6 +53,7 @@ import android.view.WindowInsets.Type.InsetsType; import android.view.WindowInsetsAnimation.Bounds; import android.view.WindowManager.LayoutParams.SoftInputModeFlags; import android.view.animation.Interpolator; import android.view.animation.LinearInterpolator; import android.view.animation.PathInterpolator; import com.android.internal.annotations.VisibleForTesting; Loading @@ -72,9 +76,20 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation private static final int ANIMATION_DURATION_SHOW_MS = 275; private static final int ANIMATION_DURATION_HIDE_MS = 340; private static final int ANIMATION_DURATION_SYNC_IME_MS = 285; private static final int ANIMATION_DURATION_UNSYNC_IME_MS = 200; private static final int PENDING_CONTROL_TIMEOUT_MS = 2000; public static final Interpolator INTERPOLATOR = new PathInterpolator(0.4f, 0f, 0.2f, 1f); public static final Interpolator SYSTEM_BARS_INTERPOLATOR = new PathInterpolator(0.4f, 0f, 0.2f, 1f); private static final Interpolator SYNC_IME_INTERPOLATOR = new PathInterpolator(0.2f, 0f, 0f, 1f); private static final Interpolator LINEAR_OUT_SLOW_IN_INTERPOLATOR = new PathInterpolator(0, 0, 0.2f, 1f); private static final Interpolator FAST_OUT_LINEAR_IN_INTERPOLATOR = new PathInterpolator(0.4f, 0f, 1f, 1f); /** * Layout mode during insets animation: The views should be laid out as if the changing inset Loading Loading @@ -138,27 +153,6 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation (int) (startValue.right + fraction * (endValue.right - startValue.right)), (int) (startValue.bottom + fraction * (endValue.bottom - startValue.bottom))); /** * Linear animation property */ private static class InsetsProperty extends Property<WindowInsetsAnimationController, Insets> { InsetsProperty() { super(Insets.class, "Insets"); } @Override public Insets get(WindowInsetsAnimationController object) { return object.getCurrentInsets(); } @Override public void set(WindowInsetsAnimationController controller, Insets value) { controller.setInsetsAndAlpha( value, 1f /* alpha */, (((InternalAnimationControlListener) ((InsetsAnimationControlImpl) controller).getListener()) .getRawFraction())); } } /** * The default implementation of listener, to be used by InsetsController and InsetsPolicy to * animate insets. Loading @@ -167,9 +161,11 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation implements WindowInsetsAnimationControlListener { private WindowInsetsAnimationController mController; private ObjectAnimator mAnimator; private ValueAnimator mAnimator; private final boolean mShow; private final boolean mUseSfVsync; private final boolean mHasAnimationCallbacks; private final @InsetsType int mRequestedTypes; private final long mDurationMs; private ThreadLocal<AnimationHandler> mSfAnimationHandlerThreadLocal = new ThreadLocal<AnimationHandler>() { Loading @@ -181,24 +177,40 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation } }; public InternalAnimationControlListener(boolean show, boolean useSfVsync) { public InternalAnimationControlListener(boolean show, boolean hasAnimationCallbacks, int requestedTypes) { mShow = show; mUseSfVsync = useSfVsync; mHasAnimationCallbacks = hasAnimationCallbacks; mRequestedTypes = requestedTypes; mDurationMs = calculateDurationMs(); } @Override public void onReady(WindowInsetsAnimationController controller, int types) { mController = controller; mAnimator = ObjectAnimator.ofObject( controller, new InsetsProperty(), sEvaluator, mShow ? controller.getHiddenStateInsets() : controller.getShownStateInsets(), mShow ? controller.getShownStateInsets() : controller.getHiddenStateInsets() ); mAnimator.setDuration(getDurationMs()); mAnimator.setInterpolator(INTERPOLATOR); mAnimator = ValueAnimator.ofFloat(0f, 1f); mAnimator.setDuration(mDurationMs); mAnimator.setInterpolator(new LinearInterpolator()); Insets start = mShow ? controller.getHiddenStateInsets() : controller.getShownStateInsets(); Insets end = mShow ? controller.getShownStateInsets() : controller.getHiddenStateInsets(); Interpolator insetsInterpolator = getInterpolator(); Interpolator alphaInterpolator = getAlphaInterpolator(); mAnimator.addUpdateListener(animation -> { float rawFraction = animation.getAnimatedFraction(); float alphaFraction = mShow ? rawFraction : 1 - rawFraction; float insetsFraction = insetsInterpolator.getInterpolation(rawFraction); controller.setInsetsAndAlpha( sEvaluator.evaluate(insetsFraction, start, end), alphaInterpolator.getInterpolation(alphaFraction), rawFraction); }); mAnimator.addListener(new AnimatorListenerAdapter() { @Override Loading @@ -206,7 +218,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation onAnimationFinish(); } }); if (mUseSfVsync) { if (!mHasAnimationCallbacks) { mAnimator.setAnimationHandler(mSfAnimationHandlerThreadLocal.get()); } mAnimator.start(); Loading @@ -224,24 +236,59 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation } } protected void onAnimationFinish() { mController.finish(mShow); Interpolator getInterpolator() { if ((mRequestedTypes & ime()) != 0) { if (mHasAnimationCallbacks) { return SYNC_IME_INTERPOLATOR; } else if (mShow) { return LINEAR_OUT_SLOW_IN_INTERPOLATOR; } else { return FAST_OUT_LINEAR_IN_INTERPOLATOR; } } else { return SYSTEM_BARS_INTERPOLATOR; } } protected float getRawFraction() { return (float) mAnimator.getCurrentPlayTime() / mAnimator.getDuration(); Interpolator getAlphaInterpolator() { if ((mRequestedTypes & ime()) != 0) { if (mHasAnimationCallbacks) { return input -> 1f; } else if (mShow) { // Alpha animation takes half the time with linear interpolation; return input -> Math.min(1f, 2 * input); } else { return FAST_OUT_LINEAR_IN_INTERPOLATOR; } } else { return input -> 1f; } } protected void onAnimationFinish() { mController.finish(mShow); } /** * To get the animation duration in MS. */ public long getDurationMs() { if (mAnimator != null) { return mAnimator.getDuration(); return mDurationMs; } private long calculateDurationMs() { if ((mRequestedTypes & ime()) != 0) { if (mHasAnimationCallbacks) { return ANIMATION_DURATION_SYNC_IME_MS; } else { return ANIMATION_DURATION_UNSYNC_IME_MS; } } else { return mShow ? ANIMATION_DURATION_SHOW_MS : ANIMATION_DURATION_HIDE_MS; } } } /** * Represents a running animation Loading Loading @@ -525,7 +572,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation pendingRequest.types, pendingRequest.cancellationSignal, pendingRequest.listener, mFrame, true /* fromIme */, pendingRequest.durationMs, pendingRequest.interpolator, false /* fade */, pendingRequest.animationType, pendingRequest.animationType, pendingRequest.layoutInsetsDuringAnimation, pendingRequest.useInsetsAnimationThread); return; Loading Loading @@ -590,9 +637,9 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation listener.onCancelled(null); return; } controlAnimationUnchecked(types, cancellationSignal, listener, mFrame, fromIme, durationMs, interpolator, false /* fade */, animationType, getLayoutInsetsDuringAnimationMode(types), interpolator, animationType, getLayoutInsetsDuringAnimationMode(types), false /* useInsetsAnimationThread */); } Loading @@ -606,7 +653,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation private void controlAnimationUnchecked(@InsetsType int types, @Nullable CancellationSignal cancellationSignal, WindowInsetsAnimationControlListener listener, Rect frame, boolean fromIme, long durationMs, Interpolator interpolator, boolean fade, long durationMs, Interpolator interpolator, @AnimationType int animationType, @LayoutInsetsDuringAnimation int layoutInsetsDuringAnimation, boolean useInsetsAnimationThread) { Loading Loading @@ -652,10 +699,10 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation final InsetsAnimationControlRunner runner = useInsetsAnimationThread ? new InsetsAnimationThreadControlRunner(controls, frame, mState, listener, typesReady, this, durationMs, interpolator, fade, frame, mState, listener, typesReady, this, durationMs, interpolator, animationType, mViewRoot.mHandler) : new InsetsAnimationControlImpl(controls, frame, mState, listener, typesReady, this, durationMs, interpolator, fade, frame, mState, listener, typesReady, this, durationMs, interpolator, animationType); mRunningAnimations.add(new RunningAnimation(runner, animationType)); if (cancellationSignal != null) { Loading Loading @@ -921,25 +968,26 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation return; } boolean useInsetsAnimationThread = canUseInsetsAnimationThread(); boolean hasAnimationCallbacks = hasAnimationCallbacks(); final InternalAnimationControlListener listener = new InternalAnimationControlListener(show, useInsetsAnimationThread); new InternalAnimationControlListener(show, hasAnimationCallbacks, types); // Show/hide animations always need to be relative to the display frame, in order that shown // and hidden state insets are correct. controlAnimationUnchecked( types, null /* cancellationSignal */, listener, mState.getDisplayFrame(), fromIme, listener.getDurationMs(), INTERPOLATOR, true /* fade */, show ? ANIMATION_TYPE_SHOW : ANIMATION_TYPE_HIDE, show ? LAYOUT_INSETS_DURING_ANIMATION_SHOWN : LAYOUT_INSETS_DURING_ANIMATION_HIDDEN, useInsetsAnimationThread); listener.getDurationMs(), listener.getInterpolator(), show ? ANIMATION_TYPE_SHOW : ANIMATION_TYPE_HIDE, show ? LAYOUT_INSETS_DURING_ANIMATION_SHOWN : LAYOUT_INSETS_DURING_ANIMATION_HIDDEN, !hasAnimationCallbacks /* useInsetsAnimationThread */); } private boolean canUseInsetsAnimationThread() { private boolean hasAnimationCallbacks() { if (mViewRoot.mView == null) { return true; return false; } return !mViewRoot.mView.hasWindowInsetsAnimationCallback(); return mViewRoot.mView.hasWindowInsetsAnimationCallback(); } private void hideDirectly( Loading core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java +3 −4 Original line number Diff line number Diff line Loading @@ -20,7 +20,6 @@ import static android.view.InsetsState.ITYPE_NAVIGATION_BAR; import static android.view.InsetsState.ITYPE_STATUS_BAR; import static android.view.ViewRootImpl.NEW_INSETS_MODE_FULL; import static android.view.WindowInsets.Type.systemBars; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; Loading @@ -44,8 +43,6 @@ import android.view.SyncRtSurfaceTransactionApplier.SurfaceParams; import android.view.animation.LinearInterpolator; import android.view.test.InsetsModeSession; import androidx.test.runner.AndroidJUnit4; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; Loading @@ -57,6 +54,8 @@ import org.mockito.MockitoAnnotations; import java.util.List; import androidx.test.runner.AndroidJUnit4; /** * Tests for {@link InsetsAnimationControlImpl}. * Loading Loading @@ -124,7 +123,7 @@ public class InsetsAnimationControlImplTest { mController = new InsetsAnimationControlImpl(controls, new Rect(0, 0, 500, 500), mInsetsState, mMockListener, systemBars(), mMockController, 10 /* durationMs */, new LinearInterpolator(), false /* fade */, 0 /* animationType */); 0 /* animationType */); } @Test Loading services/core/java/com/android/server/wm/InsetsPolicy.java +4 −6 Original line number Diff line number Diff line Loading @@ -22,8 +22,6 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY; import static android.view.InsetsController.ANIMATION_TYPE_HIDE; import static android.view.InsetsController.ANIMATION_TYPE_SHOW; import static android.view.InsetsController.LAYOUT_INSETS_DURING_ANIMATION_HIDDEN; import static android.view.InsetsController.LAYOUT_INSETS_DURING_ANIMATION_SHOWN; import static android.view.InsetsState.ITYPE_NAVIGATION_BAR; import static android.view.InsetsState.ITYPE_STATUS_BAR; import static android.view.SyncRtSurfaceTransactionApplier.applyParams; Loading Loading @@ -299,7 +297,7 @@ class InsetsPolicy { private void controlAnimationUnchecked(int typesReady, SparseArray<InsetsSourceControl> controls, boolean show, Runnable callback) { InsetsPolicyAnimationControlListener listener = new InsetsPolicyAnimationControlListener(show, callback); new InsetsPolicyAnimationControlListener(show, callback, typesReady); listener.mControlCallbacks.controlAnimationUnchecked(typesReady, controls, show); } Loading Loading @@ -328,8 +326,8 @@ class InsetsPolicy { Runnable mFinishCallback; InsetsPolicyAnimationControlCallbacks mControlCallbacks; InsetsPolicyAnimationControlListener(boolean show, Runnable finishCallback) { super(show, true /* useSfVsync */); InsetsPolicyAnimationControlListener(boolean show, Runnable finishCallback, int types) { super(show, false /* hasCallbacks */, types); mFinishCallback = finishCallback; mControlCallbacks = new InsetsPolicyAnimationControlCallbacks(this); } Loading Loading @@ -361,7 +359,7 @@ class InsetsPolicy { mAnimationControl = new InsetsAnimationControlImpl(controls, mFocusedWin.getDisplayContent().getBounds(), getState(), mListener, typesReady, this, mListener.getDurationMs(), InsetsController.INTERPOLATOR, true, InsetsController.SYSTEM_BARS_INTERPOLATOR, show ? ANIMATION_TYPE_SHOW : ANIMATION_TYPE_HIDE); SurfaceAnimationThread.getHandler().post( () -> mListener.onReady(mAnimationControl, typesReady)); Loading Loading
core/java/android/view/InsetsAnimationControlImpl.java +1 −5 Original line number Diff line number Diff line Loading @@ -68,7 +68,6 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll private final @InsetsType int mTypes; private final InsetsAnimationControlCallbacks mController; private final WindowInsetsAnimation mAnimation; private final boolean mFade; private Insets mCurrentInsets; private Insets mPendingInsets; private float mPendingFraction; Loading @@ -83,11 +82,10 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll InsetsState state, WindowInsetsAnimationControlListener listener, @InsetsType int types, InsetsAnimationControlCallbacks controller, long durationMs, Interpolator interpolator, boolean fade, @AnimationType int animationType) { @AnimationType int animationType) { mControls = controls; mListener = listener; mTypes = types; mFade = fade; mController = controller; mInitialInsetsState = new InsetsState(state, true /* copySources */); mCurrentInsets = getInsetsFromState(mInitialInsetsState, frame, null /* typeSideMap */); Loading Loading @@ -299,8 +297,6 @@ public class InsetsAnimationControlImpl implements WindowInsetsAnimationControll // If the system is controlling the insets source, the leash can be null. if (leash != null) { // TODO: use a better interpolation for fade. alpha = mFade ? ((float) inset / maxInset * 0.3f + 0.7f) : alpha; SurfaceParams params = new SurfaceParams.Builder(leash) .withAlpha(side == ISIDE_FLOATING ? 1 : alpha) .withMatrix(mTmpMatrix) Loading
core/java/android/view/InsetsAnimationThreadControlRunner.java +2 −2 Original line number Diff line number Diff line Loading @@ -88,11 +88,11 @@ public class InsetsAnimationThreadControlRunner implements InsetsAnimationContro InsetsState state, WindowInsetsAnimationControlListener listener, @InsetsType int types, InsetsAnimationControlCallbacks controller, long durationMs, Interpolator interpolator, boolean fade, @AnimationType int animationType, Handler mainThreadHandler) { @AnimationType int animationType, Handler mainThreadHandler) { mMainThreadHandler = mainThreadHandler; mOuterCallbacks = controller; mControl = new InsetsAnimationControlImpl(copyControls(controls), frame, state, listener, types, mCallbacks, durationMs, interpolator, fade, animationType); types, mCallbacks, durationMs, interpolator, animationType); InsetsAnimationThread.getHandler().post(() -> listener.onReady(mControl, types)); } Loading
core/java/android/view/InsetsController.java +108 −60 Original line number Diff line number Diff line Loading @@ -27,7 +27,9 @@ import android.animation.AnimationHandler; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ObjectAnimator; import android.animation.PropertyValuesHolder; import android.animation.TypeEvaluator; import android.animation.ValueAnimator; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; Loading @@ -36,6 +38,7 @@ import android.graphics.Rect; import android.os.CancellationSignal; import android.os.Handler; import android.os.RemoteException; import android.renderscript.Sampler.Value; import android.util.ArraySet; import android.util.Log; import android.util.Pair; Loading @@ -50,6 +53,7 @@ import android.view.WindowInsets.Type.InsetsType; import android.view.WindowInsetsAnimation.Bounds; import android.view.WindowManager.LayoutParams.SoftInputModeFlags; import android.view.animation.Interpolator; import android.view.animation.LinearInterpolator; import android.view.animation.PathInterpolator; import com.android.internal.annotations.VisibleForTesting; Loading @@ -72,9 +76,20 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation private static final int ANIMATION_DURATION_SHOW_MS = 275; private static final int ANIMATION_DURATION_HIDE_MS = 340; private static final int ANIMATION_DURATION_SYNC_IME_MS = 285; private static final int ANIMATION_DURATION_UNSYNC_IME_MS = 200; private static final int PENDING_CONTROL_TIMEOUT_MS = 2000; public static final Interpolator INTERPOLATOR = new PathInterpolator(0.4f, 0f, 0.2f, 1f); public static final Interpolator SYSTEM_BARS_INTERPOLATOR = new PathInterpolator(0.4f, 0f, 0.2f, 1f); private static final Interpolator SYNC_IME_INTERPOLATOR = new PathInterpolator(0.2f, 0f, 0f, 1f); private static final Interpolator LINEAR_OUT_SLOW_IN_INTERPOLATOR = new PathInterpolator(0, 0, 0.2f, 1f); private static final Interpolator FAST_OUT_LINEAR_IN_INTERPOLATOR = new PathInterpolator(0.4f, 0f, 1f, 1f); /** * Layout mode during insets animation: The views should be laid out as if the changing inset Loading Loading @@ -138,27 +153,6 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation (int) (startValue.right + fraction * (endValue.right - startValue.right)), (int) (startValue.bottom + fraction * (endValue.bottom - startValue.bottom))); /** * Linear animation property */ private static class InsetsProperty extends Property<WindowInsetsAnimationController, Insets> { InsetsProperty() { super(Insets.class, "Insets"); } @Override public Insets get(WindowInsetsAnimationController object) { return object.getCurrentInsets(); } @Override public void set(WindowInsetsAnimationController controller, Insets value) { controller.setInsetsAndAlpha( value, 1f /* alpha */, (((InternalAnimationControlListener) ((InsetsAnimationControlImpl) controller).getListener()) .getRawFraction())); } } /** * The default implementation of listener, to be used by InsetsController and InsetsPolicy to * animate insets. Loading @@ -167,9 +161,11 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation implements WindowInsetsAnimationControlListener { private WindowInsetsAnimationController mController; private ObjectAnimator mAnimator; private ValueAnimator mAnimator; private final boolean mShow; private final boolean mUseSfVsync; private final boolean mHasAnimationCallbacks; private final @InsetsType int mRequestedTypes; private final long mDurationMs; private ThreadLocal<AnimationHandler> mSfAnimationHandlerThreadLocal = new ThreadLocal<AnimationHandler>() { Loading @@ -181,24 +177,40 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation } }; public InternalAnimationControlListener(boolean show, boolean useSfVsync) { public InternalAnimationControlListener(boolean show, boolean hasAnimationCallbacks, int requestedTypes) { mShow = show; mUseSfVsync = useSfVsync; mHasAnimationCallbacks = hasAnimationCallbacks; mRequestedTypes = requestedTypes; mDurationMs = calculateDurationMs(); } @Override public void onReady(WindowInsetsAnimationController controller, int types) { mController = controller; mAnimator = ObjectAnimator.ofObject( controller, new InsetsProperty(), sEvaluator, mShow ? controller.getHiddenStateInsets() : controller.getShownStateInsets(), mShow ? controller.getShownStateInsets() : controller.getHiddenStateInsets() ); mAnimator.setDuration(getDurationMs()); mAnimator.setInterpolator(INTERPOLATOR); mAnimator = ValueAnimator.ofFloat(0f, 1f); mAnimator.setDuration(mDurationMs); mAnimator.setInterpolator(new LinearInterpolator()); Insets start = mShow ? controller.getHiddenStateInsets() : controller.getShownStateInsets(); Insets end = mShow ? controller.getShownStateInsets() : controller.getHiddenStateInsets(); Interpolator insetsInterpolator = getInterpolator(); Interpolator alphaInterpolator = getAlphaInterpolator(); mAnimator.addUpdateListener(animation -> { float rawFraction = animation.getAnimatedFraction(); float alphaFraction = mShow ? rawFraction : 1 - rawFraction; float insetsFraction = insetsInterpolator.getInterpolation(rawFraction); controller.setInsetsAndAlpha( sEvaluator.evaluate(insetsFraction, start, end), alphaInterpolator.getInterpolation(alphaFraction), rawFraction); }); mAnimator.addListener(new AnimatorListenerAdapter() { @Override Loading @@ -206,7 +218,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation onAnimationFinish(); } }); if (mUseSfVsync) { if (!mHasAnimationCallbacks) { mAnimator.setAnimationHandler(mSfAnimationHandlerThreadLocal.get()); } mAnimator.start(); Loading @@ -224,24 +236,59 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation } } protected void onAnimationFinish() { mController.finish(mShow); Interpolator getInterpolator() { if ((mRequestedTypes & ime()) != 0) { if (mHasAnimationCallbacks) { return SYNC_IME_INTERPOLATOR; } else if (mShow) { return LINEAR_OUT_SLOW_IN_INTERPOLATOR; } else { return FAST_OUT_LINEAR_IN_INTERPOLATOR; } } else { return SYSTEM_BARS_INTERPOLATOR; } } protected float getRawFraction() { return (float) mAnimator.getCurrentPlayTime() / mAnimator.getDuration(); Interpolator getAlphaInterpolator() { if ((mRequestedTypes & ime()) != 0) { if (mHasAnimationCallbacks) { return input -> 1f; } else if (mShow) { // Alpha animation takes half the time with linear interpolation; return input -> Math.min(1f, 2 * input); } else { return FAST_OUT_LINEAR_IN_INTERPOLATOR; } } else { return input -> 1f; } } protected void onAnimationFinish() { mController.finish(mShow); } /** * To get the animation duration in MS. */ public long getDurationMs() { if (mAnimator != null) { return mAnimator.getDuration(); return mDurationMs; } private long calculateDurationMs() { if ((mRequestedTypes & ime()) != 0) { if (mHasAnimationCallbacks) { return ANIMATION_DURATION_SYNC_IME_MS; } else { return ANIMATION_DURATION_UNSYNC_IME_MS; } } else { return mShow ? ANIMATION_DURATION_SHOW_MS : ANIMATION_DURATION_HIDE_MS; } } } /** * Represents a running animation Loading Loading @@ -525,7 +572,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation pendingRequest.types, pendingRequest.cancellationSignal, pendingRequest.listener, mFrame, true /* fromIme */, pendingRequest.durationMs, pendingRequest.interpolator, false /* fade */, pendingRequest.animationType, pendingRequest.animationType, pendingRequest.layoutInsetsDuringAnimation, pendingRequest.useInsetsAnimationThread); return; Loading Loading @@ -590,9 +637,9 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation listener.onCancelled(null); return; } controlAnimationUnchecked(types, cancellationSignal, listener, mFrame, fromIme, durationMs, interpolator, false /* fade */, animationType, getLayoutInsetsDuringAnimationMode(types), interpolator, animationType, getLayoutInsetsDuringAnimationMode(types), false /* useInsetsAnimationThread */); } Loading @@ -606,7 +653,7 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation private void controlAnimationUnchecked(@InsetsType int types, @Nullable CancellationSignal cancellationSignal, WindowInsetsAnimationControlListener listener, Rect frame, boolean fromIme, long durationMs, Interpolator interpolator, boolean fade, long durationMs, Interpolator interpolator, @AnimationType int animationType, @LayoutInsetsDuringAnimation int layoutInsetsDuringAnimation, boolean useInsetsAnimationThread) { Loading Loading @@ -652,10 +699,10 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation final InsetsAnimationControlRunner runner = useInsetsAnimationThread ? new InsetsAnimationThreadControlRunner(controls, frame, mState, listener, typesReady, this, durationMs, interpolator, fade, frame, mState, listener, typesReady, this, durationMs, interpolator, animationType, mViewRoot.mHandler) : new InsetsAnimationControlImpl(controls, frame, mState, listener, typesReady, this, durationMs, interpolator, fade, frame, mState, listener, typesReady, this, durationMs, interpolator, animationType); mRunningAnimations.add(new RunningAnimation(runner, animationType)); if (cancellationSignal != null) { Loading Loading @@ -921,25 +968,26 @@ public class InsetsController implements WindowInsetsController, InsetsAnimation return; } boolean useInsetsAnimationThread = canUseInsetsAnimationThread(); boolean hasAnimationCallbacks = hasAnimationCallbacks(); final InternalAnimationControlListener listener = new InternalAnimationControlListener(show, useInsetsAnimationThread); new InternalAnimationControlListener(show, hasAnimationCallbacks, types); // Show/hide animations always need to be relative to the display frame, in order that shown // and hidden state insets are correct. controlAnimationUnchecked( types, null /* cancellationSignal */, listener, mState.getDisplayFrame(), fromIme, listener.getDurationMs(), INTERPOLATOR, true /* fade */, show ? ANIMATION_TYPE_SHOW : ANIMATION_TYPE_HIDE, show ? LAYOUT_INSETS_DURING_ANIMATION_SHOWN : LAYOUT_INSETS_DURING_ANIMATION_HIDDEN, useInsetsAnimationThread); listener.getDurationMs(), listener.getInterpolator(), show ? ANIMATION_TYPE_SHOW : ANIMATION_TYPE_HIDE, show ? LAYOUT_INSETS_DURING_ANIMATION_SHOWN : LAYOUT_INSETS_DURING_ANIMATION_HIDDEN, !hasAnimationCallbacks /* useInsetsAnimationThread */); } private boolean canUseInsetsAnimationThread() { private boolean hasAnimationCallbacks() { if (mViewRoot.mView == null) { return true; return false; } return !mViewRoot.mView.hasWindowInsetsAnimationCallback(); return mViewRoot.mView.hasWindowInsetsAnimationCallback(); } private void hideDirectly( Loading
core/tests/coretests/src/android/view/InsetsAnimationControlImplTest.java +3 −4 Original line number Diff line number Diff line Loading @@ -20,7 +20,6 @@ import static android.view.InsetsState.ITYPE_NAVIGATION_BAR; import static android.view.InsetsState.ITYPE_STATUS_BAR; import static android.view.ViewRootImpl.NEW_INSETS_MODE_FULL; import static android.view.WindowInsets.Type.systemBars; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; Loading @@ -44,8 +43,6 @@ import android.view.SyncRtSurfaceTransactionApplier.SurfaceParams; import android.view.animation.LinearInterpolator; import android.view.test.InsetsModeSession; import androidx.test.runner.AndroidJUnit4; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; Loading @@ -57,6 +54,8 @@ import org.mockito.MockitoAnnotations; import java.util.List; import androidx.test.runner.AndroidJUnit4; /** * Tests for {@link InsetsAnimationControlImpl}. * Loading Loading @@ -124,7 +123,7 @@ public class InsetsAnimationControlImplTest { mController = new InsetsAnimationControlImpl(controls, new Rect(0, 0, 500, 500), mInsetsState, mMockListener, systemBars(), mMockController, 10 /* durationMs */, new LinearInterpolator(), false /* fade */, 0 /* animationType */); 0 /* animationType */); } @Test Loading
services/core/java/com/android/server/wm/InsetsPolicy.java +4 −6 Original line number Diff line number Diff line Loading @@ -22,8 +22,6 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY; import static android.view.InsetsController.ANIMATION_TYPE_HIDE; import static android.view.InsetsController.ANIMATION_TYPE_SHOW; import static android.view.InsetsController.LAYOUT_INSETS_DURING_ANIMATION_HIDDEN; import static android.view.InsetsController.LAYOUT_INSETS_DURING_ANIMATION_SHOWN; import static android.view.InsetsState.ITYPE_NAVIGATION_BAR; import static android.view.InsetsState.ITYPE_STATUS_BAR; import static android.view.SyncRtSurfaceTransactionApplier.applyParams; Loading Loading @@ -299,7 +297,7 @@ class InsetsPolicy { private void controlAnimationUnchecked(int typesReady, SparseArray<InsetsSourceControl> controls, boolean show, Runnable callback) { InsetsPolicyAnimationControlListener listener = new InsetsPolicyAnimationControlListener(show, callback); new InsetsPolicyAnimationControlListener(show, callback, typesReady); listener.mControlCallbacks.controlAnimationUnchecked(typesReady, controls, show); } Loading Loading @@ -328,8 +326,8 @@ class InsetsPolicy { Runnable mFinishCallback; InsetsPolicyAnimationControlCallbacks mControlCallbacks; InsetsPolicyAnimationControlListener(boolean show, Runnable finishCallback) { super(show, true /* useSfVsync */); InsetsPolicyAnimationControlListener(boolean show, Runnable finishCallback, int types) { super(show, false /* hasCallbacks */, types); mFinishCallback = finishCallback; mControlCallbacks = new InsetsPolicyAnimationControlCallbacks(this); } Loading Loading @@ -361,7 +359,7 @@ class InsetsPolicy { mAnimationControl = new InsetsAnimationControlImpl(controls, mFocusedWin.getDisplayContent().getBounds(), getState(), mListener, typesReady, this, mListener.getDurationMs(), InsetsController.INTERPOLATOR, true, InsetsController.SYSTEM_BARS_INTERPOLATOR, show ? ANIMATION_TYPE_SHOW : ANIMATION_TYPE_HIDE); SurfaceAnimationThread.getHandler().post( () -> mListener.onReady(mAnimationControl, typesReady)); Loading