Loading packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java +24 −3 Original line number Diff line number Diff line Loading @@ -69,6 +69,7 @@ public class KeyguardPasswordView extends KeyguardAbsKeyInputView { private Interpolator mLinearOutSlowInInterpolator; private Interpolator mFastOutLinearInInterpolator; private DisappearAnimationListener mDisappearAnimationListener; public KeyguardPasswordView(Context context) { this(context, null); Loading Loading @@ -186,9 +187,13 @@ public class KeyguardPasswordView extends KeyguardAbsKeyInputView { return; } Insets shownInsets = controller.getShownStateInsets(); Insets insets = Insets.add(shownInsets, Insets.of(0, 0, 0, (int) (-shownInsets.bottom / 4 * anim.getAnimatedFraction()))); int dist = (int) (-shownInsets.bottom / 4 * anim.getAnimatedFraction()); Insets insets = Insets.add(shownInsets, Insets.of(0, 0, 0, dist)); if (mDisappearAnimationListener != null) { mDisappearAnimationListener.setTranslationY(-dist); } controller.setInsetsAndAlpha(insets, (float) animation.getAnimatedValue(), anim.getAnimatedFraction()); Loading @@ -209,6 +214,7 @@ public class KeyguardPasswordView extends KeyguardAbsKeyInputView { controller.finish(false); runOnFinishImeAnimationRunnable(); finishRunnable.run(); mDisappearAnimationListener = null; Trace.endSection(); }); } Loading Loading @@ -286,4 +292,19 @@ public class KeyguardPasswordView extends KeyguardAbsKeyInputView { } }); } /** * Listens to the progress of the disappear animation and handles it. */ interface DisappearAnimationListener { void setTranslationY(int transY); } /** * Set an instance of the disappear animation listener to this class. This will be * removed when the animation completes. */ public void setDisappearAnimationListener(DisappearAnimationListener listener) { mDisappearAnimationListener = listener; } } packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java +27 −3 Original line number Diff line number Diff line Loading @@ -173,6 +173,17 @@ public class KeyguardSecurityContainer extends ConstraintLayout { private @Mode int mCurrentMode = MODE_UNINITIALIZED; private int mWidth = -1; /** * This callback is used to animate KeyguardSecurityContainer and its child views based on * the interaction with the ime. After * {@link WindowInsetsAnimation.Callback#onPrepare(WindowInsetsAnimation)}, * {@link #onApplyWindowInsets} is called where we * set the bottom padding to be the height of the keyboard. We use this padding to determine * the delta of vertical distance for y-translation animations. * Note that bottom padding is not set when the disappear animation is started because * we are deferring the y translation logic to the animator in * {@link KeyguardPasswordView#startDisappearAnimation(Runnable)} */ private final WindowInsetsAnimation.Callback mWindowInsetsAnimationCallback = new WindowInsetsAnimation.Callback(DISPATCH_MODE_STOP) { Loading Loading @@ -213,7 +224,6 @@ public class KeyguardSecurityContainer extends ConstraintLayout { continue; } interpolatedFraction = animation.getInterpolatedFraction(); final int paddingBottom = (int) MathUtils.lerp( start, end, interpolatedFraction); Loading Loading @@ -568,13 +578,21 @@ public class KeyguardSecurityContainer extends ConstraintLayout { */ public void startDisappearAnimation(SecurityMode securitySelection) { mDisappearAnimRunning = true; if (securitySelection == SecurityMode.Password && mSecurityViewFlipper.getSecurityView() instanceof KeyguardPasswordView) { ((KeyguardPasswordView) mSecurityViewFlipper.getSecurityView()) .setDisappearAnimationListener(this::setTranslationY); } else { mViewMode.startDisappearAnimation(securitySelection); } } /** * This will run when the bouncer shows in all cases except when the user drags the bouncer up. */ public void startAppearAnimation(SecurityMode securityMode) { setTranslationY(0f); setAlpha(1f); updateChildren(0 /* translationY */, 1f /* alpha */); mViewMode.startAppearAnimation(securityMode); } Loading Loading @@ -623,7 +641,13 @@ public class KeyguardSecurityContainer extends ConstraintLayout { int inset = max(bottomInset, imeInset); int paddingBottom = max(inset, getContext().getResources() .getDimensionPixelSize(R.dimen.keyguard_security_view_bottom_margin)); // If security mode is password, we rely on the animation value of defined in // KeyguardPasswordView to determine the y translation animation. // This means that we will prevent the WindowInsetsAnimationCallback from setting any y // translation values by preventing the setting of the padding here. if (!mDisappearAnimRunning) { setPadding(getPaddingLeft(), getPaddingTop(), getPaddingRight(), paddingBottom); } return insets.inset(0, 0, 0, inset); } Loading packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java +43 −0 Original line number Diff line number Diff line Loading @@ -37,6 +37,7 @@ import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; Loading Loading @@ -159,6 +160,29 @@ public class KeyguardSecurityContainerTest extends SysuiTestCase { assertThat(mKeyguardSecurityContainer.getPaddingBottom()).isEqualTo(systemBarInsetAmount); } @Test public void testOnApplyWindowInsets_disappearAnimation_paddingNotSet() { int paddingBottom = getContext().getResources() .getDimensionPixelSize(R.dimen.keyguard_security_view_bottom_margin); int imeInsetAmount = paddingBottom + 1; int systemBarInsetAmount = 0; initMode(MODE_DEFAULT); Insets imeInset = Insets.of(0, 0, 0, imeInsetAmount); Insets systemBarInset = Insets.of(0, 0, 0, systemBarInsetAmount); WindowInsets insets = new WindowInsets.Builder() .setInsets(ime(), imeInset) .setInsetsIgnoringVisibility(systemBars(), systemBarInset) .build(); ensureViewFlipperIsMocked(); mKeyguardSecurityContainer.startDisappearAnimation( KeyguardSecurityModel.SecurityMode.Password); mKeyguardSecurityContainer.onApplyWindowInsets(insets); assertThat(mKeyguardSecurityContainer.getPaddingBottom()).isNotEqualTo(imeInsetAmount); } @Test public void testDefaultViewMode() { initMode(MODE_ONE_HANDED); Loading Loading @@ -376,6 +400,17 @@ public class KeyguardSecurityContainerTest extends SysuiTestCase { assertThat(mKeyguardSecurityContainer.getScaleY()).isEqualTo(1); } @Test public void testDisappearAnimationPassword() { ensureViewFlipperIsMocked(); KeyguardPasswordView keyguardPasswordView = mock(KeyguardPasswordView.class); when(mSecurityViewFlipper.getSecurityView()).thenReturn(keyguardPasswordView); mKeyguardSecurityContainer .startDisappearAnimation(KeyguardSecurityModel.SecurityMode.Password); verify(keyguardPasswordView).setDisappearAnimationListener(any()); } private BackEvent createBackEvent(float touchX, float progress) { return new BackEvent(0, 0, progress, BackEvent.EDGE_LEFT); } Loading Loading @@ -446,4 +481,12 @@ public class KeyguardSecurityContainerTest extends SysuiTestCase { mUserSwitcherController, () -> { }, mFalsingA11yDelegate); } private void ensureViewFlipperIsMocked() { mSecurityViewFlipper = mock(KeyguardSecurityViewFlipper.class); KeyguardPasswordView keyguardPasswordView = mock(KeyguardPasswordView.class); when(mSecurityViewFlipper.getSecurityView()).thenReturn(keyguardPasswordView); mKeyguardSecurityContainer.mSecurityViewFlipper = mSecurityViewFlipper; } } Loading
packages/SystemUI/src/com/android/keyguard/KeyguardPasswordView.java +24 −3 Original line number Diff line number Diff line Loading @@ -69,6 +69,7 @@ public class KeyguardPasswordView extends KeyguardAbsKeyInputView { private Interpolator mLinearOutSlowInInterpolator; private Interpolator mFastOutLinearInInterpolator; private DisappearAnimationListener mDisappearAnimationListener; public KeyguardPasswordView(Context context) { this(context, null); Loading Loading @@ -186,9 +187,13 @@ public class KeyguardPasswordView extends KeyguardAbsKeyInputView { return; } Insets shownInsets = controller.getShownStateInsets(); Insets insets = Insets.add(shownInsets, Insets.of(0, 0, 0, (int) (-shownInsets.bottom / 4 * anim.getAnimatedFraction()))); int dist = (int) (-shownInsets.bottom / 4 * anim.getAnimatedFraction()); Insets insets = Insets.add(shownInsets, Insets.of(0, 0, 0, dist)); if (mDisappearAnimationListener != null) { mDisappearAnimationListener.setTranslationY(-dist); } controller.setInsetsAndAlpha(insets, (float) animation.getAnimatedValue(), anim.getAnimatedFraction()); Loading @@ -209,6 +214,7 @@ public class KeyguardPasswordView extends KeyguardAbsKeyInputView { controller.finish(false); runOnFinishImeAnimationRunnable(); finishRunnable.run(); mDisappearAnimationListener = null; Trace.endSection(); }); } Loading Loading @@ -286,4 +292,19 @@ public class KeyguardPasswordView extends KeyguardAbsKeyInputView { } }); } /** * Listens to the progress of the disappear animation and handles it. */ interface DisappearAnimationListener { void setTranslationY(int transY); } /** * Set an instance of the disappear animation listener to this class. This will be * removed when the animation completes. */ public void setDisappearAnimationListener(DisappearAnimationListener listener) { mDisappearAnimationListener = listener; } }
packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java +27 −3 Original line number Diff line number Diff line Loading @@ -173,6 +173,17 @@ public class KeyguardSecurityContainer extends ConstraintLayout { private @Mode int mCurrentMode = MODE_UNINITIALIZED; private int mWidth = -1; /** * This callback is used to animate KeyguardSecurityContainer and its child views based on * the interaction with the ime. After * {@link WindowInsetsAnimation.Callback#onPrepare(WindowInsetsAnimation)}, * {@link #onApplyWindowInsets} is called where we * set the bottom padding to be the height of the keyboard. We use this padding to determine * the delta of vertical distance for y-translation animations. * Note that bottom padding is not set when the disappear animation is started because * we are deferring the y translation logic to the animator in * {@link KeyguardPasswordView#startDisappearAnimation(Runnable)} */ private final WindowInsetsAnimation.Callback mWindowInsetsAnimationCallback = new WindowInsetsAnimation.Callback(DISPATCH_MODE_STOP) { Loading Loading @@ -213,7 +224,6 @@ public class KeyguardSecurityContainer extends ConstraintLayout { continue; } interpolatedFraction = animation.getInterpolatedFraction(); final int paddingBottom = (int) MathUtils.lerp( start, end, interpolatedFraction); Loading Loading @@ -568,13 +578,21 @@ public class KeyguardSecurityContainer extends ConstraintLayout { */ public void startDisappearAnimation(SecurityMode securitySelection) { mDisappearAnimRunning = true; if (securitySelection == SecurityMode.Password && mSecurityViewFlipper.getSecurityView() instanceof KeyguardPasswordView) { ((KeyguardPasswordView) mSecurityViewFlipper.getSecurityView()) .setDisappearAnimationListener(this::setTranslationY); } else { mViewMode.startDisappearAnimation(securitySelection); } } /** * This will run when the bouncer shows in all cases except when the user drags the bouncer up. */ public void startAppearAnimation(SecurityMode securityMode) { setTranslationY(0f); setAlpha(1f); updateChildren(0 /* translationY */, 1f /* alpha */); mViewMode.startAppearAnimation(securityMode); } Loading Loading @@ -623,7 +641,13 @@ public class KeyguardSecurityContainer extends ConstraintLayout { int inset = max(bottomInset, imeInset); int paddingBottom = max(inset, getContext().getResources() .getDimensionPixelSize(R.dimen.keyguard_security_view_bottom_margin)); // If security mode is password, we rely on the animation value of defined in // KeyguardPasswordView to determine the y translation animation. // This means that we will prevent the WindowInsetsAnimationCallback from setting any y // translation values by preventing the setting of the padding here. if (!mDisappearAnimRunning) { setPadding(getPaddingLeft(), getPaddingTop(), getPaddingRight(), paddingBottom); } return insets.inset(0, 0, 0, inset); } Loading
packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java +43 −0 Original line number Diff line number Diff line Loading @@ -37,6 +37,7 @@ import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; Loading Loading @@ -159,6 +160,29 @@ public class KeyguardSecurityContainerTest extends SysuiTestCase { assertThat(mKeyguardSecurityContainer.getPaddingBottom()).isEqualTo(systemBarInsetAmount); } @Test public void testOnApplyWindowInsets_disappearAnimation_paddingNotSet() { int paddingBottom = getContext().getResources() .getDimensionPixelSize(R.dimen.keyguard_security_view_bottom_margin); int imeInsetAmount = paddingBottom + 1; int systemBarInsetAmount = 0; initMode(MODE_DEFAULT); Insets imeInset = Insets.of(0, 0, 0, imeInsetAmount); Insets systemBarInset = Insets.of(0, 0, 0, systemBarInsetAmount); WindowInsets insets = new WindowInsets.Builder() .setInsets(ime(), imeInset) .setInsetsIgnoringVisibility(systemBars(), systemBarInset) .build(); ensureViewFlipperIsMocked(); mKeyguardSecurityContainer.startDisappearAnimation( KeyguardSecurityModel.SecurityMode.Password); mKeyguardSecurityContainer.onApplyWindowInsets(insets); assertThat(mKeyguardSecurityContainer.getPaddingBottom()).isNotEqualTo(imeInsetAmount); } @Test public void testDefaultViewMode() { initMode(MODE_ONE_HANDED); Loading Loading @@ -376,6 +400,17 @@ public class KeyguardSecurityContainerTest extends SysuiTestCase { assertThat(mKeyguardSecurityContainer.getScaleY()).isEqualTo(1); } @Test public void testDisappearAnimationPassword() { ensureViewFlipperIsMocked(); KeyguardPasswordView keyguardPasswordView = mock(KeyguardPasswordView.class); when(mSecurityViewFlipper.getSecurityView()).thenReturn(keyguardPasswordView); mKeyguardSecurityContainer .startDisappearAnimation(KeyguardSecurityModel.SecurityMode.Password); verify(keyguardPasswordView).setDisappearAnimationListener(any()); } private BackEvent createBackEvent(float touchX, float progress) { return new BackEvent(0, 0, progress, BackEvent.EDGE_LEFT); } Loading Loading @@ -446,4 +481,12 @@ public class KeyguardSecurityContainerTest extends SysuiTestCase { mUserSwitcherController, () -> { }, mFalsingA11yDelegate); } private void ensureViewFlipperIsMocked() { mSecurityViewFlipper = mock(KeyguardSecurityViewFlipper.class); KeyguardPasswordView keyguardPasswordView = mock(KeyguardPasswordView.class); when(mSecurityViewFlipper.getSecurityView()).thenReturn(keyguardPasswordView); mKeyguardSecurityContainer.mSecurityViewFlipper = mSecurityViewFlipper; } }