(2/N) Biometric error dialog
Add an error dialog to help user recover from biometric error for for identity check while trying to factory reset Flag: android.hardware.biometrics.flag.mandatory_biometrics Bug: 358641110 Bug: 358179610 Test: atest MainClearTest Change-Id: Ia20389a3146aa45ad42bdc4d31f1bd9488f2dc42
This commit is contained in:
@@ -942,8 +942,10 @@
|
||||
<string name="go_to_settings">Go to Settings</string>
|
||||
<!-- Dialog title when identity check auth is requested but biometrics is in lockout state [CHAR LIMIT=NONE] -->
|
||||
<string name="identity_check_lockout_error_title">Identity Check is on and can’t verify it’s you</string>
|
||||
<!-- Dialog title when identity check auth is requested but biometric hardware has an error. [CHAR LIMIT=NONE] -->
|
||||
<!-- Dialog message when identity check auth is requested but biometrics is in lockout state. [CHAR LIMIT=NONE] -->
|
||||
<string name="identity_check_lockout_error_description_1">Biometrics failed too many times. Lock and unlock your device to retry.</string>
|
||||
<!-- Dialog message when identity check auth is requested but biometrics is in lockout state and there is a two factor authentication. [CHAR LIMIT=NONE] -->
|
||||
<string name="identity_check_lockout_error_two_factor_auth_description_1">Biometrics failed too many times. Try again.</string>
|
||||
<!-- Dialog message when identity check auth is requested but biometrics is in lockout state. "Go to Settings" launches theft protection settings, in case user wishes to disable the feature. [CHAR LIMIT=NONE] -->
|
||||
<string name="identity_check_lockout_error_description_2">You can manage Identity Check in theft protection settings. Go to Settings</string>
|
||||
<!-- Dialog title when identity check auth is requested but biometric hardware has an error. [CHAR LIMIT=100] -->
|
||||
|
@@ -65,11 +65,13 @@ import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import com.android.settings.biometrics.IdentityCheckBiometricErrorDialog;
|
||||
import com.android.settings.core.InstrumentedFragment;
|
||||
import com.android.settings.enterprise.ActionDisabledByAdminDialogHelper;
|
||||
import com.android.settings.flags.Flags;
|
||||
import com.android.settings.network.SubscriptionUtil;
|
||||
import com.android.settings.password.ChooseLockSettingsHelper;
|
||||
import com.android.settings.password.ConfirmDeviceCredentialActivity;
|
||||
import com.android.settings.password.ConfirmLockPattern;
|
||||
import com.android.settingslib.RestrictedLockUtilsInternal;
|
||||
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
|
||||
@@ -178,6 +180,12 @@ public class MainClear extends InstrumentedFragment implements OnGlobalLayoutLis
|
||||
|
||||
if (resultCode != Activity.RESULT_OK) {
|
||||
establishInitialState();
|
||||
if (requestCode == BIOMETRICS_REQUEST) {
|
||||
if (resultCode == ConfirmDeviceCredentialActivity.BIOMETRIC_LOCKOUT_ERROR_RESULT) {
|
||||
IdentityCheckBiometricErrorDialog.showBiometricErrorDialog(getActivity(),
|
||||
Utils.BiometricStatus.LOCKOUT, true /* twoFactorAuthentication */);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -192,6 +200,8 @@ public class MainClear extends InstrumentedFragment implements OnGlobalLayoutLis
|
||||
userId, false /* hideBackground */);
|
||||
return;
|
||||
} else if (biometricAuthStatus != Utils.BiometricStatus.NOT_ACTIVE) {
|
||||
IdentityCheckBiometricErrorDialog.showBiometricErrorDialog(getActivity(),
|
||||
biometricAuthStatus, true /* twoFactorAuthentication */);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@@ -1522,6 +1522,7 @@ public final class Utils extends com.android.settingslib.Utils {
|
||||
case BiometricManager.BIOMETRIC_ERROR_LOCKOUT:
|
||||
return BiometricStatus.LOCKOUT;
|
||||
case BiometricManager.BIOMETRIC_ERROR_MANDATORY_NOT_ACTIVE:
|
||||
case BiometricManager.BIOMETRIC_ERROR_NOT_ENABLED_FOR_APPS:
|
||||
return BiometricStatus.NOT_ACTIVE;
|
||||
default:
|
||||
return BiometricStatus.ERROR;
|
||||
|
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settings.development;
|
||||
package com.android.settings.biometrics;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
@@ -45,10 +45,12 @@ import com.android.settings.Utils;
|
||||
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
|
||||
|
||||
/** Initializes and shows biometric error dialogs related to identity check. */
|
||||
public class BiometricErrorDialog extends InstrumentedDialogFragment {
|
||||
public class IdentityCheckBiometricErrorDialog extends InstrumentedDialogFragment {
|
||||
private static final String TAG = "BiometricErrorDialog";
|
||||
|
||||
private static final String KEY_ERROR_CODE = "key_error_code";
|
||||
private static final String KEY_TWO_FACTOR_AUTHENTICATION = "key_two_factor_authentication";
|
||||
|
||||
private String mActionIdentityCheckSettings = Settings.ACTION_SETTINGS;
|
||||
@Nullable private BroadcastReceiver mBroadcastReceiver;
|
||||
|
||||
@@ -62,17 +64,19 @@ public class BiometricErrorDialog extends InstrumentedDialogFragment {
|
||||
Utils.BiometricStatus.LOCKOUT.name());
|
||||
final View customView = inflater.inflate(R.layout.biometric_lockout_error_dialog,
|
||||
null);
|
||||
final boolean twoFactorAuthentication = getArguments().getBoolean(
|
||||
KEY_TWO_FACTOR_AUTHENTICATION);
|
||||
final String identityCheckSettingsAction = getActivity().getString(
|
||||
R.string.identity_check_settings_action);
|
||||
mActionIdentityCheckSettings = identityCheckSettingsAction.isEmpty()
|
||||
? mActionIdentityCheckSettings : identityCheckSettingsAction;
|
||||
Log.d(TAG, mActionIdentityCheckSettings);
|
||||
setTitle(customView, isLockoutError);
|
||||
setBody(customView, isLockoutError);
|
||||
setBody(customView, isLockoutError, twoFactorAuthentication);
|
||||
alertDialogBuilder.setView(customView);
|
||||
setPositiveButton(alertDialogBuilder, isLockoutError);
|
||||
setPositiveButton(alertDialogBuilder, isLockoutError, twoFactorAuthentication);
|
||||
if (!isLockoutError || !twoFactorAuthentication) {
|
||||
setNegativeButton(alertDialogBuilder, isLockoutError);
|
||||
|
||||
}
|
||||
if (isLockoutError) {
|
||||
mBroadcastReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
@@ -103,15 +107,16 @@ public class BiometricErrorDialog extends InstrumentedDialogFragment {
|
||||
* @param fragmentActivity calling activity
|
||||
* @param errorCode refers to the biometric error
|
||||
*/
|
||||
public static BiometricErrorDialog showBiometricErrorDialog(FragmentActivity fragmentActivity,
|
||||
Utils.BiometricStatus errorCode) {
|
||||
final BiometricErrorDialog biometricErrorDialog = new BiometricErrorDialog();
|
||||
public static void showBiometricErrorDialog(FragmentActivity fragmentActivity,
|
||||
Utils.BiometricStatus errorCode, boolean twoFactorAuthentication) {
|
||||
final IdentityCheckBiometricErrorDialog identityCheckBiometricErrorDialog =
|
||||
new IdentityCheckBiometricErrorDialog();
|
||||
final Bundle args = new Bundle();
|
||||
args.putCharSequence(KEY_ERROR_CODE, errorCode.name());
|
||||
biometricErrorDialog.setArguments(args);
|
||||
biometricErrorDialog.show(fragmentActivity.getSupportFragmentManager(),
|
||||
BiometricErrorDialog.class.getName());
|
||||
return biometricErrorDialog;
|
||||
args.putBoolean(KEY_TWO_FACTOR_AUTHENTICATION, twoFactorAuthentication);
|
||||
identityCheckBiometricErrorDialog.setArguments(args);
|
||||
identityCheckBiometricErrorDialog.show(fragmentActivity.getSupportFragmentManager(),
|
||||
IdentityCheckBiometricErrorDialog.class.getName());
|
||||
}
|
||||
|
||||
private void setTitle(View view, boolean lockout) {
|
||||
@@ -123,12 +128,17 @@ public class BiometricErrorDialog extends InstrumentedDialogFragment {
|
||||
}
|
||||
}
|
||||
|
||||
private void setBody(View view, boolean lockout) {
|
||||
private void setBody(View view, boolean lockout, boolean twoFactorAuthentication) {
|
||||
final TextView textView1 = view.findViewById(R.id.description_1);
|
||||
final TextView textView2 = view.findViewById(R.id.description_2);
|
||||
|
||||
if (lockout) {
|
||||
if (twoFactorAuthentication) {
|
||||
textView1.setText(
|
||||
R.string.identity_check_lockout_error_two_factor_auth_description_1);
|
||||
} else {
|
||||
textView1.setText(R.string.identity_check_lockout_error_description_1);
|
||||
}
|
||||
textView2.setText(getClickableDescriptionForLockoutError());
|
||||
textView2.setMovementMethod(LinkMovementMethod.getInstance());
|
||||
} else {
|
||||
@@ -167,15 +177,22 @@ public class BiometricErrorDialog extends InstrumentedDialogFragment {
|
||||
return spannableString;
|
||||
}
|
||||
|
||||
private void setPositiveButton(AlertDialog.Builder alertDialogBuilder, boolean lockout) {
|
||||
private void setPositiveButton(AlertDialog.Builder alertDialogBuilder, boolean lockout,
|
||||
boolean twoFactorAuthentication) {
|
||||
if (lockout) {
|
||||
if (twoFactorAuthentication) {
|
||||
alertDialogBuilder.setPositiveButton((R.string.okay),
|
||||
(dialog, which) -> dialog.dismiss());
|
||||
} else {
|
||||
DevicePolicyManager devicePolicyManager = (DevicePolicyManager)
|
||||
getContext().getSystemService(Context.DEVICE_POLICY_SERVICE);
|
||||
alertDialogBuilder.setPositiveButton(R.string.identity_check_lockout_error_lock_screen,
|
||||
alertDialogBuilder.setPositiveButton(
|
||||
R.string.identity_check_lockout_error_lock_screen,
|
||||
(dialog, which) -> {
|
||||
dialog.dismiss();
|
||||
devicePolicyManager.lockNow();
|
||||
});
|
||||
}
|
||||
} else {
|
||||
alertDialogBuilder.setPositiveButton(R.string.identity_check_biometric_error_ok,
|
||||
(dialog, which) -> dialog.dismiss());
|
@@ -57,6 +57,7 @@ import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.SettingsActivity;
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.biometrics.IdentityCheckBiometricErrorDialog;
|
||||
import com.android.settings.core.SubSettingLauncher;
|
||||
import com.android.settings.dashboard.RestrictedDashboardFragment;
|
||||
import com.android.settings.development.autofill.AutofillCategoryController;
|
||||
@@ -378,8 +379,8 @@ public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFra
|
||||
userId, false /* hideBackground */);
|
||||
} else if (biometricAuthStatus != Utils.BiometricStatus.NOT_ACTIVE) {
|
||||
mSwitchBar.setChecked(false);
|
||||
BiometricErrorDialog.showBiometricErrorDialog(
|
||||
getActivity(), biometricAuthStatus);
|
||||
IdentityCheckBiometricErrorDialog.showBiometricErrorDialog(getActivity(),
|
||||
biometricAuthStatus, false /* twoFactorAuthentication */);
|
||||
} else {
|
||||
//Reset biometrics once enable dialog is shown
|
||||
mIsBiometricsAuthenticated = false;
|
||||
@@ -564,8 +565,8 @@ public class DevelopmentSettingsDashboardFragment extends RestrictedDashboardFra
|
||||
mSwitchBar.setChecked(true);
|
||||
} else if (resultCode
|
||||
== ConfirmDeviceCredentialActivity.BIOMETRIC_LOCKOUT_ERROR_RESULT) {
|
||||
BiometricErrorDialog.showBiometricErrorDialog(getActivity(),
|
||||
Utils.BiometricStatus.LOCKOUT);
|
||||
IdentityCheckBiometricErrorDialog.showBiometricErrorDialog(getActivity(),
|
||||
Utils.BiometricStatus.LOCKOUT, false /* twoFactorAuthentication */);
|
||||
}
|
||||
}
|
||||
for (AbstractPreferenceController controller : mPreferenceControllers) {
|
||||
|
@@ -36,10 +36,12 @@ import androidx.preference.Preference;
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.biometrics.IdentityCheckBiometricErrorDialog;
|
||||
import com.android.settings.core.BasePreferenceController;
|
||||
import com.android.settings.core.InstrumentedPreferenceFragment;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
import com.android.settings.password.ChooseLockSettingsHelper;
|
||||
import com.android.settings.password.ConfirmDeviceCredentialActivity;
|
||||
import com.android.settingslib.RestrictedLockUtils;
|
||||
import com.android.settingslib.RestrictedLockUtilsInternal;
|
||||
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
|
||||
@@ -235,10 +237,18 @@ public class BuildNumberPreferenceController extends BasePreferenceController im
|
||||
userId, false /* hideBackground */);
|
||||
} else if (biometricAuthStatus == Utils.BiometricStatus.NOT_ACTIVE) {
|
||||
enableDevelopmentSettings();
|
||||
} else {
|
||||
IdentityCheckBiometricErrorDialog.showBiometricErrorDialog(mFragment.getActivity(),
|
||||
biometricAuthStatus, true /* twoFactorAuthentication */);
|
||||
}
|
||||
} else if (requestCode == REQUEST_IDENTITY_CHECK_FOR_DEV_PREF
|
||||
&& resultCode == Activity.RESULT_OK) {
|
||||
} else if (requestCode == REQUEST_IDENTITY_CHECK_FOR_DEV_PREF) {
|
||||
if (resultCode == Activity.RESULT_OK) {
|
||||
enableDevelopmentSettings();
|
||||
} else if (resultCode
|
||||
== ConfirmDeviceCredentialActivity.BIOMETRIC_LOCKOUT_ERROR_RESULT) {
|
||||
IdentityCheckBiometricErrorDialog.showBiometricErrorDialog(mFragment.getActivity(),
|
||||
Utils.BiometricStatus.LOCKOUT, true /* twoFactorAuthentication */);
|
||||
}
|
||||
}
|
||||
mProcessingLastDevHit = false;
|
||||
return true;
|
||||
|
@@ -55,7 +55,11 @@ import android.widget.LinearLayout;
|
||||
import android.widget.ScrollView;
|
||||
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.fragment.app.FragmentTransaction;
|
||||
|
||||
import com.android.settings.biometrics.IdentityCheckBiometricErrorDialog;
|
||||
import com.android.settings.password.ConfirmDeviceCredentialActivity;
|
||||
import com.android.settings.testutils.shadow.ShadowUserManager;
|
||||
import com.android.settings.testutils.shadow.ShadowUtils;
|
||||
import com.android.settingslib.development.DevelopmentSettingsEnabler;
|
||||
@@ -114,6 +118,10 @@ public class MainClearTest {
|
||||
|
||||
@Mock
|
||||
private Intent mMockIntent;
|
||||
@Mock
|
||||
private FragmentManager mMockFragmentManager;
|
||||
@Mock
|
||||
private FragmentTransaction mMockFragmentTransaction;
|
||||
|
||||
private MainClear mMainClear;
|
||||
private ShadowActivity mShadowActivity;
|
||||
@@ -391,6 +399,9 @@ public class MainClearTest {
|
||||
@Test
|
||||
@EnableFlags(Flags.FLAG_MANDATORY_BIOMETRICS)
|
||||
public void testOnActivityResultInternal_keyguardRequestNotTriggeringBiometricPrompt_lockoutError() {
|
||||
final ArgumentCaptor<IdentityCheckBiometricErrorDialog> argumentCaptor =
|
||||
ArgumentCaptor.forClass(IdentityCheckBiometricErrorDialog.class);
|
||||
|
||||
when(mContext.getResources()).thenReturn(mResources);
|
||||
when(mMockActivity.getSystemService(BiometricManager.class)).thenReturn(mBiometricManager);
|
||||
when(mResources.getString(anyInt())).thenReturn(TEST_ACCOUNT_NAME);
|
||||
@@ -400,12 +411,17 @@ public class MainClearTest {
|
||||
doReturn(true).when(mMainClear).isValidRequestCode(eq(MainClear.KEYGUARD_REQUEST));
|
||||
doNothing().when(mMainClear).startActivityForResult(any(), anyInt());
|
||||
doReturn(mMockActivity).when(mMainClear).getActivity();
|
||||
doReturn(mMockFragmentManager).when(mMockActivity).getSupportFragmentManager();
|
||||
doReturn(mMockFragmentTransaction).when(mMockFragmentManager).beginTransaction();
|
||||
doReturn(mContext).when(mMainClear).getContext();
|
||||
|
||||
mMainClear
|
||||
.onActivityResultInternal(MainClear.KEYGUARD_REQUEST, Activity.RESULT_OK, null);
|
||||
|
||||
verify(mMainClear).isValidRequestCode(eq(MainClear.KEYGUARD_REQUEST));
|
||||
verify(mMainClear.getActivity().getSupportFragmentManager().beginTransaction()).add(
|
||||
argumentCaptor.capture(), any());
|
||||
assertThat(argumentCaptor.getValue()).isInstanceOf(IdentityCheckBiometricErrorDialog.class);
|
||||
verify(mMainClear, never()).startActivityForResult(any(), eq(MainClear.BIOMETRICS_REQUEST));
|
||||
verify(mMainClear, never()).establishInitialState();
|
||||
verify(mMainClear, never()).getAccountConfirmationIntent();
|
||||
@@ -427,6 +443,29 @@ public class MainClearTest {
|
||||
verify(mMainClear).showFinalConfirmation();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnActivityResultInternal_biometricRequestTriggeringBiometricErrorDialog() {
|
||||
final ArgumentCaptor<IdentityCheckBiometricErrorDialog> argumentCaptor =
|
||||
ArgumentCaptor.forClass(IdentityCheckBiometricErrorDialog.class);
|
||||
|
||||
doReturn(true).when(mMainClear).isValidRequestCode(
|
||||
eq(MainClear.BIOMETRICS_REQUEST));
|
||||
doNothing().when(mMainClear).establishInitialState();
|
||||
doReturn(mMockActivity).when(mMainClear).getActivity();
|
||||
doReturn(mMockFragmentManager).when(mMockActivity).getSupportFragmentManager();
|
||||
doReturn(mMockFragmentTransaction).when(mMockFragmentManager).beginTransaction();
|
||||
doReturn(mContext).when(mMainClear).getContext();
|
||||
|
||||
mMainClear
|
||||
.onActivityResultInternal(MainClear.BIOMETRICS_REQUEST,
|
||||
ConfirmDeviceCredentialActivity.BIOMETRIC_LOCKOUT_ERROR_RESULT, null);
|
||||
|
||||
verify(mMainClear).isValidRequestCode(eq(MainClear.BIOMETRICS_REQUEST));
|
||||
verify(mMainClear.getActivity().getSupportFragmentManager().beginTransaction()).add(
|
||||
argumentCaptor.capture(), any());
|
||||
verify(mMainClear).establishInitialState();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnActivityResultInternal_biometricRequestTriggeringInitialState() {
|
||||
doReturn(true).when(mMainClear).isValidRequestCode(eq(MainClear.BIOMETRICS_REQUEST));
|
||||
|
@@ -42,6 +42,7 @@ import androidx.fragment.app.FragmentActivity;
|
||||
import com.android.internal.logging.nano.MetricsProto;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.biometrics.IdentityCheckBiometricErrorDialog;
|
||||
import com.android.settings.password.ConfirmDeviceCredentialActivity;
|
||||
import com.android.settings.testutils.shadow.ShadowAlertDialogCompat;
|
||||
import com.android.settings.testutils.shadow.ShadowUserManager;
|
||||
@@ -236,7 +237,8 @@ public class DevelopmentSettingsDashboardFragmentTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@Config(shadows = ShadowBiometricErrorDialog.class)
|
||||
@Config(shadows = ShadowIdentityCheckBiometricErrorDialog.class)
|
||||
@Ignore("b/354820314")
|
||||
@EnableFlags(Flags.FLAG_MANDATORY_BIOMETRICS)
|
||||
public void onActivityResult_requestBiometricPrompt_showErrorDialog() {
|
||||
when(mDashboard.getContext()).thenReturn(mContext);
|
||||
@@ -247,7 +249,7 @@ public class DevelopmentSettingsDashboardFragmentTest {
|
||||
ConfirmDeviceCredentialActivity.BIOMETRIC_LOCKOUT_ERROR_RESULT, null);
|
||||
|
||||
assertThat(mSwitchBar.isChecked()).isFalse();
|
||||
assertThat(ShadowBiometricErrorDialog.sShown).isTrue();
|
||||
assertThat(ShadowIdentityCheckBiometricErrorDialog.sShown).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -379,8 +381,8 @@ public class DevelopmentSettingsDashboardFragmentTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Implements(BiometricErrorDialog.class)
|
||||
public static class ShadowBiometricErrorDialog {
|
||||
@Implements(IdentityCheckBiometricErrorDialog.class)
|
||||
public static class ShadowIdentityCheckBiometricErrorDialog {
|
||||
static boolean sShown;
|
||||
@Implementation
|
||||
public static void showBiometricErrorDialog(FragmentActivity fragmentActivity,
|
||||
|
@@ -246,26 +246,6 @@ public class BuildNumberPreferenceControllerTest {
|
||||
eq(BuildNumberPreferenceController.REQUEST_IDENTITY_CHECK_FOR_DEV_PREF));
|
||||
}
|
||||
|
||||
@Test
|
||||
@UiThreadTest
|
||||
@RequiresFlagsEnabled(Flags.FLAG_MANDATORY_BIOMETRICS)
|
||||
public void onActivityResult_confirmPasswordRequestCompleted_lockoutError() {
|
||||
when(mUserManager.isAdminUser()).thenReturn(true);
|
||||
when(mBiometricManager.canAuthenticate(mContext.getUserId(),
|
||||
BiometricManager.Authenticators.MANDATORY_BIOMETRICS))
|
||||
.thenReturn(BiometricManager.BIOMETRIC_ERROR_LOCKOUT);
|
||||
|
||||
final boolean activityResultHandled = mController.onActivityResult(
|
||||
BuildNumberPreferenceController.REQUEST_CONFIRM_PASSWORD_FOR_DEV_PREF,
|
||||
Activity.RESULT_OK,
|
||||
null);
|
||||
|
||||
assertThat(activityResultHandled).isTrue();
|
||||
verify(mFragment, never()).startActivityForResult(any(),
|
||||
eq(BuildNumberPreferenceController.REQUEST_IDENTITY_CHECK_FOR_DEV_PREF));
|
||||
assertThat(DevelopmentSettingsEnabler.isDevelopmentSettingsEnabled(mContext)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onActivityResult_confirmBiometricAuthentication_enableDevPref() {
|
||||
when(mUserManager.isAdminUser()).thenReturn(true);
|
||||
|
Reference in New Issue
Block a user