Add mandatory biometric prompt to platform surfaces (2/N)

1. Factory reset

Flag: android.hardware.biometrics.Flags.MANDATORY_BIOMETRICS
Bug: 339910718
Test: atest MainClearTest

Change-Id: I7216f991a2550197c520af860da67f8452cff323
This commit is contained in:
Diya Bera
2024-07-02 20:57:43 +00:00
parent 0037dfe9a9
commit 606bfb3057
3 changed files with 92 additions and 13 deletions

View File

@@ -99,6 +99,7 @@ public class MainClear extends InstrumentedFragment implements OnGlobalLayoutLis
static final int KEYGUARD_REQUEST = 55; static final int KEYGUARD_REQUEST = 55;
@VisibleForTesting @VisibleForTesting
static final int CREDENTIAL_CONFIRM_REQUEST = 56; static final int CREDENTIAL_CONFIRM_REQUEST = 56;
static final int BIOMETRICS_REQUEST = 57;
private static final String KEY_SHOW_ESIM_RESET_CHECKBOX = private static final String KEY_SHOW_ESIM_RESET_CHECKBOX =
"masterclear.allow_retain_esim_profiles_after_fdr"; "masterclear.allow_retain_esim_profiles_after_fdr";
@@ -156,7 +157,8 @@ public class MainClear extends InstrumentedFragment implements OnGlobalLayoutLis
@VisibleForTesting @VisibleForTesting
boolean isValidRequestCode(int requestCode) { boolean isValidRequestCode(int requestCode) {
return !((requestCode != KEYGUARD_REQUEST) && (requestCode != CREDENTIAL_CONFIRM_REQUEST)); return !((requestCode != KEYGUARD_REQUEST) && (requestCode != CREDENTIAL_CONFIRM_REQUEST)
&& (requestCode != BIOMETRICS_REQUEST));
} }
@Override @Override
@@ -179,9 +181,18 @@ public class MainClear extends InstrumentedFragment implements OnGlobalLayoutLis
return; return;
} }
if (requestCode == KEYGUARD_REQUEST) {
if (Utils.requestBiometricAuthenticationForMandatoryBiometrics(getActivity(),
false /* biometricsSuccessfullyAuthenticated */,
false /* biometricsAuthenticationRequested */)) {
Utils.launchBiometricPromptForMandatoryBiometrics(this, BIOMETRICS_REQUEST);
return;
}
}
Intent intent = null; Intent intent = null;
// If returning from a Keyguard request, try to show an account confirmation request if // If returning from a Keyguard request, try to show an account confirmation request if
// applciable. // applicable.
if (CREDENTIAL_CONFIRM_REQUEST != requestCode if (CREDENTIAL_CONFIRM_REQUEST != requestCode
&& (intent = getAccountConfirmationIntent()) != null) { && (intent = getAccountConfirmationIntent()) != null) {
showAccountCredentialConfirmation(intent); showAccountCredentialConfirmation(intent);

View File

@@ -18,6 +18,7 @@ package com.android.settings;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.any; import static org.mockito.Mockito.any;
import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doReturn;
@@ -39,7 +40,12 @@ import android.content.Intent;
import android.content.pm.ActivityInfo; import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo; import android.content.pm.ResolveInfo;
import android.content.res.Resources;
import android.hardware.biometrics.BiometricManager;
import android.hardware.biometrics.Flags;
import android.os.UserManager; import android.os.UserManager;
import android.platform.test.annotations.EnableFlags;
import android.platform.test.flag.junit.SetFlagsRule;
import android.provider.Settings; import android.provider.Settings;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
@@ -57,6 +63,7 @@ import com.android.settingslib.development.DevelopmentSettingsEnabler;
import org.junit.After; import org.junit.After;
import org.junit.Before; import org.junit.Before;
import org.junit.Ignore; import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor; import org.mockito.ArgumentCaptor;
@@ -77,6 +84,9 @@ import org.robolectric.shadows.ShadowActivity;
}) })
public class MainClearTest { public class MainClearTest {
@Rule
public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
private static final String TEST_ACCOUNT_TYPE = "android.test.account.type"; private static final String TEST_ACCOUNT_TYPE = "android.test.account.type";
private static final String TEST_CONFIRMATION_PACKAGE = "android.test.conf.pkg"; private static final String TEST_CONFIRMATION_PACKAGE = "android.test.conf.pkg";
private static final String TEST_CONFIRMATION_CLASS = "android.test.conf.pkg.ConfActivity"; private static final String TEST_CONFIRMATION_CLASS = "android.test.conf.pkg.ConfActivity";
@@ -95,6 +105,12 @@ public class MainClearTest {
@Mock @Mock
private FragmentActivity mMockActivity; private FragmentActivity mMockActivity;
@Mock
private BiometricManager mBiometricManager;
@Mock
private Resources mResources;
@Mock
private Context mContext;
@Mock @Mock
private Intent mMockIntent; private Intent mMockIntent;
@@ -122,6 +138,7 @@ public class MainClearTest {
// Make scrollView only have one child // Make scrollView only have one child
when(mScrollView.getChildAt(0)).thenReturn(mLinearLayout); when(mScrollView.getChildAt(0)).thenReturn(mLinearLayout);
when(mScrollView.getChildCount()).thenReturn(1); when(mScrollView.getChildCount()).thenReturn(1);
doReturn(mActivity).when(mMainClear).getActivity();
} }
@After @After
@@ -343,6 +360,59 @@ public class MainClearTest {
verify(mMainClear, times(1)).showFinalConfirmation(); verify(mMainClear, times(1)).showFinalConfirmation();
} }
@Test
@EnableFlags(Flags.FLAG_MANDATORY_BIOMETRICS)
public void testOnActivityResultInternal_keyguardRequestTriggeringBiometricPrompt() {
when(mContext.getResources()).thenReturn(mResources);
when(mMockActivity.getSystemService(BiometricManager.class)).thenReturn(mBiometricManager);
when(mResources.getString(anyInt())).thenReturn(TEST_ACCOUNT_NAME);
when(mBiometricManager.canAuthenticate(
BiometricManager.Authenticators.MANDATORY_BIOMETRICS))
.thenReturn(BiometricManager.BIOMETRIC_SUCCESS);
doReturn(true).when(mMainClear).isValidRequestCode(eq(MainClear.KEYGUARD_REQUEST));
doNothing().when(mMainClear).startActivityForResult(any(), anyInt());
doReturn(mMockActivity).when(mMainClear).getActivity();
doReturn(mContext).when(mMainClear).getContext();
mMainClear
.onActivityResultInternal(MainClear.KEYGUARD_REQUEST, Activity.RESULT_OK, null);
verify(mMainClear, times(1)).isValidRequestCode(eq(MainClear.KEYGUARD_REQUEST));
verify(mMainClear).startActivityForResult(any(), eq(MainClear.BIOMETRICS_REQUEST));
verify(mMainClear, times(0)).establishInitialState();
verify(mMainClear, times(0)).getAccountConfirmationIntent();
verify(mMainClear, times(0)).showFinalConfirmation();
}
@Test
public void testOnActivityResultInternal_biometricRequestTriggeringFinalConfirmation() {
doReturn(true).when(mMainClear).isValidRequestCode(eq(MainClear.BIOMETRICS_REQUEST));
doReturn(null).when(mMainClear).getAccountConfirmationIntent();
doNothing().when(mMainClear).showFinalConfirmation();
mMainClear
.onActivityResultInternal(MainClear.BIOMETRICS_REQUEST, Activity.RESULT_OK, null);
verify(mMainClear, times(1)).isValidRequestCode(eq(MainClear.BIOMETRICS_REQUEST));
verify(mMainClear, times(0)).establishInitialState();
verify(mMainClear, times(1)).getAccountConfirmationIntent();
verify(mMainClear, times(1)).showFinalConfirmation();
}
@Test
public void testOnActivityResultInternal_biometricRequestTriggeringInitialState() {
doReturn(true).when(mMainClear).isValidRequestCode(eq(MainClear.BIOMETRICS_REQUEST));
doNothing().when(mMainClear).establishInitialState();
mMainClear.onActivityResultInternal(MainClear.BIOMETRICS_REQUEST, Activity.RESULT_CANCELED,
null);
verify(mMainClear, times(1)).isValidRequestCode(eq(MainClear.BIOMETRICS_REQUEST));
verify(mMainClear, times(1)).establishInitialState();
verify(mMainClear, times(0)).getAccountConfirmationIntent();
verify(mMainClear, times(0)).showFinalConfirmation();
}
@Test @Test
public void testOnActivityResultInternal_confirmRequestTriggeringShowFinal() { public void testOnActivityResultInternal_confirmRequestTriggeringShowFinal() {
doReturn(true).when(mMainClear) doReturn(true).when(mMainClear)

View File

@@ -69,9 +69,8 @@ import android.os.UserManager;
import android.os.storage.DiskInfo; import android.os.storage.DiskInfo;
import android.os.storage.StorageManager; import android.os.storage.StorageManager;
import android.os.storage.VolumeInfo; import android.os.storage.VolumeInfo;
import android.platform.test.annotations.RequiresFlagsEnabled; import android.platform.test.annotations.EnableFlags;
import android.platform.test.flag.junit.CheckFlagsRule; import android.platform.test.flag.junit.SetFlagsRule;
import android.platform.test.flag.junit.DeviceFlagsValueProvider;
import android.util.IconDrawableFactory; import android.util.IconDrawableFactory;
import android.widget.EditText; import android.widget.EditText;
import android.widget.ScrollView; import android.widget.ScrollView;
@@ -108,7 +107,7 @@ import java.util.List;
public class UtilsTest { public class UtilsTest {
@Rule @Rule
public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule(); public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
private static final String PACKAGE_NAME = "com.android.app"; private static final String PACKAGE_NAME = "com.android.app";
private static final int USER_ID = 1; private static final int USER_ID = 1;
@@ -528,18 +527,17 @@ public class UtilsTest {
} }
@Test @Test
@RequiresFlagsEnabled(Flags.FLAG_MANDATORY_BIOMETRICS) @EnableFlags(Flags.FLAG_MANDATORY_BIOMETRICS)
public void testRequestBiometricAuthentication_biometricManagerNull_shouldReturnFalse() { public void testRequestBiometricAuthentication_biometricManagerNull_shouldReturnFalse() {
when(mContext.getSystemService(Context.BIOMETRIC_SERVICE)).thenReturn(null); when(mContext.getSystemService(BiometricManager.class)).thenReturn(null);
assertThat(Utils.requestBiometricAuthenticationForMandatoryBiometrics(mContext, assertThat(Utils.requestBiometricAuthenticationForMandatoryBiometrics(mContext,
false /* biometricsSuccessfullyAuthenticated */, false /* biometricsSuccessfullyAuthenticated */,
false /* biometricsAuthenticationRequested */)).isFalse(); false /* biometricsAuthenticationRequested */)).isFalse();
} }
@Test @Test
@RequiresFlagsEnabled(Flags.FLAG_MANDATORY_BIOMETRICS) @EnableFlags(Flags.FLAG_MANDATORY_BIOMETRICS)
public void testRequestBiometricAuthentication_biometricManagerReturnsSuccess_shouldReturnTrue() public void testRequestBiometricAuthentication_biometricManagerReturnsSuccess_shouldReturnTrue() {
throws InterruptedException {
when(mBiometricManager.canAuthenticate( when(mBiometricManager.canAuthenticate(
BiometricManager.Authenticators.MANDATORY_BIOMETRICS)) BiometricManager.Authenticators.MANDATORY_BIOMETRICS))
.thenReturn(BiometricManager.BIOMETRIC_SUCCESS); .thenReturn(BiometricManager.BIOMETRIC_SUCCESS);
@@ -551,7 +549,7 @@ public class UtilsTest {
} }
@Test @Test
@RequiresFlagsEnabled(Flags.FLAG_MANDATORY_BIOMETRICS) @EnableFlags(Flags.FLAG_MANDATORY_BIOMETRICS)
public void testRequestBiometricAuthentication_biometricManagerReturnsError_shouldReturnFalse() { public void testRequestBiometricAuthentication_biometricManagerReturnsError_shouldReturnFalse() {
when(mBiometricManager.canAuthenticate( when(mBiometricManager.canAuthenticate(
BiometricManager.Authenticators.MANDATORY_BIOMETRICS)) BiometricManager.Authenticators.MANDATORY_BIOMETRICS))
@@ -562,7 +560,7 @@ public class UtilsTest {
} }
@Test @Test
@RequiresFlagsEnabled(Flags.FLAG_MANDATORY_BIOMETRICS) @EnableFlags(Flags.FLAG_MANDATORY_BIOMETRICS)
public void testLaunchBiometricPrompt_checkIntentValues() { public void testLaunchBiometricPrompt_checkIntentValues() {
when(mFragment.getContext()).thenReturn(mContext); when(mFragment.getContext()).thenReturn(mContext);