Move invalid input test to regular CTS
Bug: 152240892
Test: atest CtsBiometricsTestCases
Test: make -j CtsVerifier
Change-Id: Ifb2d2d41b3b29cd74919171537ff4c0517e09989
diff --git a/apps/CtsVerifier/res/layout/biometric_test_strong_tests.xml b/apps/CtsVerifier/res/layout/biometric_test_strong_tests.xml
index 26e66f1..41227b4 100644
--- a/apps/CtsVerifier/res/layout/biometric_test_strong_tests.xml
+++ b/apps/CtsVerifier/res/layout/biometric_test_strong_tests.xml
@@ -57,13 +57,6 @@
android:text="@string/biometric_test_strong_authenticate_strongbox_button"
android:enabled="false"/>
<Button
- android:id="@+id/authenticate_invalid_inputs"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_centerInParent="true"
- android:text="@string/biometric_test_invalid_inputs"
- android:enabled="false"/>
- <Button
android:id="@+id/authenticate_reject_first"
android:layout_width="match_parent"
android:layout_height="wrap_content"
diff --git a/apps/CtsVerifier/res/layout/biometric_test_weak_tests.xml b/apps/CtsVerifier/res/layout/biometric_test_weak_tests.xml
index 19fdbff..55886fe 100644
--- a/apps/CtsVerifier/res/layout/biometric_test_weak_tests.xml
+++ b/apps/CtsVerifier/res/layout/biometric_test_weak_tests.xml
@@ -48,13 +48,6 @@
android:text="@string/biometric_test_weak_authenticate_time_based_keys"
android:enabled="false"/>
<Button
- android:id="@+id/authenticate_invalid_inputs"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_centerInParent="true"
- android:text="@string/biometric_test_invalid_inputs"
- android:enabled="false"/>
- <Button
android:id="@+id/authenticate_reject_first"
android:layout_width="match_parent"
android:layout_height="wrap_content"
diff --git a/apps/CtsVerifier/res/values/strings.xml b/apps/CtsVerifier/res/values/strings.xml
index 41d8129..d42c3b8 100644
--- a/apps/CtsVerifier/res/values/strings.xml
+++ b/apps/CtsVerifier/res/values/strings.xml
@@ -266,8 +266,6 @@
<string name="biometric_test_ui_verification_dialog_title">Please enter your recorded contents</string>
<string name="biometric_test_ui_verification_dialog_check">Check</string>
- <!-- Invoking the public API with non-public constants -->
- <string name="biometric_test_invalid_inputs">Test invalid inputs</string>
<!-- Rejecting does not end the authentication lifecycle -->
<string name="biometric_test_reject_first">Reject, then authenticate</string>
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/biometrics/AbstractBaseTest.java b/apps/CtsVerifier/src/com/android/cts/verifier/biometrics/AbstractBaseTest.java
index a4d360f..f154f18 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/biometrics/AbstractBaseTest.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/biometrics/AbstractBaseTest.java
@@ -141,71 +141,6 @@
startActivityForResult(enrollIntent, requestCode);
}
- private boolean isPublicAuthenticatorConstant(int authenticator) {
- final int[] publicConstants = {
- Authenticators.BIOMETRIC_STRONG,
- Authenticators.BIOMETRIC_WEAK,
- Authenticators.DEVICE_CREDENTIAL
- };
- for (int constant : publicConstants) {
- if (authenticator == constant) {
- return true;
- }
- }
- return false;
- }
-
- void testInvalidInputs(Runnable successRunnable) {
- for (int i = 0; i < 32; i++) {
- final int authenticator = 1 << i;
- // If it's a public constant, no need to test
- if (isPublicAuthenticatorConstant(authenticator)) {
- continue;
- }
-
- // Test canAuthenticate(int)
- boolean exceptionCaught = false;
- try {
- mBiometricManager.canAuthenticate(authenticator);
- } catch (Exception e) {
- exceptionCaught = true;
- }
-
- if (!exceptionCaught) {
- showToastAndLog("Non-public constants provided to canAuthenticate(int) must throw an"
- + " exception");
- return;
- }
-
- // Test setAllowedAuthenticators(int)
- exceptionCaught = false;
- try {
- final BiometricPrompt.Builder builder = new BiometricPrompt.Builder(this);
- builder.setAllowedAuthenticators(authenticator);
- builder.setTitle("This should never be shown");
- builder.setNegativeButton("Cancel", mExecutor,
- (dialog, which) -> {
- // Do nothing
- });
- final BiometricPrompt prompt = builder.build();
- prompt.authenticate(new CancellationSignal(), mExecutor,
- new AuthenticationCallback() {
-
- });
- } catch (Exception e) {
- exceptionCaught = true;
- }
-
- if (!exceptionCaught) {
- showToastAndLog("Non-public constants provided to setAllowedAuthenticators(int) must"
- + " throw an exception");
- return;
- }
- }
-
- successRunnable.run();
- }
-
void testBiometricRejectDoesNotEndAuthentication(Runnable successRunnable) {
Utils.showInstructionDialog(this,
R.string.biometric_test_reject_continues_instruction_title,
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/biometrics/BiometricStrongTests.java b/apps/CtsVerifier/src/com/android/cts/verifier/biometrics/BiometricStrongTests.java
index 3392a05..c356322 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/biometrics/BiometricStrongTests.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/biometrics/BiometricStrongTests.java
@@ -69,13 +69,11 @@
private Button mCheckAndEnrollButton;
private Button mAuthenticateWithoutStrongBoxButton;
private Button mAuthenticateWithStrongBoxButton;
- private Button mCheckInvalidInputsButton;
private Button mRejectThenAuthenticateButton;
private Button mKeyInvalidatedButton;
private boolean mAuthenticateWithoutStrongBoxPassed;
private boolean mAuthenticateWithStrongBoxPassed;
- private boolean mCheckInvalidInputsPassed;
private boolean mRejectThenAuthenticatePassed;
private boolean mKeyInvalidatedStrongboxPassed;
private boolean mKeyInvalidatedNoStrongboxPassed;
@@ -94,7 +92,6 @@
mCheckAndEnrollButton.setEnabled(false);
mAuthenticateWithoutStrongBoxButton.setEnabled(true);
mAuthenticateWithStrongBoxButton.setEnabled(true);
- mCheckInvalidInputsButton.setEnabled(true);
mRejectThenAuthenticateButton.setEnabled(true);
} else {
showToastAndLog("Unexpected result after enrollment: " + biometricStatus);
@@ -111,7 +108,6 @@
mCheckAndEnrollButton = findViewById(R.id.check_and_enroll_button);
mAuthenticateWithoutStrongBoxButton = findViewById(R.id.authenticate_no_strongbox_button);
mAuthenticateWithStrongBoxButton = findViewById(R.id.authenticate_strongbox_button);
- mCheckInvalidInputsButton = findViewById(R.id.authenticate_invalid_inputs);
mRejectThenAuthenticateButton = findViewById(R.id.authenticate_reject_first);
mKeyInvalidatedButton = findViewById(R.id.authenticate_key_invalidated_button);
@@ -139,14 +135,6 @@
true /* useStrongBox */);
});
- mCheckInvalidInputsButton.setOnClickListener((view) -> {
- testInvalidInputs(() -> {
- mCheckInvalidInputsPassed = true;
- mCheckInvalidInputsButton.setEnabled(false);
- updatePassButton();
- });
- });
-
mRejectThenAuthenticateButton.setOnClickListener((view) -> {
testBiometricRejectDoesNotEndAuthentication(() -> {
mRejectThenAuthenticatePassed = true;
@@ -197,7 +185,7 @@
// completed, let's allow onPause (allow tester to go into settings multiple times if
// needed).
if (mAuthenticateWithoutStrongBoxPassed && mAuthenticateWithStrongBoxPassed
- && mCheckInvalidInputsPassed && mRejectThenAuthenticatePassed) {
+ && mRejectThenAuthenticatePassed) {
return true;
}
@@ -286,7 +274,7 @@
private void updatePassButton() {
if (mAuthenticateWithoutStrongBoxPassed && mAuthenticateWithStrongBoxPassed
- && mCheckInvalidInputsPassed && mRejectThenAuthenticatePassed) {
+ && mRejectThenAuthenticatePassed) {
if (!mKeyInvalidatedStrongboxPassed || !mKeyInvalidatedNoStrongboxPassed) {
mKeyInvalidatedButton.setEnabled(true);
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/biometrics/BiometricWeakTests.java b/apps/CtsVerifier/src/com/android/cts/verifier/biometrics/BiometricWeakTests.java
index 13fb2e8..ffac0ab 100644
--- a/apps/CtsVerifier/src/com/android/cts/verifier/biometrics/BiometricWeakTests.java
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/biometrics/BiometricWeakTests.java
@@ -51,11 +51,9 @@
private Button mEnrollButton;
private Button mAuthenticateTimeBasedKeysButton;
- private Button mCheckInvalidInputsButton;
private Button mRejectThenAuthenticateButton;
private boolean mAuthenticateTimeBasedKeysPassed;
- private boolean mCheckInvalidInputsPassed;
private boolean mRejectThenAuthenticatePassed;
@Override
@@ -73,7 +71,6 @@
mEnrollButton = findViewById(R.id.biometric_test_weak_enroll_button);
mAuthenticateTimeBasedKeysButton = findViewById(
R.id.biometric_test_weak_authenticate_time_based_keys_button);
- mCheckInvalidInputsButton = findViewById(R.id.authenticate_invalid_inputs);
mRejectThenAuthenticateButton = findViewById(R.id.authenticate_reject_first);
mEnrollButton.setOnClickListener((view) -> {
@@ -198,14 +195,6 @@
});
- mCheckInvalidInputsButton.setOnClickListener((view) -> {
- testInvalidInputs(() -> {
- mCheckInvalidInputsPassed = true;
- mCheckInvalidInputsButton.setEnabled(false);
- updatePassButton();
- });
- });
-
mRejectThenAuthenticateButton.setOnClickListener((view) -> {
testBiometricRejectDoesNotEndAuthentication(() -> {
mRejectThenAuthenticatePassed = true;
@@ -231,7 +220,6 @@
private void updatePassButton() {
if (mAuthenticateTimeBasedKeysPassed
- && mCheckInvalidInputsPassed
&& mRejectThenAuthenticatePassed) {
showToastAndLog("All tests passed");
getPassButton().setEnabled(true);
@@ -246,7 +234,6 @@
showToastAndLog("Successfully enrolled, please continue the test");
mEnrollButton.setEnabled(false);
mAuthenticateTimeBasedKeysButton.setEnabled(true);
- mCheckInvalidInputsButton.setEnabled(true);
mRejectThenAuthenticateButton.setEnabled(true);
} else {
showToastAndLog("Unexpected result after enrollment: " + biometricStatus);
diff --git a/tests/framework/base/biometrics/src/android/server/biometrics/BiometricSimpleTests.java b/tests/framework/base/biometrics/src/android/server/biometrics/BiometricSimpleTests.java
index 1cb339e..3cfc9ea 100644
--- a/tests/framework/base/biometrics/src/android/server/biometrics/BiometricSimpleTests.java
+++ b/tests/framework/base/biometrics/src/android/server/biometrics/BiometricSimpleTests.java
@@ -17,7 +17,9 @@
package android.server.biometrics;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
@@ -93,6 +95,29 @@
state.mSensorStates.containsModality(SensorStateProto.IRIS));
}
+ @Test
+ public void testInvalidInputs() {
+ for (int i = 0; i < 32; i++) {
+ final int authenticator = 1 << i;
+ // If it's a public constant, no need to test
+ if (Utils.isPublicAuthenticatorConstant(authenticator)) {
+ continue;
+ }
+
+ // Test canAuthenticate(int)
+ assertThrows("Invalid authenticator in canAuthenticate must throw exception: "
+ + authenticator,
+ Exception.class,
+ () -> mBiometricManager.canAuthenticate(authenticator));
+
+ // Test BiometricPrompt
+ assertThrows("Invalid authenticator in authenticate must throw exception: "
+ + authenticator,
+ Exception.class,
+ () -> showBiometricPromptWithAuthenticators(authenticator));
+ }
+ }
+
/**
* When device credential is not enrolled, check the behavior for
* 1) BiometricManager#canAuthenticate(DEVICE_CREDENTIAL)
diff --git a/tests/framework/base/biometrics/src/android/server/biometrics/BiometricTestBase.java b/tests/framework/base/biometrics/src/android/server/biometrics/BiometricTestBase.java
index d5a40a3..83345e5 100644
--- a/tests/framework/base/biometrics/src/android/server/biometrics/BiometricTestBase.java
+++ b/tests/framework/base/biometrics/src/android/server/biometrics/BiometricTestBase.java
@@ -414,6 +414,34 @@
successfullyAuthenticate(session, userId);
}
+ protected void showBiometricPromptWithAuthenticators(int authenticators) {
+ final Handler handler = new Handler(Looper.getMainLooper());
+ final Executor executor = handler::post;
+ final BiometricPrompt prompt = new BiometricPrompt.Builder(mContext)
+ .setTitle("Title")
+ .setSubtitle("Subtitle")
+ .setDescription("Description")
+ .setNegativeButton("Negative Button", executor, (dialog, which) -> {
+ Log.d(TAG, "Negative button pressed");
+ })
+ .setAllowBackgroundAuthentication(true)
+ .setAllowedAuthenticators(authenticators)
+ .build();
+ prompt.authenticate(new CancellationSignal(), executor,
+ new BiometricPrompt.AuthenticationCallback() {
+ @Override
+ public void onAuthenticationError(int errorCode, CharSequence errString) {
+ Log.d(TAG, "onAuthenticationError: " + errorCode);
+ }
+
+ @Override
+ public void onAuthenticationSucceeded(
+ BiometricPrompt.AuthenticationResult result) {
+ Log.d(TAG, "onAuthenticationSucceeded");
+ }
+ });
+ }
+
@NonNull
protected static BiometricCallbackHelper.State getCallbackState(@NonNull TestJournal journal) {
Utils.waitFor("Waiting for authentication callback",
diff --git a/tests/framework/base/biometrics/src/android/server/biometrics/Utils.java b/tests/framework/base/biometrics/src/android/server/biometrics/Utils.java
index 1947f76..8be3b55 100644
--- a/tests/framework/base/biometrics/src/android/server/biometrics/Utils.java
+++ b/tests/framework/base/biometrics/src/android/server/biometrics/Utils.java
@@ -19,6 +19,7 @@
import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
import android.content.ComponentName;
+import android.hardware.biometrics.BiometricManager;
import android.hardware.biometrics.BiometricPrompt;
import android.os.ParcelFileDescriptor;
import android.security.keystore.KeyGenParameterSpec;
@@ -176,4 +177,15 @@
new BiometricPrompt.CryptoObject(cipher);
return cryptoObject;
}
+
+ public static boolean isPublicAuthenticatorConstant(int authenticator) {
+ switch (authenticator) {
+ case BiometricManager.Authenticators.BIOMETRIC_STRONG:
+ case BiometricManager.Authenticators.BIOMETRIC_WEAK:
+ case BiometricManager.Authenticators.DEVICE_CREDENTIAL:
+ return true;
+ default:
+ return false;
+ }
+ }
}