summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java15
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/AuthCredentialPasswordView.java27
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt51
3 files changed, 70 insertions, 23 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
index 94f71580901c..68e1f72d042a 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
@@ -129,6 +129,7 @@ public class AuthContainerView extends LinearLayout
private final float mTranslationY;
@VisibleForTesting @ContainerState int mContainerState = STATE_UNKNOWN;
private final Set<Integer> mFailedModalities = new HashSet<Integer>();
+ private OnBackInvokedDispatcher mOnBackInvokedDispatcher;
private final OnBackInvokedCallback mBackCallback = this::onBackInvoked;
private final @Background DelayableExecutor mBackgroundExecutor;
@@ -497,9 +498,9 @@ public class AuthContainerView extends LinearLayout
.start();
});
}
- OnBackInvokedDispatcher dispatcher = findOnBackInvokedDispatcher();
- if (dispatcher != null) {
- dispatcher.registerOnBackInvokedCallback(
+ mOnBackInvokedDispatcher = findOnBackInvokedDispatcher();
+ if (mOnBackInvokedDispatcher != null) {
+ mOnBackInvokedDispatcher.registerOnBackInvokedCallback(
OnBackInvokedDispatcher.PRIORITY_DEFAULT, mBackCallback);
}
}
@@ -600,11 +601,11 @@ public class AuthContainerView extends LinearLayout
@Override
public void onDetachedFromWindow() {
- OnBackInvokedDispatcher dispatcher = findOnBackInvokedDispatcher();
- if (dispatcher != null) {
- findOnBackInvokedDispatcher().unregisterOnBackInvokedCallback(mBackCallback);
- }
super.onDetachedFromWindow();
+ if (mOnBackInvokedDispatcher != null) {
+ mOnBackInvokedDispatcher.unregisterOnBackInvokedCallback(mBackCallback);
+ mOnBackInvokedDispatcher = null;
+ }
mWakefulnessLifecycle.removeObserver(this);
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthCredentialPasswordView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthCredentialPasswordView.java
index 76cd3f4c4f1d..e43c0b9987ab 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthCredentialPasswordView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthCredentialPasswordView.java
@@ -35,6 +35,8 @@ import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import android.widget.ImeAwareEditText;
import android.widget.TextView;
+import android.window.OnBackInvokedCallback;
+import android.window.OnBackInvokedDispatcher;
import com.android.internal.widget.LockPatternChecker;
import com.android.internal.widget.LockPatternUtils;
@@ -58,6 +60,8 @@ public class AuthCredentialPasswordView extends AuthCredentialView
private ViewGroup mAuthCredentialHeader;
private ViewGroup mAuthCredentialInput;
private int mBottomInset = 0;
+ private OnBackInvokedDispatcher mOnBackInvokedDispatcher;
+ private final OnBackInvokedCallback mBackCallback = this::onBackInvoked;
public AuthCredentialPasswordView(Context context,
AttributeSet attrs) {
@@ -79,8 +83,7 @@ public class AuthCredentialPasswordView extends AuthCredentialView
return false;
}
if (event.getAction() == KeyEvent.ACTION_UP) {
- mContainerView.sendEarlyUserCanceled();
- mContainerView.animateAway(AuthDialogCallback.DISMISSED_USER_CANCELED);
+ onBackInvoked();
}
return true;
});
@@ -88,6 +91,11 @@ public class AuthCredentialPasswordView extends AuthCredentialView
setOnApplyWindowInsetsListener(this);
}
+ private void onBackInvoked() {
+ mContainerView.sendEarlyUserCanceled();
+ mContainerView.animateAway(AuthDialogCallback.DISMISSED_USER_CANCELED);
+ }
+
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
@@ -100,6 +108,12 @@ public class AuthCredentialPasswordView extends AuthCredentialView
mPasswordField.requestFocus();
mPasswordField.scheduleShowSoftInput();
+
+ mOnBackInvokedDispatcher = findOnBackInvokedDispatcher();
+ if (mOnBackInvokedDispatcher != null) {
+ mOnBackInvokedDispatcher.registerOnBackInvokedCallback(
+ OnBackInvokedDispatcher.PRIORITY_DEFAULT, mBackCallback);
+ }
}
@Override
@@ -137,6 +151,15 @@ public class AuthCredentialPasswordView extends AuthCredentialView
}
@Override
+ public void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ if (mOnBackInvokedDispatcher != null) {
+ mOnBackInvokedDispatcher.unregisterOnBackInvokedCallback(mBackCallback);
+ mOnBackInvokedDispatcher = null;
+ }
+ }
+
+ @Override
protected void onCredentialVerified(@NonNull VerifyCredentialResponse response,
int timeoutMs) {
super.onCredentialVerified(response, timeoutMs);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt
index eaef159e9020..5e6acd29e520 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt
@@ -111,6 +111,21 @@ class AuthContainerViewTest : SysuiTestCase() {
}
@Test
+ fun testCredentialPasswordDismissesOnBack() {
+ val container = initializeCredentialPasswordContainer(addToView = true)
+ assertThat(container.parent).isNotNull()
+ val root = container.rootView
+
+ // Simulate back invocation
+ container.dispatchKeyEvent(KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK))
+ container.dispatchKeyEvent(KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_BACK))
+ waitForIdleSync()
+
+ assertThat(container.parent).isNull()
+ assertThat(root.isAttachedToWindow).isFalse()
+ }
+
+ @Test
fun testIgnoresAnimatedInWhenDismissed() {
val container = initializeFingerprintContainer(addToView = false)
container.dismissFromSystemServer()
@@ -355,20 +370,7 @@ class AuthContainerViewTest : SysuiTestCase() {
@Test
fun testCredentialUI_disablesClickingOnBackground() {
- whenever(userManager.getCredentialOwnerProfile(anyInt())).thenReturn(20)
- whenever(lockPatternUtils.getKeyguardStoredPasswordQuality(eq(20))).thenReturn(
- DevicePolicyManager.PASSWORD_QUALITY_NUMERIC
- )
-
- // In the credential view, clicking on the background (to cancel authentication) is not
- // valid. Thus, the listener should be null, and it should not be in the accessibility
- // hierarchy.
- val container = initializeFingerprintContainer(
- authenticators = BiometricManager.Authenticators.DEVICE_CREDENTIAL
- )
- waitForIdleSync()
-
- assertThat(container.hasCredentialPasswordView()).isTrue()
+ val container = initializeCredentialPasswordContainer()
assertThat(container.hasBiometricPrompt()).isFalse()
assertThat(
container.findViewById<View>(R.id.background)?.isImportantForAccessibility
@@ -428,6 +430,27 @@ class AuthContainerViewTest : SysuiTestCase() {
verify(callback).onTryAgainPressed(authContainer?.requestId ?: 0L)
}
+ private fun initializeCredentialPasswordContainer(
+ addToView: Boolean = true,
+ ): TestAuthContainerView {
+ whenever(userManager.getCredentialOwnerProfile(anyInt())).thenReturn(20)
+ whenever(lockPatternUtils.getKeyguardStoredPasswordQuality(eq(20))).thenReturn(
+ DevicePolicyManager.PASSWORD_QUALITY_NUMERIC
+ )
+
+ // In the credential view, clicking on the background (to cancel authentication) is not
+ // valid. Thus, the listener should be null, and it should not be in the accessibility
+ // hierarchy.
+ val container = initializeFingerprintContainer(
+ authenticators = BiometricManager.Authenticators.DEVICE_CREDENTIAL,
+ addToView = addToView,
+ )
+ waitForIdleSync()
+
+ assertThat(container.hasCredentialPasswordView()).isTrue()
+ return container
+ }
+
private fun initializeFingerprintContainer(
authenticators: Int = BiometricManager.Authenticators.BIOMETRIC_WEAK,
addToView: Boolean = true