[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
This commit is contained in:
@@ -84,6 +84,10 @@
|
||||
<!-- The translation for disappearing security views after having solved them. -->
|
||||
<dimen name="disappear_y_translation">-32dp</dimen>
|
||||
|
||||
<!-- Dimens for animation for the Bouncer PIN view -->
|
||||
<dimen name="pin_view_trans_y_entry">120dp</dimen>
|
||||
<dimen name="pin_view_trans_y_entry_offset">10dp</dimen>
|
||||
|
||||
<!-- Spacing around each button used for PIN view -->
|
||||
<dimen name="num_pad_key_width">72dp</dimen>
|
||||
<dimen name="num_pad_entry_row_margin_bottom">12dp</dimen>
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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<BouncerKeyguardMessageArea>
|
||||
|
||||
@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<View>(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)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user