[Bouncer] Refine bouncer title.
Add animation to bouncer title. Also remove setMessageIfEmpty. Remove instances of hiding the message in many cases as these cases were mean to prevent the textview from flashing when bouncer isn't being shown. Test: Tested simpin, simpuk, pattern, password, and pin on device. Also added unit tests Fixes: 174020764 Change-Id: I2f8e6f3d1a0400ead7e658b7d003dbc7b608a1cf
This commit is contained in:
@@ -16,19 +16,29 @@
|
||||
|
||||
package com.android.keyguard
|
||||
|
||||
import android.animation.Animator
|
||||
import android.animation.AnimatorListenerAdapter
|
||||
import android.animation.AnimatorSet
|
||||
import android.animation.ObjectAnimator
|
||||
import android.content.Context
|
||||
import android.content.res.ColorStateList
|
||||
import android.content.res.TypedArray
|
||||
import android.graphics.Color
|
||||
import android.util.AttributeSet
|
||||
import android.view.View
|
||||
import com.android.settingslib.Utils
|
||||
import com.android.systemui.animation.Interpolators
|
||||
|
||||
/** Displays security messages for the keyguard bouncer. */
|
||||
class BouncerKeyguardMessageArea(context: Context?, attrs: AttributeSet?) :
|
||||
open class BouncerKeyguardMessageArea(context: Context?, attrs: AttributeSet?) :
|
||||
KeyguardMessageArea(context, attrs) {
|
||||
private val DEFAULT_COLOR = -1
|
||||
private var mDefaultColorState: ColorStateList? = null
|
||||
private var mNextMessageColorState: ColorStateList? = ColorStateList.valueOf(DEFAULT_COLOR)
|
||||
private val animatorSet = AnimatorSet()
|
||||
private var textAboutToShow: CharSequence? = null
|
||||
protected open val SHOW_DURATION_MILLIS = 150L
|
||||
protected open val HIDE_DURATION_MILLIS = 200L
|
||||
|
||||
override fun updateTextColor() {
|
||||
var colorState = mDefaultColorState
|
||||
@@ -58,4 +68,46 @@ class BouncerKeyguardMessageArea(context: Context?, attrs: AttributeSet?) :
|
||||
mDefaultColorState = Utils.getColorAttr(context, android.R.attr.textColorPrimary)
|
||||
super.reloadColor()
|
||||
}
|
||||
|
||||
override fun setMessage(msg: CharSequence?) {
|
||||
if (msg == textAboutToShow || msg == text) {
|
||||
return
|
||||
}
|
||||
textAboutToShow = msg
|
||||
|
||||
if (animatorSet.isRunning) {
|
||||
animatorSet.cancel()
|
||||
textAboutToShow = null
|
||||
}
|
||||
|
||||
val hideAnimator =
|
||||
ObjectAnimator.ofFloat(this, View.ALPHA, 1f, 0f).apply {
|
||||
duration = HIDE_DURATION_MILLIS
|
||||
interpolator = Interpolators.STANDARD_ACCELERATE
|
||||
}
|
||||
|
||||
hideAnimator.addListener(
|
||||
object : AnimatorListenerAdapter() {
|
||||
override fun onAnimationEnd(animation: Animator?) {
|
||||
super@BouncerKeyguardMessageArea.setMessage(msg)
|
||||
}
|
||||
}
|
||||
)
|
||||
val showAnimator =
|
||||
ObjectAnimator.ofFloat(this, View.ALPHA, 0f, 1f).apply {
|
||||
duration = SHOW_DURATION_MILLIS
|
||||
interpolator = Interpolators.STANDARD_DECELERATE
|
||||
}
|
||||
|
||||
showAnimator.addListener(
|
||||
object : AnimatorListenerAdapter() {
|
||||
override fun onAnimationEnd(animation: Animator?) {
|
||||
textAboutToShow = null
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
animatorSet.playSequentially(hideAnimator, showAnimator)
|
||||
animatorSet.start()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -152,6 +152,7 @@ public abstract class KeyguardInputViewController<T extends KeyguardInputView>
|
||||
}
|
||||
|
||||
public void startAppearAnimation() {
|
||||
mMessageAreaController.setMessage(getInitialMessageResId());
|
||||
mView.startAppearAnimation();
|
||||
}
|
||||
|
||||
@@ -169,6 +170,11 @@ public abstract class KeyguardInputViewController<T extends KeyguardInputView>
|
||||
return view.indexOfChild(mView);
|
||||
}
|
||||
|
||||
/** Determines the message to show in the bouncer when it first appears. */
|
||||
protected int getInitialMessageResId() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Factory for a {@link KeyguardInputViewController}. */
|
||||
public static class Factory {
|
||||
private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
|
||||
|
||||
@@ -18,7 +18,6 @@ package com.android.keyguard;
|
||||
|
||||
import android.content.res.ColorStateList;
|
||||
import android.content.res.Configuration;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.android.systemui.statusbar.policy.ConfigurationController;
|
||||
import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
|
||||
@@ -100,15 +99,6 @@ public class KeyguardMessageAreaController<T extends KeyguardMessageArea>
|
||||
mView.setMessage(resId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Text if KeyguardMessageArea is empty.
|
||||
*/
|
||||
public void setMessageIfEmpty(int resId) {
|
||||
if (TextUtils.isEmpty(mView.getText())) {
|
||||
setMessage(resId);
|
||||
}
|
||||
}
|
||||
|
||||
public void setNextMessageColor(ColorStateList colorState) {
|
||||
mView.setNextMessageColor(colorState);
|
||||
}
|
||||
|
||||
@@ -187,7 +187,7 @@ public class KeyguardPasswordViewController
|
||||
@Override
|
||||
void resetState() {
|
||||
mPasswordEntry.setTextOperationUser(UserHandle.of(KeyguardUpdateMonitor.getCurrentUser()));
|
||||
mMessageAreaController.setMessage("");
|
||||
mMessageAreaController.setMessage(getInitialMessageResId());
|
||||
final boolean wasDisabled = mPasswordEntry.isEnabled();
|
||||
mView.setPasswordEntryEnabled(true);
|
||||
mView.setPasswordEntryInputEnabled(true);
|
||||
@@ -207,7 +207,6 @@ public class KeyguardPasswordViewController
|
||||
if (reason != KeyguardSecurityView.SCREEN_ON || mShowImeAtScreenOn) {
|
||||
showInput();
|
||||
}
|
||||
mMessageAreaController.setMessageIfEmpty(R.string.keyguard_enter_your_password);
|
||||
}
|
||||
|
||||
private void showInput() {
|
||||
@@ -324,4 +323,9 @@ public class KeyguardPasswordViewController
|
||||
//enabled input method subtype (The current IME should be LatinIME.)
|
||||
|| imm.getEnabledInputMethodSubtypeList(null, false).size() > 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getInitialMessageResId() {
|
||||
return R.string.keyguard_enter_your_password;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -297,12 +297,6 @@ public class KeyguardPatternViewController
|
||||
displayDefaultSecurityMessage();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume(int reason) {
|
||||
super.onResume(reason);
|
||||
mMessageAreaController.setMessageIfEmpty(R.string.keyguard_enter_your_pattern);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean needsInput() {
|
||||
return false;
|
||||
@@ -361,7 +355,7 @@ public class KeyguardPatternViewController
|
||||
}
|
||||
|
||||
private void displayDefaultSecurityMessage() {
|
||||
mMessageAreaController.setMessage("");
|
||||
mMessageAreaController.setMessage(getInitialMessageResId());
|
||||
}
|
||||
|
||||
private void handleAttemptLockout(long elapsedRealtimeDeadline) {
|
||||
@@ -392,4 +386,9 @@ public class KeyguardPatternViewController
|
||||
|
||||
}.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getInitialMessageResId() {
|
||||
return R.string.keyguard_enter_your_pattern;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,7 +127,6 @@ public abstract class KeyguardPinBasedInputViewController<T extends KeyguardPinB
|
||||
public void onResume(int reason) {
|
||||
super.onResume(reason);
|
||||
mPasswordEntry.requestFocus();
|
||||
mMessageAreaController.setMessageIfEmpty(R.string.keyguard_enter_your_pin);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -75,21 +75,14 @@ public class KeyguardPinViewController
|
||||
mView.reloadColors();
|
||||
}
|
||||
|
||||
@Override
|
||||
void resetState() {
|
||||
super.resetState();
|
||||
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(
|
||||
mKeyguardUpdateMonitor.needsSlowUnlockTransition(), finishRunnable);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getInitialMessageResId() {
|
||||
return R.string.keyguard_enter_your_pin;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (C) 2020 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.content.Context
|
||||
import android.testing.AndroidTestingRunner
|
||||
import android.testing.TestableLooper.RunWithLooper
|
||||
import android.util.AttributeSet
|
||||
import androidx.test.filters.SmallTest
|
||||
import com.android.systemui.SysuiTestCase
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mockito.Mockito.spy
|
||||
import org.mockito.Mockito.times
|
||||
import org.mockito.Mockito.verify
|
||||
|
||||
@SmallTest
|
||||
@RunWith(AndroidTestingRunner::class)
|
||||
@RunWithLooper
|
||||
class BouncerKeyguardMessageAreaTest : SysuiTestCase() {
|
||||
class FakeBouncerKeyguardMessageArea(context: Context, attrs: AttributeSet?) :
|
||||
BouncerKeyguardMessageArea(context, attrs) {
|
||||
override val SHOW_DURATION_MILLIS = 0L
|
||||
override val HIDE_DURATION_MILLIS = 0L
|
||||
}
|
||||
lateinit var underTest: BouncerKeyguardMessageArea
|
||||
|
||||
@Before
|
||||
fun setup() {
|
||||
underTest = FakeBouncerKeyguardMessageArea(context, null)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testSetSameMessage() {
|
||||
val underTestSpy = spy(underTest)
|
||||
underTestSpy.setMessage("abc")
|
||||
underTestSpy.setMessage("abc")
|
||||
verify(underTestSpy, times(1)).text = "abc"
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testSetDifferentMessage() {
|
||||
underTest.setMessage("abc")
|
||||
underTest.setMessage("def")
|
||||
assertThat(underTest.text).isEqualTo("def")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testSetNullMessage() {
|
||||
underTest.setMessage(null)
|
||||
assertThat(underTest.text).isEqualTo("")
|
||||
}
|
||||
}
|
||||
@@ -17,13 +17,11 @@
|
||||
package com.android.keyguard;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import android.test.suitebuilder.annotation.SmallTest;
|
||||
import android.testing.AndroidTestingRunner;
|
||||
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
import com.android.systemui.statusbar.policy.ConfigurationController;
|
||||
import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
|
||||
@@ -92,19 +90,4 @@ public class KeyguardMessageAreaControllerTest extends SysuiTestCase {
|
||||
mMessageAreaController.setIsVisible(true);
|
||||
verify(mKeyguardMessageArea).setIsVisible(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetMessageIfEmpty_empty() {
|
||||
mMessageAreaController.setMessage("");
|
||||
mMessageAreaController.setMessageIfEmpty(R.string.keyguard_enter_your_pin);
|
||||
verify(mKeyguardMessageArea).setMessage(R.string.keyguard_enter_your_pin);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetMessageIfEmpty_notEmpty() {
|
||||
mMessageAreaController.setMessage("abc");
|
||||
mMessageAreaController.setMessageIfEmpty(R.string.keyguard_enter_your_pin);
|
||||
verify(mKeyguardMessageArea, never()).setMessage(getContext()
|
||||
.getResources().getText(R.string.keyguard_enter_your_pin));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,9 +114,8 @@ class KeyguardPasswordViewControllerTest : SysuiTestCase() {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun onResume_testSetInitialText() {
|
||||
keyguardPasswordViewController.onResume(KeyguardSecurityView.SCREEN_ON)
|
||||
verify(mKeyguardMessageAreaController)
|
||||
.setMessageIfEmpty(R.string.keyguard_enter_your_password)
|
||||
fun startAppearAnimation() {
|
||||
keyguardPasswordViewController.startAppearAnimation()
|
||||
verify(mKeyguardMessageAreaController).setMessage(R.string.keyguard_enter_your_password)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,16 +100,16 @@ class KeyguardPatternViewControllerTest : SysuiTestCase() {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun onPause_clearsTextField() {
|
||||
fun onPause_resetsText() {
|
||||
mKeyguardPatternViewController.init()
|
||||
mKeyguardPatternViewController.onPause()
|
||||
verify(mKeyguardMessageAreaController).setMessage("")
|
||||
verify(mKeyguardMessageAreaController).setMessage(R.string.keyguard_enter_your_pattern)
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
fun onResume_setInitialText() {
|
||||
mKeyguardPatternViewController.onResume(KeyguardSecurityView.SCREEN_ON)
|
||||
verify(mKeyguardMessageAreaController)
|
||||
.setMessageIfEmpty(R.string.keyguard_enter_your_pattern)
|
||||
fun startAppearAnimation() {
|
||||
mKeyguardPatternViewController.startAppearAnimation()
|
||||
verify(mKeyguardMessageAreaController).setMessage(R.string.keyguard_enter_your_pattern)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,11 +113,4 @@ public class KeyguardPinBasedInputViewControllerTest extends SysuiTestCase {
|
||||
mKeyguardPinViewController.onResume(KeyguardSecurityView.SCREEN_ON);
|
||||
verify(mPasswordEntry).requestFocus();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onResume_setInitialText() {
|
||||
mKeyguardPinViewController.onResume(KeyguardSecurityView.SCREEN_ON);
|
||||
verify(mKeyguardMessageAreaController).setMessageIfEmpty(R.string.keyguard_enter_your_pin);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -98,6 +98,6 @@ class KeyguardPinViewControllerTest : SysuiTestCase() {
|
||||
@Test
|
||||
fun startAppearAnimation() {
|
||||
pinViewController.startAppearAnimation()
|
||||
verify(keyguardMessageAreaController).setMessageIfEmpty(R.string.keyguard_enter_your_pin)
|
||||
verify(keyguardMessageAreaController).setMessage(R.string.keyguard_enter_your_pin)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user