From 8a6d11abb52a044fbe5fbeaf72b35a0a0fc0a6a5 Mon Sep 17 00:00:00 2001 From: Aaron Liu Date: Fri, 9 Sep 2022 12:04:14 -0700 Subject: [PATCH] [Keyguard Bouncer] Refine entry animation. Animate bouncer message area and add decelerate curves to y translation. Test: Manual on device and add a unit test Bug: 239532368 Change-Id: Id039530a9a3cbd917469f9dc19c10c82d94cd018 --- .../SystemUI/res-keyguard/values/dimens.xml | 4 + .../com/android/keyguard/KeyguardPINView.java | 21 +++- .../keyguard/KeyguardPinViewController.java | 6 + .../com/android/keyguard/NumPadAnimator.java | 2 +- .../keyguard/KeyguardPinViewControllerTest.kt | 103 ++++++++++++++++++ 5 files changed, 131 insertions(+), 5 deletions(-) create mode 100644 packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinViewControllerTest.kt diff --git a/packages/SystemUI/res-keyguard/values/dimens.xml b/packages/SystemUI/res-keyguard/values/dimens.xml index 32871f0abb4f7..ac131ae1c99fd 100644 --- a/packages/SystemUI/res-keyguard/values/dimens.xml +++ b/packages/SystemUI/res-keyguard/values/dimens.xml @@ -84,6 +84,10 @@ -32dp + + 120dp + 10dp + 72dp 12dp diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java index 20fa8f817dc05..453072bc42da3 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java @@ -48,6 +48,9 @@ public class KeyguardPINView extends KeyguardPinBasedInputView { private ConstraintLayout mContainer; private int mDisappearYTranslation; private View[][] mViews; + private int mYTrans; + private int mYTransOffset; + private View mBouncerMessageView; @DevicePostureInt private int mLastDevicePosture = DEVICE_POSTURE_UNKNOWN; public KeyguardPINView(Context context) { @@ -67,6 +70,8 @@ public class KeyguardPINView extends KeyguardPinBasedInputView { mContext, android.R.interpolator.fast_out_linear_in)); mDisappearYTranslation = getResources().getDimensionPixelSize( R.dimen.disappear_y_translation); + mYTrans = getResources().getDimensionPixelSize(R.dimen.pin_view_trans_y_entry); + mYTransOffset = getResources().getDimensionPixelSize(R.dimen.pin_view_trans_y_entry_offset); } @Override @@ -138,6 +143,7 @@ public class KeyguardPINView extends KeyguardPinBasedInputView { super.onFinishInflate(); mContainer = findViewById(R.id.pin_container); + mBouncerMessageView = findViewById(R.id.bouncer_message_area); mViews = new View[][]{ new View[]{ findViewById(R.id.row0), null, null @@ -206,6 +212,12 @@ public class KeyguardPINView extends KeyguardPinBasedInputView { /** Animate subviews according to expansion or time. */ private void animate(float progress) { + Interpolator standardDecelerate = Interpolators.STANDARD_DECELERATE; + Interpolator legacyDecelerate = Interpolators.LEGACY_DECELERATE; + + mBouncerMessageView.setTranslationY( + mYTrans - mYTrans * standardDecelerate.getInterpolation(progress)); + for (int i = 0; i < mViews.length; i++) { View[] row = mViews[i]; for (View view : row) { @@ -213,14 +225,15 @@ public class KeyguardPINView extends KeyguardPinBasedInputView { continue; } - float scaledProgress = MathUtils.constrain( + float scaledProgress = legacyDecelerate.getInterpolation(MathUtils.constrain( (progress - 0.075f * i) / (1f - 0.075f * mViews.length), 0f, 1f - ); + )); view.setAlpha(scaledProgress); - Interpolator interpolator = Interpolators.STANDARD_ACCELERATE; - view.setTranslationY(40 - (40 * interpolator.getInterpolation(scaledProgress))); + int yDistance = mYTrans + mYTransOffset * i; + view.setTranslationY( + yDistance - (yDistance * standardDecelerate.getInterpolation(progress))); if (view instanceof NumPadAnimationListener) { ((NumPadAnimationListener) view).setProgress(scaledProgress); } diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPinViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPinViewController.java index 9f4585fb1a922..89fcc47caf576 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardPinViewController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPinViewController.java @@ -81,6 +81,12 @@ public class KeyguardPinViewController mMessageAreaController.setMessage(""); } + @Override + public void startAppearAnimation() { + mMessageAreaController.setMessageIfEmpty(R.string.keyguard_enter_your_pin); + super.startAppearAnimation(); + } + @Override public boolean startDisappearAnimation(Runnable finishRunnable) { return mView.startDisappearAnimation( diff --git a/packages/SystemUI/src/com/android/keyguard/NumPadAnimator.java b/packages/SystemUI/src/com/android/keyguard/NumPadAnimator.java index e0cafaed5a353..41111e3d3c6cf 100644 --- a/packages/SystemUI/src/com/android/keyguard/NumPadAnimator.java +++ b/packages/SystemUI/src/com/android/keyguard/NumPadAnimator.java @@ -86,7 +86,7 @@ class NumPadAnimator { public void setProgress(float progress) { mBackground.setCornerRadius(mEndRadius + (mStartRadius - mEndRadius) * progress); - int height = (int) (mHeight * 0.8f + mHeight * 0.2 * progress); + int height = (int) (mHeight * 0.7f + mHeight * 0.3 * progress); int difference = mHeight - height; mBackground.setBounds(0, difference / 2, mHeight, mHeight - difference / 2); } diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinViewControllerTest.kt new file mode 100644 index 0000000000000..9e5bfe53ea053 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardPinViewControllerTest.kt @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.keyguard + +import android.testing.AndroidTestingRunner +import android.testing.TestableLooper +import android.view.View +import androidx.test.filters.SmallTest +import com.android.internal.util.LatencyTracker +import com.android.internal.widget.LockPatternUtils +import com.android.keyguard.KeyguardSecurityModel.SecurityMode +import com.android.systemui.R +import com.android.systemui.SysuiTestCase +import com.android.systemui.classifier.FalsingCollector +import com.android.systemui.classifier.FalsingCollectorFake +import com.android.systemui.statusbar.policy.DevicePostureController +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mock +import org.mockito.Mockito +import org.mockito.Mockito.any +import org.mockito.Mockito.verify +import org.mockito.MockitoAnnotations + +@SmallTest +@RunWith(AndroidTestingRunner::class) +@TestableLooper.RunWithLooper +class KeyguardPinViewControllerTest : SysuiTestCase() { + @Mock private lateinit var keyguardPinView: KeyguardPINView + + @Mock private lateinit var keyguardMessageArea: BouncerKeyguardMessageArea + + @Mock private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor + + @Mock private lateinit var securityMode: SecurityMode + + @Mock private lateinit var lockPatternUtils: LockPatternUtils + + @Mock private lateinit var mKeyguardSecurityCallback: KeyguardSecurityCallback + + @Mock + private lateinit var keyguardMessageAreaControllerFactory: KeyguardMessageAreaController.Factory + + @Mock + private lateinit var keyguardMessageAreaController: + KeyguardMessageAreaController + + @Mock private lateinit var mLatencyTracker: LatencyTracker + + @Mock private lateinit var liftToActivateListener: LiftToActivateListener + + @Mock private val mEmergencyButtonController: EmergencyButtonController? = null + private val falsingCollector: FalsingCollector = FalsingCollectorFake() + @Mock lateinit var postureController: DevicePostureController + + lateinit var pinViewController: KeyguardPinViewController + + @Before + fun setup() { + MockitoAnnotations.initMocks(this) + Mockito.`when`(keyguardPinView.requireViewById(R.id.bouncer_message_area)) + .thenReturn(keyguardMessageArea) + Mockito.`when`( + keyguardMessageAreaControllerFactory.create(any(KeyguardMessageArea::class.java)) + ) + .thenReturn(keyguardMessageAreaController) + pinViewController = + KeyguardPinViewController( + keyguardPinView, + keyguardUpdateMonitor, + securityMode, + lockPatternUtils, + mKeyguardSecurityCallback, + keyguardMessageAreaControllerFactory, + mLatencyTracker, + liftToActivateListener, + mEmergencyButtonController, + falsingCollector, + postureController + ) + } + + @Test + fun startAppearAnimation() { + pinViewController.startAppearAnimation() + verify(keyguardMessageAreaController).setMessageIfEmpty(R.string.keyguard_enter_your_pin) + } +}