Added sensor privacy message to biometric prompt
Bug: 201045056 Test: Verified that BiometricPrompt shows an error message if the user is using face authentication and camera privacy is enabled. Change-Id: Idc2140062c4aa87e0bcffb14e07336dc6cd7d955
This commit is contained in:
@@ -150,6 +150,12 @@ public interface BiometricConstants {
|
||||
*/
|
||||
int BIOMETRIC_ERROR_RE_ENROLL = 16;
|
||||
|
||||
/**
|
||||
* The privacy setting has been enabled and will block use of the sensor.
|
||||
* @hide
|
||||
*/
|
||||
int BIOMETRIC_ERROR_SENSOR_PRIVACY_ENABLED = 18;
|
||||
|
||||
/**
|
||||
* This constant is only used by SystemUI. It notifies SystemUI that authentication was paused
|
||||
* because the authentication attempt was unsuccessful.
|
||||
|
||||
@@ -1666,6 +1666,8 @@
|
||||
<string name="face_setup_notification_title">Set up Face Unlock</string>
|
||||
<!-- Contents of a notification that directs the user to set up face unlock by enrolling their face. [CHAR LIMIT=NONE] -->
|
||||
<string name="face_setup_notification_content">Unlock your phone by looking at it</string>
|
||||
<!-- Error message indicating that the camera privacy sensor has been turned on [CHAR LIMIT=NONE] -->
|
||||
<string name="face_sensor_privacy_enabled">To use Face Unlock, turn on <b>Camera access</b> in Settings > Privacy</string>
|
||||
<!-- Title of a notification that directs the user to enroll a fingerprint. [CHAR LIMIT=NONE] -->
|
||||
<string name="fingerprint_setup_notification_title">Set up more ways to unlock</string>
|
||||
<!-- Contents of a notification that directs the user to enroll a fingerprint. [CHAR LIMIT=NONE] -->
|
||||
|
||||
@@ -2570,6 +2570,7 @@
|
||||
<java-symbol type="string" name="face_recalibrate_notification_name" />
|
||||
<java-symbol type="string" name="face_recalibrate_notification_title" />
|
||||
<java-symbol type="string" name="face_recalibrate_notification_content" />
|
||||
<java-symbol type="string" name="face_sensor_privacy_enabled" />
|
||||
<java-symbol type="string" name="face_error_unable_to_process" />
|
||||
<java-symbol type="string" name="face_error_hw_not_available" />
|
||||
<java-symbol type="string" name="face_error_no_space" />
|
||||
|
||||
@@ -31,6 +31,7 @@ import android.content.IntentFilter;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.PointF;
|
||||
import android.hardware.SensorPrivacyManager;
|
||||
import android.hardware.biometrics.BiometricAuthenticator.Modality;
|
||||
import android.hardware.biometrics.BiometricConstants;
|
||||
import android.hardware.biometrics.BiometricManager.Authenticators;
|
||||
@@ -89,6 +90,7 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks,
|
||||
|
||||
private static final String TAG = "AuthController";
|
||||
private static final boolean DEBUG = true;
|
||||
private static final int SENSOR_PRIVACY_DELAY = 500;
|
||||
|
||||
private final Handler mHandler = new Handler(Looper.getMainLooper());
|
||||
private final CommandQueue mCommandQueue;
|
||||
@@ -122,6 +124,7 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks,
|
||||
@Nullable private List<FingerprintSensorPropertiesInternal> mSidefpsProps;
|
||||
|
||||
@NonNull private final SparseBooleanArray mUdfpsEnrolledForUser;
|
||||
private SensorPrivacyManager mSensorPrivacyManager;
|
||||
|
||||
private class BiometricTaskStackListener extends TaskStackListener {
|
||||
@Override
|
||||
@@ -492,6 +495,7 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks,
|
||||
filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
|
||||
|
||||
context.registerReceiver(mBroadcastReceiver, filter);
|
||||
mSensorPrivacyManager = context.getSystemService(SensorPrivacyManager.class);
|
||||
}
|
||||
|
||||
private void updateFingerprintLocation() {
|
||||
@@ -642,10 +646,16 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks,
|
||||
final boolean isLockout = (error == BiometricConstants.BIOMETRIC_ERROR_LOCKOUT)
|
||||
|| (error == BiometricConstants.BIOMETRIC_ERROR_LOCKOUT_PERMANENT);
|
||||
|
||||
boolean isCameraPrivacyEnabled = false;
|
||||
if (error == BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE
|
||||
&& mSensorPrivacyManager.isSensorPrivacyEnabled(SensorPrivacyManager.Sensors.CAMERA,
|
||||
mCurrentDialogArgs.argi1 /* userId */)) {
|
||||
isCameraPrivacyEnabled = true;
|
||||
}
|
||||
// TODO(b/141025588): Create separate methods for handling hard and soft errors.
|
||||
final boolean isSoftError = (error == BiometricConstants.BIOMETRIC_PAUSED_REJECTED
|
||||
|| error == BiometricConstants.BIOMETRIC_ERROR_TIMEOUT);
|
||||
|
||||
|| error == BiometricConstants.BIOMETRIC_ERROR_TIMEOUT
|
||||
|| isCameraPrivacyEnabled);
|
||||
if (mCurrentDialog != null) {
|
||||
if (mCurrentDialog.isAllowDeviceCredentials() && isLockout) {
|
||||
if (DEBUG) Log.d(TAG, "onBiometricError, lockout");
|
||||
@@ -655,12 +665,23 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks,
|
||||
? mContext.getString(R.string.biometric_not_recognized)
|
||||
: getErrorString(modality, error, vendorCode);
|
||||
if (DEBUG) Log.d(TAG, "onBiometricError, soft error: " + errorMessage);
|
||||
mCurrentDialog.onAuthenticationFailed(modality, errorMessage);
|
||||
// The camera privacy error can return before the prompt initializes its state,
|
||||
// causing the prompt to appear to endlessly authenticate. Add a small delay
|
||||
// to stop this.
|
||||
if (isCameraPrivacyEnabled) {
|
||||
mHandler.postDelayed(() -> {
|
||||
mCurrentDialog.onAuthenticationFailed(modality,
|
||||
mContext.getString(R.string.face_sensor_privacy_enabled));
|
||||
}, SENSOR_PRIVACY_DELAY);
|
||||
} else {
|
||||
mCurrentDialog.onAuthenticationFailed(modality, errorMessage);
|
||||
}
|
||||
} else {
|
||||
final String errorMessage = getErrorString(modality, error, vendorCode);
|
||||
if (DEBUG) Log.d(TAG, "onBiometricError, hard error: " + errorMessage);
|
||||
mCurrentDialog.onError(modality, errorMessage);
|
||||
}
|
||||
|
||||
} else {
|
||||
Log.w(TAG, "onBiometricError callback but dialog is gone");
|
||||
}
|
||||
|
||||
@@ -1036,7 +1036,8 @@ public class BiometricService extends SystemService {
|
||||
promptInfo.setAuthenticators(authenticators);
|
||||
|
||||
return PreAuthInfo.create(mTrustManager, mDevicePolicyManager, mSettingObserver, mSensors,
|
||||
userId, promptInfo, opPackageName, false /* checkDevicePolicyManager */);
|
||||
userId, promptInfo, opPackageName, false /* checkDevicePolicyManager */,
|
||||
getContext());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1375,7 +1376,8 @@ public class BiometricService extends SystemService {
|
||||
try {
|
||||
final PreAuthInfo preAuthInfo = PreAuthInfo.create(mTrustManager,
|
||||
mDevicePolicyManager, mSettingObserver, mSensors, userId, promptInfo,
|
||||
opPackageName, promptInfo.isDisallowBiometricsIfPolicyExists());
|
||||
opPackageName, promptInfo.isDisallowBiometricsIfPolicyExists(),
|
||||
getContext());
|
||||
|
||||
final Pair<Integer, Integer> preAuthStatus = preAuthInfo.getPreAuthenticateStatus();
|
||||
|
||||
@@ -1383,8 +1385,11 @@ public class BiometricService extends SystemService {
|
||||
+ "), status(" + preAuthStatus.second + "), preAuthInfo: " + preAuthInfo
|
||||
+ " requestId: " + requestId + " promptInfo.isIgnoreEnrollmentState: "
|
||||
+ promptInfo.isIgnoreEnrollmentState());
|
||||
|
||||
if (preAuthStatus.second == BiometricConstants.BIOMETRIC_SUCCESS) {
|
||||
// BIOMETRIC_ERROR_SENSOR_PRIVACY_ENABLED is added so that BiometricPrompt can
|
||||
// be shown for this case.
|
||||
if (preAuthStatus.second == BiometricConstants.BIOMETRIC_SUCCESS
|
||||
|| preAuthStatus.second
|
||||
== BiometricConstants.BIOMETRIC_ERROR_SENSOR_PRIVACY_ENABLED) {
|
||||
// If BIOMETRIC_WEAK or BIOMETRIC_STRONG are allowed, but not enrolled, but
|
||||
// CREDENTIAL is requested and available, set the bundle to only request
|
||||
// CREDENTIAL.
|
||||
|
||||
@@ -26,6 +26,8 @@ import android.annotation.IntDef;
|
||||
import android.annotation.NonNull;
|
||||
import android.app.admin.DevicePolicyManager;
|
||||
import android.app.trust.ITrustManager;
|
||||
import android.content.Context;
|
||||
import android.hardware.SensorPrivacyManager;
|
||||
import android.hardware.biometrics.BiometricAuthenticator;
|
||||
import android.hardware.biometrics.BiometricManager;
|
||||
import android.hardware.biometrics.PromptInfo;
|
||||
@@ -59,6 +61,7 @@ class PreAuthInfo {
|
||||
static final int CREDENTIAL_NOT_ENROLLED = 9;
|
||||
static final int BIOMETRIC_LOCKOUT_TIMED = 10;
|
||||
static final int BIOMETRIC_LOCKOUT_PERMANENT = 11;
|
||||
static final int BIOMETRIC_SENSOR_PRIVACY_ENABLED = 12;
|
||||
@IntDef({AUTHENTICATOR_OK,
|
||||
BIOMETRIC_NO_HARDWARE,
|
||||
BIOMETRIC_DISABLED_BY_DEVICE_POLICY,
|
||||
@@ -69,7 +72,8 @@ class PreAuthInfo {
|
||||
BIOMETRIC_NOT_ENABLED_FOR_APPS,
|
||||
CREDENTIAL_NOT_ENROLLED,
|
||||
BIOMETRIC_LOCKOUT_TIMED,
|
||||
BIOMETRIC_LOCKOUT_PERMANENT})
|
||||
BIOMETRIC_LOCKOUT_PERMANENT,
|
||||
BIOMETRIC_SENSOR_PRIVACY_ENABLED})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@interface AuthenticatorStatus {}
|
||||
|
||||
@@ -84,13 +88,15 @@ class PreAuthInfo {
|
||||
final boolean credentialAvailable;
|
||||
final boolean confirmationRequested;
|
||||
final boolean ignoreEnrollmentState;
|
||||
final int userId;
|
||||
final Context context;
|
||||
|
||||
static PreAuthInfo create(ITrustManager trustManager,
|
||||
DevicePolicyManager devicePolicyManager,
|
||||
BiometricService.SettingObserver settingObserver,
|
||||
List<BiometricSensor> sensors,
|
||||
int userId, PromptInfo promptInfo, String opPackageName,
|
||||
boolean checkDevicePolicyManager)
|
||||
boolean checkDevicePolicyManager, Context context)
|
||||
throws RemoteException {
|
||||
|
||||
final boolean confirmationRequested = promptInfo.isConfirmationRequested();
|
||||
@@ -116,14 +122,22 @@ class PreAuthInfo {
|
||||
devicePolicyManager, settingObserver, sensor, userId, opPackageName,
|
||||
checkDevicePolicyManager, requestedStrength,
|
||||
promptInfo.getAllowedSensorIds(),
|
||||
promptInfo.isIgnoreEnrollmentState());
|
||||
promptInfo.isIgnoreEnrollmentState(),
|
||||
context);
|
||||
|
||||
Slog.d(TAG, "Package: " + opPackageName
|
||||
+ " Sensor ID: " + sensor.id
|
||||
+ " Modality: " + sensor.modality
|
||||
+ " Status: " + status);
|
||||
|
||||
if (status == AUTHENTICATOR_OK) {
|
||||
// A sensor with privacy enabled will still be eligible to
|
||||
// authenticate with biometric prompt. This is so the framework can display
|
||||
// a sensor privacy error message to users after briefly showing the
|
||||
// Biometric Prompt.
|
||||
//
|
||||
// Note: if only a certain sensor is required and the privacy is enabled,
|
||||
// canAuthenticate() will return false.
|
||||
if (status == AUTHENTICATOR_OK || status == BIOMETRIC_SENSOR_PRIVACY_ENABLED) {
|
||||
eligibleSensors.add(sensor);
|
||||
} else {
|
||||
ineligibleSensors.add(new Pair<>(sensor, status));
|
||||
@@ -133,7 +147,7 @@ class PreAuthInfo {
|
||||
|
||||
return new PreAuthInfo(biometricRequested, requestedStrength, credentialRequested,
|
||||
eligibleSensors, ineligibleSensors, credentialAvailable, confirmationRequested,
|
||||
promptInfo.isIgnoreEnrollmentState());
|
||||
promptInfo.isIgnoreEnrollmentState(), userId, context);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -149,7 +163,7 @@ class PreAuthInfo {
|
||||
BiometricSensor sensor, int userId, String opPackageName,
|
||||
boolean checkDevicePolicyManager, int requestedStrength,
|
||||
@NonNull List<Integer> requestedSensorIds,
|
||||
boolean ignoreEnrollmentState) {
|
||||
boolean ignoreEnrollmentState, Context context) {
|
||||
|
||||
if (!requestedSensorIds.isEmpty() && !requestedSensorIds.contains(sensor.id)) {
|
||||
return BIOMETRIC_NO_HARDWARE;
|
||||
@@ -175,6 +189,16 @@ class PreAuthInfo {
|
||||
&& !ignoreEnrollmentState) {
|
||||
return BIOMETRIC_NOT_ENROLLED;
|
||||
}
|
||||
final SensorPrivacyManager sensorPrivacyManager = context
|
||||
.getSystemService(SensorPrivacyManager.class);
|
||||
|
||||
if (sensorPrivacyManager != null && sensor.modality == TYPE_FACE) {
|
||||
if (sensorPrivacyManager
|
||||
.isSensorPrivacyEnabled(SensorPrivacyManager.Sensors.CAMERA, userId)) {
|
||||
return BIOMETRIC_SENSOR_PRIVACY_ENABLED;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
final @LockoutTracker.LockoutMode int lockoutMode =
|
||||
sensor.impl.getLockoutModeForUser(userId);
|
||||
@@ -243,7 +267,8 @@ class PreAuthInfo {
|
||||
private PreAuthInfo(boolean biometricRequested, int biometricStrengthRequested,
|
||||
boolean credentialRequested, List<BiometricSensor> eligibleSensors,
|
||||
List<Pair<BiometricSensor, Integer>> ineligibleSensors, boolean credentialAvailable,
|
||||
boolean confirmationRequested, boolean ignoreEnrollmentState) {
|
||||
boolean confirmationRequested, boolean ignoreEnrollmentState, int userId,
|
||||
Context context) {
|
||||
mBiometricRequested = biometricRequested;
|
||||
mBiometricStrengthRequested = biometricStrengthRequested;
|
||||
this.credentialRequested = credentialRequested;
|
||||
@@ -253,6 +278,8 @@ class PreAuthInfo {
|
||||
this.credentialAvailable = credentialAvailable;
|
||||
this.confirmationRequested = confirmationRequested;
|
||||
this.ignoreEnrollmentState = ignoreEnrollmentState;
|
||||
this.userId = userId;
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
private Pair<BiometricSensor, Integer> calculateErrorByPriority() {
|
||||
@@ -280,15 +307,35 @@ class PreAuthInfo {
|
||||
private Pair<Integer, Integer> getInternalStatus() {
|
||||
@AuthenticatorStatus final int status;
|
||||
@BiometricAuthenticator.Modality int modality = TYPE_NONE;
|
||||
|
||||
final SensorPrivacyManager sensorPrivacyManager = context
|
||||
.getSystemService(SensorPrivacyManager.class);
|
||||
|
||||
boolean cameraPrivacyEnabled = false;
|
||||
if (sensorPrivacyManager != null) {
|
||||
cameraPrivacyEnabled = sensorPrivacyManager
|
||||
.isSensorPrivacyEnabled(SensorPrivacyManager.Sensors.CAMERA, userId);
|
||||
}
|
||||
|
||||
if (mBiometricRequested && credentialRequested) {
|
||||
if (credentialAvailable || !eligibleSensors.isEmpty()) {
|
||||
status = AUTHENTICATOR_OK;
|
||||
if (credentialAvailable) {
|
||||
modality |= TYPE_CREDENTIAL;
|
||||
}
|
||||
for (BiometricSensor sensor : eligibleSensors) {
|
||||
modality |= sensor.modality;
|
||||
}
|
||||
|
||||
if (credentialAvailable) {
|
||||
modality |= TYPE_CREDENTIAL;
|
||||
status = AUTHENTICATOR_OK;
|
||||
} else if (modality == TYPE_FACE && cameraPrivacyEnabled) {
|
||||
// If the only modality requested is face, credential is unavailable,
|
||||
// and the face sensor privacy is enabled then return
|
||||
// BIOMETRIC_SENSOR_PRIVACY_ENABLED.
|
||||
//
|
||||
// Note: This sensor will still be eligible for calls to authenticate.
|
||||
status = BIOMETRIC_SENSOR_PRIVACY_ENABLED;
|
||||
} else {
|
||||
status = AUTHENTICATOR_OK;
|
||||
}
|
||||
} else {
|
||||
// Pick the first sensor error if it exists
|
||||
if (!ineligibleSensors.isEmpty()) {
|
||||
@@ -302,10 +349,18 @@ class PreAuthInfo {
|
||||
}
|
||||
} else if (mBiometricRequested) {
|
||||
if (!eligibleSensors.isEmpty()) {
|
||||
status = AUTHENTICATOR_OK;
|
||||
for (BiometricSensor sensor : eligibleSensors) {
|
||||
modality |= sensor.modality;
|
||||
}
|
||||
for (BiometricSensor sensor : eligibleSensors) {
|
||||
modality |= sensor.modality;
|
||||
}
|
||||
if (modality == TYPE_FACE && cameraPrivacyEnabled) {
|
||||
// If the only modality requested is face and the privacy is enabled
|
||||
// then return BIOMETRIC_SENSOR_PRIVACY_ENABLED.
|
||||
//
|
||||
// Note: This sensor will still be eligible for calls to authenticate.
|
||||
status = BIOMETRIC_SENSOR_PRIVACY_ENABLED;
|
||||
} else {
|
||||
status = AUTHENTICATOR_OK;
|
||||
}
|
||||
} else {
|
||||
// Pick the first sensor error if it exists
|
||||
if (!ineligibleSensors.isEmpty()) {
|
||||
@@ -326,9 +381,9 @@ class PreAuthInfo {
|
||||
Slog.e(TAG, "No authenticators requested");
|
||||
status = BIOMETRIC_NO_HARDWARE;
|
||||
}
|
||||
|
||||
Slog.d(TAG, "getCanAuthenticateInternal Modality: " + modality
|
||||
+ " AuthenticatorStatus: " + status);
|
||||
|
||||
return new Pair<>(modality, status);
|
||||
}
|
||||
|
||||
@@ -362,6 +417,7 @@ class PreAuthInfo {
|
||||
case CREDENTIAL_NOT_ENROLLED:
|
||||
case BIOMETRIC_LOCKOUT_TIMED:
|
||||
case BIOMETRIC_LOCKOUT_PERMANENT:
|
||||
case BIOMETRIC_SENSOR_PRIVACY_ENABLED:
|
||||
break;
|
||||
|
||||
case BIOMETRIC_DISABLED_BY_DEVICE_POLICY:
|
||||
|
||||
@@ -33,6 +33,7 @@ import static com.android.server.biometrics.PreAuthInfo.BIOMETRIC_LOCKOUT_TIMED;
|
||||
import static com.android.server.biometrics.PreAuthInfo.BIOMETRIC_NOT_ENABLED_FOR_APPS;
|
||||
import static com.android.server.biometrics.PreAuthInfo.BIOMETRIC_NOT_ENROLLED;
|
||||
import static com.android.server.biometrics.PreAuthInfo.BIOMETRIC_NO_HARDWARE;
|
||||
import static com.android.server.biometrics.PreAuthInfo.BIOMETRIC_SENSOR_PRIVACY_ENABLED;
|
||||
import static com.android.server.biometrics.PreAuthInfo.CREDENTIAL_NOT_ENROLLED;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
@@ -278,6 +279,9 @@ public class Utils {
|
||||
case BiometricConstants.BIOMETRIC_ERROR_LOCKOUT_PERMANENT:
|
||||
biometricManagerCode = BiometricManager.BIOMETRIC_SUCCESS;
|
||||
break;
|
||||
case BiometricConstants.BIOMETRIC_ERROR_SENSOR_PRIVACY_ENABLED:
|
||||
biometricManagerCode = BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE;
|
||||
break;
|
||||
default:
|
||||
Slog.e(BiometricService.TAG, "Unhandled result code: " + biometricConstantsCode);
|
||||
biometricManagerCode = BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE;
|
||||
@@ -337,7 +341,8 @@ public class Utils {
|
||||
|
||||
case BIOMETRIC_LOCKOUT_PERMANENT:
|
||||
return BiometricConstants.BIOMETRIC_ERROR_LOCKOUT_PERMANENT;
|
||||
|
||||
case BIOMETRIC_SENSOR_PRIVACY_ENABLED:
|
||||
return BiometricConstants.BIOMETRIC_ERROR_SENSOR_PRIVACY_ENABLED;
|
||||
case BIOMETRIC_DISABLED_BY_DEVICE_POLICY:
|
||||
case BIOMETRIC_HARDWARE_NOT_DETECTED:
|
||||
case BIOMETRIC_NOT_ENABLED_FOR_APPS:
|
||||
|
||||
@@ -302,6 +302,65 @@ public class AuthSessionTest {
|
||||
testInvokesCancel(session -> session.onDialogDismissed(DISMISSED_REASON_NEGATIVE, null));
|
||||
}
|
||||
|
||||
// TODO (b/208484275) : Enable these tests
|
||||
// @Test
|
||||
// public void testPreAuth_canAuthAndPrivacyDisabled() throws Exception {
|
||||
// SensorPrivacyManager manager = ExtendedMockito.mock(SensorPrivacyManager.class);
|
||||
// when(manager
|
||||
// .isSensorPrivacyEnabled(SensorPrivacyManager.Sensors.CAMERA, anyInt()))
|
||||
// .thenReturn(false);
|
||||
// when(mContext.getSystemService(SensorPrivacyManager.class))
|
||||
// .thenReturn(manager);
|
||||
// setupFace(1 /* id */, false /* confirmationAlwaysRequired */,
|
||||
// mock(IBiometricAuthenticator.class));
|
||||
// final PromptInfo promptInfo = createPromptInfo(Authenticators.BIOMETRIC_STRONG);
|
||||
// final PreAuthInfo preAuthInfo = createPreAuthInfo(mSensors, 0, promptInfo, false);
|
||||
// assertEquals(BiometricManager.BIOMETRIC_SUCCESS, preAuthInfo.getCanAuthenticateResult());
|
||||
// for (BiometricSensor sensor : preAuthInfo.eligibleSensors) {
|
||||
// assertEquals(BiometricSensor.STATE_UNKNOWN, sensor.getSensorState());
|
||||
// }
|
||||
// }
|
||||
|
||||
// @Test
|
||||
// public void testPreAuth_cannotAuthAndPrivacyEnabled() throws Exception {
|
||||
// SensorPrivacyManager manager = ExtendedMockito.mock(SensorPrivacyManager.class);
|
||||
// when(manager
|
||||
// .isSensorPrivacyEnabled(SensorPrivacyManager.Sensors.CAMERA, anyInt()))
|
||||
// .thenReturn(true);
|
||||
// when(mContext.getSystemService(SensorPrivacyManager.class))
|
||||
// .thenReturn(manager);
|
||||
// setupFace(1 /* id */, false /* confirmationAlwaysRequired */,
|
||||
// mock(IBiometricAuthenticator.class));
|
||||
// final PromptInfo promptInfo = createPromptInfo(Authenticators.BIOMETRIC_STRONG);
|
||||
// final PreAuthInfo preAuthInfo = createPreAuthInfo(mSensors, 0, promptInfo, false);
|
||||
// assertEquals(BiometricManager.BIOMETRIC_ERROR_SENSOR_PRIVACY_ENABLED,
|
||||
// preAuthInfo.getCanAuthenticateResult());
|
||||
// // Even though canAuth returns privacy enabled, we should still be able to authenticate.
|
||||
// for (BiometricSensor sensor : preAuthInfo.eligibleSensors) {
|
||||
// assertEquals(BiometricSensor.STATE_UNKNOWN, sensor.getSensorState());
|
||||
// }
|
||||
// }
|
||||
|
||||
// @Test
|
||||
// public void testPreAuth_canAuthAndPrivacyEnabledCredentialEnabled() throws Exception {
|
||||
// SensorPrivacyManager manager = ExtendedMockito.mock(SensorPrivacyManager.class);
|
||||
// when(manager
|
||||
// .isSensorPrivacyEnabled(SensorPrivacyManager.Sensors.CAMERA, anyInt()))
|
||||
// .thenReturn(true);
|
||||
// when(mContext.getSystemService(SensorPrivacyManager.class))
|
||||
// .thenReturn(manager);
|
||||
// setupFace(1 /* id */, false /* confirmationAlwaysRequired */,
|
||||
// mock(IBiometricAuthenticator.class));
|
||||
// final PromptInfo promptInfo =
|
||||
// createPromptInfo(Authenticators.BIOMETRIC_STRONG
|
||||
// | Authenticators. DEVICE_CREDENTIAL);
|
||||
// final PreAuthInfo preAuthInfo = createPreAuthInfo(mSensors, 0, promptInfo, false);
|
||||
// assertEquals(BiometricManager.BIOMETRIC_SUCCESS, preAuthInfo.getCanAuthenticateResult());
|
||||
// for (BiometricSensor sensor : preAuthInfo.eligibleSensors) {
|
||||
// assertEquals(BiometricSensor.STATE_UNKNOWN, sensor.getSensorState());
|
||||
// }
|
||||
// }
|
||||
|
||||
private void testInvokesCancel(Consumer<AuthSession> sessionConsumer) throws RemoteException {
|
||||
final IBiometricAuthenticator faceAuthenticator = mock(IBiometricAuthenticator.class);
|
||||
|
||||
@@ -331,7 +390,8 @@ public class AuthSessionTest {
|
||||
userId,
|
||||
promptInfo,
|
||||
TEST_PACKAGE,
|
||||
checkDevicePolicyManager);
|
||||
checkDevicePolicyManager,
|
||||
mContext);
|
||||
}
|
||||
|
||||
private AuthSession createAuthSession(List<BiometricSensor> sensors,
|
||||
|
||||
Reference in New Issue
Block a user