Merge changes Ia1128b9d,I018e067e into udc-dev
* changes: Fix lockout state for auto pin confirm Fix pin error scenario for talkback.
This commit is contained in:
@@ -179,10 +179,10 @@ public abstract class KeyguardAbsKeyInputViewController<T extends KeyguardAbsKey
|
|||||||
handleAttemptLockout(deadline);
|
handleAttemptLockout(deadline);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
mView.resetPasswordText(true /* animate */, false /* announce deletion if no match */);
|
||||||
if (timeoutMs == 0) {
|
if (timeoutMs == 0) {
|
||||||
mMessageAreaController.setMessage(mView.getWrongPasswordStringId());
|
mMessageAreaController.setMessage(mView.getWrongPasswordStringId());
|
||||||
}
|
}
|
||||||
mView.resetPasswordText(true /* animate */, false /* announce deletion if no match */);
|
|
||||||
startErrorAnimation();
|
startErrorAnimation();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,9 @@ package com.android.keyguard;
|
|||||||
|
|
||||||
import android.content.res.ColorStateList;
|
import android.content.res.ColorStateList;
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
|
import android.text.Editable;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
import android.text.TextWatcher;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
import androidx.annotation.VisibleForTesting;
|
import androidx.annotation.VisibleForTesting;
|
||||||
@@ -45,6 +47,31 @@ public class KeyguardMessageAreaController<T extends KeyguardMessageArea>
|
|||||||
private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
|
private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
|
||||||
private final ConfigurationController mConfigurationController;
|
private final ConfigurationController mConfigurationController;
|
||||||
private final AnnounceRunnable mAnnounceRunnable;
|
private final AnnounceRunnable mAnnounceRunnable;
|
||||||
|
private final TextWatcher mTextWatcher = new TextWatcher() {
|
||||||
|
@Override
|
||||||
|
public void afterTextChanged(Editable editable) {
|
||||||
|
CharSequence msg = editable;
|
||||||
|
if (!TextUtils.isEmpty(msg)) {
|
||||||
|
mView.removeCallbacks(mAnnounceRunnable);
|
||||||
|
mAnnounceRunnable.setTextToAnnounce(msg);
|
||||||
|
mView.postDelayed(() -> {
|
||||||
|
if (msg == mView.getText()) {
|
||||||
|
mAnnounceRunnable.run();
|
||||||
|
}
|
||||||
|
}, ANNOUNCEMENT_DELAY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
|
||||||
|
/* no-op */
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
|
||||||
|
/* no-op */
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
private KeyguardUpdateMonitorCallback mInfoCallback = new KeyguardUpdateMonitorCallback() {
|
private KeyguardUpdateMonitorCallback mInfoCallback = new KeyguardUpdateMonitorCallback() {
|
||||||
public void onFinishedGoingToSleep(int why) {
|
public void onFinishedGoingToSleep(int why) {
|
||||||
@@ -89,12 +116,14 @@ public class KeyguardMessageAreaController<T extends KeyguardMessageArea>
|
|||||||
mKeyguardUpdateMonitor.registerCallback(mInfoCallback);
|
mKeyguardUpdateMonitor.registerCallback(mInfoCallback);
|
||||||
mView.setSelected(mKeyguardUpdateMonitor.isDeviceInteractive());
|
mView.setSelected(mKeyguardUpdateMonitor.isDeviceInteractive());
|
||||||
mView.onThemeChanged();
|
mView.onThemeChanged();
|
||||||
|
mView.addTextChangedListener(mTextWatcher);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onViewDetached() {
|
protected void onViewDetached() {
|
||||||
mConfigurationController.removeCallback(mConfigurationListener);
|
mConfigurationController.removeCallback(mConfigurationListener);
|
||||||
mKeyguardUpdateMonitor.removeCallback(mInfoCallback);
|
mKeyguardUpdateMonitor.removeCallback(mInfoCallback);
|
||||||
|
mView.removeTextChangedListener(mTextWatcher);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -113,12 +142,6 @@ public class KeyguardMessageAreaController<T extends KeyguardMessageArea>
|
|||||||
*/
|
*/
|
||||||
public void setMessage(CharSequence s, boolean animate) {
|
public void setMessage(CharSequence s, boolean animate) {
|
||||||
mView.setMessage(s, animate);
|
mView.setMessage(s, animate);
|
||||||
CharSequence msg = mView.getText();
|
|
||||||
if (!TextUtils.isEmpty(msg)) {
|
|
||||||
mView.removeCallbacks(mAnnounceRunnable);
|
|
||||||
mAnnounceRunnable.setTextToAnnounce(msg);
|
|
||||||
mView.postDelayed(mAnnounceRunnable, ANNOUNCEMENT_DELAY);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMessage(int resId) {
|
public void setMessage(int resId) {
|
||||||
|
|||||||
@@ -82,9 +82,6 @@ public abstract class KeyguardPinBasedInputView extends KeyguardAbsKeyInputView
|
|||||||
protected void setPasswordEntryInputEnabled(boolean enabled) {
|
protected void setPasswordEntryInputEnabled(boolean enabled) {
|
||||||
mPasswordEntry.setEnabled(enabled);
|
mPasswordEntry.setEnabled(enabled);
|
||||||
mOkButton.setEnabled(enabled);
|
mOkButton.setEnabled(enabled);
|
||||||
if (enabled && !mPasswordEntry.hasFocus()) {
|
|
||||||
mPasswordEntry.requestFocus();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -16,8 +16,6 @@
|
|||||||
|
|
||||||
package com.android.keyguard;
|
package com.android.keyguard;
|
||||||
|
|
||||||
import static com.android.systemui.keyguard.shared.constants.KeyguardBouncerConstants.DEFAULT_PIN_LENGTH;
|
|
||||||
|
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
import com.android.internal.util.LatencyTracker;
|
import com.android.internal.util.LatencyTracker;
|
||||||
@@ -42,10 +40,9 @@ public class KeyguardPinViewController
|
|||||||
private NumPadButton mBackspaceKey;
|
private NumPadButton mBackspaceKey;
|
||||||
private View mOkButton = mView.findViewById(R.id.key_enter);
|
private View mOkButton = mView.findViewById(R.id.key_enter);
|
||||||
|
|
||||||
private int mUserId;
|
|
||||||
private long mPinLength;
|
private long mPinLength;
|
||||||
|
|
||||||
private int mPasswordFailedAttempts;
|
private boolean mDisabledAutoConfirmation;
|
||||||
|
|
||||||
protected KeyguardPinViewController(KeyguardPINView view,
|
protected KeyguardPinViewController(KeyguardPINView view,
|
||||||
KeyguardUpdateMonitor keyguardUpdateMonitor,
|
KeyguardUpdateMonitor keyguardUpdateMonitor,
|
||||||
@@ -84,9 +81,8 @@ public class KeyguardPinViewController
|
|||||||
|
|
||||||
protected void onUserInput() {
|
protected void onUserInput() {
|
||||||
super.onUserInput();
|
super.onUserInput();
|
||||||
if (isAutoConfirmation()) {
|
if (isAutoPinConfirmEnabledInSettings()) {
|
||||||
updateOKButtonVisibility();
|
updateAutoConfirmationState();
|
||||||
updateBackSpaceVisibility();
|
|
||||||
if (mPasswordEntry.getText().length() == mPinLength
|
if (mPasswordEntry.getText().length() == mPinLength
|
||||||
&& mOkButton.getVisibility() == View.INVISIBLE) {
|
&& mOkButton.getVisibility() == View.INVISIBLE) {
|
||||||
verifyPasswordAndUnlock();
|
verifyPasswordAndUnlock();
|
||||||
@@ -103,13 +99,9 @@ public class KeyguardPinViewController
|
|||||||
@Override
|
@Override
|
||||||
public void startAppearAnimation() {
|
public void startAppearAnimation() {
|
||||||
if (mFeatureFlags.isEnabled(Flags.AUTO_PIN_CONFIRMATION)) {
|
if (mFeatureFlags.isEnabled(Flags.AUTO_PIN_CONFIRMATION)) {
|
||||||
mUserId = KeyguardUpdateMonitor.getCurrentUser();
|
mPinLength = mLockPatternUtils.getPinLength(KeyguardUpdateMonitor.getCurrentUser());
|
||||||
mPinLength = mLockPatternUtils.getPinLength(mUserId);
|
|
||||||
mBackspaceKey.setTransparentMode(/* isTransparentMode= */ isAutoConfirmation());
|
|
||||||
updateOKButtonVisibility();
|
|
||||||
updateBackSpaceVisibility();
|
|
||||||
mPasswordEntry.setUsePinShapes(true);
|
mPasswordEntry.setUsePinShapes(true);
|
||||||
mPasswordEntry.setIsPinHinting(isAutoConfirmation() && isPinHinting());
|
updateAutoConfirmationState();
|
||||||
}
|
}
|
||||||
super.startAppearAnimation();
|
super.startAppearAnimation();
|
||||||
}
|
}
|
||||||
@@ -120,13 +112,25 @@ public class KeyguardPinViewController
|
|||||||
mKeyguardUpdateMonitor.needsSlowUnlockTransition(), finishRunnable);
|
mKeyguardUpdateMonitor.needsSlowUnlockTransition(), finishRunnable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void handleAttemptLockout(long elapsedRealtimeDeadline) {
|
||||||
|
super.handleAttemptLockout(elapsedRealtimeDeadline);
|
||||||
|
updateAutoConfirmationState();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateAutoConfirmationState() {
|
||||||
|
mDisabledAutoConfirmation = mLockPatternUtils.getCurrentFailedPasswordAttempts(
|
||||||
|
KeyguardUpdateMonitor.getCurrentUser()) >= MIN_FAILED_PIN_ATTEMPTS;
|
||||||
|
updateOKButtonVisibility();
|
||||||
|
updateBackSpaceVisibility();
|
||||||
|
updatePinHinting();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the visibility of the OK button for auto confirm feature
|
* Updates the visibility of the OK button for auto confirm feature
|
||||||
*/
|
*/
|
||||||
private void updateOKButtonVisibility() {
|
private void updateOKButtonVisibility() {
|
||||||
mPasswordFailedAttempts = mLockPatternUtils.getCurrentFailedPasswordAttempts(mUserId);
|
if (isAutoPinConfirmEnabledInSettings() && !mDisabledAutoConfirmation) {
|
||||||
if (isAutoConfirmation() && mPasswordFailedAttempts < MIN_FAILED_PIN_ATTEMPTS) {
|
|
||||||
mOkButton.setVisibility(View.INVISIBLE);
|
mOkButton.setVisibility(View.INVISIBLE);
|
||||||
} else {
|
} else {
|
||||||
mOkButton.setVisibility(View.VISIBLE);
|
mOkButton.setVisibility(View.VISIBLE);
|
||||||
@@ -134,33 +138,41 @@ public class KeyguardPinViewController
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the visibility and the enabled state of the backspace.
|
* Updates the visibility and the enabled state of the backspace.
|
||||||
* Visibility changes are only for auto confirmation configuration.
|
* Visibility changes are only for auto confirmation configuration.
|
||||||
*/
|
*/
|
||||||
private void updateBackSpaceVisibility() {
|
private void updateBackSpaceVisibility() {
|
||||||
if (!isAutoConfirmation()) {
|
boolean isAutoConfirmation = isAutoPinConfirmEnabledInSettings();
|
||||||
return;
|
mBackspaceKey.setTransparentMode(/* isTransparentMode= */
|
||||||
}
|
isAutoConfirmation && !mDisabledAutoConfirmation);
|
||||||
|
if (isAutoConfirmation) {
|
||||||
if (mPasswordEntry.getText().length() > 0) {
|
if (mPasswordEntry.getText().length() > 0
|
||||||
mBackspaceKey.setVisibility(View.VISIBLE);
|
|| mDisabledAutoConfirmation) {
|
||||||
} else {
|
mBackspaceKey.setVisibility(View.VISIBLE);
|
||||||
mBackspaceKey.setVisibility(View.INVISIBLE);
|
} else {
|
||||||
|
mBackspaceKey.setVisibility(View.INVISIBLE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/** Updates whether to use pin hinting or not. */
|
||||||
|
void updatePinHinting() {
|
||||||
|
mPasswordEntry.setIsPinHinting(isAutoPinConfirmEnabledInSettings() && isPinHinting()
|
||||||
|
&& !mDisabledAutoConfirmation);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Responsible for identifying if PIN hinting is to be enabled or not
|
* Responsible for identifying if PIN hinting is to be enabled or not
|
||||||
*/
|
*/
|
||||||
private boolean isPinHinting() {
|
private boolean isPinHinting() {
|
||||||
return mLockPatternUtils.getPinLength(mUserId) == DEFAULT_PIN_LENGTH;
|
return mLockPatternUtils.getPinLength(KeyguardUpdateMonitor.getCurrentUser())
|
||||||
|
== DEFAULT_PIN_LENGTH;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Responsible for identifying if auto confirm is enabled or not in Settings
|
* Responsible for identifying if auto confirm is enabled or not in Settings
|
||||||
*/
|
*/
|
||||||
private boolean isAutoConfirmation() {
|
private boolean isAutoPinConfirmEnabledInSettings() {
|
||||||
//Checks if user has enabled the auto confirm in Settings
|
//Checks if user has enabled the auto confirm in Settings
|
||||||
return mLockPatternUtils.isAutoPinConfirmEnabled(mUserId);
|
return mLockPatternUtils.isAutoPinConfirmEnabled(KeyguardUpdateMonitor.getCurrentUser());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -116,7 +116,12 @@ public class NumPadButton extends AlphaOptimizedImageButton implements NumPadAni
|
|||||||
* @param isTransparentMode
|
* @param isTransparentMode
|
||||||
*/
|
*/
|
||||||
public void setTransparentMode(boolean isTransparentMode) {
|
public void setTransparentMode(boolean isTransparentMode) {
|
||||||
|
if (mIsTransparentMode == isTransparentMode) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
mIsTransparentMode = isTransparentMode;
|
mIsTransparentMode = isTransparentMode;
|
||||||
|
|
||||||
if (isTransparentMode) {
|
if (isTransparentMode) {
|
||||||
setBackgroundColor(getResources().getColor(android.R.color.transparent));
|
setBackgroundColor(getResources().getColor(android.R.color.transparent));
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -101,6 +101,7 @@ public class PasswordTextView extends FrameLayout {
|
|||||||
private Interpolator mFastOutSlowInInterpolator;
|
private Interpolator mFastOutSlowInInterpolator;
|
||||||
private boolean mShowPassword = true;
|
private boolean mShowPassword = true;
|
||||||
private UserActivityListener mUserActivityListener;
|
private UserActivityListener mUserActivityListener;
|
||||||
|
private boolean mIsPinHinting;
|
||||||
private PinShapeInput mPinShapeInput;
|
private PinShapeInput mPinShapeInput;
|
||||||
private boolean mUsePinShapes = false;
|
private boolean mUsePinShapes = false;
|
||||||
|
|
||||||
@@ -419,10 +420,15 @@ public class PasswordTextView extends FrameLayout {
|
|||||||
/**
|
/**
|
||||||
* Determines whether AutoConfirmation feature is on.
|
* Determines whether AutoConfirmation feature is on.
|
||||||
*
|
*
|
||||||
* @param usePinShapes
|
|
||||||
* @param isPinHinting
|
* @param isPinHinting
|
||||||
*/
|
*/
|
||||||
public void setIsPinHinting(boolean isPinHinting) {
|
public void setIsPinHinting(boolean isPinHinting) {
|
||||||
|
// Do not reinflate the view if we are using the same one.
|
||||||
|
if (mPinShapeInput != null && mIsPinHinting == isPinHinting) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mIsPinHinting = isPinHinting;
|
||||||
|
|
||||||
if (mPinShapeInput != null) {
|
if (mPinShapeInput != null) {
|
||||||
removeView(mPinShapeInput.getView());
|
removeView(mPinShapeInput.getView());
|
||||||
mPinShapeInput = null;
|
mPinShapeInput = null;
|
||||||
|
|||||||
@@ -27,6 +27,8 @@ import static org.mockito.Mockito.when;
|
|||||||
import android.test.suitebuilder.annotation.SmallTest;
|
import android.test.suitebuilder.annotation.SmallTest;
|
||||||
import android.testing.AndroidTestingRunner;
|
import android.testing.AndroidTestingRunner;
|
||||||
import android.testing.TestableLooper;
|
import android.testing.TestableLooper;
|
||||||
|
import android.text.Editable;
|
||||||
|
import android.text.TextWatcher;
|
||||||
|
|
||||||
import com.android.systemui.SysuiTestCase;
|
import com.android.systemui.SysuiTestCase;
|
||||||
import com.android.systemui.statusbar.policy.ConfigurationController;
|
import com.android.systemui.statusbar.policy.ConfigurationController;
|
||||||
@@ -93,16 +95,16 @@ public class KeyguardMessageAreaControllerTest extends SysuiTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSetMessage_AnnounceForAccessibility() {
|
public void textChanged_AnnounceForAccessibility() {
|
||||||
ArgumentCaptor<Runnable> argumentCaptor = ArgumentCaptor.forClass(Runnable.class);
|
ArgumentCaptor<TextWatcher> textWatcherArgumentCaptor = ArgumentCaptor.forClass(
|
||||||
when(mKeyguardMessageArea.getText()).thenReturn("abc");
|
TextWatcher.class);
|
||||||
mMessageAreaController.setMessage("abc");
|
mMessageAreaController.onViewAttached();
|
||||||
|
verify(mKeyguardMessageArea).addTextChangedListener(textWatcherArgumentCaptor.capture());
|
||||||
|
|
||||||
verify(mKeyguardMessageArea).setMessage("abc", /* animate= */ true);
|
textWatcherArgumentCaptor.getValue().afterTextChanged(
|
||||||
|
Editable.Factory.getInstance().newEditable("abc"));
|
||||||
verify(mKeyguardMessageArea).removeCallbacks(any(Runnable.class));
|
verify(mKeyguardMessageArea).removeCallbacks(any(Runnable.class));
|
||||||
verify(mKeyguardMessageArea).postDelayed(argumentCaptor.capture(), anyLong());
|
verify(mKeyguardMessageArea).postDelayed(any(Runnable.class), anyLong());
|
||||||
argumentCaptor.getValue().run();
|
|
||||||
verify(mKeyguardMessageArea).announceForAccessibility("abc");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
@@ -152,9 +152,15 @@ class KeyguardPinViewControllerTest : SysuiTestCase() {
|
|||||||
`when`(passwordTextView.text).thenReturn("")
|
`when`(passwordTextView.text).thenReturn("")
|
||||||
|
|
||||||
pinViewController.startAppearAnimation()
|
pinViewController.startAppearAnimation()
|
||||||
verify(deleteButton).visibility = View.INVISIBLE
|
verify(deleteButton).visibility = View.VISIBLE
|
||||||
verify(enterButton).visibility = View.VISIBLE
|
verify(enterButton).visibility = View.VISIBLE
|
||||||
verify(passwordTextView).setUsePinShapes(true)
|
verify(passwordTextView).setUsePinShapes(true)
|
||||||
verify(passwordTextView).setIsPinHinting(true)
|
verify(passwordTextView).setIsPinHinting(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun handleLockout_readsNumberOfErrorAttempts() {
|
||||||
|
pinViewController.handleAttemptLockout(0)
|
||||||
|
verify(lockPatternUtils).getCurrentFailedPasswordAttempts(anyInt())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user