[Bouncer] refine entry for bouncer user switcher.

Match the animation of the user switcher with the pin view.
Increase the duration of the animation and add a y translation animation
when invoking the appear animation.

Also refine the entry text animation. Ensure that prompt is shown first
by removing animation time. Also ensure that initial text does not
animate in so that the entry animation is better refined. Added tests as
well.

For some of the tests, ktfmt reformatted the tests...these should just
be formatting changes.

Bug: 261571180
Test: Manually open bouncer with a quick swipe up in tablet device.
Test: Added unit tests.

Change-Id: Ic36b1554a7c3c73e0e8805db972e1bd3f0de57fe
This commit is contained in:
Aaron Liu
2022-12-06 12:55:30 -08:00
parent 71d3dbf23b
commit 66430ca292
8 changed files with 190 additions and 164 deletions

View File

@@ -260,7 +260,8 @@ public abstract class KeyguardAbsKeyInputViewController<T extends KeyguardAbsKey
if (reason != PROMPT_REASON_NONE) {
int promtReasonStringRes = mView.getPromptReasonStringRes(reason);
if (promtReasonStringRes != 0) {
mMessageAreaController.setMessage(promtReasonStringRes);
mMessageAreaController.setMessage(
mView.getResources().getString(promtReasonStringRes), false);
}
}
}

View File

@@ -143,7 +143,9 @@ public abstract class KeyguardInputViewController<T extends KeyguardInputView>
public void startAppearAnimation() {
if (TextUtils.isEmpty(mMessageAreaController.getMessage())) {
mMessageAreaController.setMessage(getInitialMessageResId());
mMessageAreaController.setMessage(
mView.getResources().getString(getInitialMessageResId()),
/* animate= */ false);
}
mView.startAppearAnimation();
}

View File

@@ -52,6 +52,7 @@ public class KeyguardPINView extends KeyguardPinBasedInputView {
private int mYTransOffset;
private View mBouncerMessageView;
@DevicePostureInt private int mLastDevicePosture = DEVICE_POSTURE_UNKNOWN;
public static final long ANIMATION_DURATION = 650;
public KeyguardPINView(Context context) {
this(context, null);
@@ -181,7 +182,7 @@ public class KeyguardPINView extends KeyguardPinBasedInputView {
if (mAppearAnimator.isRunning()) {
mAppearAnimator.cancel();
}
mAppearAnimator.setDuration(650);
mAppearAnimator.setDuration(ANIMATION_DURATION);
mAppearAnimator.addUpdateListener(animation -> animate(animation.getAnimatedFraction()));
mAppearAnimator.start();
}

View File

@@ -36,8 +36,11 @@ import static com.android.systemui.plugins.FalsingManager.LOW_PENALTY;
import static java.lang.Integer.max;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.admin.DevicePolicyManager;
@@ -967,11 +970,23 @@ public class KeyguardSecurityContainer extends ConstraintLayout {
}
mUserSwitcherViewGroup.setAlpha(0f);
ObjectAnimator alphaAnim = ObjectAnimator.ofFloat(mUserSwitcherViewGroup, View.ALPHA,
1f);
alphaAnim.setInterpolator(Interpolators.ALPHA_IN);
alphaAnim.setDuration(500);
alphaAnim.start();
ValueAnimator animator = ValueAnimator.ofFloat(0f, 1f);
int yTrans = mView.getResources().getDimensionPixelSize(R.dimen.pin_view_trans_y_entry);
animator.setInterpolator(Interpolators.STANDARD_DECELERATE);
animator.setDuration(650);
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
mUserSwitcherViewGroup.setAlpha(1f);
mUserSwitcherViewGroup.setTranslationY(0f);
}
});
animator.addUpdateListener(animation -> {
float value = (float) animation.getAnimatedValue();
mUserSwitcherViewGroup.setAlpha(value);
mUserSwitcherViewGroup.setTranslationY(yTrans - yTrans * value);
});
animator.start();
}
@Override

View File

