Merge changes from topic "more-cancel-sc-qpr1-dev" into sc-qpr1-dev am: 16a7d2e7bd
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/15727904 Change-Id: Id9964610269328c04806b44d10b9bb555b1f63e0
This commit is contained in:
@@ -438,9 +438,16 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan
|
||||
}
|
||||
|
||||
private class OnAuthenticationCancelListener implements CancellationSignal.OnCancelListener {
|
||||
private final long mAuthRequestId;
|
||||
|
||||
OnAuthenticationCancelListener(long id) {
|
||||
mAuthRequestId = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCancel() {
|
||||
cancelAuthentication();
|
||||
Log.d(TAG, "Cancel BP authentication requested for: " + mAuthRequestId);
|
||||
cancelAuthentication(mAuthRequestId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -853,10 +860,12 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan
|
||||
* @param userId The user to authenticate
|
||||
* @param operationId The keystore operation associated with authentication
|
||||
*
|
||||
* @return A requestId that can be used to cancel this operation.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@RequiresPermission(USE_BIOMETRIC_INTERNAL)
|
||||
public void authenticateUserForOperation(
|
||||
public long authenticateUserForOperation(
|
||||
@NonNull CancellationSignal cancel,
|
||||
@NonNull @CallbackExecutor Executor executor,
|
||||
@NonNull AuthenticationCallback callback,
|
||||
@@ -871,7 +880,8 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan
|
||||
if (callback == null) {
|
||||
throw new IllegalArgumentException("Must supply a callback");
|
||||
}
|
||||
authenticateInternal(operationId, cancel, executor, callback, userId);
|
||||
|
||||
return authenticateInternal(operationId, cancel, executor, callback, userId);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1002,10 +1012,10 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan
|
||||
authenticateInternal(null /* crypto */, cancel, executor, callback, mContext.getUserId());
|
||||
}
|
||||
|
||||
private void cancelAuthentication() {
|
||||
private void cancelAuthentication(long requestId) {
|
||||
if (mService != null) {
|
||||
try {
|
||||
mService.cancelAuthentication(mToken, mContext.getOpPackageName());
|
||||
mService.cancelAuthentication(mToken, mContext.getOpPackageName(), requestId);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Unable to cancel authentication", e);
|
||||
}
|
||||
@@ -1024,7 +1034,7 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan
|
||||
authenticateInternal(operationId, cancel, executor, callback, userId);
|
||||
}
|
||||
|
||||
private void authenticateInternal(
|
||||
private long authenticateInternal(
|
||||
long operationId,
|
||||
@NonNull CancellationSignal cancel,
|
||||
@NonNull @CallbackExecutor Executor executor,
|
||||
@@ -1040,9 +1050,7 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan
|
||||
try {
|
||||
if (cancel.isCanceled()) {
|
||||
Log.w(TAG, "Authentication already canceled");
|
||||
return;
|
||||
} else {
|
||||
cancel.setOnCancelListener(new OnAuthenticationCancelListener());
|
||||
return -1;
|
||||
}
|
||||
|
||||
mExecutor = executor;
|
||||
@@ -1065,14 +1073,16 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan
|
||||
promptInfo = mPromptInfo;
|
||||
}
|
||||
|
||||
mService.authenticate(mToken, operationId, userId, mBiometricServiceReceiver,
|
||||
mContext.getOpPackageName(), promptInfo);
|
||||
|
||||
final long authId = mService.authenticate(mToken, operationId, userId,
|
||||
mBiometricServiceReceiver, mContext.getOpPackageName(), promptInfo);
|
||||
cancel.setOnCancelListener(new OnAuthenticationCancelListener(authId));
|
||||
return authId;
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Remote exception while authenticating", e);
|
||||
mExecutor.execute(() -> callback.onAuthenticationError(
|
||||
BiometricPrompt.BIOMETRIC_ERROR_HW_UNAVAILABLE,
|
||||
mContext.getString(R.string.biometric_error_hw_unavailable)));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -41,13 +41,14 @@ interface IAuthService {
|
||||
// Retrieve the package where BIometricOrompt's UI is implemented
|
||||
String getUiPackage();
|
||||
|
||||
// Requests authentication. The service choose the appropriate biometric to use, and show
|
||||
// the corresponding BiometricDialog.
|
||||
void authenticate(IBinder token, long sessionId, int userId,
|
||||
// Requests authentication. The service chooses the appropriate biometric to use, and shows
|
||||
// the corresponding BiometricDialog. A requestId is returned that can be used to cancel
|
||||
// this operation.
|
||||
long authenticate(IBinder token, long sessionId, int userId,
|
||||
IBiometricServiceReceiver receiver, String opPackageName, in PromptInfo promptInfo);
|
||||
|
||||
// Cancel authentication for the given sessionId
|
||||
void cancelAuthentication(IBinder token, String opPackageName);
|
||||
// Cancel authentication for the given requestId.
|
||||
void cancelAuthentication(IBinder token, String opPackageName, long requestId);
|
||||
|
||||
// TODO(b/141025588): Make userId the first arg to be consistent with hasEnrolledBiometrics.
|
||||
// Checks if biometrics can be used.
|
||||
|
||||
@@ -48,13 +48,13 @@ interface IBiometricAuthenticator {
|
||||
// startPreparedClient().
|
||||
void prepareForAuthentication(boolean requireConfirmation, IBinder token, long operationId,
|
||||
int userId, IBiometricSensorReceiver sensorReceiver, String opPackageName,
|
||||
int cookie, boolean allowBackgroundAuthentication);
|
||||
long requestId, int cookie, boolean allowBackgroundAuthentication);
|
||||
|
||||
// Starts authentication with the previously prepared client.
|
||||
void startPreparedClient(int cookie);
|
||||
|
||||
// Cancels authentication.
|
||||
void cancelAuthenticationFromService(IBinder token, String opPackageName);
|
||||
// Cancels authentication for the given requestId.
|
||||
void cancelAuthenticationFromService(IBinder token, String opPackageName, long requestId);
|
||||
|
||||
// Determine if HAL is loaded and ready
|
||||
boolean isHardwareDetected(String opPackageName);
|
||||
|
||||
@@ -36,13 +36,14 @@ interface IBiometricService {
|
||||
// Retrieve static sensor properties for all biometric sensors
|
||||
List<SensorPropertiesInternal> getSensorProperties(String opPackageName);
|
||||
|
||||
// Requests authentication. The service choose the appropriate biometric to use, and show
|
||||
// the corresponding BiometricDialog.
|
||||
void authenticate(IBinder token, long operationId, int userId,
|
||||
// Requests authentication. The service chooses the appropriate biometric to use, and shows
|
||||
// the corresponding BiometricDialog. A requestId is returned that can be used to cancel
|
||||
// this operation.
|
||||
long authenticate(IBinder token, long operationId, int userId,
|
||||
IBiometricServiceReceiver receiver, String opPackageName, in PromptInfo promptInfo);
|
||||
|
||||
// Cancel authentication for the given session.
|
||||
void cancelAuthentication(IBinder token, String opPackageName);
|
||||
// Cancel authentication for the given requestId.
|
||||
void cancelAuthentication(IBinder token, String opPackageName, long requestId);
|
||||
|
||||
// Checks if biometrics can be used.
|
||||
int canAuthenticate(String opPackageName, int userId, int callingUserId, int authenticators);
|
||||
|
||||
@@ -58,7 +58,7 @@ import java.util.List;
|
||||
public class FaceManager implements BiometricAuthenticator, BiometricFaceConstants {
|
||||
|
||||
private static final String TAG = "FaceManager";
|
||||
private static final boolean DEBUG = true;
|
||||
|
||||
private static final int MSG_ENROLL_RESULT = 100;
|
||||
private static final int MSG_ACQUIRED = 101;
|
||||
private static final int MSG_AUTHENTICATION_SUCCEEDED = 102;
|
||||
@@ -207,13 +207,9 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan
|
||||
throw new IllegalArgumentException("Must supply an authentication callback");
|
||||
}
|
||||
|
||||
if (cancel != null) {
|
||||
if (cancel.isCanceled()) {
|
||||
Slog.w(TAG, "authentication already canceled");
|
||||
return;
|
||||
} else {
|
||||
cancel.setOnCancelListener(new OnAuthenticationCancelListener(crypto));
|
||||
}
|
||||
if (cancel != null && cancel.isCanceled()) {
|
||||
Slog.w(TAG, "authentication already canceled");
|
||||
return;
|
||||
}
|
||||
|
||||
if (mService != null) {
|
||||
@@ -223,17 +219,18 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan
|
||||
mCryptoObject = crypto;
|
||||
final long operationId = crypto != null ? crypto.getOpId() : 0;
|
||||
Trace.beginSection("FaceManager#authenticate");
|
||||
mService.authenticate(mToken, operationId, userId, mServiceReceiver,
|
||||
mContext.getOpPackageName(), isKeyguardBypassEnabled);
|
||||
final long authId = mService.authenticate(mToken, operationId, userId,
|
||||
mServiceReceiver, mContext.getOpPackageName(), isKeyguardBypassEnabled);
|
||||
if (cancel != null) {
|
||||
cancel.setOnCancelListener(new OnAuthenticationCancelListener(authId));
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
Slog.w(TAG, "Remote exception while authenticating: ", e);
|
||||
if (callback != null) {
|
||||
// Though this may not be a hardware issue, it will cause apps to give up or
|
||||
// try again later.
|
||||
callback.onAuthenticationError(FACE_ERROR_HW_UNAVAILABLE,
|
||||
getErrorString(mContext, FACE_ERROR_HW_UNAVAILABLE,
|
||||
0 /* vendorCode */));
|
||||
}
|
||||
// Though this may not be a hardware issue, it will cause apps to give up or
|
||||
// try again later.
|
||||
callback.onAuthenticationError(FACE_ERROR_HW_UNAVAILABLE,
|
||||
getErrorString(mContext, FACE_ERROR_HW_UNAVAILABLE,
|
||||
0 /* vendorCode */));
|
||||
} finally {
|
||||
Trace.endSection();
|
||||
}
|
||||
@@ -255,14 +252,14 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan
|
||||
if (cancel.isCanceled()) {
|
||||
Slog.w(TAG, "Detection already cancelled");
|
||||
return;
|
||||
} else {
|
||||
cancel.setOnCancelListener(new OnFaceDetectionCancelListener());
|
||||
}
|
||||
|
||||
mFaceDetectionCallback = callback;
|
||||
|
||||
try {
|
||||
mService.detectFace(mToken, userId, mServiceReceiver, mContext.getOpPackageName());
|
||||
final long authId = mService.detectFace(
|
||||
mToken, userId, mServiceReceiver, mContext.getOpPackageName());
|
||||
cancel.setOnCancelListener(new OnFaceDetectionCancelListener(authId));
|
||||
} catch (RemoteException e) {
|
||||
Slog.w(TAG, "Remote exception when requesting finger detect", e);
|
||||
}
|
||||
@@ -726,23 +723,23 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan
|
||||
}
|
||||
}
|
||||
|
||||
private void cancelAuthentication(CryptoObject cryptoObject) {
|
||||
private void cancelAuthentication(long requestId) {
|
||||
if (mService != null) {
|
||||
try {
|
||||
mService.cancelAuthentication(mToken, mContext.getOpPackageName());
|
||||
mService.cancelAuthentication(mToken, mContext.getOpPackageName(), requestId);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void cancelFaceDetect() {
|
||||
private void cancelFaceDetect(long requestId) {
|
||||
if (mService == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
mService.cancelFaceDetect(mToken, mContext.getOpPackageName());
|
||||
mService.cancelFaceDetect(mToken, mContext.getOpPackageName(), requestId);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
@@ -1110,22 +1107,30 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan
|
||||
}
|
||||
|
||||
private class OnAuthenticationCancelListener implements OnCancelListener {
|
||||
private final CryptoObject mCrypto;
|
||||
private final long mAuthRequestId;
|
||||
|
||||
OnAuthenticationCancelListener(CryptoObject crypto) {
|
||||
mCrypto = crypto;
|
||||
OnAuthenticationCancelListener(long id) {
|
||||
mAuthRequestId = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCancel() {
|
||||
cancelAuthentication(mCrypto);
|
||||
Slog.d(TAG, "Cancel face authentication requested for: " + mAuthRequestId);
|
||||
cancelAuthentication(mAuthRequestId);
|
||||
}
|
||||
}
|
||||
|
||||
private class OnFaceDetectionCancelListener implements OnCancelListener {
|
||||
private final long mAuthRequestId;
|
||||
|
||||
OnFaceDetectionCancelListener(long id) {
|
||||
mAuthRequestId = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCancel() {
|
||||
cancelFaceDetect();
|
||||
Slog.d(TAG, "Cancel face detect requested for: " + mAuthRequestId);
|
||||
cancelFaceDetect(mAuthRequestId);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -44,34 +44,36 @@ interface IFaceService {
|
||||
// Retrieve static sensor properties for the specified sensor
|
||||
FaceSensorPropertiesInternal getSensorProperties(int sensorId, String opPackageName);
|
||||
|
||||
// Authenticate the given sessionId with a face
|
||||
void authenticate(IBinder token, long operationId, int userId, IFaceServiceReceiver receiver,
|
||||
// Authenticate with a face. A requestId is returned that can be used to cancel this operation.
|
||||
long authenticate(IBinder token, long operationId, int userId, IFaceServiceReceiver receiver,
|
||||
String opPackageName, boolean isKeyguardBypassEnabled);
|
||||
|
||||
// Uses the face hardware to detect for the presence of a face, without giving details
|
||||
// about accept/reject/lockout.
|
||||
void detectFace(IBinder token, int userId, IFaceServiceReceiver receiver, String opPackageName);
|
||||
// about accept/reject/lockout. A requestId is returned that can be used to cancel this
|
||||
// operation.
|
||||
long detectFace(IBinder token, int userId, IFaceServiceReceiver receiver, String opPackageName);
|
||||
|
||||
// This method prepares the service to start authenticating, but doesn't start authentication.
|
||||
// This is protected by the MANAGE_BIOMETRIC signatuer permission. This method should only be
|
||||
// called from BiometricService. The additional uid, pid, userId arguments should be determined
|
||||
// by BiometricService. To start authentication after the clients are ready, use
|
||||
// startPreparedClient().
|
||||
void prepareForAuthentication(int sensorId, boolean requireConfirmation, IBinder token, long operationId,
|
||||
int userId, IBiometricSensorReceiver sensorReceiver, String opPackageName,
|
||||
int cookie, boolean allowBackgroundAuthentication);
|
||||
void prepareForAuthentication(int sensorId, boolean requireConfirmation, IBinder token,
|
||||
long operationId, int userId, IBiometricSensorReceiver sensorReceiver,
|
||||
String opPackageName, long requestId, int cookie,
|
||||
boolean allowBackgroundAuthentication);
|
||||
|
||||
// Starts authentication with the previously prepared client.
|
||||
void startPreparedClient(int sensorId, int cookie);
|
||||
|
||||
// Cancel authentication for the given sessionId
|
||||
void cancelAuthentication(IBinder token, String opPackageName);
|
||||
// Cancel authentication for the given requestId.
|
||||
void cancelAuthentication(IBinder token, String opPackageName, long requestId);
|
||||
|
||||
// Cancel face detection
|
||||
void cancelFaceDetect(IBinder token, String opPackageName);
|
||||
// Cancel face detection for the given requestId.
|
||||
void cancelFaceDetect(IBinder token, String opPackageName, long requestId);
|
||||
|
||||
// Same as above, with extra arguments.
|
||||
void cancelAuthenticationFromService(int sensorId, IBinder token, String opPackageName);
|
||||
void cancelAuthenticationFromService(int sensorId, IBinder token, String opPackageName, long requestId);
|
||||
|
||||
// Start face enrollment
|
||||
void enroll(int userId, IBinder token, in byte [] hardwareAuthToken, IFaceServiceReceiver receiver,
|
||||
|
||||
@@ -189,22 +189,30 @@ public class FingerprintManager implements BiometricAuthenticator, BiometricFing
|
||||
}
|
||||
|
||||
private class OnAuthenticationCancelListener implements OnCancelListener {
|
||||
private android.hardware.biometrics.CryptoObject mCrypto;
|
||||
private final long mAuthRequestId;
|
||||
|
||||
public OnAuthenticationCancelListener(android.hardware.biometrics.CryptoObject crypto) {
|
||||
mCrypto = crypto;
|
||||
OnAuthenticationCancelListener(long id) {
|
||||
mAuthRequestId = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCancel() {
|
||||
cancelAuthentication(mCrypto);
|
||||
Slog.d(TAG, "Cancel fingerprint authentication requested for: " + mAuthRequestId);
|
||||
cancelAuthentication(mAuthRequestId);
|
||||
}
|
||||
}
|
||||
|
||||
private class OnFingerprintDetectionCancelListener implements OnCancelListener {
|
||||
private final long mAuthRequestId;
|
||||
|
||||
OnFingerprintDetectionCancelListener(long id) {
|
||||
mAuthRequestId = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCancel() {
|
||||
cancelFingerprintDetect();
|
||||
Slog.d(TAG, "Cancel fingerprint detect requested for: " + mAuthRequestId);
|
||||
cancelFingerprintDetect(mAuthRequestId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -552,13 +560,9 @@ public class FingerprintManager implements BiometricAuthenticator, BiometricFing
|
||||
throw new IllegalArgumentException("Must supply an authentication callback");
|
||||
}
|
||||
|
||||
if (cancel != null) {
|
||||
if (cancel.isCanceled()) {
|
||||
Slog.w(TAG, "authentication already canceled");
|
||||
return;
|
||||
} else {
|
||||
cancel.setOnCancelListener(new OnAuthenticationCancelListener(crypto));
|
||||
}
|
||||
if (cancel != null && cancel.isCanceled()) {
|
||||
Slog.w(TAG, "authentication already canceled");
|
||||
return;
|
||||
}
|
||||
|
||||
if (mService != null) {
|
||||
@@ -567,8 +571,11 @@ public class FingerprintManager implements BiometricAuthenticator, BiometricFing
|
||||
mAuthenticationCallback = callback;
|
||||
mCryptoObject = crypto;
|
||||
final long operationId = crypto != null ? crypto.getOpId() : 0;
|
||||
mService.authenticate(mToken, operationId, sensorId, userId, mServiceReceiver,
|
||||
mContext.getOpPackageName());
|
||||
final long authId = mService.authenticate(mToken, operationId, sensorId, userId,
|
||||
mServiceReceiver, mContext.getOpPackageName());
|
||||
if (cancel != null) {
|
||||
cancel.setOnCancelListener(new OnAuthenticationCancelListener(authId));
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
Slog.w(TAG, "Remote exception while authenticating: ", e);
|
||||
// Though this may not be a hardware issue, it will cause apps to give up or try
|
||||
@@ -595,15 +602,14 @@ public class FingerprintManager implements BiometricAuthenticator, BiometricFing
|
||||
if (cancel.isCanceled()) {
|
||||
Slog.w(TAG, "Detection already cancelled");
|
||||
return;
|
||||
} else {
|
||||
cancel.setOnCancelListener(new OnFingerprintDetectionCancelListener());
|
||||
}
|
||||
|
||||
mFingerprintDetectionCallback = callback;
|
||||
|
||||
try {
|
||||
mService.detectFingerprint(mToken, userId, mServiceReceiver,
|
||||
final long authId = mService.detectFingerprint(mToken, userId, mServiceReceiver,
|
||||
mContext.getOpPackageName());
|
||||
cancel.setOnCancelListener(new OnFingerprintDetectionCancelListener(authId));
|
||||
} catch (RemoteException e) {
|
||||
Slog.w(TAG, "Remote exception when requesting finger detect", e);
|
||||
}
|
||||
@@ -1320,21 +1326,21 @@ public class FingerprintManager implements BiometricAuthenticator, BiometricFing
|
||||
}
|
||||
}
|
||||
|
||||
private void cancelAuthentication(android.hardware.biometrics.CryptoObject cryptoObject) {
|
||||
private void cancelAuthentication(long requestId) {
|
||||
if (mService != null) try {
|
||||
mService.cancelAuthentication(mToken, mContext.getOpPackageName());
|
||||
mService.cancelAuthentication(mToken, mContext.getOpPackageName(), requestId);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
private void cancelFingerprintDetect() {
|
||||
private void cancelFingerprintDetect(long requestId) {
|
||||
if (mService == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
mService.cancelFingerprintDetect(mToken, mContext.getOpPackageName());
|
||||
mService.cancelFingerprintDetect(mToken, mContext.getOpPackageName(), requestId);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
|
||||
@@ -48,15 +48,16 @@ interface IFingerprintService {
|
||||
// Retrieve static sensor properties for the specified sensor
|
||||
FingerprintSensorPropertiesInternal getSensorProperties(int sensorId, String opPackageName);
|
||||
|
||||
// Authenticate the given sessionId with a fingerprint. This is protected by
|
||||
// USE_FINGERPRINT/USE_BIOMETRIC permission. This is effectively deprecated, since it only comes
|
||||
// through FingerprintManager now.
|
||||
void authenticate(IBinder token, long operationId, int sensorId, int userId,
|
||||
// Authenticate with a fingerprint. This is protected by USE_FINGERPRINT/USE_BIOMETRIC
|
||||
// permission. This is effectively deprecated, since it only comes through FingerprintManager
|
||||
// now. A requestId is returned that can be used to cancel this operation.
|
||||
long authenticate(IBinder token, long operationId, int sensorId, int userId,
|
||||
IFingerprintServiceReceiver receiver, String opPackageName);
|
||||
|
||||
// Uses the fingerprint hardware to detect for the presence of a finger, without giving details
|
||||
// about accept/reject/lockout.
|
||||
void detectFingerprint(IBinder token, int userId, IFingerprintServiceReceiver receiver,
|
||||
// about accept/reject/lockout. A requestId is returned that can be used to cancel this
|
||||
// operation.
|
||||
long detectFingerprint(IBinder token, int userId, IFingerprintServiceReceiver receiver,
|
||||
String opPackageName);
|
||||
|
||||
// This method prepares the service to start authenticating, but doesn't start authentication.
|
||||
@@ -65,21 +66,21 @@ interface IFingerprintService {
|
||||
// by BiometricService. To start authentication after the clients are ready, use
|
||||
// startPreparedClient().
|
||||
void prepareForAuthentication(int sensorId, IBinder token, long operationId, int userId,
|
||||
IBiometricSensorReceiver sensorReceiver, String opPackageName, int cookie,
|
||||
boolean allowBackgroundAuthentication);
|
||||
IBiometricSensorReceiver sensorReceiver, String opPackageName, long requestId,
|
||||
int cookie, boolean allowBackgroundAuthentication);
|
||||
|
||||
// Starts authentication with the previously prepared client.
|
||||
void startPreparedClient(int sensorId, int cookie);
|
||||
|
||||
// Cancel authentication for the given sessionId
|
||||
void cancelAuthentication(IBinder token, String opPackageName);
|
||||
// Cancel authentication for the given requestId.
|
||||
void cancelAuthentication(IBinder token, String opPackageName, long requestId);
|
||||
|
||||
// Cancel finger detection
|
||||
void cancelFingerprintDetect(IBinder token, String opPackageName);
|
||||
// Cancel finger detection for the given requestId.
|
||||
void cancelFingerprintDetect(IBinder token, String opPackageName, long requestId);
|
||||
|
||||
// Same as above, except this is protected by the MANAGE_BIOMETRIC signature permission. Takes
|
||||
// an additional uid, pid, userid.
|
||||
void cancelAuthenticationFromService(int sensorId, IBinder token, String opPackageName);
|
||||
void cancelAuthenticationFromService(int sensorId, IBinder token, String opPackageName, long requestId);
|
||||
|
||||
// Start fingerprint enrollment
|
||||
void enroll(IBinder token, in byte [] hardwareAuthToken, int userId, IFingerprintServiceReceiver receiver,
|
||||
|
||||
@@ -148,7 +148,7 @@ oneway interface IStatusBar
|
||||
*/
|
||||
void showAuthenticationDialog(in PromptInfo promptInfo, IBiometricSysuiReceiver sysuiReceiver,
|
||||
in int[] sensorIds, boolean credentialAllowed, boolean requireConfirmation, int userId,
|
||||
String opPackageName, long operationId, int multiSensorConfig);
|
||||
long operationId, String opPackageName, long requestId, int multiSensorConfig);
|
||||
/**
|
||||
* Used to notify the authentication dialog that a biometric has been authenticated.
|
||||
*/
|
||||
|
||||
@@ -110,7 +110,8 @@ interface IStatusBarService
|
||||
// Used to show the authentication dialog (Biometrics, Device Credential)
|
||||
void showAuthenticationDialog(in PromptInfo promptInfo, IBiometricSysuiReceiver sysuiReceiver,
|
||||
in int[] sensorIds, boolean credentialAllowed, boolean requireConfirmation,
|
||||
int userId, String opPackageName, long operationId, int multiSensorConfig);
|
||||
int userId, long operationId, String opPackageName, long requestId,
|
||||
int multiSensorConfig);
|
||||
|
||||
// Used to notify the authentication dialog that a biometric has been authenticated
|
||||
void onBiometricAuthenticated();
|
||||
|
||||
@@ -126,6 +126,7 @@ public class AuthContainerView extends LinearLayout
|
||||
boolean mCredentialAllowed;
|
||||
boolean mSkipIntro;
|
||||
long mOperationId;
|
||||
long mRequestId;
|
||||
@BiometricMultiSensorMode int mMultiSensorConfig;
|
||||
}
|
||||
|
||||
@@ -172,6 +173,12 @@ public class AuthContainerView extends LinearLayout
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Unique id for this request. */
|
||||
public Builder setRequestId(long requestId) {
|
||||
mConfig.mRequestId = requestId;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** The multi-sensor mode. */
|
||||
public Builder setMultiSensorConfig(@BiometricMultiSensorMode int multiSensorConfig) {
|
||||
mConfig.mMultiSensorConfig = multiSensorConfig;
|
||||
|
||||
@@ -501,7 +501,7 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks,
|
||||
@Override
|
||||
public void showAuthenticationDialog(PromptInfo promptInfo, IBiometricSysuiReceiver receiver,
|
||||
int[] sensorIds, boolean credentialAllowed, boolean requireConfirmation,
|
||||
int userId, String opPackageName, long operationId,
|
||||
int userId, long operationId, String opPackageName, long requestId,
|
||||
@BiometricMultiSensorMode int multiSensorConfig) {
|
||||
@Authenticators.Types final int authenticators = promptInfo.getAuthenticators();
|
||||
|
||||
@@ -515,6 +515,7 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks,
|
||||
+ ", credentialAllowed: " + credentialAllowed
|
||||
+ ", requireConfirmation: " + requireConfirmation
|
||||
+ ", operationId: " + operationId
|
||||
+ ", requestId: " + requestId
|
||||
+ ", multiSensorConfig: " + multiSensorConfig);
|
||||
}
|
||||
SomeArgs args = SomeArgs.obtain();
|
||||
@@ -526,6 +527,7 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks,
|
||||
args.argi1 = userId;
|
||||
args.arg6 = opPackageName;
|
||||
args.arg7 = operationId;
|
||||
args.arg8 = requestId;
|
||||
args.argi2 = multiSensorConfig;
|
||||
|
||||
boolean skipAnimation = false;
|
||||
@@ -629,6 +631,7 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks,
|
||||
if (mCurrentDialog == null) {
|
||||
// Could be possible if the caller canceled authentication after credential success
|
||||
// but before the client was notified.
|
||||
if (DEBUG) Log.d(TAG, "dialog already gone");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -683,6 +686,7 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks,
|
||||
final int userId = args.argi1;
|
||||
final String opPackageName = (String) args.arg6;
|
||||
final long operationId = (long) args.arg7;
|
||||
final long requestId = (long) args.arg8;
|
||||
final @BiometricMultiSensorMode int multiSensorConfig = args.argi2;
|
||||
|
||||
// Create a new dialog but do not replace the current one yet.
|
||||
@@ -695,6 +699,7 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks,
|
||||
opPackageName,
|
||||
skipAnimation,
|
||||
operationId,
|
||||
requestId,
|
||||
multiSensorConfig);
|
||||
|
||||
if (newDialog == null) {
|
||||
@@ -772,7 +777,7 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks,
|
||||
|
||||
protected AuthDialog buildDialog(PromptInfo promptInfo, boolean requireConfirmation,
|
||||
int userId, int[] sensorIds, boolean credentialAllowed, String opPackageName,
|
||||
boolean skipIntro, long operationId,
|
||||
boolean skipIntro, long operationId, long requestId,
|
||||
@BiometricMultiSensorMode int multiSensorConfig) {
|
||||
return new AuthContainerView.Builder(mContext)
|
||||
.setCallback(this)
|
||||
@@ -782,6 +787,7 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks,
|
||||
.setOpPackageName(opPackageName)
|
||||
.setSkipIntro(skipIntro)
|
||||
.setOperationId(operationId)
|
||||
.setRequestId(requestId)
|
||||
.setMultiSensorConfig(multiSensorConfig)
|
||||
.build(sensorIds, credentialAllowed, mFpProps, mFaceProps);
|
||||
}
|
||||
|
||||
@@ -290,8 +290,8 @@ public class CommandQueue extends IStatusBar.Stub implements CallbackController<
|
||||
default void showAuthenticationDialog(PromptInfo promptInfo,
|
||||
IBiometricSysuiReceiver receiver,
|
||||
int[] sensorIds, boolean credentialAllowed,
|
||||
boolean requireConfirmation, int userId, String opPackageName,
|
||||
long operationId, @BiometricMultiSensorMode int multiSensorConfig) {
|
||||
boolean requireConfirmation, int userId, long operationId, String opPackageName,
|
||||
long requestId, @BiometricMultiSensorMode int multiSensorConfig) {
|
||||
}
|
||||
|
||||
/** @see IStatusBar#onBiometricAuthenticated() */
|
||||
@@ -843,7 +843,7 @@ public class CommandQueue extends IStatusBar.Stub implements CallbackController<
|
||||
@Override
|
||||
public void showAuthenticationDialog(PromptInfo promptInfo, IBiometricSysuiReceiver receiver,
|
||||
int[] sensorIds, boolean credentialAllowed, boolean requireConfirmation,
|
||||
int userId, String opPackageName, long operationId,
|
||||
int userId, long operationId, String opPackageName, long requestId,
|
||||
@BiometricMultiSensorMode int multiSensorConfig) {
|
||||
synchronized (mLock) {
|
||||
SomeArgs args = SomeArgs.obtain();
|
||||
@@ -855,6 +855,7 @@ public class CommandQueue extends IStatusBar.Stub implements CallbackController<
|
||||
args.argi1 = userId;
|
||||
args.arg6 = opPackageName;
|
||||
args.arg7 = operationId;
|
||||
args.arg8 = requestId;
|
||||
args.argi2 = multiSensorConfig;
|
||||
mHandler.obtainMessage(MSG_BIOMETRIC_SHOW, args)
|
||||
.sendToTarget();
|
||||
@@ -1312,8 +1313,9 @@ public class CommandQueue extends IStatusBar.Stub implements CallbackController<
|
||||
(boolean) someArgs.arg4 /* credentialAllowed */,
|
||||
(boolean) someArgs.arg5 /* requireConfirmation */,
|
||||
someArgs.argi1 /* userId */,
|
||||
(String) someArgs.arg6 /* opPackageName */,
|
||||
(long) someArgs.arg7 /* operationId */,
|
||||
(String) someArgs.arg6 /* opPackageName */,
|
||||
(long) someArgs.arg8 /* requestId */,
|
||||
someArgs.argi2 /* multiSensorConfig */);
|
||||
}
|
||||
someArgs.recycle();
|
||||
|
||||
@@ -565,8 +565,9 @@ public class AuthControllerTest extends SysuiTestCase {
|
||||
credentialAllowed,
|
||||
true /* requireConfirmation */,
|
||||
0 /* userId */,
|
||||
"testPackage",
|
||||
0 /* operationId */,
|
||||
"testPackage",
|
||||
1 /* requestId */,
|
||||
BIOMETRIC_MULTI_SENSOR_FACE_THEN_FINGERPRINT);
|
||||
}
|
||||
|
||||
@@ -612,7 +613,7 @@ public class AuthControllerTest extends SysuiTestCase {
|
||||
@Override
|
||||
protected AuthDialog buildDialog(PromptInfo promptInfo,
|
||||
boolean requireConfirmation, int userId, int[] sensorIds, boolean credentialAllowed,
|
||||
String opPackageName, boolean skipIntro, long operationId,
|
||||
String opPackageName, boolean skipIntro, long operationId, long requestId,
|
||||
@BiometricManager.BiometricMultiSensorMode int multiSensorConfig) {
|
||||
|
||||
mLastBiometricPromptInfo = promptInfo;
|
||||
|
||||
@@ -423,17 +423,18 @@ public class CommandQueueTest extends SysuiTestCase {
|
||||
final boolean credentialAllowed = true;
|
||||
final boolean requireConfirmation = true;
|
||||
final int userId = 10;
|
||||
final String packageName = "test";
|
||||
final long operationId = 1;
|
||||
final String packageName = "test";
|
||||
final long requestId = 10;
|
||||
final int multiSensorConfig = BiometricManager.BIOMETRIC_MULTI_SENSOR_DEFAULT;
|
||||
|
||||
mCommandQueue.showAuthenticationDialog(promptInfo, receiver, sensorIds,
|
||||
credentialAllowed, requireConfirmation , userId, packageName, operationId,
|
||||
credentialAllowed, requireConfirmation, userId, operationId, packageName, requestId,
|
||||
multiSensorConfig);
|
||||
waitForIdleSync();
|
||||
verify(mCallbacks).showAuthenticationDialog(eq(promptInfo), eq(receiver), eq(sensorIds),
|
||||
eq(credentialAllowed), eq(requireConfirmation), eq(userId), eq(packageName),
|
||||
eq(operationId), eq(multiSensorConfig));
|
||||
eq(credentialAllowed), eq(requireConfirmation), eq(userId), eq(operationId),
|
||||
eq(packageName), eq(requestId), eq(multiSensorConfig));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -206,7 +206,7 @@ public class AuthService extends SystemService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void authenticate(IBinder token, long sessionId, int userId,
|
||||
public long authenticate(IBinder token, long sessionId, int userId,
|
||||
IBiometricServiceReceiver receiver, String opPackageName, PromptInfo promptInfo)
|
||||
throws RemoteException {
|
||||
// Only allow internal clients to authenticate with a different userId.
|
||||
@@ -223,18 +223,18 @@ public class AuthService extends SystemService {
|
||||
|
||||
if (!checkAppOps(callingUid, opPackageName, "authenticate()")) {
|
||||
authenticateFastFail("Denied by app ops: " + opPackageName, receiver);
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (token == null || receiver == null || opPackageName == null || promptInfo == null) {
|
||||
authenticateFastFail(
|
||||
"Unable to authenticate, one or more null arguments", receiver);
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!Utils.isForeground(callingUid, callingPid)) {
|
||||
authenticateFastFail("Caller is not foreground: " + opPackageName, receiver);
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (promptInfo.containsTestConfigurations()) {
|
||||
@@ -251,7 +251,7 @@ public class AuthService extends SystemService {
|
||||
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
mBiometricService.authenticate(
|
||||
return mBiometricService.authenticate(
|
||||
token, sessionId, userId, receiver, opPackageName, promptInfo);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
@@ -270,7 +270,7 @@ public class AuthService extends SystemService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancelAuthentication(IBinder token, String opPackageName)
|
||||
public void cancelAuthentication(IBinder token, String opPackageName, long requestId)
|
||||
throws RemoteException {
|
||||
checkPermission();
|
||||
|
||||
@@ -281,7 +281,7 @@ public class AuthService extends SystemService {
|
||||
|
||||
final long identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
mBiometricService.cancelAuthentication(token, opPackageName);
|
||||
mBiometricService.cancelAuthentication(token, opPackageName, requestId);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
}
|
||||
|
||||
@@ -128,6 +128,7 @@ public final class AuthSession implements IBinder.DeathRecipient {
|
||||
@VisibleForTesting final IBinder mToken;
|
||||
// Info to be shown on BiometricDialog when all cookies are returned.
|
||||
@VisibleForTesting final PromptInfo mPromptInfo;
|
||||
private final long mRequestId;
|
||||
private final long mOperationId;
|
||||
private final int mUserId;
|
||||
private final IBiometricSensorReceiver mSensorReceiver;
|
||||
@@ -142,6 +143,8 @@ public final class AuthSession implements IBinder.DeathRecipient {
|
||||
private @BiometricMultiSensorMode int mMultiSensorMode;
|
||||
private @MultiSensorState int mMultiSensorState;
|
||||
private int[] mSensors;
|
||||
// TODO(b/197265902): merge into state
|
||||
private boolean mCancelled;
|
||||
// For explicit confirmation, do not send to keystore until the user has confirmed
|
||||
// the authentication.
|
||||
private byte[] mTokenEscrow;
|
||||
@@ -162,6 +165,7 @@ public final class AuthSession implements IBinder.DeathRecipient {
|
||||
@NonNull ClientDeathReceiver clientDeathReceiver,
|
||||
@NonNull PreAuthInfo preAuthInfo,
|
||||
@NonNull IBinder token,
|
||||
long requestId,
|
||||
long operationId,
|
||||
int userId,
|
||||
@NonNull IBiometricSensorReceiver sensorReceiver,
|
||||
@@ -179,6 +183,7 @@ public final class AuthSession implements IBinder.DeathRecipient {
|
||||
mClientDeathReceiver = clientDeathReceiver;
|
||||
mPreAuthInfo = preAuthInfo;
|
||||
mToken = token;
|
||||
mRequestId = requestId;
|
||||
mOperationId = operationId;
|
||||
mUserId = userId;
|
||||
mSensorReceiver = sensorReceiver;
|
||||
@@ -187,6 +192,7 @@ public final class AuthSession implements IBinder.DeathRecipient {
|
||||
mPromptInfo = promptInfo;
|
||||
mDebugEnabled = debugEnabled;
|
||||
mFingerprintSensorProperties = fingerprintSensorProperties;
|
||||
mCancelled = false;
|
||||
|
||||
try {
|
||||
mClientReceiver.asBinder().linkToDeath(this, 0 /* flags */);
|
||||
@@ -233,7 +239,7 @@ public final class AuthSession implements IBinder.DeathRecipient {
|
||||
Slog.v(TAG, "waiting for cooking for sensor: " + sensor.id);
|
||||
}
|
||||
sensor.goToStateWaitingForCookie(requireConfirmation, mToken, mOperationId,
|
||||
mUserId, mSensorReceiver, mOpPackageName, cookie,
|
||||
mUserId, mSensorReceiver, mOpPackageName, mRequestId, cookie,
|
||||
mPromptInfo.isAllowBackgroundAuthentication());
|
||||
}
|
||||
}
|
||||
@@ -255,8 +261,9 @@ public final class AuthSession implements IBinder.DeathRecipient {
|
||||
true /* credentialAllowed */,
|
||||
false /* requireConfirmation */,
|
||||
mUserId,
|
||||
mOpPackageName,
|
||||
mOperationId,
|
||||
mOpPackageName,
|
||||
mRequestId,
|
||||
mMultiSensorMode);
|
||||
} else if (!mPreAuthInfo.eligibleSensors.isEmpty()) {
|
||||
// Some combination of biometric or biometric|credential is requested
|
||||
@@ -270,6 +277,11 @@ public final class AuthSession implements IBinder.DeathRecipient {
|
||||
}
|
||||
|
||||
void onCookieReceived(int cookie) {
|
||||
if (mCancelled) {
|
||||
Slog.w(TAG, "Received cookie but already cancelled (ignoring): " + cookie);
|
||||
return;
|
||||
}
|
||||
|
||||
for (BiometricSensor sensor : mPreAuthInfo.eligibleSensors) {
|
||||
sensor.goToStateCookieReturnedIfCookieMatches(cookie);
|
||||
}
|
||||
@@ -301,8 +313,9 @@ public final class AuthSession implements IBinder.DeathRecipient {
|
||||
mPreAuthInfo.shouldShowCredential(),
|
||||
requireConfirmation,
|
||||
mUserId,
|
||||
mOpPackageName,
|
||||
mOperationId,
|
||||
mOpPackageName,
|
||||
mRequestId,
|
||||
mMultiSensorMode);
|
||||
mState = STATE_AUTH_STARTED;
|
||||
} catch (RemoteException e) {
|
||||
@@ -369,7 +382,7 @@ public final class AuthSession implements IBinder.DeathRecipient {
|
||||
final boolean shouldCancel = filter.apply(sensor);
|
||||
Slog.d(TAG, "sensorId: " + sensor.id + ", shouldCancel: " + shouldCancel);
|
||||
if (shouldCancel) {
|
||||
sensor.goToStateCancelling(mToken, mOpPackageName);
|
||||
sensor.goToStateCancelling(mToken, mOpPackageName, mRequestId);
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
Slog.e(TAG, "Unable to cancel authentication");
|
||||
@@ -425,8 +438,9 @@ public final class AuthSession implements IBinder.DeathRecipient {
|
||||
true /* credentialAllowed */,
|
||||
false /* requireConfirmation */,
|
||||
mUserId,
|
||||
mOpPackageName,
|
||||
mOperationId,
|
||||
mOpPackageName,
|
||||
mRequestId,
|
||||
mMultiSensorMode);
|
||||
} else {
|
||||
mClientReceiver.onError(modality, error, vendorCode);
|
||||
@@ -775,6 +789,8 @@ public final class AuthSession implements IBinder.DeathRecipient {
|
||||
* @return true if this AuthSession is finished, e.g. should be set to null
|
||||
*/
|
||||
boolean onCancelAuthSession(boolean force) {
|
||||
mCancelled = true;
|
||||
|
||||
final boolean authStarted = mState == STATE_AUTH_CALLED
|
||||
|| mState == STATE_AUTH_STARTED
|
||||
|| mState == STATE_AUTH_STARTED_UI_SHOWING;
|
||||
@@ -820,6 +836,7 @@ public final class AuthSession implements IBinder.DeathRecipient {
|
||||
return Utils.isCredentialRequested(mPromptInfo);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
boolean allCookiesReceived() {
|
||||
final int remainingCookies = mPreAuthInfo.numSensorsWaitingForCookie();
|
||||
Slog.d(TAG, "Remaining cookies: " + remainingCookies);
|
||||
@@ -839,6 +856,10 @@ public final class AuthSession implements IBinder.DeathRecipient {
|
||||
return mState;
|
||||
}
|
||||
|
||||
long getRequestId() {
|
||||
return mRequestId;
|
||||
}
|
||||
|
||||
private int statsModality() {
|
||||
int modality = 0;
|
||||
|
||||
@@ -901,7 +922,9 @@ public final class AuthSession implements IBinder.DeathRecipient {
|
||||
@Override
|
||||
public String toString() {
|
||||
return "State: " + mState
|
||||
+ ", cancelled: " + mCancelled
|
||||
+ ", isCrypto: " + isCrypto()
|
||||
+ ", PreAuthInfo: " + mPreAuthInfo;
|
||||
+ ", PreAuthInfo: " + mPreAuthInfo
|
||||
+ ", requestId: " + mRequestId;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,11 +108,11 @@ public abstract class BiometricSensor {
|
||||
|
||||
void goToStateWaitingForCookie(boolean requireConfirmation, IBinder token, long sessionId,
|
||||
int userId, IBiometricSensorReceiver sensorReceiver, String opPackageName,
|
||||
int cookie, boolean allowBackgroundAuthentication)
|
||||
long requestId, int cookie, boolean allowBackgroundAuthentication)
|
||||
throws RemoteException {
|
||||
mCookie = cookie;
|
||||
impl.prepareForAuthentication(requireConfirmation, token,
|
||||
sessionId, userId, sensorReceiver, opPackageName, mCookie,
|
||||
sessionId, userId, sensorReceiver, opPackageName, requestId, mCookie,
|
||||
allowBackgroundAuthentication);
|
||||
mSensorState = STATE_WAITING_FOR_COOKIE;
|
||||
}
|
||||
@@ -129,8 +129,9 @@ public abstract class BiometricSensor {
|
||||
mSensorState = STATE_AUTHENTICATING;
|
||||
}
|
||||
|
||||
void goToStateCancelling(IBinder token, String opPackageName) throws RemoteException {
|
||||
impl.cancelAuthenticationFromService(token, opPackageName);
|
||||
void goToStateCancelling(IBinder token, String opPackageName, long requestId)
|
||||
throws RemoteException {
|
||||
impl.cancelAuthenticationFromService(token, opPackageName, requestId);
|
||||
mSensorState = STATE_CANCELING;
|
||||
}
|
||||
|
||||
|
||||
@@ -83,6 +83,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
/**
|
||||
* System service that arbitrates the modality for BiometricPrompt to use.
|
||||
@@ -115,6 +116,7 @@ public class BiometricService extends SystemService {
|
||||
final SettingObserver mSettingObserver;
|
||||
private final List<EnabledOnKeyguardCallback> mEnabledOnKeyguardCallbacks;
|
||||
private final Random mRandom = new Random();
|
||||
@NonNull private final AtomicLong mRequestCounter;
|
||||
|
||||
@VisibleForTesting
|
||||
IStatusBarService mStatusBarService;
|
||||
@@ -194,6 +196,7 @@ public class BiometricService extends SystemService {
|
||||
SomeArgs args = (SomeArgs) msg.obj;
|
||||
handleAuthenticate(
|
||||
(IBinder) args.arg1 /* token */,
|
||||
(long) args.arg6 /* requestId */,
|
||||
(long) args.arg2 /* operationId */,
|
||||
args.argi1 /* userid */,
|
||||
(IBiometricServiceReceiver) args.arg3 /* receiver */,
|
||||
@@ -204,7 +207,9 @@ public class BiometricService extends SystemService {
|
||||
}
|
||||
|
||||
case MSG_CANCEL_AUTHENTICATION: {
|
||||
handleCancelAuthentication();
|
||||
SomeArgs args = (SomeArgs) msg.obj;
|
||||
handleCancelAuthentication((long) args.arg3 /* requestId */);
|
||||
args.recycle();
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -683,13 +688,13 @@ public class BiometricService extends SystemService {
|
||||
}
|
||||
|
||||
@Override // Binder call
|
||||
public void authenticate(IBinder token, long operationId, int userId,
|
||||
public long authenticate(IBinder token, long operationId, int userId,
|
||||
IBiometricServiceReceiver receiver, String opPackageName, PromptInfo promptInfo) {
|
||||
checkInternalPermission();
|
||||
|
||||
if (token == null || receiver == null || opPackageName == null || promptInfo == null) {
|
||||
Slog.e(TAG, "Unable to authenticate, one or more null arguments");
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!Utils.isValidAuthenticatorConfig(promptInfo)) {
|
||||
@@ -706,6 +711,8 @@ public class BiometricService extends SystemService {
|
||||
}
|
||||
}
|
||||
|
||||
final long requestId = mRequestCounter.incrementAndGet();
|
||||
|
||||
SomeArgs args = SomeArgs.obtain();
|
||||
args.arg1 = token;
|
||||
args.arg2 = operationId;
|
||||
@@ -713,15 +720,23 @@ public class BiometricService extends SystemService {
|
||||
args.arg3 = receiver;
|
||||
args.arg4 = opPackageName;
|
||||
args.arg5 = promptInfo;
|
||||
args.arg6 = requestId;
|
||||
|
||||
mHandler.obtainMessage(MSG_AUTHENTICATE, args).sendToTarget();
|
||||
|
||||
return requestId;
|
||||
}
|
||||
|
||||
@Override // Binder call
|
||||
public void cancelAuthentication(IBinder token, String opPackageName) {
|
||||
public void cancelAuthentication(IBinder token, String opPackageName, long requestId) {
|
||||
checkInternalPermission();
|
||||
|
||||
mHandler.obtainMessage(MSG_CANCEL_AUTHENTICATION).sendToTarget();
|
||||
SomeArgs args = SomeArgs.obtain();
|
||||
args.arg1 = token;
|
||||
args.arg2 = opPackageName;
|
||||
args.arg3 = requestId;
|
||||
|
||||
mHandler.obtainMessage(MSG_CANCEL_AUTHENTICATION, args).sendToTarget();
|
||||
}
|
||||
|
||||
@Override // Binder call
|
||||
@@ -1111,6 +1126,10 @@ public class BiometricService extends SystemService {
|
||||
return Settings.Secure.getInt(context.getContentResolver(),
|
||||
CoexCoordinator.FACE_HAPTIC_DISABLE, 1) != 0;
|
||||
}
|
||||
|
||||
public AtomicLong getRequestGenerator() {
|
||||
return new AtomicLong(0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1136,6 +1155,7 @@ public class BiometricService extends SystemService {
|
||||
mEnabledOnKeyguardCallbacks = new ArrayList<>();
|
||||
mSettingObserver = mInjector.getSettingObserver(context, mHandler,
|
||||
mEnabledOnKeyguardCallbacks);
|
||||
mRequestCounter = mInjector.getRequestGenerator();
|
||||
|
||||
// TODO(b/193089985) This logic lives here (outside of CoexCoordinator) so that it doesn't
|
||||
// need to depend on context. We can remove this code once the advanced logic is enabled
|
||||
@@ -1349,7 +1369,7 @@ public class BiometricService extends SystemService {
|
||||
mCurrentAuthSession.onCookieReceived(cookie);
|
||||
}
|
||||
|
||||
private void handleAuthenticate(IBinder token, long operationId, int userId,
|
||||
private void handleAuthenticate(IBinder token, long requestId, long operationId, int userId,
|
||||
IBiometricServiceReceiver receiver, String opPackageName, PromptInfo promptInfo) {
|
||||
mHandler.post(() -> {
|
||||
try {
|
||||
@@ -1360,7 +1380,8 @@ public class BiometricService extends SystemService {
|
||||
final Pair<Integer, Integer> preAuthStatus = preAuthInfo.getPreAuthenticateStatus();
|
||||
|
||||
Slog.d(TAG, "handleAuthenticate: modality(" + preAuthStatus.first
|
||||
+ "), status(" + preAuthStatus.second + "), preAuthInfo: " + preAuthInfo);
|
||||
+ "), status(" + preAuthStatus.second + "), preAuthInfo: " + preAuthInfo
|
||||
+ " requestId: " + requestId);
|
||||
|
||||
if (preAuthStatus.second == BiometricConstants.BIOMETRIC_SUCCESS) {
|
||||
// If BIOMETRIC_WEAK or BIOMETRIC_STRONG are allowed, but not enrolled, but
|
||||
@@ -1372,8 +1393,8 @@ public class BiometricService extends SystemService {
|
||||
promptInfo.setAuthenticators(Authenticators.DEVICE_CREDENTIAL);
|
||||
}
|
||||
|
||||
authenticateInternal(token, operationId, userId, receiver, opPackageName,
|
||||
promptInfo, preAuthInfo);
|
||||
authenticateInternal(token, requestId, operationId, userId, receiver,
|
||||
opPackageName, promptInfo, preAuthInfo);
|
||||
} else {
|
||||
receiver.onError(preAuthStatus.first /* modality */,
|
||||
preAuthStatus.second /* errorCode */,
|
||||
@@ -1394,7 +1415,7 @@ public class BiometricService extends SystemService {
|
||||
* Note that this path is NOT invoked when the BiometricPrompt "Try again" button is pressed.
|
||||
* In that case, see {@link #handleOnTryAgainPressed()}.
|
||||
*/
|
||||
private void authenticateInternal(IBinder token, long operationId, int userId,
|
||||
private void authenticateInternal(IBinder token, long requestId, long operationId, int userId,
|
||||
IBiometricServiceReceiver receiver, String opPackageName, PromptInfo promptInfo,
|
||||
PreAuthInfo preAuthInfo) {
|
||||
Slog.d(TAG, "Creating authSession with authRequest: " + preAuthInfo);
|
||||
@@ -1412,9 +1433,9 @@ public class BiometricService extends SystemService {
|
||||
|
||||
final boolean debugEnabled = mInjector.isDebugEnabled(getContext(), userId);
|
||||
mCurrentAuthSession = new AuthSession(getContext(), mStatusBarService, mSysuiReceiver,
|
||||
mKeyStore, mRandom, mClientDeathReceiver, preAuthInfo, token, operationId, userId,
|
||||
mBiometricSensorReceiver, receiver, opPackageName, promptInfo, debugEnabled,
|
||||
mInjector.getFingerprintSensorProperties(getContext()));
|
||||
mKeyStore, mRandom, mClientDeathReceiver, preAuthInfo, token, requestId,
|
||||
operationId, userId, mBiometricSensorReceiver, receiver, opPackageName, promptInfo,
|
||||
debugEnabled, mInjector.getFingerprintSensorProperties(getContext()));
|
||||
try {
|
||||
mCurrentAuthSession.goToInitialState();
|
||||
} catch (RemoteException e) {
|
||||
@@ -1422,11 +1443,21 @@ public class BiometricService extends SystemService {
|
||||
}
|
||||
}
|
||||
|
||||
private void handleCancelAuthentication() {
|
||||
private void handleCancelAuthentication(long requestId) {
|
||||
if (mCurrentAuthSession == null) {
|
||||
Slog.e(TAG, "handleCancelAuthentication: AuthSession is null");
|
||||
return;
|
||||
}
|
||||
if (mCurrentAuthSession.getRequestId() != requestId) {
|
||||
// TODO: actually cancel the operation
|
||||
// This can happen if the operation has been queued, but is cancelled before
|
||||
// it reaches the head of the scheduler. Consider it a programming error for now
|
||||
// and ignore it.
|
||||
Slog.e(TAG, "handleCancelAuthentication: AuthSession mismatch current requestId: "
|
||||
+ mCurrentAuthSession.getRequestId() + " cancel for: " + requestId
|
||||
+ " (ignoring cancellation)");
|
||||
return;
|
||||
}
|
||||
|
||||
final boolean finished = mCurrentAuthSession.onCancelAuthSession(false /* force */);
|
||||
if (finished) {
|
||||
|
||||
@@ -101,6 +101,7 @@ public abstract class BaseClientMonitor extends LoggableMonitor
|
||||
private final int mSensorId; // sensorId as configured by the framework
|
||||
|
||||
@Nullable private IBinder mToken;
|
||||
private long mRequestId;
|
||||
@Nullable private ClientMonitorCallbackConverter mListener;
|
||||
// Currently only used for authentication client. The cookie generated by BiometricService
|
||||
// is never 0.
|
||||
@@ -154,6 +155,7 @@ public abstract class BaseClientMonitor extends LoggableMonitor
|
||||
mSequentialId = sCount++;
|
||||
mContext = context;
|
||||
mToken = token;
|
||||
mRequestId = -1;
|
||||
mListener = listener;
|
||||
mTargetUserId = userId;
|
||||
mOwner = owner;
|
||||
@@ -258,6 +260,29 @@ public abstract class BaseClientMonitor extends LoggableMonitor
|
||||
return mSensorId;
|
||||
}
|
||||
|
||||
/** Unique request id. */
|
||||
public final long getRequestId() {
|
||||
return mRequestId;
|
||||
}
|
||||
|
||||
/** If a unique id has been set via {@link #setRequestId(long)} */
|
||||
public final boolean hasRequestId() {
|
||||
return mRequestId > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* A unique identifier used to tie this operation to a request (i.e an API invocation).
|
||||
*
|
||||
* Subclasses should not call this method if this operation does not have a direct
|
||||
* correspondence to a request and {@link #hasRequestId()} will return false.
|
||||
*/
|
||||
protected final void setRequestId(long id) {
|
||||
if (id <= 0) {
|
||||
throw new IllegalArgumentException("request id must be positive");
|
||||
}
|
||||
mRequestId = id;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public Callback getCallback() {
|
||||
return mCallback;
|
||||
@@ -270,6 +295,7 @@ public abstract class BaseClientMonitor extends LoggableMonitor
|
||||
+ ", proto=" + getProtoEnum()
|
||||
+ ", owner=" + getOwnerString()
|
||||
+ ", cookie=" + getCookie()
|
||||
+ ", requestId=" + getRequestId()
|
||||
+ ", userId=" + getTargetUserId() + "}";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -643,22 +643,18 @@ public class BiometricScheduler {
|
||||
/**
|
||||
* Requests to cancel authentication or detection.
|
||||
* @param token from the caller, should match the token passed in when requesting authentication
|
||||
* @param requestId the id returned when requesting authentication
|
||||
*/
|
||||
public void cancelAuthenticationOrDetection(IBinder token) {
|
||||
if (mCurrentOperation == null) {
|
||||
Slog.e(getTag(), "Unable to cancel authentication, null operation");
|
||||
return;
|
||||
}
|
||||
final boolean isCorrectClient = isAuthenticationOrDetectionOperation(mCurrentOperation);
|
||||
final boolean tokenMatches = mCurrentOperation.mClientMonitor.getToken() == token;
|
||||
public void cancelAuthenticationOrDetection(IBinder token, long requestId) {
|
||||
Slog.d(getTag(), "cancelAuthenticationOrDetection, requestId: " + requestId
|
||||
+ " current: " + mCurrentOperation
|
||||
+ " stack size: " + mPendingOperations.size());
|
||||
|
||||
Slog.d(getTag(), "cancelAuthenticationOrDetection, isCorrectClient: " + isCorrectClient
|
||||
+ ", tokenMatches: " + tokenMatches);
|
||||
|
||||
if (isCorrectClient && tokenMatches) {
|
||||
if (mCurrentOperation != null
|
||||
&& canCancelAuthOperation(mCurrentOperation, token, requestId)) {
|
||||
Slog.d(getTag(), "Cancelling: " + mCurrentOperation);
|
||||
cancelInternal(mCurrentOperation);
|
||||
} else if (!isCorrectClient) {
|
||||
} else {
|
||||
// Look through the current queue for all authentication clients for the specified
|
||||
// token, and mark them as STATE_WAITING_IN_QUEUE_CANCELING. Note that we're marking
|
||||
// all of them, instead of just the first one, since the API surface currently doesn't
|
||||
@@ -666,8 +662,7 @@ public class BiometricScheduler {
|
||||
// process. However, this generally does not happen anyway, and would be a class of
|
||||
// bugs on its own.
|
||||
for (Operation operation : mPendingOperations) {
|
||||
if (isAuthenticationOrDetectionOperation(operation)
|
||||
&& operation.mClientMonitor.getToken() == token) {
|
||||
if (canCancelAuthOperation(operation, token, requestId)) {
|
||||
Slog.d(getTag(), "Marking " + operation
|
||||
+ " as STATE_WAITING_IN_QUEUE_CANCELING");
|
||||
operation.mState = Operation.STATE_WAITING_IN_QUEUE_CANCELING;
|
||||
@@ -676,10 +671,26 @@ public class BiometricScheduler {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isAuthenticationOrDetectionOperation(@NonNull Operation operation) {
|
||||
final boolean isAuthentication = operation.mClientMonitor
|
||||
instanceof AuthenticationConsumer;
|
||||
final boolean isDetection = operation.mClientMonitor instanceof DetectionConsumer;
|
||||
private static boolean canCancelAuthOperation(Operation operation, IBinder token,
|
||||
long requestId) {
|
||||
// TODO: restrict callers that can cancel without requestId (negative value)?
|
||||
return isAuthenticationOrDetectionOperation(operation)
|
||||
&& operation.mClientMonitor.getToken() == token
|
||||
&& isMatchingRequestId(operation, requestId);
|
||||
}
|
||||
|
||||
// By default, monitors are not associated with a request id to retain the original
|
||||
// behavior (i.e. if no requestId is explicitly set then assume it matches)
|
||||
private static boolean isMatchingRequestId(Operation operation, long requestId) {
|
||||
return !operation.mClientMonitor.hasRequestId()
|
||||
|| operation.mClientMonitor.getRequestId() == requestId;
|
||||
}
|
||||
|
||||
private static boolean isAuthenticationOrDetectionOperation(@NonNull Operation operation) {
|
||||
final boolean isAuthentication =
|
||||
operation.mClientMonitor instanceof AuthenticationConsumer;
|
||||
final boolean isDetection =
|
||||
operation.mClientMonitor instanceof DetectionConsumer;
|
||||
return isAuthentication || isDetection;
|
||||
}
|
||||
|
||||
|
||||
@@ -61,10 +61,11 @@ public final class FaceAuthenticator extends IBiometricAuthenticator.Stub {
|
||||
@Override
|
||||
public void prepareForAuthentication(boolean requireConfirmation, IBinder token,
|
||||
long operationId, int userId, IBiometricSensorReceiver sensorReceiver,
|
||||
String opPackageName, int cookie, boolean allowBackgroundAuthentication)
|
||||
String opPackageName, long requestId, int cookie, boolean allowBackgroundAuthentication)
|
||||
throws RemoteException {
|
||||
mFaceService.prepareForAuthentication(mSensorId, requireConfirmation, token, operationId,
|
||||
userId, sensorReceiver, opPackageName, cookie, allowBackgroundAuthentication);
|
||||
userId, sensorReceiver, opPackageName, requestId, cookie,
|
||||
allowBackgroundAuthentication);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -73,9 +74,9 @@ public final class FaceAuthenticator extends IBiometricAuthenticator.Stub {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancelAuthenticationFromService(IBinder token, String opPackageName)
|
||||
public void cancelAuthenticationFromService(IBinder token, String opPackageName, long requestId)
|
||||
throws RemoteException {
|
||||
mFaceService.cancelAuthenticationFromService(mSensorId, token, opPackageName);
|
||||
mFaceService.cancelAuthenticationFromService(mSensorId, token, opPackageName, requestId);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -250,7 +250,7 @@ public class FaceService extends SystemService {
|
||||
}
|
||||
|
||||
@Override // Binder call
|
||||
public void authenticate(final IBinder token, final long operationId, int userId,
|
||||
public long authenticate(final IBinder token, final long operationId, int userId,
|
||||
final IFaceServiceReceiver receiver, final String opPackageName,
|
||||
boolean isKeyguardBypassEnabled) {
|
||||
Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
|
||||
@@ -270,38 +270,38 @@ public class FaceService extends SystemService {
|
||||
final Pair<Integer, ServiceProvider> provider = getSingleProvider();
|
||||
if (provider == null) {
|
||||
Slog.w(TAG, "Null provider for authenticate");
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
|
||||
provider.second.scheduleAuthenticate(provider.first, token, operationId, userId,
|
||||
return provider.second.scheduleAuthenticate(provider.first, token, operationId, userId,
|
||||
0 /* cookie */,
|
||||
new ClientMonitorCallbackConverter(receiver), opPackageName, restricted,
|
||||
statsClient, isKeyguard, isKeyguardBypassEnabled);
|
||||
}
|
||||
|
||||
@Override // Binder call
|
||||
public void detectFace(final IBinder token, final int userId,
|
||||
public long detectFace(final IBinder token, final int userId,
|
||||
final IFaceServiceReceiver receiver, final String opPackageName) {
|
||||
Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
|
||||
if (!Utils.isKeyguard(getContext(), opPackageName)) {
|
||||
Slog.w(TAG, "detectFace called from non-sysui package: " + opPackageName);
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!Utils.isUserEncryptedOrLockdown(mLockPatternUtils, userId)) {
|
||||
// If this happens, something in KeyguardUpdateMonitor is wrong. This should only
|
||||
// ever be invoked when the user is encrypted or lockdown.
|
||||
Slog.e(TAG, "detectFace invoked when user is not encrypted or lockdown");
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
|
||||
final Pair<Integer, ServiceProvider> provider = getSingleProvider();
|
||||
if (provider == null) {
|
||||
Slog.w(TAG, "Null provider for detectFace");
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
|
||||
provider.second.scheduleFaceDetect(provider.first, token, userId,
|
||||
return provider.second.scheduleFaceDetect(provider.first, token, userId,
|
||||
new ClientMonitorCallbackConverter(receiver), opPackageName,
|
||||
BiometricsProtoEnums.CLIENT_KEYGUARD);
|
||||
}
|
||||
@@ -309,8 +309,8 @@ public class FaceService extends SystemService {
|
||||
@Override // Binder call
|
||||
public void prepareForAuthentication(int sensorId, boolean requireConfirmation,
|
||||
IBinder token, long operationId, int userId,
|
||||
IBiometricSensorReceiver sensorReceiver, String opPackageName, int cookie,
|
||||
boolean allowBackgroundAuthentication) {
|
||||
IBiometricSensorReceiver sensorReceiver, String opPackageName, long requestId,
|
||||
int cookie, boolean allowBackgroundAuthentication) {
|
||||
Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
|
||||
|
||||
final ServiceProvider provider = getProviderForSensor(sensorId);
|
||||
@@ -322,9 +322,9 @@ public class FaceService extends SystemService {
|
||||
final boolean isKeyguardBypassEnabled = false; // only valid for keyguard clients
|
||||
final boolean restricted = true; // BiometricPrompt is always restricted
|
||||
provider.scheduleAuthenticate(sensorId, token, operationId, userId, cookie,
|
||||
new ClientMonitorCallbackConverter(sensorReceiver), opPackageName, restricted,
|
||||
BiometricsProtoEnums.CLIENT_BIOMETRIC_PROMPT, allowBackgroundAuthentication,
|
||||
isKeyguardBypassEnabled);
|
||||
new ClientMonitorCallbackConverter(sensorReceiver), opPackageName, requestId,
|
||||
restricted, BiometricsProtoEnums.CLIENT_BIOMETRIC_PROMPT,
|
||||
allowBackgroundAuthentication, isKeyguardBypassEnabled);
|
||||
}
|
||||
|
||||
@Override // Binder call
|
||||
@@ -341,7 +341,8 @@ public class FaceService extends SystemService {
|
||||
}
|
||||
|
||||
@Override // Binder call
|
||||
public void cancelAuthentication(final IBinder token, final String opPackageName) {
|
||||
public void cancelAuthentication(final IBinder token, final String opPackageName,
|
||||
final long requestId) {
|
||||
Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
|
||||
|
||||
final Pair<Integer, ServiceProvider> provider = getSingleProvider();
|
||||
@@ -350,11 +351,12 @@ public class FaceService extends SystemService {
|
||||
return;
|
||||
}
|
||||
|
||||
provider.second.cancelAuthentication(provider.first, token);
|
||||
provider.second.cancelAuthentication(provider.first, token, requestId);
|
||||
}
|
||||
|
||||
@Override // Binder call
|
||||
public void cancelFaceDetect(final IBinder token, final String opPackageName) {
|
||||
public void cancelFaceDetect(final IBinder token, final String opPackageName,
|
||||
final long requestId) {
|
||||
Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
|
||||
if (!Utils.isKeyguard(getContext(), opPackageName)) {
|
||||
Slog.w(TAG, "cancelFaceDetect called from non-sysui package: "
|
||||
@@ -368,12 +370,12 @@ public class FaceService extends SystemService {
|
||||
return;
|
||||
}
|
||||
|
||||
provider.second.cancelFaceDetect(provider.first, token);
|
||||
provider.second.cancelFaceDetect(provider.first, token, requestId);
|
||||
}
|
||||
|
||||
@Override // Binder call
|
||||
public void cancelAuthenticationFromService(int sensorId, final IBinder token,
|
||||
final String opPackageName) {
|
||||
final String opPackageName, final long requestId) {
|
||||
Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
|
||||
|
||||
final ServiceProvider provider = getProviderForSensor(sensorId);
|
||||
@@ -382,7 +384,7 @@ public class FaceService extends SystemService {
|
||||
return;
|
||||
}
|
||||
|
||||
provider.cancelAuthentication(sensorId, token);
|
||||
provider.cancelAuthentication(sensorId, token, requestId);
|
||||
}
|
||||
|
||||
@Override // Binder call
|
||||
|
||||
@@ -101,18 +101,23 @@ public interface ServiceProvider {
|
||||
|
||||
void cancelEnrollment(int sensorId, @NonNull IBinder token);
|
||||
|
||||
void scheduleFaceDetect(int sensorId, @NonNull IBinder token, int userId,
|
||||
long scheduleFaceDetect(int sensorId, @NonNull IBinder token, int userId,
|
||||
@NonNull ClientMonitorCallbackConverter callback, @NonNull String opPackageName,
|
||||
int statsClient);
|
||||
|
||||
void cancelFaceDetect(int sensorId, @NonNull IBinder token);
|
||||
void cancelFaceDetect(int sensorId, @NonNull IBinder token, long requestId);
|
||||
|
||||
void scheduleAuthenticate(int sensorId, @NonNull IBinder token, long operationId, int userId,
|
||||
long scheduleAuthenticate(int sensorId, @NonNull IBinder token, long operationId, int userId,
|
||||
int cookie, @NonNull ClientMonitorCallbackConverter callback,
|
||||
@NonNull String opPackageName, boolean restricted, int statsClient,
|
||||
boolean allowBackgroundAuthentication, boolean isKeyguardBypassEnabled);
|
||||
|
||||
void cancelAuthentication(int sensorId, @NonNull IBinder token);
|
||||
void scheduleAuthenticate(int sensorId, @NonNull IBinder token, long operationId, int userId,
|
||||
int cookie, @NonNull ClientMonitorCallbackConverter callback,
|
||||
@NonNull String opPackageName, long requestId, boolean restricted, int statsClient,
|
||||
boolean allowBackgroundAuthentication, boolean isKeyguardBypassEnabled);
|
||||
|
||||
void cancelAuthentication(int sensorId, @NonNull IBinder token, long requestId);
|
||||
|
||||
void scheduleRemove(int sensorId, @NonNull IBinder token, int faceId, int userId,
|
||||
@NonNull IFaceServiceReceiver receiver, @NonNull String opPackageName);
|
||||
|
||||
@@ -65,7 +65,8 @@ class FaceAuthenticationClient extends AuthenticationClient<ISession> implements
|
||||
@FaceManager.FaceAcquired private int mLastAcquire = FaceManager.FACE_ACQUIRED_UNKNOWN;
|
||||
|
||||
FaceAuthenticationClient(@NonNull Context context,
|
||||
@NonNull LazyDaemon<ISession> lazyDaemon, @NonNull IBinder token,
|
||||
@NonNull LazyDaemon<ISession> lazyDaemon,
|
||||
@NonNull IBinder token, long requestId,
|
||||
@NonNull ClientMonitorCallbackConverter listener, int targetUserId, long operationId,
|
||||
boolean restricted, String owner, int cookie, boolean requireConfirmation, int sensorId,
|
||||
boolean isStrongBiometric, int statsClient, @NonNull UsageStats usageStats,
|
||||
@@ -76,6 +77,7 @@ class FaceAuthenticationClient extends AuthenticationClient<ISession> implements
|
||||
BiometricsProtoEnums.MODALITY_FACE, statsClient, null /* taskStackListener */,
|
||||
lockoutCache, allowBackgroundAuthentication, true /* shouldVibrate */,
|
||||
isKeyguardBypassEnabled);
|
||||
setRequestId(requestId);
|
||||
mUsageStats = usageStats;
|
||||
mLockoutCache = lockoutCache;
|
||||
mNotificationManager = context.getSystemService(NotificationManager.class);
|
||||
|
||||
@@ -43,11 +43,13 @@ public class FaceDetectClient extends AcquisitionClient<ISession> implements Det
|
||||
@Nullable private ICancellationSignal mCancellationSignal;
|
||||
|
||||
public FaceDetectClient(@NonNull Context context, @NonNull LazyDaemon<ISession> lazyDaemon,
|
||||
@NonNull IBinder token, @NonNull ClientMonitorCallbackConverter listener, int userId,
|
||||
@NonNull IBinder token, long requestId,
|
||||
@NonNull ClientMonitorCallbackConverter listener, int userId,
|
||||
@NonNull String owner, int sensorId, boolean isStrongBiometric, int statsClient) {
|
||||
super(context, lazyDaemon, token, listener, userId, owner, 0 /* cookie */, sensorId,
|
||||
true /* shouldVibrate */, BiometricsProtoEnums.MODALITY_FACE,
|
||||
BiometricsProtoEnums.ACTION_AUTHENTICATE, statsClient);
|
||||
setRequestId(requestId);
|
||||
mIsStrongBiometric = isStrongBiometric;
|
||||
}
|
||||
|
||||
|
||||
@@ -65,6 +65,7 @@ import java.io.FileDescriptor;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
/**
|
||||
* Provider for a single instance of the {@link IFace} HAL.
|
||||
@@ -83,6 +84,8 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider {
|
||||
@NonNull private final UsageStats mUsageStats;
|
||||
@NonNull private final ActivityTaskManager mActivityTaskManager;
|
||||
@NonNull private final BiometricTaskStackListener mTaskStackListener;
|
||||
// for requests that do not use biometric prompt
|
||||
@NonNull private final AtomicLong mRequestCounter = new AtomicLong(0);
|
||||
|
||||
@Nullable private IFace mDaemon;
|
||||
|
||||
@@ -110,8 +113,8 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider {
|
||||
&& !client.isAlreadyDone()) {
|
||||
Slog.e(getTag(), "Stopping background authentication, top: "
|
||||
+ topPackage + " currentClient: " + client);
|
||||
mSensors.valueAt(i).getScheduler()
|
||||
.cancelAuthenticationOrDetection(client.getToken());
|
||||
mSensors.valueAt(i).getScheduler().cancelAuthenticationOrDetection(
|
||||
client.getToken(), client.getRequestId());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -356,34 +359,39 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void scheduleFaceDetect(int sensorId, @NonNull IBinder token,
|
||||
public long scheduleFaceDetect(int sensorId, @NonNull IBinder token,
|
||||
int userId, @NonNull ClientMonitorCallbackConverter callback,
|
||||
@NonNull String opPackageName, int statsClient) {
|
||||
final long id = mRequestCounter.incrementAndGet();
|
||||
|
||||
mHandler.post(() -> {
|
||||
final boolean isStrongBiometric = Utils.isStrongBiometric(sensorId);
|
||||
final FaceDetectClient client = new FaceDetectClient(mContext,
|
||||
mSensors.get(sensorId).getLazySession(), token, callback, userId, opPackageName,
|
||||
mSensors.get(sensorId).getLazySession(),
|
||||
token, id, callback, userId, opPackageName,
|
||||
sensorId, isStrongBiometric, statsClient);
|
||||
scheduleForSensor(sensorId, client);
|
||||
});
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancelFaceDetect(int sensorId, @NonNull IBinder token) {
|
||||
public void cancelFaceDetect(int sensorId, @NonNull IBinder token, long requestId) {
|
||||
mHandler.post(() -> mSensors.get(sensorId).getScheduler()
|
||||
.cancelAuthenticationOrDetection(token));
|
||||
.cancelAuthenticationOrDetection(token, requestId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void scheduleAuthenticate(int sensorId, @NonNull IBinder token, long operationId,
|
||||
int userId, int cookie, @NonNull ClientMonitorCallbackConverter callback,
|
||||
@NonNull String opPackageName, boolean restricted, int statsClient,
|
||||
@NonNull String opPackageName, long requestId, boolean restricted, int statsClient,
|
||||
boolean allowBackgroundAuthentication, boolean isKeyguardBypassEnabled) {
|
||||
mHandler.post(() -> {
|
||||
final boolean isStrongBiometric = Utils.isStrongBiometric(sensorId);
|
||||
final FaceAuthenticationClient client = new FaceAuthenticationClient(
|
||||
mContext, mSensors.get(sensorId).getLazySession(), token, callback, userId,
|
||||
operationId, restricted, opPackageName, cookie,
|
||||
mContext, mSensors.get(sensorId).getLazySession(), token, requestId, callback,
|
||||
userId, operationId, restricted, opPackageName, cookie,
|
||||
false /* requireConfirmation */, sensorId, isStrongBiometric, statsClient,
|
||||
mUsageStats, mSensors.get(sensorId).getLockoutCache(),
|
||||
allowBackgroundAuthentication, isKeyguardBypassEnabled);
|
||||
@@ -392,9 +400,23 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancelAuthentication(int sensorId, @NonNull IBinder token) {
|
||||
public long scheduleAuthenticate(int sensorId, @NonNull IBinder token, long operationId,
|
||||
int userId, int cookie, @NonNull ClientMonitorCallbackConverter callback,
|
||||
@NonNull String opPackageName, boolean restricted, int statsClient,
|
||||
boolean allowBackgroundAuthentication, boolean isKeyguardBypassEnabled) {
|
||||
final long id = mRequestCounter.incrementAndGet();
|
||||
|
||||
scheduleAuthenticate(sensorId, token, operationId, userId, cookie, callback,
|
||||
opPackageName, id, restricted, statsClient,
|
||||
allowBackgroundAuthentication, isKeyguardBypassEnabled);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancelAuthentication(int sensorId, @NonNull IBinder token, long requestId) {
|
||||
mHandler.post(() -> mSensors.get(sensorId).getScheduler()
|
||||
.cancelAuthenticationOrDetection(token));
|
||||
.cancelAuthenticationOrDetection(token, requestId));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -87,6 +87,7 @@ import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
/**
|
||||
* Supports a single instance of the {@link android.hardware.biometrics.face.V1_0} or its extended
|
||||
@@ -115,6 +116,8 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider {
|
||||
@NonNull private final Map<Integer, Long> mAuthenticatorIds;
|
||||
@Nullable private IBiometricsFace mDaemon;
|
||||
@NonNull private final HalResultController mHalResultController;
|
||||
// for requests that do not use biometric prompt
|
||||
@NonNull private final AtomicLong mRequestCounter = new AtomicLong(0);
|
||||
private int mCurrentUserId = UserHandle.USER_NULL;
|
||||
private final int mSensorId;
|
||||
private final List<Long> mGeneratedChallengeCount = new ArrayList<>();
|
||||
@@ -605,7 +608,7 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void scheduleFaceDetect(int sensorId, @NonNull IBinder token,
|
||||
public long scheduleFaceDetect(int sensorId, @NonNull IBinder token,
|
||||
int userId, @NonNull ClientMonitorCallbackConverter callback,
|
||||
@NonNull String opPackageName, int statsClient) {
|
||||
throw new IllegalStateException("Face detect not supported by IBiometricsFace@1.0. Did you"
|
||||
@@ -613,7 +616,7 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancelFaceDetect(int sensorId, @NonNull IBinder token) {
|
||||
public void cancelFaceDetect(int sensorId, @NonNull IBinder token, long requestId) {
|
||||
throw new IllegalStateException("Face detect not supported by IBiometricsFace@1.0. Did you"
|
||||
+ "forget to check the supportsFaceDetection flag?");
|
||||
}
|
||||
@@ -621,26 +624,38 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider {
|
||||
@Override
|
||||
public void scheduleAuthenticate(int sensorId, @NonNull IBinder token, long operationId,
|
||||
int userId, int cookie, @NonNull ClientMonitorCallbackConverter receiver,
|
||||
@NonNull String opPackageName, boolean restricted, int statsClient,
|
||||
@NonNull String opPackageName, long requestId, boolean restricted, int statsClient,
|
||||
boolean allowBackgroundAuthentication, boolean isKeyguardBypassEnabled) {
|
||||
mHandler.post(() -> {
|
||||
scheduleUpdateActiveUserWithoutHandler(userId);
|
||||
|
||||
final boolean isStrongBiometric = Utils.isStrongBiometric(mSensorId);
|
||||
final FaceAuthenticationClient client = new FaceAuthenticationClient(mContext,
|
||||
mLazyDaemon, token, receiver, userId, operationId, restricted, opPackageName,
|
||||
cookie, false /* requireConfirmation */, mSensorId, isStrongBiometric,
|
||||
statsClient, mLockoutTracker, mUsageStats, allowBackgroundAuthentication,
|
||||
isKeyguardBypassEnabled);
|
||||
mLazyDaemon, token, requestId, receiver, userId, operationId, restricted,
|
||||
opPackageName, cookie, false /* requireConfirmation */, mSensorId,
|
||||
isStrongBiometric, statsClient, mLockoutTracker, mUsageStats,
|
||||
allowBackgroundAuthentication, isKeyguardBypassEnabled);
|
||||
mScheduler.scheduleClientMonitor(client);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancelAuthentication(int sensorId, @NonNull IBinder token) {
|
||||
mHandler.post(() -> {
|
||||
mScheduler.cancelAuthenticationOrDetection(token);
|
||||
});
|
||||
public long scheduleAuthenticate(int sensorId, @NonNull IBinder token, long operationId,
|
||||
int userId, int cookie, @NonNull ClientMonitorCallbackConverter receiver,
|
||||
@NonNull String opPackageName, boolean restricted, int statsClient,
|
||||
boolean allowBackgroundAuthentication, boolean isKeyguardBypassEnabled) {
|
||||
final long id = mRequestCounter.incrementAndGet();
|
||||
|
||||
scheduleAuthenticate(sensorId, token, operationId, userId, cookie, receiver,
|
||||
opPackageName, id, restricted, statsClient,
|
||||
allowBackgroundAuthentication, isKeyguardBypassEnabled);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancelAuthentication(int sensorId, @NonNull IBinder token, long requestId) {
|
||||
mHandler.post(() -> mScheduler.cancelAuthenticationOrDetection(token, requestId));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -57,7 +57,8 @@ class FaceAuthenticationClient extends AuthenticationClient<IBiometricsFace> {
|
||||
private int mLastAcquire;
|
||||
|
||||
FaceAuthenticationClient(@NonNull Context context,
|
||||
@NonNull LazyDaemon<IBiometricsFace> lazyDaemon, @NonNull IBinder token,
|
||||
@NonNull LazyDaemon<IBiometricsFace> lazyDaemon,
|
||||
@NonNull IBinder token, long requestId,
|
||||
@NonNull ClientMonitorCallbackConverter listener, int targetUserId, long operationId,
|
||||
boolean restricted, String owner, int cookie, boolean requireConfirmation, int sensorId,
|
||||
boolean isStrongBiometric, int statsClient, @NonNull LockoutTracker lockoutTracker,
|
||||
@@ -68,6 +69,7 @@ class FaceAuthenticationClient extends AuthenticationClient<IBiometricsFace> {
|
||||
BiometricsProtoEnums.MODALITY_FACE, statsClient, null /* taskStackListener */,
|
||||
lockoutTracker, allowBackgroundAuthentication, true /* shouldVibrate */,
|
||||
isKeyguardBypassEnabled);
|
||||
setRequestId(requestId);
|
||||
mUsageStats = usageStats;
|
||||
|
||||
final Resources resources = getContext().getResources();
|
||||
|
||||
@@ -61,10 +61,10 @@ public final class FingerprintAuthenticator extends IBiometricAuthenticator.Stub
|
||||
@Override
|
||||
public void prepareForAuthentication(boolean requireConfirmation, IBinder token,
|
||||
long operationId, int userId, IBiometricSensorReceiver sensorReceiver,
|
||||
String opPackageName, int cookie, boolean allowBackgroundAuthentication)
|
||||
String opPackageName, long requestId, int cookie, boolean allowBackgroundAuthentication)
|
||||
throws RemoteException {
|
||||
mFingerprintService.prepareForAuthentication(mSensorId, token, operationId, userId,
|
||||
sensorReceiver, opPackageName, cookie, allowBackgroundAuthentication);
|
||||
sensorReceiver, opPackageName, requestId, cookie, allowBackgroundAuthentication);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -73,9 +73,10 @@ public final class FingerprintAuthenticator extends IBiometricAuthenticator.Stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancelAuthenticationFromService(IBinder token, String opPackageName)
|
||||
public void cancelAuthenticationFromService(IBinder token, String opPackageName, long requestId)
|
||||
throws RemoteException {
|
||||
mFingerprintService.cancelAuthenticationFromService(mSensorId, token, opPackageName);
|
||||
mFingerprintService.cancelAuthenticationFromService(
|
||||
mSensorId, token, opPackageName, requestId);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -245,7 +245,7 @@ public class FingerprintService extends SystemService {
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override // Binder call
|
||||
public void authenticate(final IBinder token, final long operationId,
|
||||
public long authenticate(final IBinder token, final long operationId,
|
||||
final int sensorId, final int userId, final IFingerprintServiceReceiver receiver,
|
||||
final String opPackageName) {
|
||||
final int callingUid = Binder.getCallingUid();
|
||||
@@ -255,7 +255,7 @@ public class FingerprintService extends SystemService {
|
||||
if (!canUseFingerprint(opPackageName, true /* requireForeground */, callingUid,
|
||||
callingPid, callingUserId)) {
|
||||
Slog.w(TAG, "Authenticate rejecting package: " + opPackageName);
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Keyguard check must be done on the caller's binder identity, since it also checks
|
||||
@@ -270,7 +270,7 @@ public class FingerprintService extends SystemService {
|
||||
// SafetyNet for b/79776455
|
||||
EventLog.writeEvent(0x534e4554, "79776455");
|
||||
Slog.e(TAG, "Authenticate invoked when user is encrypted or lockdown");
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
@@ -290,7 +290,7 @@ public class FingerprintService extends SystemService {
|
||||
}
|
||||
if (provider == null) {
|
||||
Slog.w(TAG, "Null provider for authenticate");
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
|
||||
final FingerprintSensorPropertiesInternal sensorProps =
|
||||
@@ -299,18 +299,17 @@ public class FingerprintService extends SystemService {
|
||||
&& sensorProps != null && sensorProps.isAnyUdfpsType()) {
|
||||
identity = Binder.clearCallingIdentity();
|
||||
try {
|
||||
authenticateWithPrompt(operationId, sensorProps, userId, receiver);
|
||||
return authenticateWithPrompt(operationId, sensorProps, userId, receiver);
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
}
|
||||
} else {
|
||||
provider.second.scheduleAuthenticate(provider.first, token, operationId, userId,
|
||||
0 /* cookie */, new ClientMonitorCallbackConverter(receiver), opPackageName,
|
||||
restricted, statsClient, isKeyguard, mFingerprintStateCallback);
|
||||
}
|
||||
return provider.second.scheduleAuthenticate(provider.first, token, operationId, userId,
|
||||
0 /* cookie */, new ClientMonitorCallbackConverter(receiver), opPackageName,
|
||||
restricted, statsClient, isKeyguard, mFingerprintStateCallback);
|
||||
}
|
||||
|
||||
private void authenticateWithPrompt(
|
||||
private long authenticateWithPrompt(
|
||||
final long operationId,
|
||||
@NonNull final FingerprintSensorPropertiesInternal props,
|
||||
final int userId,
|
||||
@@ -387,33 +386,33 @@ public class FingerprintService extends SystemService {
|
||||
}
|
||||
};
|
||||
|
||||
biometricPrompt.authenticateUserForOperation(
|
||||
return biometricPrompt.authenticateUserForOperation(
|
||||
new CancellationSignal(), executor, promptCallback, userId, operationId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void detectFingerprint(final IBinder token, final int userId,
|
||||
public long detectFingerprint(final IBinder token, final int userId,
|
||||
final IFingerprintServiceReceiver receiver, final String opPackageName) {
|
||||
Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
|
||||
if (!Utils.isKeyguard(getContext(), opPackageName)) {
|
||||
Slog.w(TAG, "detectFingerprint called from non-sysui package: " + opPackageName);
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!Utils.isUserEncryptedOrLockdown(mLockPatternUtils, userId)) {
|
||||
// If this happens, something in KeyguardUpdateMonitor is wrong. This should only
|
||||
// ever be invoked when the user is encrypted or lockdown.
|
||||
Slog.e(TAG, "detectFingerprint invoked when user is not encrypted or lockdown");
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
|
||||
final Pair<Integer, ServiceProvider> provider = getSingleProvider();
|
||||
if (provider == null) {
|
||||
Slog.w(TAG, "Null provider for detectFingerprint");
|
||||
return;
|
||||
return -1;
|
||||
}
|
||||
|
||||
provider.second.scheduleFingerDetect(provider.first, token, userId,
|
||||
return provider.second.scheduleFingerDetect(provider.first, token, userId,
|
||||
new ClientMonitorCallbackConverter(receiver), opPackageName,
|
||||
BiometricsProtoEnums.CLIENT_KEYGUARD, mFingerprintStateCallback);
|
||||
}
|
||||
@@ -421,7 +420,7 @@ public class FingerprintService extends SystemService {
|
||||
@Override // Binder call
|
||||
public void prepareForAuthentication(int sensorId, IBinder token, long operationId,
|
||||
int userId, IBiometricSensorReceiver sensorReceiver, String opPackageName,
|
||||
int cookie, boolean allowBackgroundAuthentication) {
|
||||
long requestId, int cookie, boolean allowBackgroundAuthentication) {
|
||||
Utils.checkPermission(getContext(), MANAGE_BIOMETRIC);
|
||||
|
||||
final ServiceProvider provider = getProviderForSensor(sensorId);
|
||||
@@ -432,9 +431,9 @@ public class FingerprintService extends SystemService {
|
||||
|
||||
final boolean restricted = true; // BiometricPrompt is always restricted
|
||||
provider.scheduleAuthenticate(sensorId, token, operationId, userId, cookie,
|
||||
new ClientMonitorCallbackConverter(sensorReceiver), opPackageName, restricted,
|
||||
BiometricsProtoEnums.CLIENT_BIOMETRIC_PROMPT, allowBackgroundAuthentication,
|
||||
mFingerprintStateCallback);
|
||||
new ClientMonitorCallbackConverter(sensorReceiver), opPackageName, requestId,
|
||||
restricted, BiometricsProtoEnums.CLIENT_BIOMETRIC_PROMPT,
|
||||
allowBackgroundAuthentication, mFingerprintStateCallback);
|
||||
}
|
||||
|
||||
@Override // Binder call
|
||||
@@ -452,7 +451,8 @@ public class FingerprintService extends SystemService {
|
||||
|
||||
|
||||
@Override // Binder call
|
||||
public void cancelAuthentication(final IBinder token, final String opPackageName) {
|
||||
public void cancelAuthentication(final IBinder token, final String opPackageName,
|
||||
long requestId) {
|
||||
final int callingUid = Binder.getCallingUid();
|
||||
final int callingPid = Binder.getCallingPid();
|
||||
final int callingUserId = UserHandle.getCallingUserId();
|
||||
@@ -469,11 +469,12 @@ public class FingerprintService extends SystemService {
|
||||
return;
|
||||
}
|
||||
|
||||
provider.second.cancelAuthentication(provider.first, token);
|
||||
provider.second.cancelAuthentication(provider.first, token, requestId);
|
||||
}
|
||||
|
||||
@Override // Binder call
|
||||
public void cancelFingerprintDetect(final IBinder token, final String opPackageName) {
|
||||
public void cancelFingerprintDetect(final IBinder token, final String opPackageName,
|
||||
final long requestId) {
|
||||
Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
|
||||
if (!Utils.isKeyguard(getContext(), opPackageName)) {
|
||||
Slog.w(TAG, "cancelFingerprintDetect called from non-sysui package: "
|
||||
@@ -489,12 +490,12 @@ public class FingerprintService extends SystemService {
|
||||
return;
|
||||
}
|
||||
|
||||
provider.second.cancelAuthentication(provider.first, token);
|
||||
provider.second.cancelAuthentication(provider.first, token, requestId);
|
||||
}
|
||||
|
||||
@Override // Binder call
|
||||
public void cancelAuthenticationFromService(final int sensorId, final IBinder token,
|
||||
final String opPackageName) {
|
||||
final String opPackageName, final long requestId) {
|
||||
|
||||
Utils.checkPermission(getContext(), MANAGE_BIOMETRIC);
|
||||
|
||||
@@ -506,7 +507,7 @@ public class FingerprintService extends SystemService {
|
||||
return;
|
||||
}
|
||||
|
||||
provider.cancelAuthentication(sensorId, token);
|
||||
provider.cancelAuthentication(sensorId, token, requestId);
|
||||
}
|
||||
|
||||
@Override // Binder call
|
||||
|
||||
@@ -95,12 +95,18 @@ public interface ServiceProvider {
|
||||
|
||||
void cancelEnrollment(int sensorId, @NonNull IBinder token);
|
||||
|
||||
void scheduleFingerDetect(int sensorId, @NonNull IBinder token, int userId,
|
||||
long scheduleFingerDetect(int sensorId, @NonNull IBinder token, int userId,
|
||||
@NonNull ClientMonitorCallbackConverter callback, @NonNull String opPackageName,
|
||||
int statsClient,
|
||||
@NonNull FingerprintStateCallback fingerprintStateCallback);
|
||||
|
||||
void scheduleAuthenticate(int sensorId, @NonNull IBinder token, long operationId, int userId,
|
||||
int cookie, @NonNull ClientMonitorCallbackConverter callback,
|
||||
@NonNull String opPackageName, long requestId, boolean restricted, int statsClient,
|
||||
boolean allowBackgroundAuthentication,
|
||||
@NonNull FingerprintStateCallback fingerprintStateCallback);
|
||||
|
||||
long scheduleAuthenticate(int sensorId, @NonNull IBinder token, long operationId, int userId,
|
||||
int cookie, @NonNull ClientMonitorCallbackConverter callback,
|
||||
@NonNull String opPackageName, boolean restricted, int statsClient,
|
||||
boolean allowBackgroundAuthentication,
|
||||
@@ -108,7 +114,7 @@ public interface ServiceProvider {
|
||||
|
||||
void startPreparedClient(int sensorId, int cookie);
|
||||
|
||||
void cancelAuthentication(int sensorId, @NonNull IBinder token);
|
||||
void cancelAuthentication(int sensorId, @NonNull IBinder token, long requestId);
|
||||
|
||||
void scheduleRemove(int sensorId, @NonNull IBinder token,
|
||||
@NonNull IFingerprintServiceReceiver receiver, int fingerId, int userId,
|
||||
|
||||
@@ -61,7 +61,8 @@ class FingerprintAuthenticationClient extends AuthenticationClient<ISession> imp
|
||||
private boolean mIsPointerDown;
|
||||
|
||||
FingerprintAuthenticationClient(@NonNull Context context,
|
||||
@NonNull LazyDaemon<ISession> lazyDaemon, @NonNull IBinder token,
|
||||
@NonNull LazyDaemon<ISession> lazyDaemon,
|
||||
@NonNull IBinder token, long requestId,
|
||||
@NonNull ClientMonitorCallbackConverter listener, int targetUserId, long operationId,
|
||||
boolean restricted, @NonNull String owner, int cookie, boolean requireConfirmation,
|
||||
int sensorId, boolean isStrongBiometric, int statsClient,
|
||||
@@ -74,6 +75,7 @@ class FingerprintAuthenticationClient extends AuthenticationClient<ISession> imp
|
||||
BiometricsProtoEnums.MODALITY_FINGERPRINT, statsClient, taskStackListener,
|
||||
lockoutCache, allowBackgroundAuthentication, true /* shouldVibrate */,
|
||||
false /* isKeyguardBypassEnabled */);
|
||||
setRequestId(requestId);
|
||||
mLockoutCache = lockoutCache;
|
||||
mUdfpsOverlayController = udfpsOverlayController;
|
||||
mSensorProps = sensorProps;
|
||||
|
||||
@@ -47,13 +47,15 @@ class FingerprintDetectClient extends AcquisitionClient<ISession> implements Det
|
||||
@Nullable private ICancellationSignal mCancellationSignal;
|
||||
|
||||
FingerprintDetectClient(@NonNull Context context, @NonNull LazyDaemon<ISession> lazyDaemon,
|
||||
@NonNull IBinder token, @NonNull ClientMonitorCallbackConverter listener, int userId,
|
||||
@NonNull IBinder token, long requestId,
|
||||
@NonNull ClientMonitorCallbackConverter listener, int userId,
|
||||
@NonNull String owner, int sensorId,
|
||||
@Nullable IUdfpsOverlayController udfpsOverlayController, boolean isStrongBiometric,
|
||||
int statsClient) {
|
||||
super(context, lazyDaemon, token, listener, userId, owner, 0 /* cookie */, sensorId,
|
||||
true /* shouldVibrate */, BiometricsProtoEnums.MODALITY_FINGERPRINT,
|
||||
BiometricsProtoEnums.ACTION_AUTHENTICATE, statsClient);
|
||||
setRequestId(requestId);
|
||||
mIsStrongBiometric = isStrongBiometric;
|
||||
mUdfpsOverlayController = udfpsOverlayController;
|
||||
}
|
||||
|
||||
@@ -71,6 +71,7 @@ import java.io.FileDescriptor;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
/**
|
||||
* Provider for a single instance of the {@link IFingerprint} HAL.
|
||||
@@ -88,6 +89,8 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi
|
||||
@NonNull private final LockoutResetDispatcher mLockoutResetDispatcher;
|
||||
@NonNull private final ActivityTaskManager mActivityTaskManager;
|
||||
@NonNull private final BiometricTaskStackListener mTaskStackListener;
|
||||
// for requests that do not use biometric prompt
|
||||
@NonNull private final AtomicLong mRequestCounter = new AtomicLong(0);
|
||||
|
||||
@Nullable private IFingerprint mDaemon;
|
||||
@Nullable private IUdfpsOverlayController mUdfpsOverlayController;
|
||||
@@ -118,8 +121,8 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi
|
||||
&& !client.isAlreadyDone()) {
|
||||
Slog.e(getTag(), "Stopping background authentication, top: "
|
||||
+ topPackage + " currentClient: " + client);
|
||||
mSensors.valueAt(i).getScheduler()
|
||||
.cancelAuthenticationOrDetection(client.getToken());
|
||||
mSensors.valueAt(i).getScheduler().cancelAuthenticationOrDetection(
|
||||
client.getToken(), client.getRequestId());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -369,31 +372,35 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi
|
||||
}
|
||||
|
||||
@Override
|
||||
public void scheduleFingerDetect(int sensorId, @NonNull IBinder token, int userId,
|
||||
public long scheduleFingerDetect(int sensorId, @NonNull IBinder token, int userId,
|
||||
@NonNull ClientMonitorCallbackConverter callback, @NonNull String opPackageName,
|
||||
int statsClient,
|
||||
@NonNull FingerprintStateCallback fingerprintStateCallback) {
|
||||
final long id = mRequestCounter.incrementAndGet();
|
||||
|
||||
mHandler.post(() -> {
|
||||
final boolean isStrongBiometric = Utils.isStrongBiometric(sensorId);
|
||||
final FingerprintDetectClient client = new FingerprintDetectClient(mContext,
|
||||
mSensors.get(sensorId).getLazySession(), token, callback, userId,
|
||||
mSensors.get(sensorId).getLazySession(), token, id, callback, userId,
|
||||
opPackageName, sensorId, mUdfpsOverlayController, isStrongBiometric,
|
||||
statsClient);
|
||||
scheduleForSensor(sensorId, client, fingerprintStateCallback);
|
||||
});
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void scheduleAuthenticate(int sensorId, @NonNull IBinder token, long operationId,
|
||||
int userId, int cookie, @NonNull ClientMonitorCallbackConverter callback,
|
||||
@NonNull String opPackageName, boolean restricted, int statsClient,
|
||||
@NonNull String opPackageName, long requestId, boolean restricted, int statsClient,
|
||||
boolean allowBackgroundAuthentication,
|
||||
@NonNull FingerprintStateCallback fingerprintStateCallback) {
|
||||
mHandler.post(() -> {
|
||||
final boolean isStrongBiometric = Utils.isStrongBiometric(sensorId);
|
||||
final FingerprintAuthenticationClient client = new FingerprintAuthenticationClient(
|
||||
mContext, mSensors.get(sensorId).getLazySession(), token, callback, userId,
|
||||
operationId, restricted, opPackageName, cookie,
|
||||
mContext, mSensors.get(sensorId).getLazySession(), token, requestId, callback,
|
||||
userId, operationId, restricted, opPackageName, cookie,
|
||||
false /* requireConfirmation */, sensorId, isStrongBiometric, statsClient,
|
||||
mTaskStackListener, mSensors.get(sensorId).getLockoutCache(),
|
||||
mUdfpsOverlayController, allowBackgroundAuthentication,
|
||||
@@ -402,15 +409,30 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public long scheduleAuthenticate(int sensorId, @NonNull IBinder token, long operationId,
|
||||
int userId, int cookie, @NonNull ClientMonitorCallbackConverter callback,
|
||||
@NonNull String opPackageName, boolean restricted, int statsClient,
|
||||
boolean allowBackgroundAuthentication,
|
||||
@NonNull FingerprintStateCallback fingerprintStateCallback) {
|
||||
final long id = mRequestCounter.incrementAndGet();
|
||||
|
||||
scheduleAuthenticate(sensorId, token, operationId, userId, cookie, callback,
|
||||
opPackageName, id, restricted, statsClient, allowBackgroundAuthentication,
|
||||
fingerprintStateCallback);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startPreparedClient(int sensorId, int cookie) {
|
||||
mHandler.post(() -> mSensors.get(sensorId).getScheduler().startPreparedClient(cookie));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancelAuthentication(int sensorId, @NonNull IBinder token) {
|
||||
public void cancelAuthentication(int sensorId, @NonNull IBinder token, long requestId) {
|
||||
mHandler.post(() -> mSensors.get(sensorId).getScheduler()
|
||||
.cancelAuthenticationOrDetection(token));
|
||||
.cancelAuthenticationOrDetection(token, requestId));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -88,6 +88,7 @@ import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
/**
|
||||
* Supports a single instance of the {@link android.hardware.biometrics.fingerprint.V2_1} or
|
||||
@@ -115,6 +116,8 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider
|
||||
@NonNull private final HalResultController mHalResultController;
|
||||
@Nullable private IUdfpsOverlayController mUdfpsOverlayController;
|
||||
@Nullable private ISidefpsController mSidefpsController;
|
||||
// for requests that do not use biometric prompt
|
||||
@NonNull private final AtomicLong mRequestCounter = new AtomicLong(0);
|
||||
private int mCurrentUserId = UserHandle.USER_NULL;
|
||||
private final boolean mIsUdfps;
|
||||
private final int mSensorId;
|
||||
@@ -142,7 +145,8 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider
|
||||
&& !client.isAlreadyDone()) {
|
||||
Slog.e(TAG, "Stopping background authentication, top: "
|
||||
+ topPackage + " currentClient: " + client);
|
||||
mScheduler.cancelAuthenticationOrDetection(client.getToken());
|
||||
mScheduler.cancelAuthenticationOrDetection(
|
||||
client.getToken(), client.getRequestId());
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -591,26 +595,30 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider
|
||||
}
|
||||
|
||||
@Override
|
||||
public void scheduleFingerDetect(int sensorId, @NonNull IBinder token, int userId,
|
||||
public long scheduleFingerDetect(int sensorId, @NonNull IBinder token, int userId,
|
||||
@NonNull ClientMonitorCallbackConverter listener, @NonNull String opPackageName,
|
||||
int statsClient,
|
||||
@NonNull FingerprintStateCallback fingerprintStateCallback) {
|
||||
final long id = mRequestCounter.incrementAndGet();
|
||||
|
||||
mHandler.post(() -> {
|
||||
scheduleUpdateActiveUserWithoutHandler(userId);
|
||||
|
||||
final boolean isStrongBiometric = Utils.isStrongBiometric(mSensorProperties.sensorId);
|
||||
final FingerprintDetectClient client = new FingerprintDetectClient(mContext,
|
||||
mLazyDaemon, token, listener, userId, opPackageName,
|
||||
mLazyDaemon, token, id, listener, userId, opPackageName,
|
||||
mSensorProperties.sensorId, mUdfpsOverlayController, isStrongBiometric,
|
||||
statsClient);
|
||||
mScheduler.scheduleClientMonitor(client, fingerprintStateCallback);
|
||||
});
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void scheduleAuthenticate(int sensorId, @NonNull IBinder token, long operationId,
|
||||
int userId, int cookie, @NonNull ClientMonitorCallbackConverter listener,
|
||||
@NonNull String opPackageName, boolean restricted, int statsClient,
|
||||
@NonNull String opPackageName, long requestId, boolean restricted, int statsClient,
|
||||
boolean allowBackgroundAuthentication,
|
||||
@NonNull FingerprintStateCallback fingerprintStateCallback) {
|
||||
mHandler.post(() -> {
|
||||
@@ -618,8 +626,8 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider
|
||||
|
||||
final boolean isStrongBiometric = Utils.isStrongBiometric(mSensorProperties.sensorId);
|
||||
final FingerprintAuthenticationClient client = new FingerprintAuthenticationClient(
|
||||
mContext, mLazyDaemon, token, listener, userId, operationId, restricted,
|
||||
opPackageName, cookie, false /* requireConfirmation */,
|
||||
mContext, mLazyDaemon, token, requestId, listener, userId, operationId,
|
||||
restricted, opPackageName, cookie, false /* requireConfirmation */,
|
||||
mSensorProperties.sensorId, isStrongBiometric, statsClient,
|
||||
mTaskStackListener, mLockoutTracker, mUdfpsOverlayController,
|
||||
allowBackgroundAuthentication, mSensorProperties);
|
||||
@@ -627,15 +635,30 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public long scheduleAuthenticate(int sensorId, @NonNull IBinder token, long operationId,
|
||||
int userId, int cookie, @NonNull ClientMonitorCallbackConverter listener,
|
||||
@NonNull String opPackageName, boolean restricted, int statsClient,
|
||||
boolean allowBackgroundAuthentication,
|
||||
@NonNull FingerprintStateCallback fingerprintStateCallback) {
|
||||
final long id = mRequestCounter.incrementAndGet();
|
||||
|
||||
scheduleAuthenticate(sensorId, token, operationId, userId, cookie, listener,
|
||||
opPackageName, id, restricted, statsClient, allowBackgroundAuthentication,
|
||||
fingerprintStateCallback);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startPreparedClient(int sensorId, int cookie) {
|
||||
mHandler.post(() -> mScheduler.startPreparedClient(cookie));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancelAuthentication(int sensorId, @NonNull IBinder token) {
|
||||
public void cancelAuthentication(int sensorId, @NonNull IBinder token, long requestId) {
|
||||
Slog.d(TAG, "cancelAuthentication, sensorId: " + sensorId);
|
||||
mHandler.post(() -> mScheduler.cancelAuthenticationOrDetection(token));
|
||||
mHandler.post(() -> mScheduler.cancelAuthenticationOrDetection(token, requestId));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -59,7 +59,8 @@ class FingerprintAuthenticationClient extends AuthenticationClient<IBiometricsFi
|
||||
private boolean mIsPointerDown;
|
||||
|
||||
FingerprintAuthenticationClient(@NonNull Context context,
|
||||
@NonNull LazyDaemon<IBiometricsFingerprint> lazyDaemon, @NonNull IBinder token,
|
||||
@NonNull LazyDaemon<IBiometricsFingerprint> lazyDaemon,
|
||||
@NonNull IBinder token, long requestId,
|
||||
@NonNull ClientMonitorCallbackConverter listener, int targetUserId, long operationId,
|
||||
boolean restricted, @NonNull String owner, int cookie, boolean requireConfirmation,
|
||||
int sensorId, boolean isStrongBiometric, int statsClient,
|
||||
@@ -73,6 +74,7 @@ class FingerprintAuthenticationClient extends AuthenticationClient<IBiometricsFi
|
||||
BiometricsProtoEnums.MODALITY_FINGERPRINT, statsClient, taskStackListener,
|
||||
lockoutTracker, allowBackgroundAuthentication, true /* shouldVibrate */,
|
||||
false /* isKeyguardBypassEnabled */);
|
||||
setRequestId(requestId);
|
||||
mLockoutFrameworkImpl = lockoutTracker;
|
||||
mUdfpsOverlayController = udfpsOverlayController;
|
||||
mSensorProps = sensorProps;
|
||||
|
||||
@@ -52,13 +52,15 @@ class FingerprintDetectClient extends AcquisitionClient<IBiometricsFingerprint>
|
||||
private boolean mIsPointerDown;
|
||||
|
||||
public FingerprintDetectClient(@NonNull Context context,
|
||||
@NonNull LazyDaemon<IBiometricsFingerprint> lazyDaemon, @NonNull IBinder token,
|
||||
@NonNull LazyDaemon<IBiometricsFingerprint> lazyDaemon,
|
||||
@NonNull IBinder token, long requestId,
|
||||
@NonNull ClientMonitorCallbackConverter listener, int userId, @NonNull String owner,
|
||||
int sensorId, @Nullable IUdfpsOverlayController udfpsOverlayController,
|
||||
boolean isStrongBiometric, int statsClient) {
|
||||
super(context, lazyDaemon, token, listener, userId, owner, 0 /* cookie */, sensorId,
|
||||
true /* shouldVibrate */, BiometricsProtoEnums.MODALITY_FINGERPRINT,
|
||||
BiometricsProtoEnums.ACTION_AUTHENTICATE, statsClient);
|
||||
setRequestId(requestId);
|
||||
mUdfpsOverlayController = udfpsOverlayController;
|
||||
mIsStrongBiometric = isStrongBiometric;
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ public final class IrisAuthenticator extends IBiometricAuthenticator.Stub {
|
||||
@Override
|
||||
public void prepareForAuthentication(boolean requireConfirmation, IBinder token,
|
||||
long sessionId, int userId, IBiometricSensorReceiver sensorReceiver,
|
||||
String opPackageName, int cookie, boolean allowBackgroundAuthentication)
|
||||
String opPackageName, long requestId, int cookie, boolean allowBackgroundAuthentication)
|
||||
throws RemoteException {
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ public final class IrisAuthenticator extends IBiometricAuthenticator.Stub {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancelAuthenticationFromService(IBinder token, String opPackageName)
|
||||
public void cancelAuthenticationFromService(IBinder token, String opPackageName, long requestId)
|
||||
throws RemoteException {
|
||||
}
|
||||
|
||||
|
||||
@@ -783,13 +783,14 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D
|
||||
@Override
|
||||
public void showAuthenticationDialog(PromptInfo promptInfo, IBiometricSysuiReceiver receiver,
|
||||
int[] sensorIds, boolean credentialAllowed, boolean requireConfirmation,
|
||||
int userId, String opPackageName, long operationId,
|
||||
int userId, long operationId, String opPackageName, long requestId,
|
||||
@BiometricMultiSensorMode int multiSensorConfig) {
|
||||
enforceBiometricDialog();
|
||||
if (mBar != null) {
|
||||
try {
|
||||
mBar.showAuthenticationDialog(promptInfo, receiver, sensorIds, credentialAllowed,
|
||||
requireConfirmation, userId, opPackageName, operationId, multiSensorConfig);
|
||||
requireConfirmation, userId, operationId, opPackageName, requestId,
|
||||
multiSensorConfig);
|
||||
} catch (RemoteException ex) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,6 +74,7 @@ import java.util.function.Consumer;
|
||||
public class AuthSessionTest {
|
||||
|
||||
private static final String TEST_PACKAGE = "test_package";
|
||||
private static final long TEST_REQUEST_ID = 22;
|
||||
|
||||
@Mock private Context mContext;
|
||||
@Mock private ITrustManager mTrustManager;
|
||||
@@ -112,6 +113,7 @@ public class AuthSessionTest {
|
||||
final AuthSession session = createAuthSession(mSensors,
|
||||
false /* checkDevicePolicyManager */,
|
||||
Authenticators.BIOMETRIC_STRONG,
|
||||
TEST_REQUEST_ID,
|
||||
0 /* operationId */,
|
||||
0 /* userId */);
|
||||
|
||||
@@ -133,6 +135,7 @@ public class AuthSessionTest {
|
||||
final AuthSession session = createAuthSession(mSensors,
|
||||
false /* checkDevicePolicyManager */,
|
||||
Authenticators.BIOMETRIC_STRONG,
|
||||
TEST_REQUEST_ID,
|
||||
operationId,
|
||||
userId);
|
||||
assertEquals(mSensors.size(), session.mPreAuthInfo.eligibleSensors.size());
|
||||
@@ -153,6 +156,7 @@ public class AuthSessionTest {
|
||||
eq(userId),
|
||||
eq(mSensorReceiver),
|
||||
eq(TEST_PACKAGE),
|
||||
eq(TEST_REQUEST_ID),
|
||||
eq(sensor.getCookie()),
|
||||
anyBoolean() /* allowBackgroundAuthentication */);
|
||||
}
|
||||
@@ -184,6 +188,33 @@ public class AuthSessionTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCancelReducesAppetiteForCookies() throws Exception {
|
||||
setupFace(0 /* id */, false /* confirmationAlwaysRequired */,
|
||||
mock(IBiometricAuthenticator.class));
|
||||
setupFingerprint(1 /* id */, FingerprintSensorProperties.TYPE_UDFPS_OPTICAL);
|
||||
|
||||
final AuthSession session = createAuthSession(mSensors,
|
||||
false /* checkDevicePolicyManager */,
|
||||
Authenticators.BIOMETRIC_STRONG,
|
||||
TEST_REQUEST_ID,
|
||||
44 /* operationId */,
|
||||
2 /* userId */);
|
||||
|
||||
session.goToInitialState();
|
||||
|
||||
for (BiometricSensor sensor : session.mPreAuthInfo.eligibleSensors) {
|
||||
assertEquals(BiometricSensor.STATE_WAITING_FOR_COOKIE, sensor.getSensorState());
|
||||
}
|
||||
|
||||
session.onCancelAuthSession(false /* force */);
|
||||
|
||||
for (BiometricSensor sensor : session.mPreAuthInfo.eligibleSensors) {
|
||||
session.onCookieReceived(sensor.getCookie());
|
||||
assertEquals(BiometricSensor.STATE_CANCELING, sensor.getSensorState());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultiAuth_singleSensor_fingerprintSensorStartsAfterDialogAnimationCompletes()
|
||||
throws Exception {
|
||||
@@ -212,6 +243,7 @@ public class AuthSessionTest {
|
||||
final AuthSession session = createAuthSession(mSensors,
|
||||
false /* checkDevicePolicyManager */,
|
||||
Authenticators.BIOMETRIC_STRONG,
|
||||
TEST_REQUEST_ID,
|
||||
operationId,
|
||||
userId);
|
||||
assertEquals(mSensors.size(), session.mPreAuthInfo.eligibleSensors.size());
|
||||
@@ -238,7 +270,7 @@ public class AuthSessionTest {
|
||||
// fingerprint sensor does not start even if all cookies are received
|
||||
assertEquals(STATE_AUTH_STARTED, session.getState());
|
||||
verify(mStatusBarService).showAuthenticationDialog(any(), any(), any(),
|
||||
anyBoolean(), anyBoolean(), anyInt(), any(), anyLong(), anyInt());
|
||||
anyBoolean(), anyBoolean(), anyInt(), anyLong(), any(), anyLong(), anyInt());
|
||||
|
||||
// Notify AuthSession that the UI is shown. Then, fingerprint sensor should be started.
|
||||
session.onDialogAnimatedIn();
|
||||
@@ -277,6 +309,7 @@ public class AuthSessionTest {
|
||||
final AuthSession session = createAuthSession(mSensors,
|
||||
false /* checkDevicePolicyManager */,
|
||||
Authenticators.BIOMETRIC_STRONG,
|
||||
TEST_REQUEST_ID,
|
||||
0 /* operationId */,
|
||||
0 /* userId */);
|
||||
|
||||
@@ -285,7 +318,8 @@ public class AuthSessionTest {
|
||||
|
||||
sessionConsumer.accept(session);
|
||||
|
||||
verify(faceAuthenticator).cancelAuthenticationFromService(eq(mToken), eq(TEST_PACKAGE));
|
||||
verify(faceAuthenticator).cancelAuthenticationFromService(
|
||||
eq(mToken), eq(TEST_PACKAGE), eq(TEST_REQUEST_ID));
|
||||
}
|
||||
|
||||
private PreAuthInfo createPreAuthInfo(List<BiometricSensor> sensors, int userId,
|
||||
@@ -302,14 +336,14 @@ public class AuthSessionTest {
|
||||
|
||||
private AuthSession createAuthSession(List<BiometricSensor> sensors,
|
||||
boolean checkDevicePolicyManager, @Authenticators.Types int authenticators,
|
||||
long operationId, int userId) throws RemoteException {
|
||||
long requestId, long operationId, int userId) throws RemoteException {
|
||||
|
||||
final PromptInfo promptInfo = createPromptInfo(authenticators);
|
||||
|
||||
final PreAuthInfo preAuthInfo = createPreAuthInfo(sensors, userId, promptInfo,
|
||||
checkDevicePolicyManager);
|
||||
return new AuthSession(mContext, mStatusBarService, mSysuiReceiver, mKeyStore,
|
||||
mRandom, mClientDeathReceiver, preAuthInfo, mToken, operationId, userId,
|
||||
mRandom, mClientDeathReceiver, preAuthInfo, mToken, requestId, operationId, userId,
|
||||
mSensorReceiver, mClientReceiver, TEST_PACKAGE, promptInfo,
|
||||
false /* debugEnabled */, mFingerprintSensorProps);
|
||||
}
|
||||
|
||||
@@ -85,6 +85,7 @@ import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
@Presubmit
|
||||
@SmallTest
|
||||
@@ -93,6 +94,7 @@ public class BiometricServiceTest {
|
||||
private static final String TAG = "BiometricServiceTest";
|
||||
|
||||
private static final String TEST_PACKAGE_NAME = "test_package";
|
||||
private static final long TEST_REQUEST_ID = 44;
|
||||
|
||||
private static final String ERROR_HW_UNAVAILABLE = "hw_unavailable";
|
||||
private static final String ERROR_NOT_RECOGNIZED = "not_recognized";
|
||||
@@ -151,6 +153,7 @@ public class BiometricServiceTest {
|
||||
.thenReturn(mock(BiometricStrengthController.class));
|
||||
when(mInjector.getTrustManager()).thenReturn(mTrustManager);
|
||||
when(mInjector.getDevicePolicyManager(any())).thenReturn(mDevicePolicyManager);
|
||||
when(mInjector.getRequestGenerator()).thenReturn(new AtomicLong(TEST_REQUEST_ID - 1));
|
||||
|
||||
when(mResources.getString(R.string.biometric_error_hw_unavailable))
|
||||
.thenReturn(ERROR_HW_UNAVAILABLE);
|
||||
@@ -215,8 +218,7 @@ public class BiometricServiceTest {
|
||||
mBiometricService.mCurrentAuthSession.getState());
|
||||
|
||||
verify(mBiometricService.mCurrentAuthSession.mPreAuthInfo.eligibleSensors.get(0).impl)
|
||||
.cancelAuthenticationFromService(any(),
|
||||
any());
|
||||
.cancelAuthenticationFromService(any(), any(), anyLong());
|
||||
|
||||
// Simulate ERROR_CANCELED received from HAL
|
||||
mBiometricService.mBiometricSensorReceiver.onError(
|
||||
@@ -272,8 +274,9 @@ public class BiometricServiceTest {
|
||||
eq(true) /* credentialAllowed */,
|
||||
anyBoolean() /* requireConfirmation */,
|
||||
anyInt() /* userId */,
|
||||
anyLong() /* operationId */,
|
||||
eq(TEST_PACKAGE_NAME),
|
||||
anyLong() /* sessionId */,
|
||||
eq(TEST_REQUEST_ID),
|
||||
eq(BIOMETRIC_MULTI_SENSOR_DEFAULT));
|
||||
}
|
||||
|
||||
@@ -357,8 +360,9 @@ public class BiometricServiceTest {
|
||||
eq(false) /* credentialAllowed */,
|
||||
eq(false) /* requireConfirmation */,
|
||||
anyInt() /* userId */,
|
||||
anyLong() /* operationId */,
|
||||
eq(TEST_PACKAGE_NAME),
|
||||
anyLong() /* sessionId */,
|
||||
eq(TEST_REQUEST_ID),
|
||||
eq(BIOMETRIC_MULTI_SENSOR_DEFAULT));
|
||||
}
|
||||
|
||||
@@ -467,6 +471,7 @@ public class BiometricServiceTest {
|
||||
anyInt() /* userId */,
|
||||
any(IBiometricSensorReceiver.class),
|
||||
anyString() /* opPackageName */,
|
||||
eq(TEST_REQUEST_ID),
|
||||
cookieCaptor.capture() /* cookie */,
|
||||
anyBoolean() /* allowBackgroundAuthentication */);
|
||||
|
||||
@@ -488,8 +493,9 @@ public class BiometricServiceTest {
|
||||
eq(false) /* credentialAllowed */,
|
||||
anyBoolean() /* requireConfirmation */,
|
||||
anyInt() /* userId */,
|
||||
anyLong() /* operationId */,
|
||||
eq(TEST_PACKAGE_NAME),
|
||||
anyLong() /* sessionId */,
|
||||
eq(TEST_REQUEST_ID),
|
||||
eq(BIOMETRIC_MULTI_SENSOR_DEFAULT));
|
||||
|
||||
// Hardware authenticated
|
||||
@@ -543,8 +549,9 @@ public class BiometricServiceTest {
|
||||
eq(true) /* credentialAllowed */,
|
||||
anyBoolean() /* requireConfirmation */,
|
||||
anyInt() /* userId */,
|
||||
anyLong() /* operationId */,
|
||||
eq(TEST_PACKAGE_NAME),
|
||||
anyLong() /* sessionId */,
|
||||
eq(TEST_REQUEST_ID),
|
||||
eq(BIOMETRIC_MULTI_SENSOR_DEFAULT));
|
||||
}
|
||||
|
||||
@@ -705,8 +712,9 @@ public class BiometricServiceTest {
|
||||
anyBoolean() /* credentialAllowed */,
|
||||
anyBoolean() /* requireConfirmation */,
|
||||
anyInt() /* userId */,
|
||||
anyLong() /* operationId */,
|
||||
anyString(),
|
||||
anyLong() /* sessionId */,
|
||||
anyLong() /* requestId */,
|
||||
eq(BIOMETRIC_MULTI_SENSOR_DEFAULT));
|
||||
}
|
||||
|
||||
@@ -805,8 +813,9 @@ public class BiometricServiceTest {
|
||||
eq(true) /* credentialAllowed */,
|
||||
anyBoolean() /* requireConfirmation */,
|
||||
anyInt() /* userId */,
|
||||
anyLong() /* operationId */,
|
||||
eq(TEST_PACKAGE_NAME),
|
||||
anyLong() /* sessionId */,
|
||||
eq(TEST_REQUEST_ID),
|
||||
eq(BIOMETRIC_MULTI_SENSOR_DEFAULT));
|
||||
}
|
||||
|
||||
@@ -885,8 +894,9 @@ public class BiometricServiceTest {
|
||||
eq(true) /* credentialAllowed */,
|
||||
anyBoolean() /* requireConfirmation */,
|
||||
anyInt() /* userId */,
|
||||
anyLong() /* operationId */,
|
||||
eq(TEST_PACKAGE_NAME),
|
||||
anyLong() /* sessionId */,
|
||||
eq(TEST_REQUEST_ID),
|
||||
eq(BIOMETRIC_MULTI_SENSOR_DEFAULT));
|
||||
}
|
||||
|
||||
@@ -1030,8 +1040,7 @@ public class BiometricServiceTest {
|
||||
eq(BiometricConstants.BIOMETRIC_ERROR_USER_CANCELED),
|
||||
eq(0 /* vendorCode */));
|
||||
verify(mBiometricService.mSensors.get(0).impl).cancelAuthenticationFromService(
|
||||
any(),
|
||||
any());
|
||||
any(), any(), anyLong());
|
||||
assertNull(mBiometricService.mCurrentAuthSession);
|
||||
}
|
||||
|
||||
@@ -1051,7 +1060,7 @@ public class BiometricServiceTest {
|
||||
waitForIdle();
|
||||
|
||||
verify(mBiometricService.mSensors.get(0).impl)
|
||||
.cancelAuthenticationFromService(any(), any());
|
||||
.cancelAuthenticationFromService(any(), any(), anyLong());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1071,7 +1080,7 @@ public class BiometricServiceTest {
|
||||
waitForIdle();
|
||||
|
||||
verify(mBiometricService.mSensors.get(0).impl)
|
||||
.cancelAuthenticationFromService(any(), any());
|
||||
.cancelAuthenticationFromService(any(), any(), anyLong());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1088,7 +1097,7 @@ public class BiometricServiceTest {
|
||||
waitForIdle();
|
||||
|
||||
verify(mBiometricService.mSensors.get(0).impl)
|
||||
.cancelAuthenticationFromService(any(), any());
|
||||
.cancelAuthenticationFromService(any(), any(), anyLong());
|
||||
verify(mReceiver1).onError(
|
||||
eq(BiometricAuthenticator.TYPE_FACE),
|
||||
eq(BiometricConstants.BIOMETRIC_ERROR_USER_CANCELED),
|
||||
@@ -1126,7 +1135,7 @@ public class BiometricServiceTest {
|
||||
false /* requireConfirmation */, null /* authenticators */);
|
||||
|
||||
mBiometricService.mImpl.cancelAuthentication(mBiometricService.mCurrentAuthSession.mToken,
|
||||
TEST_PACKAGE_NAME);
|
||||
TEST_PACKAGE_NAME, TEST_REQUEST_ID);
|
||||
waitForIdle();
|
||||
|
||||
// Pretend that the HAL has responded to cancel with ERROR_CANCELED
|
||||
@@ -1353,8 +1362,8 @@ public class BiometricServiceTest {
|
||||
int authenticators = Authenticators.BIOMETRIC_STRONG;
|
||||
assertEquals(BiometricManager.BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED,
|
||||
invokeCanAuthenticate(mBiometricService, authenticators));
|
||||
invokeAuthenticate(mBiometricService.mImpl, mReceiver1, false /* requireConfirmation */,
|
||||
authenticators);
|
||||
long requestId = invokeAuthenticate(mBiometricService.mImpl, mReceiver1,
|
||||
false /* requireConfirmation */, authenticators);
|
||||
waitForIdle();
|
||||
verify(mReceiver1).onError(
|
||||
eq(BiometricAuthenticator.TYPE_FINGERPRINT),
|
||||
@@ -1366,7 +1375,7 @@ public class BiometricServiceTest {
|
||||
authenticators = Authenticators.BIOMETRIC_WEAK;
|
||||
assertEquals(BiometricManager.BIOMETRIC_SUCCESS,
|
||||
invokeCanAuthenticate(mBiometricService, authenticators));
|
||||
invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
|
||||
requestId = invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
|
||||
false /* requireConfirmation */,
|
||||
authenticators);
|
||||
waitForIdle();
|
||||
@@ -1377,8 +1386,9 @@ public class BiometricServiceTest {
|
||||
eq(false) /* credentialAllowed */,
|
||||
anyBoolean() /* requireConfirmation */,
|
||||
anyInt() /* userId */,
|
||||
anyLong() /* operationId */,
|
||||
eq(TEST_PACKAGE_NAME),
|
||||
anyLong() /* sessionId */,
|
||||
eq(requestId),
|
||||
eq(BIOMETRIC_MULTI_SENSOR_DEFAULT));
|
||||
|
||||
// Requesting strong and credential, when credential is setup
|
||||
@@ -1387,7 +1397,7 @@ public class BiometricServiceTest {
|
||||
when(mTrustManager.isDeviceSecure(anyInt())).thenReturn(true);
|
||||
assertEquals(BiometricManager.BIOMETRIC_SUCCESS,
|
||||
invokeCanAuthenticate(mBiometricService, authenticators));
|
||||
invokeAuthenticate(mBiometricService.mImpl, mReceiver1,
|
||||
requestId = invokeAuthenticate(mBiometricService.mImpl, mReceiver1,
|
||||
false /* requireConfirmation */,
|
||||
authenticators);
|
||||
waitForIdle();
|
||||
@@ -1399,8 +1409,9 @@ public class BiometricServiceTest {
|
||||
eq(true) /* credentialAllowed */,
|
||||
anyBoolean() /* requireConfirmation */,
|
||||
anyInt() /* userId */,
|
||||
anyLong() /* operationId */,
|
||||
eq(TEST_PACKAGE_NAME),
|
||||
anyLong() /* sessionId */,
|
||||
eq(requestId),
|
||||
eq(BIOMETRIC_MULTI_SENSOR_DEFAULT));
|
||||
|
||||
// Un-downgrading the authenticator allows successful strong auth
|
||||
@@ -1414,7 +1425,7 @@ public class BiometricServiceTest {
|
||||
authenticators = Authenticators.BIOMETRIC_STRONG;
|
||||
assertEquals(BiometricManager.BIOMETRIC_SUCCESS,
|
||||
invokeCanAuthenticate(mBiometricService, authenticators));
|
||||
invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
|
||||
requestId = invokeAuthenticateAndStart(mBiometricService.mImpl, mReceiver1,
|
||||
false /* requireConfirmation */, authenticators);
|
||||
waitForIdle();
|
||||
verify(mBiometricService.mStatusBarService).showAuthenticationDialog(
|
||||
@@ -1424,8 +1435,9 @@ public class BiometricServiceTest {
|
||||
eq(false) /* credentialAllowed */,
|
||||
anyBoolean() /* requireConfirmation */,
|
||||
anyInt() /* userId */,
|
||||
anyLong() /* operationId */,
|
||||
eq(TEST_PACKAGE_NAME),
|
||||
anyLong() /* sessionId */,
|
||||
eq(requestId),
|
||||
eq(BIOMETRIC_MULTI_SENSOR_DEFAULT));
|
||||
}
|
||||
|
||||
@@ -1617,11 +1629,12 @@ public class BiometricServiceTest {
|
||||
mBiometricService.mStatusBarService = mock(IStatusBarService.class);
|
||||
}
|
||||
|
||||
private void invokeAuthenticateAndStart(IBiometricService.Stub service,
|
||||
private long invokeAuthenticateAndStart(IBiometricService.Stub service,
|
||||
IBiometricServiceReceiver receiver, boolean requireConfirmation,
|
||||
Integer authenticators) throws Exception {
|
||||
// Request auth, creates a pending session
|
||||
invokeAuthenticate(service, receiver, requireConfirmation, authenticators);
|
||||
final long requestId = invokeAuthenticate(
|
||||
service, receiver, requireConfirmation, authenticators);
|
||||
waitForIdle();
|
||||
|
||||
startPendingAuthSession(mBiometricService);
|
||||
@@ -1629,6 +1642,8 @@ public class BiometricServiceTest {
|
||||
|
||||
assertNotNull(mBiometricService.mCurrentAuthSession);
|
||||
assertEquals(STATE_AUTH_STARTED, mBiometricService.mCurrentAuthSession.getState());
|
||||
|
||||
return requestId;
|
||||
}
|
||||
|
||||
private static void startPendingAuthSession(BiometricService service) throws Exception {
|
||||
@@ -1644,10 +1659,10 @@ public class BiometricServiceTest {
|
||||
service.mImpl.onReadyForAuthentication(cookie);
|
||||
}
|
||||
|
||||
private static void invokeAuthenticate(IBiometricService.Stub service,
|
||||
private static long invokeAuthenticate(IBiometricService.Stub service,
|
||||
IBiometricServiceReceiver receiver, boolean requireConfirmation,
|
||||
Integer authenticators) throws Exception {
|
||||
service.authenticate(
|
||||
return service.authenticate(
|
||||
new Binder() /* token */,
|
||||
0 /* operationId */,
|
||||
0 /* userId */,
|
||||
@@ -1657,9 +1672,9 @@ public class BiometricServiceTest {
|
||||
false /* checkDevicePolicy */));
|
||||
}
|
||||
|
||||
private static void invokeAuthenticateForWorkApp(IBiometricService.Stub service,
|
||||
private static long invokeAuthenticateForWorkApp(IBiometricService.Stub service,
|
||||
IBiometricServiceReceiver receiver, Integer authenticators) throws Exception {
|
||||
service.authenticate(
|
||||
return service.authenticate(
|
||||
new Binder() /* token */,
|
||||
0 /* operationId */,
|
||||
0 /* userId */,
|
||||
|
||||
@@ -40,6 +40,7 @@ import android.platform.test.annotations.Presubmit;
|
||||
import android.testing.TestableContext;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.test.InstrumentationRegistry;
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
@@ -193,7 +194,7 @@ public class BiometricSchedulerTest {
|
||||
// Request it to be canceled. The operation can be canceled immediately, and the scheduler
|
||||
// should go back to idle, since in this case the framework has not even requested the HAL
|
||||
// to authenticate yet.
|
||||
mScheduler.cancelAuthenticationOrDetection(mToken);
|
||||
mScheduler.cancelAuthenticationOrDetection(mToken, 1 /* requestId */);
|
||||
assertNull(mScheduler.mCurrentOperation);
|
||||
}
|
||||
|
||||
@@ -303,7 +304,7 @@ public class BiometricSchedulerTest {
|
||||
mScheduler.mPendingOperations.getFirst().mState);
|
||||
|
||||
// Request cancel before the authentication client has started
|
||||
mScheduler.cancelAuthenticationOrDetection(mToken);
|
||||
mScheduler.cancelAuthenticationOrDetection(mToken, 1 /* requestId */);
|
||||
waitForIdle();
|
||||
assertEquals(Operation.STATE_WAITING_IN_QUEUE_CANCELING,
|
||||
mScheduler.mPendingOperations.getFirst().mState);
|
||||
@@ -317,6 +318,107 @@ public class BiometricSchedulerTest {
|
||||
assertNull(mScheduler.getCurrentClient());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCancels_whenAuthRequestIdNotSet() {
|
||||
testCancelsWhenRequestId(null /* requestId */, 2, true /* started */);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCancels_whenAuthRequestIdNotSet_notStarted() {
|
||||
testCancelsWhenRequestId(null /* requestId */, 2, false /* started */);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCancels_whenAuthRequestIdMatches() {
|
||||
testCancelsWhenRequestId(200L, 200, true /* started */);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCancels_whenAuthRequestIdMatches_noStarted() {
|
||||
testCancelsWhenRequestId(200L, 200, false /* started */);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDoesNotCancel_whenAuthRequestIdMismatched() {
|
||||
testCancelsWhenRequestId(10L, 20, true /* started */);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDoesNotCancel_whenAuthRequestIdMismatched_notStarted() {
|
||||
testCancelsWhenRequestId(10L, 20, false /* started */);
|
||||
}
|
||||
|
||||
private void testCancelsWhenRequestId(@Nullable Long requestId, long cancelRequestId,
|
||||
boolean started) {
|
||||
final boolean matches = requestId == null || requestId == cancelRequestId;
|
||||
final HalClientMonitor.LazyDaemon<Object> lazyDaemon = () -> mock(Object.class);
|
||||
final ClientMonitorCallbackConverter callback = mock(ClientMonitorCallbackConverter.class);
|
||||
final TestAuthenticationClient client = new TestAuthenticationClient(
|
||||
mContext, lazyDaemon, mToken, callback);
|
||||
if (requestId != null) {
|
||||
client.setRequestId(requestId);
|
||||
}
|
||||
|
||||
mScheduler.scheduleClientMonitor(client);
|
||||
if (started) {
|
||||
mScheduler.startPreparedClient(client.getCookie());
|
||||
}
|
||||
waitForIdle();
|
||||
mScheduler.cancelAuthenticationOrDetection(mToken, cancelRequestId);
|
||||
waitForIdle();
|
||||
|
||||
assertEquals(matches && started ? 1 : 0, client.mNumCancels);
|
||||
|
||||
if (matches) {
|
||||
if (started) {
|
||||
assertEquals(Operation.STATE_STARTED_CANCELING,
|
||||
mScheduler.mCurrentOperation.mState);
|
||||
}
|
||||
} else {
|
||||
if (started) {
|
||||
assertEquals(Operation.STATE_STARTED,
|
||||
mScheduler.mCurrentOperation.mState);
|
||||
} else {
|
||||
assertEquals(Operation.STATE_WAITING_FOR_COOKIE,
|
||||
mScheduler.mCurrentOperation.mState);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCancelsPending_whenAuthRequestIdsSet() {
|
||||
final long requestId1 = 10;
|
||||
final long requestId2 = 20;
|
||||
final HalClientMonitor.LazyDaemon<Object> lazyDaemon = () -> mock(Object.class);
|
||||
final ClientMonitorCallbackConverter callback = mock(ClientMonitorCallbackConverter.class);
|
||||
final TestAuthenticationClient client1 = new TestAuthenticationClient(
|
||||
mContext, lazyDaemon, mToken, callback);
|
||||
client1.setRequestId(requestId1);
|
||||
final TestAuthenticationClient client2 = new TestAuthenticationClient(
|
||||
mContext, lazyDaemon, mToken, callback);
|
||||
client2.setRequestId(requestId2);
|
||||
|
||||
mScheduler.scheduleClientMonitor(client1);
|
||||
mScheduler.scheduleClientMonitor(client2);
|
||||
mScheduler.startPreparedClient(client1.getCookie());
|
||||
waitForIdle();
|
||||
mScheduler.cancelAuthenticationOrDetection(mToken, 9999);
|
||||
waitForIdle();
|
||||
|
||||
assertEquals(Operation.STATE_STARTED,
|
||||
mScheduler.mCurrentOperation.mState);
|
||||
assertEquals(Operation.STATE_WAITING_IN_QUEUE,
|
||||
mScheduler.mPendingOperations.getFirst().mState);
|
||||
|
||||
mScheduler.cancelAuthenticationOrDetection(mToken, requestId2);
|
||||
waitForIdle();
|
||||
|
||||
assertEquals(Operation.STATE_STARTED,
|
||||
mScheduler.mCurrentOperation.mState);
|
||||
assertEquals(Operation.STATE_WAITING_IN_QUEUE_CANCELING,
|
||||
mScheduler.mPendingOperations.getFirst().mState);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInterruptPrecedingClients_whenExpected() {
|
||||
final BaseClientMonitor interruptableMonitor = mock(BaseClientMonitor.class,
|
||||
@@ -377,12 +479,10 @@ public class BiometricSchedulerTest {
|
||||
|
||||
@Override
|
||||
protected void stopHalOperation() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startHalOperation() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -397,6 +497,7 @@ public class BiometricSchedulerTest {
|
||||
}
|
||||
|
||||
private static class TestAuthenticationClient extends AuthenticationClient<Object> {
|
||||
int mNumCancels = 0;
|
||||
|
||||
public TestAuthenticationClient(@NonNull Context context,
|
||||
@NonNull LazyDaemon<Object> lazyDaemon, @NonNull IBinder token,
|
||||
@@ -428,6 +529,11 @@ public class BiometricSchedulerTest {
|
||||
public boolean wasUserDetected() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void cancel() {
|
||||
mNumCancels++;
|
||||
super.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
private static class TestClientMonitor2 extends TestClientMonitor {
|
||||
|
||||
Reference in New Issue
Block a user