@@ -19,6 +19,7 @@ package com.android.keyguard;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
@@ -87,6 +88,7 @@ public class KeyguardAbsKeyInputViewControllerTest extends SysuiTestCase {
when(mAbsKeyInputView.isAttachedToWindow()).thenReturn(true);
when(mAbsKeyInputView.requireViewById(R.id.bouncer_message_area))
.thenReturn(mKeyguardMessageArea);
when(mAbsKeyInputView.getResources()).thenReturn(getContext().getResources());
mKeyguardAbsKeyInputViewController = new KeyguardAbsKeyInputViewController(mAbsKeyInputView,
mKeyguardUpdateMonitor, mSecurityMode, mLockPatternUtils, mKeyguardSecurityCallback,
mKeyguardMessageAreaControllerFactory, mLatencyTracker, mFalsingCollector,
@@ -125,4 +127,22 @@ public class KeyguardAbsKeyInputViewControllerTest extends SysuiTestCase {
verifyZeroInteractions(mKeyguardSecurityCallback);
verifyZeroInteractions(mKeyguardMessageAreaController);
}
@Test
public void onPromptReasonNone_doesNotSetMessage() {
mKeyguardAbsKeyInputViewController.showPromptReason(0);
verify(mKeyguardMessageAreaController, never()).setMessage(
getContext().getResources().getString(R.string.kg_prompt_reason_restart_password),
false);
}
@Test
public void onPromptReason_setsMessage() {
when(mAbsKeyInputView.getPromptReasonStringRes(1)).thenReturn(
R.string.kg_prompt_reason_restart_password);
mKeyguardAbsKeyInputViewController.showPromptReason(1);
verify(mKeyguardMessageAreaController).setMessage(
getContext().getResources().getString(R.string.kg_prompt_reason_restart_password),
false);
}
}

View File

@@ -30,64 +30,54 @@ import com.android.systemui.util.concurrency.DelayableExecutor
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentMatchers.anyBoolean
import org.mockito.ArgumentMatchers.anyString
import org.mockito.Mock
import org.mockito.Mockito
import org.mockito.Mockito.`when`
import org.mockito.Mockito.never
import org.mockito.Mockito.verify
import org.mockito.Mockito.`when`
import org.mockito.MockitoAnnotations
@SmallTest
@RunWith(AndroidTestingRunner::class)
@TestableLooper.RunWithLooper
class KeyguardPasswordViewControllerTest : SysuiTestCase() {
@Mock
private lateinit var keyguardPasswordView: KeyguardPasswordView
@Mock
private lateinit var passwordEntry: EditText
@Mock
lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor
@Mock
lateinit var securityMode: KeyguardSecurityModel.SecurityMode
@Mock
lateinit var lockPatternUtils: LockPatternUtils
@Mock
lateinit var keyguardSecurityCallback: KeyguardSecurityCallback
@Mock
lateinit var messageAreaControllerFactory: KeyguardMessageAreaController.Factory
@Mock
lateinit var latencyTracker: LatencyTracker
@Mock
lateinit var inputMethodManager: InputMethodManager
@Mock
lateinit var emergencyButtonController: EmergencyButtonController
@Mock
lateinit var mainExecutor: DelayableExecutor
@Mock
lateinit var falsingCollector: FalsingCollector
@Mock
lateinit var keyguardViewController: KeyguardViewController
@Mock
private lateinit var mKeyguardMessageArea: BouncerKeyguardMessageArea
@Mock
private lateinit var mKeyguardMessageAreaController:
KeyguardMessageAreaController<BouncerKeyguardMessageArea>
@Mock private lateinit var keyguardPasswordView: KeyguardPasswordView
@Mock private lateinit var passwordEntry: EditText
@Mock lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor
@Mock lateinit var securityMode: KeyguardSecurityModel.SecurityMode
@Mock lateinit var lockPatternUtils: LockPatternUtils
@Mock lateinit var keyguardSecurityCallback: KeyguardSecurityCallback
@Mock lateinit var messageAreaControllerFactory: KeyguardMessageAreaController.Factory
@Mock lateinit var latencyTracker: LatencyTracker
@Mock lateinit var inputMethodManager: InputMethodManager
@Mock lateinit var emergencyButtonController: EmergencyButtonController
@Mock lateinit var mainExecutor: DelayableExecutor
@Mock lateinit var falsingCollector: FalsingCollector
@Mock lateinit var keyguardViewController: KeyguardViewController
@Mock private lateinit var mKeyguardMessageArea: BouncerKeyguardMessageArea
@Mock
private lateinit var mKeyguardMessageAreaController:
KeyguardMessageAreaController<BouncerKeyguardMessageArea>
private lateinit var keyguardPasswordViewController: KeyguardPasswordViewController
private lateinit var keyguardPasswordViewController: KeyguardPasswordViewController
@Before
fun setup() {
MockitoAnnotations.initMocks(this)
Mockito.`when`(
keyguardPasswordView
.requireViewById<BouncerKeyguardMessageArea>(R.id.bouncer_message_area)
).thenReturn(mKeyguardMessageArea)
Mockito.`when`(messageAreaControllerFactory.create(mKeyguardMessageArea))
.thenReturn(mKeyguardMessageAreaController)
Mockito.`when`(keyguardPasswordView.passwordTextViewId).thenReturn(R.id.passwordEntry)
Mockito.`when`(keyguardPasswordView.findViewById<EditText>(R.id.passwordEntry)
).thenReturn(passwordEntry)
keyguardPasswordViewController = KeyguardPasswordViewController(
@Before
fun setup() {
MockitoAnnotations.initMocks(this)
Mockito.`when`(
keyguardPasswordView.requireViewById<BouncerKeyguardMessageArea>(
R.id.bouncer_message_area))
.thenReturn(mKeyguardMessageArea)
Mockito.`when`(messageAreaControllerFactory.create(mKeyguardMessageArea))
.thenReturn(mKeyguardMessageAreaController)
Mockito.`when`(keyguardPasswordView.passwordTextViewId).thenReturn(R.id.passwordEntry)
Mockito.`when`(keyguardPasswordView.findViewById<EditText>(R.id.passwordEntry))
.thenReturn(passwordEntry)
`when`(keyguardPasswordView.resources).thenReturn(context.resources)
keyguardPasswordViewController =
KeyguardPasswordViewController(
keyguardPasswordView,
keyguardUpdateMonitor,
securityMode,
@@ -100,51 +90,48 @@ class KeyguardPasswordViewControllerTest : SysuiTestCase() {
mainExecutor,
mContext.resources,
falsingCollector,
keyguardViewController
)
}
keyguardViewController)
}
@Test
fun testFocusWhenBouncerIsShown() {
Mockito.`when`(keyguardViewController.isBouncerShowing).thenReturn(true)
Mockito.`when`(keyguardPasswordView.isShown).thenReturn(true)
keyguardPasswordViewController.onResume(KeyguardSecurityView.VIEW_REVEALED)
keyguardPasswordView.post {
verify(keyguardPasswordView).requestFocus()
verify(keyguardPasswordView).showKeyboard()
}
@Test
fun testFocusWhenBouncerIsShown() {
Mockito.`when`(keyguardViewController.isBouncerShowing).thenReturn(true)
Mockito.`when`(keyguardPasswordView.isShown).thenReturn(true)
keyguardPasswordViewController.onResume(KeyguardSecurityView.VIEW_REVEALED)
keyguardPasswordView.post {
verify(keyguardPasswordView).requestFocus()
verify(keyguardPasswordView).showKeyboard()
}
}
@Test
fun testDoNotFocusWhenBouncerIsHidden() {
Mockito.`when`(keyguardViewController.isBouncerShowing).thenReturn(false)
Mockito.`when`(keyguardPasswordView.isShown).thenReturn(true)
keyguardPasswordViewController.onResume(KeyguardSecurityView.VIEW_REVEALED)
verify(keyguardPasswordView, never()).requestFocus()
}
@Test
fun testDoNotFocusWhenBouncerIsHidden() {
Mockito.`when`(keyguardViewController.isBouncerShowing).thenReturn(false)
Mockito.`when`(keyguardPasswordView.isShown).thenReturn(true)
keyguardPasswordViewController.onResume(KeyguardSecurityView.VIEW_REVEALED)
verify(keyguardPasswordView, never()).requestFocus()
}
@Test
fun testHideKeyboardWhenOnPause() {
keyguardPasswordViewController.onPause()
keyguardPasswordView.post {
verify(keyguardPasswordView).clearFocus()
verify(keyguardPasswordView).hideKeyboard()
}
@Test
fun testHideKeyboardWhenOnPause() {
keyguardPasswordViewController.onPause()
keyguardPasswordView.post {
verify(keyguardPasswordView).clearFocus()
verify(keyguardPasswordView).hideKeyboard()
}
}
@Test
fun startAppearAnimation() {
keyguardPasswordViewController.startAppearAnimation()
verify(mKeyguardMessageAreaController).setMessage(R.string.keyguard_enter_your_password)
}
@Test
fun startAppearAnimation() {
keyguardPasswordViewController.startAppearAnimation()
verify(mKeyguardMessageAreaController)
.setMessage(context.resources.getString(R.string.keyguard_enter_your_password), false)
}
@Test
fun startAppearAnimation_withExistingMessage() {
`when`(mKeyguardMessageAreaController.message).thenReturn("Unlock to continue.")
keyguardPasswordViewController.startAppearAnimation()
verify(
mKeyguardMessageAreaController,
never()
).setMessage(R.string.keyguard_enter_your_password)
}
@Test
fun startAppearAnimation_withExistingMessage() {
`when`(mKeyguardMessageAreaController.message).thenReturn("Unlock to continue.")
keyguardPasswordViewController.startAppearAnimation()
verify(mKeyguardMessageAreaController, never()).setMessage(anyString(), anyBoolean())
}
}

View File

@@ -30,97 +30,93 @@ import com.android.systemui.statusbar.policy.DevicePostureController
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentMatchers.anyBoolean
import org.mockito.ArgumentMatchers.anyString
import org.mockito.Mock
import org.mockito.Mockito.never
import org.mockito.Mockito.verify
import org.mockito.Mockito.`when`
import org.mockito.Mockito.never
import org.mockito.MockitoAnnotations
@SmallTest
@RunWith(AndroidTestingRunner::class)
@TestableLooper.RunWithLooper
class KeyguardPatternViewControllerTest : SysuiTestCase() {
@Mock
private lateinit var mKeyguardPatternView: KeyguardPatternView
@Mock private lateinit var mKeyguardPatternView: KeyguardPatternView
@Mock
private lateinit var mKeyguardUpdateMonitor: KeyguardUpdateMonitor
@Mock private lateinit var mKeyguardUpdateMonitor: KeyguardUpdateMonitor
@Mock
private lateinit var mSecurityMode: KeyguardSecurityModel.SecurityMode
@Mock private lateinit var mSecurityMode: KeyguardSecurityModel.SecurityMode
@Mock
private lateinit var mLockPatternUtils: LockPatternUtils
@Mock private lateinit var mLockPatternUtils: LockPatternUtils
@Mock
private lateinit var mKeyguardSecurityCallback: KeyguardSecurityCallback
@Mock private lateinit var mKeyguardSecurityCallback: KeyguardSecurityCallback
@Mock
private lateinit var mLatencyTracker: LatencyTracker
private var mFalsingCollector: FalsingCollector = FalsingCollectorFake()
@Mock private lateinit var mLatencyTracker: LatencyTracker
private var mFalsingCollector: FalsingCollector = FalsingCollectorFake()
@Mock
private lateinit var mEmergencyButtonController: EmergencyButtonController
@Mock private lateinit var mEmergencyButtonController: EmergencyButtonController
@Mock
private lateinit
var mKeyguardMessageAreaControllerFactory: KeyguardMessageAreaController.Factory
@Mock
private lateinit var mKeyguardMessageAreaControllerFactory: KeyguardMessageAreaController.Factory
@Mock
private lateinit var mKeyguardMessageArea: BouncerKeyguardMessageArea
@Mock private lateinit var mKeyguardMessageArea: BouncerKeyguardMessageArea
@Mock
private lateinit var mKeyguardMessageAreaController:
KeyguardMessageAreaController<BouncerKeyguardMessageArea>
@Mock
private lateinit var mKeyguardMessageAreaController:
KeyguardMessageAreaController<BouncerKeyguardMessageArea>
@Mock
private lateinit var mLockPatternView: LockPatternView
@Mock private lateinit var mLockPatternView: LockPatternView
@Mock
private lateinit var mPostureController: DevicePostureController
@Mock private lateinit var mPostureController: DevicePostureController
private lateinit var mKeyguardPatternViewController: KeyguardPatternViewController
private lateinit var mKeyguardPatternViewController: KeyguardPatternViewController
@Before
fun setup() {
MockitoAnnotations.initMocks(this)
`when`(mKeyguardPatternView.isAttachedToWindow).thenReturn(true)
`when`(mKeyguardPatternView
.requireViewById<BouncerKeyguardMessageArea>(R.id.bouncer_message_area))
.thenReturn(mKeyguardMessageArea)
`when`(mKeyguardPatternView.findViewById<LockPatternView>(R.id.lockPatternView))
.thenReturn(mLockPatternView)
`when`(mKeyguardMessageAreaControllerFactory.create(mKeyguardMessageArea))
.thenReturn(mKeyguardMessageAreaController)
mKeyguardPatternViewController = KeyguardPatternViewController(
@Before
fun setup() {
MockitoAnnotations.initMocks(this)
`when`(mKeyguardPatternView.isAttachedToWindow).thenReturn(true)
`when`(
mKeyguardPatternView.requireViewById<BouncerKeyguardMessageArea>(
R.id.bouncer_message_area))
.thenReturn(mKeyguardMessageArea)
`when`(mKeyguardPatternView.findViewById<LockPatternView>(R.id.lockPatternView))
.thenReturn(mLockPatternView)
`when`(mKeyguardMessageAreaControllerFactory.create(mKeyguardMessageArea))
.thenReturn(mKeyguardMessageAreaController)
`when`(mKeyguardPatternView.resources).thenReturn(context.resources)
mKeyguardPatternViewController =
KeyguardPatternViewController(
mKeyguardPatternView,
mKeyguardUpdateMonitor, mSecurityMode, mLockPatternUtils, mKeyguardSecurityCallback,
mLatencyTracker, mFalsingCollector, mEmergencyButtonController,
mKeyguardMessageAreaControllerFactory, mPostureController
)
}
mKeyguardUpdateMonitor,
mSecurityMode,
mLockPatternUtils,
mKeyguardSecurityCallback,
mLatencyTracker,
mFalsingCollector,
mEmergencyButtonController,
mKeyguardMessageAreaControllerFactory,
mPostureController)
}
@Test
fun onPause_resetsText() {
mKeyguardPatternViewController.init()
mKeyguardPatternViewController.onPause()
verify(mKeyguardMessageAreaController).setMessage(R.string.keyguard_enter_your_pattern)
}
@Test
fun onPause_resetsText() {
mKeyguardPatternViewController.init()
mKeyguardPatternViewController.onPause()
verify(mKeyguardMessageAreaController).setMessage(R.string.keyguard_enter_your_pattern)
}
@Test
fun startAppearAnimation() {
mKeyguardPatternViewController.startAppearAnimation()
verify(mKeyguardMessageAreaController)
.setMessage(context.resources.getString(R.string.keyguard_enter_your_pattern), false)
}
@Test
fun startAppearAnimation() {
mKeyguardPatternViewController.startAppearAnimation()
verify(mKeyguardMessageAreaController).setMessage(R.string.keyguard_enter_your_pattern)
}
@Test
fun startAppearAnimation_withExistingMessage() {
`when`(mKeyguardMessageAreaController.message).thenReturn("Unlock to continue.")
mKeyguardPatternViewController.startAppearAnimation()
verify(
mKeyguardMessageAreaController,
never()
).setMessage(R.string.keyguard_enter_your_password)
}
@Test
fun startAppearAnimation_withExistingMessage() {
`when`(mKeyguardMessageAreaController.message).thenReturn("Unlock to continue.")
mKeyguardPatternViewController.startAppearAnimation()
verify(mKeyguardMessageAreaController, never()).setMessage(anyString(), anyBoolean())
}
}

View File

@@ -31,10 +31,13 @@ import com.android.systemui.statusbar.policy.DevicePostureController
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentMatchers.anyBoolean
import org.mockito.ArgumentMatchers.anyString
import org.mockito.Mock
import org.mockito.Mockito
import org.mockito.Mockito.any
import org.mockito.Mockito.verify
import org.mockito.Mockito.`when`
import org.mockito.MockitoAnnotations
@SmallTest
@@ -79,6 +82,7 @@ class KeyguardPinViewControllerTest : SysuiTestCase() {
keyguardMessageAreaControllerFactory.create(any(KeyguardMessageArea::class.java))
)
.thenReturn(keyguardMessageAreaController)
`when`(keyguardPinView.resources).thenReturn(context.resources)
pinViewController =
KeyguardPinViewController(
keyguardPinView,
@@ -98,14 +102,14 @@ class KeyguardPinViewControllerTest : SysuiTestCase() {
@Test
fun startAppearAnimation() {
pinViewController.startAppearAnimation()
verify(keyguardMessageAreaController).setMessage(R.string.keyguard_enter_your_pin)
verify(keyguardMessageAreaController)
.setMessage(context.resources.getString(R.string.keyguard_enter_your_pin), false)
}
@Test
fun startAppearAnimation_withExistingMessage() {
Mockito.`when`(keyguardMessageAreaController.message).thenReturn("Unlock to continue.")
pinViewController.startAppearAnimation()
verify(keyguardMessageAreaController, Mockito.never())
.setMessage(R.string.keyguard_enter_your_password)
verify(keyguardMessageAreaController, Mockito.never()).setMessage(anyString(), anyBoolean())
}
}