Merge "Propogate face/fingerprint authenticate options to detect and authenticate clients." into udc-dev

This commit is contained in:
Joe Bolinger
2023-02-24 19:11:34 +00:00
committed by Android (Google) Code Review
32 changed files with 416 additions and 213 deletions

View File

@@ -52,7 +52,7 @@ public class FaceAuthenticateOptions implements AuthenticateOptions, Parcelable
}
/** The sensor id for this operation. */
private final int mSensorId;
private int mSensorId;
private static int defaultSensorId() {
return -1;
}
@@ -298,6 +298,15 @@ public class FaceAuthenticateOptions implements AuthenticateOptions, Parcelable
return mAttributionTag;
}
/**
* The sensor id for this operation.
*/
@DataClass.Generated.Member
public @NonNull FaceAuthenticateOptions setSensorId( int value) {
mSensorId = value;
return this;
}
/**
* The package name for that operation that should be used for
* {@link android.app.AppOpsManager} verification.
@@ -610,10 +619,10 @@ public class FaceAuthenticateOptions implements AuthenticateOptions, Parcelable
}
@DataClass.Generated(
time = 1676508211385L,
time = 1677119626034L,
codegenVersion = "1.0.23",
sourceFile = "frameworks/base/core/java/android/hardware/face/FaceAuthenticateOptions.java",
inputSignatures = "private final int mUserId\nprivate final int mSensorId\nprivate final @android.hardware.biometrics.AuthenticateOptions.DisplayState int mDisplayState\npublic static final int AUTHENTICATE_REASON_UNKNOWN\npublic static final int AUTHENTICATE_REASON_STARTED_WAKING_UP\npublic static final int AUTHENTICATE_REASON_PRIMARY_BOUNCER_SHOWN\npublic static final int AUTHENTICATE_REASON_ASSISTANT_VISIBLE\npublic static final int AUTHENTICATE_REASON_ALTERNATE_BIOMETRIC_BOUNCER_SHOWN\npublic static final int AUTHENTICATE_REASON_NOTIFICATION_PANEL_CLICKED\npublic static final int AUTHENTICATE_REASON_OCCLUDING_APP_REQUESTED\npublic static final int AUTHENTICATE_REASON_PICK_UP_GESTURE_TRIGGERED\npublic static final int AUTHENTICATE_REASON_QS_EXPANDED\npublic static final int AUTHENTICATE_REASON_SWIPE_UP_ON_BOUNCER\npublic static final int AUTHENTICATE_REASON_UDFPS_POINTER_DOWN\nprivate final @android.hardware.face.FaceAuthenticateOptions.AuthenticateReason int mAuthenticateReason\nprivate final @android.os.PowerManager.WakeReason int mWakeReason\nprivate @android.annotation.NonNull java.lang.String mOpPackageName\nprivate @android.annotation.Nullable java.lang.String mAttributionTag\nprivate static int defaultUserId()\nprivate static int defaultSensorId()\nprivate static int defaultDisplayState()\nprivate static int defaultAuthenticateReason()\nprivate static int defaultWakeReason()\nprivate static java.lang.String defaultOpPackageName()\nprivate static java.lang.String defaultAttributionTag()\nclass FaceAuthenticateOptions extends java.lang.Object implements [android.hardware.biometrics.AuthenticateOptions, android.os.Parcelable]\n@com.android.internal.util.DataClass(genParcelable=true, genAidl=true, genBuilder=true, genSetters=true, genEqualsHashCode=true)")
inputSignatures = "private final int mUserId\nprivate int mSensorId\nprivate final @android.hardware.biometrics.AuthenticateOptions.DisplayState int mDisplayState\npublic static final int AUTHENTICATE_REASON_UNKNOWN\npublic static final int AUTHENTICATE_REASON_STARTED_WAKING_UP\npublic static final int AUTHENTICATE_REASON_PRIMARY_BOUNCER_SHOWN\npublic static final int AUTHENTICATE_REASON_ASSISTANT_VISIBLE\npublic static final int AUTHENTICATE_REASON_ALTERNATE_BIOMETRIC_BOUNCER_SHOWN\npublic static final int AUTHENTICATE_REASON_NOTIFICATION_PANEL_CLICKED\npublic static final int AUTHENTICATE_REASON_OCCLUDING_APP_REQUESTED\npublic static final int AUTHENTICATE_REASON_PICK_UP_GESTURE_TRIGGERED\npublic static final int AUTHENTICATE_REASON_QS_EXPANDED\npublic static final int AUTHENTICATE_REASON_SWIPE_UP_ON_BOUNCER\npublic static final int AUTHENTICATE_REASON_UDFPS_POINTER_DOWN\nprivate final @android.hardware.face.FaceAuthenticateOptions.AuthenticateReason int mAuthenticateReason\nprivate final @android.os.PowerManager.WakeReason int mWakeReason\nprivate @android.annotation.NonNull java.lang.String mOpPackageName\nprivate @android.annotation.Nullable java.lang.String mAttributionTag\nprivate static int defaultUserId()\nprivate static int defaultSensorId()\nprivate static int defaultDisplayState()\nprivate static int defaultAuthenticateReason()\nprivate static int defaultWakeReason()\nprivate static java.lang.String defaultOpPackageName()\nprivate static java.lang.String defaultAttributionTag()\nclass FaceAuthenticateOptions extends java.lang.Object implements [android.hardware.biometrics.AuthenticateOptions, android.os.Parcelable]\n@com.android.internal.util.DataClass(genParcelable=true, genAidl=true, genBuilder=true, genSetters=true, genEqualsHashCode=true)")
@Deprecated
private void __metadata() {}

View File

@@ -68,7 +68,7 @@ interface IFaceService {
// by BiometricService. To start authentication after the clients are ready, use
// startPreparedClient().
@EnforcePermission("USE_BIOMETRIC_INTERNAL")
void prepareForAuthentication(int sensorId, boolean requireConfirmation, IBinder token,
void prepareForAuthentication(boolean requireConfirmation, IBinder token,
long operationId, IBiometricSensorReceiver sensorReceiver,
in FaceAuthenticateOptions options, long requestId, int cookie,
boolean allowBackgroundAuthentication);

View File

@@ -46,7 +46,7 @@ public final class FingerprintAuthenticateOptions implements AuthenticateOptions
}
/** The sensor id for this operation. */
private final int mSensorId;
private int mSensorId;
private static int defaultSensorId() {
return SENSOR_ID_ANY;
}
@@ -175,6 +175,15 @@ public final class FingerprintAuthenticateOptions implements AuthenticateOptions
return mAttributionTag;
}
/**
* The sensor id for this operation.
*/
@DataClass.Generated.Member
public @NonNull FingerprintAuthenticateOptions setSensorId( int value) {
mSensorId = value;
return this;
}
/**
* The package name for that operation that should be used for
* {@link android.app.AppOpsManager} verification.
@@ -433,10 +442,10 @@ public final class FingerprintAuthenticateOptions implements AuthenticateOptions
}
@DataClass.Generated(
time = 1676508212083L,
time = 1677119626721L,
codegenVersion = "1.0.23",
sourceFile = "frameworks/base/core/java/android/hardware/fingerprint/FingerprintAuthenticateOptions.java",
inputSignatures = "private final int mUserId\nprivate final int mSensorId\nprivate final boolean mIgnoreEnrollmentState\nprivate final @android.hardware.biometrics.AuthenticateOptions.DisplayState int mDisplayState\nprivate @android.annotation.NonNull java.lang.String mOpPackageName\nprivate @android.annotation.Nullable java.lang.String mAttributionTag\nprivate static int defaultUserId()\nprivate static int defaultSensorId()\nprivate static boolean defaultIgnoreEnrollmentState()\nprivate static int defaultDisplayState()\nprivate static java.lang.String defaultOpPackageName()\nprivate static java.lang.String defaultAttributionTag()\nclass FingerprintAuthenticateOptions extends java.lang.Object implements [android.hardware.biometrics.AuthenticateOptions, android.os.Parcelable]\n@com.android.internal.util.DataClass(genParcelable=true, genAidl=true, genBuilder=true, genSetters=true, genEqualsHashCode=true)")
inputSignatures = "private final int mUserId\nprivate int mSensorId\nprivate final boolean mIgnoreEnrollmentState\nprivate final @android.hardware.biometrics.AuthenticateOptions.DisplayState int mDisplayState\nprivate @android.annotation.NonNull java.lang.String mOpPackageName\nprivate @android.annotation.Nullable java.lang.String mAttributionTag\nprivate static int defaultUserId()\nprivate static int defaultSensorId()\nprivate static boolean defaultIgnoreEnrollmentState()\nprivate static int defaultDisplayState()\nprivate static java.lang.String defaultOpPackageName()\nprivate static java.lang.String defaultAttributionTag()\nclass FingerprintAuthenticateOptions extends java.lang.Object implements [android.hardware.biometrics.AuthenticateOptions, android.os.Parcelable]\n@com.android.internal.util.DataClass(genParcelable=true, genAidl=true, genBuilder=true, genSetters=true, genEqualsHashCode=true)")
@Deprecated
private void __metadata() {}

View File

@@ -73,8 +73,8 @@ interface IFingerprintService {
// by BiometricService. To start authentication after the clients are ready, use
// startPreparedClient().
@EnforcePermission("MANAGE_BIOMETRIC")
void prepareForAuthentication(int sensorId, IBinder token, long operationId, int userId,
IBiometricSensorReceiver sensorReceiver, String opPackageName, long requestId,
void prepareForAuthentication(IBinder token, long operationId,
IBiometricSensorReceiver sensorReceiver, in FingerprintAuthenticateOptions options, long requestId,
int cookie, boolean allowBackgroundAuthentication);
// Starts authentication with the previously prepared client.

View File

@@ -23,6 +23,7 @@ import android.app.ActivityTaskManager;
import android.app.TaskStackListener;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.hardware.biometrics.AuthenticateOptions;
import android.hardware.biometrics.BiometricAuthenticator;
import android.hardware.biometrics.BiometricConstants;
import android.hardware.biometrics.BiometricManager;
@@ -44,8 +45,8 @@ import java.util.function.Supplier;
/**
* A class to keep track of the authentication state for a given client.
*/
public abstract class AuthenticationClient<T> extends AcquisitionClient<T>
implements AuthenticationConsumer {
public abstract class AuthenticationClient<T, O extends AuthenticateOptions>
extends AcquisitionClient<T> implements AuthenticationConsumer {
// New, has not started yet
public static final int STATE_NEW = 0;
@@ -89,14 +90,15 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T>
public AuthenticationClient(@NonNull Context context, @NonNull Supplier<T> lazyDaemon,
@NonNull IBinder token, @NonNull ClientMonitorCallbackConverter listener,
int targetUserId, long operationId, boolean restricted, @NonNull String owner,
int cookie, boolean requireConfirmation, int sensorId,
long operationId, boolean restricted, @NonNull O options,
int cookie, boolean requireConfirmation,
@NonNull BiometricLogger biometricLogger, @NonNull BiometricContext biometricContext,
boolean isStrongBiometric, @Nullable TaskStackListener taskStackListener,
@NonNull LockoutTracker lockoutTracker, boolean allowBackgroundAuthentication,
boolean shouldVibrate, int sensorStrength) {
super(context, lazyDaemon, token, listener, targetUserId, owner, cookie, sensorId,
shouldVibrate, biometricLogger, biometricContext);
super(context, lazyDaemon, token, listener, options.getUserId(),
options.getOpPackageName(), cookie, options.getSensorId(), shouldVibrate,
biometricLogger, biometricContext);
mIsStrongBiometric = isStrongBiometric;
mOperationId = operationId;
mRequireConfirmation = requireConfirmation;

View File

@@ -17,6 +17,7 @@
package com.android.server.biometrics.sensors;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.hardware.biometrics.SensorPropertiesInternal;
import android.util.proto.ProtoOutputStream;
@@ -39,7 +40,7 @@ public interface BiometricServiceProvider<T extends SensorPropertiesInternal> {
List<T> getSensorProperties();
/** Properties for the given sensor id. */
@NonNull
@Nullable
T getSensorProperties(int sensorId);
boolean isHardwareDetected(int sensorId);

View File

@@ -92,7 +92,7 @@ public class BiometricStateCallback<T extends BiometricServiceProvider<P>,
final int previousBiometricState = mBiometricState;
if (client instanceof AuthenticationClient) {
final AuthenticationClient<?> authClient = (AuthenticationClient<?>) client;
final AuthenticationClient<?, ?> authClient = (AuthenticationClient<?, ?>) client;
if (authClient.isKeyguard()) {
mBiometricState = STATE_KEYGUARD_AUTH;
} else if (authClient.isBiometricPrompt()) {

View File

@@ -64,9 +64,10 @@ public final class FaceAuthenticator extends IBiometricAuthenticator.Stub {
long operationId, int userId, IBiometricSensorReceiver sensorReceiver,
String opPackageName, long requestId, int cookie, boolean allowBackgroundAuthentication)
throws RemoteException {
mFaceService.prepareForAuthentication(mSensorId, requireConfirmation, token, operationId,
mFaceService.prepareForAuthentication(requireConfirmation, token, operationId,
sensorReceiver, new FaceAuthenticateOptions.Builder()
.setUserId(userId)
.setSensorId(mSensorId)
.setOpPackageName(opPackageName)
.build(),
requestId, cookie, allowBackgroundAuthentication);

View File

@@ -246,7 +246,6 @@ public class FaceService extends SystemService {
super.authenticate_enforcePermission();
final int userId = options.getUserId();
final String opPackageName = options.getOpPackageName();
final boolean restricted = false; // Face APIs are private
final int statsClient = Utils.isKeyguard(getContext(), opPackageName)
@@ -261,9 +260,11 @@ public class FaceService extends SystemService {
if (provider == null) {
Slog.w(TAG, "Null provider for authenticate");
return -1;
} else {
options.setSensorId(provider.first);
}
return provider.second.scheduleAuthenticate(provider.first, token, operationId,
return provider.second.scheduleAuthenticate(token, operationId,
0 /* cookie */, new ClientMonitorCallbackConverter(receiver), options,
restricted, statsClient, isKeyguard);
}
@@ -286,28 +287,27 @@ public class FaceService extends SystemService {
return -1;
}
return provider.second.scheduleFaceDetect(provider.first, token, options.getUserId(),
new ClientMonitorCallbackConverter(receiver), opPackageName,
return provider.second.scheduleFaceDetect(token,
new ClientMonitorCallbackConverter(receiver), options,
BiometricsProtoEnums.CLIENT_KEYGUARD);
}
@android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override // Binder call
public void prepareForAuthentication(int sensorId, boolean requireConfirmation,
public void prepareForAuthentication(boolean requireConfirmation,
IBinder token, long operationId, IBiometricSensorReceiver sensorReceiver,
FaceAuthenticateOptions options, long requestId, int cookie,
boolean allowBackgroundAuthentication) {
super.prepareForAuthentication_enforcePermission();
final ServiceProvider provider = mRegistry.getProviderForSensor(sensorId);
final ServiceProvider provider = mRegistry.getProviderForSensor(options.getSensorId());
if (provider == null) {
Slog.w(TAG, "Null provider for prepareForAuthentication");
return;
}
final boolean isKeyguardBypassEnabled = false; // only valid for keyguard clients
final boolean restricted = true; // BiometricPrompt is always restricted
provider.scheduleAuthenticate(sensorId, token, operationId, cookie,
provider.scheduleAuthenticate(token, operationId, cookie,
new ClientMonitorCallbackConverter(sensorReceiver), options, requestId,
restricted, BiometricsProtoEnums.CLIENT_BIOMETRIC_PROMPT,
allowBackgroundAuthentication);

View File

@@ -83,18 +83,19 @@ public interface ServiceProvider extends BiometricServiceProvider<FaceSensorProp
void cancelEnrollment(int sensorId, @NonNull IBinder token, long requestId);
long scheduleFaceDetect(int sensorId, @NonNull IBinder token, int userId,
@NonNull ClientMonitorCallbackConverter callback, @NonNull String opPackageName,
long scheduleFaceDetect(@NonNull IBinder token,
@NonNull ClientMonitorCallbackConverter callback,
@NonNull FaceAuthenticateOptions options,
int statsClient);
void cancelFaceDetect(int sensorId, @NonNull IBinder token, long requestId);
long scheduleAuthenticate(int sensorId, @NonNull IBinder token, long operationId,
long scheduleAuthenticate(@NonNull IBinder token, long operationId,
int cookie, @NonNull ClientMonitorCallbackConverter callback,
@NonNull FaceAuthenticateOptions options,
boolean restricted, int statsClient, boolean allowBackgroundAuthentication);
void scheduleAuthenticate(int sensorId, @NonNull IBinder token, long operationId,
void scheduleAuthenticate(@NonNull IBinder token, long operationId,
int cookie, @NonNull ClientMonitorCallbackConverter callback,
@NonNull FaceAuthenticateOptions options, long requestId,
boolean restricted, int statsClient, boolean allowBackgroundAuthentication);

View File

@@ -28,6 +28,7 @@ import android.hardware.biometrics.BiometricFaceConstants;
import android.hardware.biometrics.BiometricManager.Authenticators;
import android.hardware.biometrics.common.ICancellationSignal;
import android.hardware.biometrics.face.IFace;
import android.hardware.face.FaceAuthenticateOptions;
import android.hardware.face.FaceAuthenticationFrame;
import android.hardware.face.FaceManager;
import android.os.IBinder;
@@ -56,7 +57,7 @@ import java.util.function.Supplier;
/**
* Face-specific authentication client for the {@link IFace} AIDL HAL interface.
*/
class FaceAuthenticationClient extends AuthenticationClient<AidlSession>
class FaceAuthenticationClient extends AuthenticationClient<AidlSession, FaceAuthenticateOptions>
implements LockoutConsumer {
private static final String TAG = "FaceAuthenticationClient";
@@ -80,16 +81,16 @@ class FaceAuthenticationClient extends AuthenticationClient<AidlSession>
FaceAuthenticationClient(@NonNull Context context,
@NonNull Supplier<AidlSession> lazyDaemon,
@NonNull IBinder token, long requestId,
@NonNull ClientMonitorCallbackConverter listener, int targetUserId, long operationId,
boolean restricted, String owner, int cookie, boolean requireConfirmation, int sensorId,
@NonNull ClientMonitorCallbackConverter listener, long operationId,
boolean restricted, @NonNull FaceAuthenticateOptions options, int cookie,
boolean requireConfirmation,
@NonNull BiometricLogger logger, @NonNull BiometricContext biometricContext,
boolean isStrongBiometric, @NonNull UsageStats usageStats,
@NonNull LockoutCache lockoutCache, boolean allowBackgroundAuthentication,
@Authenticators.Types int sensorStrength) {
this(context, lazyDaemon, token, requestId, listener, targetUserId, operationId,
restricted, owner, cookie, requireConfirmation, sensorId, logger, biometricContext,
isStrongBiometric, usageStats, lockoutCache /* lockoutCache */,
allowBackgroundAuthentication,
this(context, lazyDaemon, token, requestId, listener, operationId,
restricted, options, cookie, requireConfirmation, logger, biometricContext,
isStrongBiometric, usageStats, lockoutCache, allowBackgroundAuthentication,
context.getSystemService(SensorPrivacyManager.class), sensorStrength);
}
@@ -97,15 +98,16 @@ class FaceAuthenticationClient extends AuthenticationClient<AidlSession>
FaceAuthenticationClient(@NonNull Context context,
@NonNull Supplier<AidlSession> lazyDaemon,
@NonNull IBinder token, long requestId,
@NonNull ClientMonitorCallbackConverter listener, int targetUserId, long operationId,
boolean restricted, String owner, int cookie, boolean requireConfirmation, int sensorId,
@NonNull ClientMonitorCallbackConverter listener, long operationId,
boolean restricted, @NonNull FaceAuthenticateOptions options, int cookie,
boolean requireConfirmation,
@NonNull BiometricLogger logger, @NonNull BiometricContext biometricContext,
boolean isStrongBiometric, @NonNull UsageStats usageStats,
@NonNull LockoutCache lockoutCache, boolean allowBackgroundAuthentication,
SensorPrivacyManager sensorPrivacyManager,
@Authenticators.Types int biometricStrength) {
super(context, lazyDaemon, token, listener, targetUserId, operationId, restricted,
owner, cookie, requireConfirmation, sensorId, logger, biometricContext,
super(context, lazyDaemon, token, listener, operationId, restricted,
options, cookie, requireConfirmation, logger, biometricContext,
isStrongBiometric, null /* taskStackListener */, null /* lockoutCache */,
allowBackgroundAuthentication, false /* shouldVibrate */,
biometricStrength);

View File

@@ -22,6 +22,7 @@ import android.content.Context;
import android.hardware.SensorPrivacyManager;
import android.hardware.biometrics.BiometricConstants;
import android.hardware.biometrics.common.ICancellationSignal;
import android.hardware.face.FaceAuthenticateOptions;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Slog;
@@ -51,11 +52,11 @@ public class FaceDetectClient extends AcquisitionClient<AidlSession> implements
FaceDetectClient(@NonNull Context context, @NonNull Supplier<AidlSession> lazyDaemon,
@NonNull IBinder token, long requestId,
@NonNull ClientMonitorCallbackConverter listener, int userId,
@NonNull String owner, int sensorId,
@NonNull ClientMonitorCallbackConverter listener,
@NonNull FaceAuthenticateOptions options,
@NonNull BiometricLogger logger, @NonNull BiometricContext biometricContext,
boolean isStrongBiometric) {
this(context, lazyDaemon, token, requestId, listener, userId, owner, sensorId,
this(context, lazyDaemon, token, requestId, listener, options,
logger, biometricContext, isStrongBiometric,
context.getSystemService(SensorPrivacyManager.class));
}
@@ -63,11 +64,12 @@ public class FaceDetectClient extends AcquisitionClient<AidlSession> implements
@VisibleForTesting
FaceDetectClient(@NonNull Context context, @NonNull Supplier<AidlSession> lazyDaemon,
@NonNull IBinder token, long requestId,
@NonNull ClientMonitorCallbackConverter listener, int userId,
@NonNull String owner, int sensorId,
@NonNull ClientMonitorCallbackConverter listener,
@NonNull FaceAuthenticateOptions options,
@NonNull BiometricLogger logger, @NonNull BiometricContext biometricContext,
boolean isStrongBiometric, SensorPrivacyManager sensorPrivacyManager) {
super(context, lazyDaemon, token, listener, userId, owner, 0 /* cookie */, sensorId,
super(context, lazyDaemon, token, listener, options.getUserId(),
options.getOpPackageName(), 0 /* cookie */, options.getSensorId(),
true /* shouldVibrate */, logger, biometricContext);
setRequestId(requestId);
mIsStrongBiometric = isStrongBiometric;

View File

@@ -410,16 +410,17 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider {
}
@Override
public long scheduleFaceDetect(int sensorId, @NonNull IBinder token,
int userId, @NonNull ClientMonitorCallbackConverter callback,
@NonNull String opPackageName, int statsClient) {
public long scheduleFaceDetect(@NonNull IBinder token,
@NonNull ClientMonitorCallbackConverter callback,
@NonNull FaceAuthenticateOptions options, int statsClient) {
final long id = mRequestCounter.incrementAndGet();
final int sensorId = options.getSensorId();
mHandler.post(() -> {
final boolean isStrongBiometric = Utils.isStrongBiometric(sensorId);
final FaceDetectClient client = new FaceDetectClient(mContext,
mSensors.get(sensorId).getLazySession(),
token, id, callback, userId, opPackageName, sensorId,
token, id, callback, options,
createLogger(BiometricsProtoEnums.ACTION_AUTHENTICATE, statsClient),
mBiometricContext, isStrongBiometric);
scheduleForSensor(sensorId, client, mBiometricStateCallback);
@@ -435,18 +436,19 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider {
}
@Override
public void scheduleAuthenticate(int sensorId, @NonNull IBinder token, long operationId,
public void scheduleAuthenticate(@NonNull IBinder token, long operationId,
int cookie, @NonNull ClientMonitorCallbackConverter callback,
@NonNull FaceAuthenticateOptions options,
long requestId, boolean restricted, int statsClient,
boolean allowBackgroundAuthentication) {
mHandler.post(() -> {
final int userId = options.getUserId();
final int sensorId = options.getSensorId();
final boolean isStrongBiometric = Utils.isStrongBiometric(sensorId);
final FaceAuthenticationClient client = new FaceAuthenticationClient(
mContext, mSensors.get(sensorId).getLazySession(), token, requestId, callback,
userId, operationId, restricted, options.getOpPackageName(), cookie,
false /* requireConfirmation */, sensorId,
operationId, restricted, options, cookie,
false /* requireConfirmation */,
createLogger(BiometricsProtoEnums.ACTION_AUTHENTICATE, statsClient),
mBiometricContext, isStrongBiometric,
mUsageStats, mSensors.get(sensorId).getLockoutCache(),
@@ -470,13 +472,13 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider {
}
@Override
public long scheduleAuthenticate(int sensorId, @NonNull IBinder token, long operationId,
public long scheduleAuthenticate(@NonNull IBinder token, long operationId,
int cookie, @NonNull ClientMonitorCallbackConverter callback,
@NonNull FaceAuthenticateOptions options, boolean restricted, int statsClient,
boolean allowBackgroundAuthentication) {
final long id = mRequestCounter.incrementAndGet();
scheduleAuthenticate(sensorId, token, operationId, cookie, callback,
scheduleAuthenticate(token, operationId, cookie, callback,
options, id, restricted, statsClient, allowBackgroundAuthentication);
return id;

View File

@@ -651,9 +651,9 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider {
}
@Override
public long scheduleFaceDetect(int sensorId, @NonNull IBinder token,
int userId, @NonNull ClientMonitorCallbackConverter callback,
@NonNull String opPackageName, int statsClient) {
public long scheduleFaceDetect(@NonNull IBinder token,
@NonNull ClientMonitorCallbackConverter callback,
@NonNull FaceAuthenticateOptions options, int statsClient) {
throw new IllegalStateException("Face detect not supported by IBiometricsFace@1.0. Did you"
+ "forget to check the supportsFaceDetection flag?");
}
@@ -665,7 +665,7 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider {
}
@Override
public void scheduleAuthenticate(int sensorId, @NonNull IBinder token, long operationId,
public void scheduleAuthenticate(@NonNull IBinder token, long operationId,
int cookie, @NonNull ClientMonitorCallbackConverter receiver,
@NonNull FaceAuthenticateOptions options, long requestId, boolean restricted,
int statsClient, boolean allowBackgroundAuthentication) {
@@ -675,8 +675,8 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider {
final boolean isStrongBiometric = Utils.isStrongBiometric(mSensorId);
final FaceAuthenticationClient client = new FaceAuthenticationClient(mContext,
mLazyDaemon, token, requestId, receiver, userId, operationId, restricted,
options.getOpPackageName(), cookie, false /* requireConfirmation */, mSensorId,
mLazyDaemon, token, requestId, receiver, operationId, restricted,
options, cookie, false /* requireConfirmation */,
createLogger(BiometricsProtoEnums.ACTION_AUTHENTICATE, statsClient),
mBiometricContext, isStrongBiometric, mLockoutTracker,
mUsageStats, allowBackgroundAuthentication,
@@ -686,13 +686,13 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider {
}
@Override
public long scheduleAuthenticate(int sensorId, @NonNull IBinder token, long operationId,
public long scheduleAuthenticate(@NonNull IBinder token, long operationId,
int cookie, @NonNull ClientMonitorCallbackConverter receiver,
@NonNull FaceAuthenticateOptions options, boolean restricted, int statsClient,
boolean allowBackgroundAuthentication) {
final long id = mRequestCounter.incrementAndGet();
scheduleAuthenticate(sensorId, token, operationId, cookie, receiver,
scheduleAuthenticate(token, operationId, cookie, receiver,
options, id, restricted, statsClient, allowBackgroundAuthentication);
return id;

View File

@@ -25,6 +25,7 @@ import android.hardware.biometrics.BiometricConstants;
import android.hardware.biometrics.BiometricFaceConstants;
import android.hardware.biometrics.BiometricManager.Authenticators;
import android.hardware.biometrics.face.V1_0.IBiometricsFace;
import android.hardware.face.FaceAuthenticateOptions;
import android.hardware.face.FaceManager;
import android.os.IBinder;
import android.os.RemoteException;
@@ -50,7 +51,8 @@ import java.util.function.Supplier;
* Face-specific authentication client supporting the {@link android.hardware.biometrics.face.V1_0}
* HIDL interface.
*/
class FaceAuthenticationClient extends AuthenticationClient<IBiometricsFace> {
class FaceAuthenticationClient
extends AuthenticationClient<IBiometricsFace, FaceAuthenticateOptions> {
private static final String TAG = "FaceAuthenticationClient";
@@ -67,17 +69,18 @@ class FaceAuthenticationClient extends AuthenticationClient<IBiometricsFace> {
FaceAuthenticationClient(@NonNull Context context,
@NonNull Supplier<IBiometricsFace> lazyDaemon,
@NonNull IBinder token, long requestId,
@NonNull ClientMonitorCallbackConverter listener, int targetUserId, long operationId,
boolean restricted, String owner, int cookie, boolean requireConfirmation, int sensorId,
@NonNull ClientMonitorCallbackConverter listener, long operationId,
boolean restricted, @NonNull FaceAuthenticateOptions options, int cookie,
boolean requireConfirmation,
@NonNull BiometricLogger logger, @NonNull BiometricContext biometricContext,
boolean isStrongBiometric, @NonNull LockoutTracker lockoutTracker,
@NonNull UsageStats usageStats, boolean allowBackgroundAuthentication,
@Authenticators.Types int sensorStrength) {
super(context, lazyDaemon, token, listener, targetUserId, operationId, restricted,
owner, cookie, requireConfirmation, sensorId, logger, biometricContext,
super(context, lazyDaemon, token, listener, operationId, restricted,
options, cookie, requireConfirmation, logger, biometricContext,
isStrongBiometric, null /* taskStackListener */,
lockoutTracker, allowBackgroundAuthentication, false /* shouldVibrate */,
sensorStrength);
sensorStrength);
setRequestId(requestId);
mUsageStats = usageStats;
mSensorPrivacyManager = context.getSystemService(SensorPrivacyManager.class);

View File

@@ -23,6 +23,7 @@ import android.hardware.biometrics.IInvalidationCallback;
import android.hardware.biometrics.ITestSession;
import android.hardware.biometrics.ITestSessionCallback;
import android.hardware.biometrics.SensorPropertiesInternal;
import android.hardware.fingerprint.FingerprintAuthenticateOptions;
import android.hardware.fingerprint.IFingerprintService;
import android.os.IBinder;
import android.os.RemoteException;
@@ -63,8 +64,13 @@ public final class FingerprintAuthenticator extends IBiometricAuthenticator.Stub
long operationId, int userId, IBiometricSensorReceiver sensorReceiver,
String opPackageName, long requestId, int cookie, boolean allowBackgroundAuthentication)
throws RemoteException {
mFingerprintService.prepareForAuthentication(mSensorId, token, operationId, userId,
sensorReceiver, opPackageName, requestId, cookie, allowBackgroundAuthentication);
mFingerprintService.prepareForAuthentication(token, operationId, sensorReceiver,
new FingerprintAuthenticateOptions.Builder()
.setSensorId(mSensorId)
.setUserId(userId)
.setOpPackageName(opPackageName)
.build(),
requestId, cookie, allowBackgroundAuthentication);
}
@Override

View File

@@ -119,7 +119,7 @@ public class FingerprintService extends SystemService {
@NonNull
private final Supplier<String[]> mAidlInstanceNameSupplier;
@NonNull
private final Function<String, IFingerprint> mIFingerprintProvider;
private final Function<String, FingerprintProvider> mFingerprintProvider;
@NonNull
private final BiometricStateCallback<ServiceProvider, FingerprintSensorPropertiesInternal>
mBiometricStateCallback;
@@ -307,6 +307,8 @@ public class FingerprintService extends SystemService {
if (provider == null) {
Slog.w(TAG, "Null provider for authenticate");
return -1;
} else {
options.setSensorId(provider.first);
}
final FingerprintSensorPropertiesInternal sensorProps =
@@ -322,8 +324,8 @@ public class FingerprintService extends SystemService {
return -1;
}
}
return provider.second.scheduleAuthenticate(provider.first, token, operationId, userId,
0 /* cookie */, new ClientMonitorCallbackConverter(receiver), opPackageName,
return provider.second.scheduleAuthenticate(token, operationId,
0 /* cookie */, new ClientMonitorCallbackConverter(receiver), options,
restricted, statsClient, isKeyguard);
}
@@ -436,29 +438,32 @@ public class FingerprintService extends SystemService {
if (provider == null) {
Slog.w(TAG, "Null provider for detectFingerprint");
return -1;
} else {
options.setSensorId(provider.first);
}
return provider.second.scheduleFingerDetect(provider.first, token, options.getUserId(),
new ClientMonitorCallbackConverter(receiver), opPackageName,
return provider.second.scheduleFingerDetect(token,
new ClientMonitorCallbackConverter(receiver), options,
BiometricsProtoEnums.CLIENT_KEYGUARD);
}
@android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_BIOMETRIC)
@Override // Binder call
public void prepareForAuthentication(int sensorId, IBinder token, long operationId,
int userId, IBiometricSensorReceiver sensorReceiver, String opPackageName,
public void prepareForAuthentication(IBinder token, long operationId,
IBiometricSensorReceiver sensorReceiver,
@NonNull FingerprintAuthenticateOptions options,
long requestId, int cookie, boolean allowBackgroundAuthentication) {
super.prepareForAuthentication_enforcePermission();
final ServiceProvider provider = mRegistry.getProviderForSensor(sensorId);
final ServiceProvider provider = mRegistry.getProviderForSensor(options.getSensorId());
if (provider == null) {
Slog.w(TAG, "Null provider for prepareForAuthentication");
return;
}
final boolean restricted = true; // BiometricPrompt is always restricted
provider.scheduleAuthenticate(sensorId, token, operationId, userId, cookie,
new ClientMonitorCallbackConverter(sensorReceiver), opPackageName, requestId,
provider.scheduleAuthenticate(token, operationId, cookie,
new ClientMonitorCallbackConverter(sensorReceiver), options, requestId,
restricted, BiometricsProtoEnums.CLIENT_BIOMETRIC_PROMPT,
allowBackgroundAuthentication);
}
@@ -982,8 +987,7 @@ public class FingerprintService extends SystemService {
() -> IBiometricService.Stub.asInterface(
ServiceManager.getService(Context.BIOMETRIC_SERVICE)),
() -> ServiceManager.getDeclaredInstances(IFingerprint.DESCRIPTOR),
(fqName) -> IFingerprint.Stub.asInterface(
Binder.allowBlocking(ServiceManager.waitForDeclaredService(fqName))));
null /* fingerprintProvider */);
}
@VisibleForTesting
@@ -991,16 +995,35 @@ public class FingerprintService extends SystemService {
BiometricContext biometricContext,
Supplier<IBiometricService> biometricServiceSupplier,
Supplier<String[]> aidlInstanceNameSupplier,
Function<String, IFingerprint> fingerprintProvider) {
Function<String, FingerprintProvider> fingerprintProvider) {
super(context);
mBiometricContext = biometricContext;
mAidlInstanceNameSupplier = aidlInstanceNameSupplier;
mIFingerprintProvider = fingerprintProvider;
mAppOps = context.getSystemService(AppOpsManager.class);
mGestureAvailabilityDispatcher = new GestureAvailabilityDispatcher();
mLockoutResetDispatcher = new LockoutResetDispatcher(context);
mLockPatternUtils = new LockPatternUtils(context);
mBiometricStateCallback = new BiometricStateCallback<>(UserManager.get(context));
mFingerprintProvider = fingerprintProvider != null ? fingerprintProvider :
(name) -> {
final String fqName = IFingerprint.DESCRIPTOR + "/" + name;
final IFingerprint fp = IFingerprint.Stub.asInterface(
Binder.allowBlocking(ServiceManager.waitForDeclaredService(fqName)));
if (fp != null) {
try {
return new FingerprintProvider(getContext(),
mBiometricStateCallback, fp.getSensorProps(), name,
mLockoutResetDispatcher, mGestureAvailabilityDispatcher,
mBiometricContext);
} catch (RemoteException e) {
Slog.e(TAG, "Remote exception in getSensorProps: " + fqName);
}
} else {
Slog.e(TAG, "Unable to get declared service: " + fqName);
}
return null;
};
mHandler = new Handler(Looper.getMainLooper());
mRegistry = new FingerprintServiceRegistry(mServiceWrapper, biometricServiceSupplier);
mRegistry.addAllRegisteredCallback(new IFingerprintAuthenticatorsRegisteredCallback.Stub() {
@@ -1044,23 +1067,9 @@ public class FingerprintService extends SystemService {
final List<ServiceProvider> providers = new ArrayList<>();
for (String instance : instances) {
final String fqName = IFingerprint.DESCRIPTOR + "/" + instance;
final IFingerprint fp = mIFingerprintProvider.apply(fqName);
if (fp != null) {
try {
final FingerprintProvider provider = new FingerprintProvider(getContext(),
mBiometricStateCallback, fp.getSensorProps(), instance,
mLockoutResetDispatcher, mGestureAvailabilityDispatcher,
mBiometricContext);
Slog.i(TAG, "Adding AIDL provider: " + fqName);
providers.add(provider);
} catch (RemoteException e) {
Slog.e(TAG, "Remote exception in getSensorProps: " + fqName);
}
} else {
Slog.e(TAG, "Unable to get declared service: " + fqName);
}
final FingerprintProvider provider = mFingerprintProvider.apply(instance);
Slog.i(TAG, "Adding AIDL provider: " + instance);
providers.add(provider);
}
return providers;

View File

@@ -23,6 +23,7 @@ import android.hardware.biometrics.ITestSession;
import android.hardware.biometrics.ITestSessionCallback;
import android.hardware.biometrics.fingerprint.PointerContext;
import android.hardware.fingerprint.Fingerprint;
import android.hardware.fingerprint.FingerprintAuthenticateOptions;
import android.hardware.fingerprint.FingerprintManager;
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
import android.hardware.fingerprint.IFingerprintServiceReceiver;
@@ -78,19 +79,21 @@ public interface ServiceProvider extends
void cancelEnrollment(int sensorId, @NonNull IBinder token, long requestId);
long scheduleFingerDetect(int sensorId, @NonNull IBinder token, int userId,
@NonNull ClientMonitorCallbackConverter callback, @NonNull String opPackageName,
long scheduleFingerDetect(@NonNull IBinder token,
@NonNull ClientMonitorCallbackConverter callback,
@NonNull FingerprintAuthenticateOptions options,
int statsClient);
void scheduleAuthenticate(int sensorId, @NonNull IBinder token, long operationId, int userId,
void scheduleAuthenticate(@NonNull IBinder token, long operationId,
int cookie, @NonNull ClientMonitorCallbackConverter callback,
@NonNull String opPackageName, long requestId, boolean restricted, int statsClient,
@NonNull FingerprintAuthenticateOptions options,
long requestId, boolean restricted, int statsClient,
boolean allowBackgroundAuthentication);
long scheduleAuthenticate(int sensorId, @NonNull IBinder token, long operationId, int userId,
long scheduleAuthenticate(@NonNull IBinder token, long operationId,
int cookie, @NonNull ClientMonitorCallbackConverter callback,
@NonNull String opPackageName, boolean restricted, int statsClient,
boolean allowBackgroundAuthentication);
@NonNull FingerprintAuthenticateOptions options,
boolean restricted, int statsClient, boolean allowBackgroundAuthentication);
void startPreparedClient(int sensorId, int cookie);

View File

@@ -26,6 +26,7 @@ import android.hardware.biometrics.BiometricFingerprintConstants.FingerprintAcqu
import android.hardware.biometrics.BiometricManager.Authenticators;
import android.hardware.biometrics.common.ICancellationSignal;
import android.hardware.biometrics.fingerprint.PointerContext;
import android.hardware.fingerprint.FingerprintAuthenticateOptions;
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
import android.hardware.fingerprint.ISidefpsController;
import android.hardware.fingerprint.IUdfpsOverlay;
@@ -65,7 +66,8 @@ import java.util.function.Supplier;
* Fingerprint-specific authentication client supporting the {@link
* android.hardware.biometrics.fingerprint.IFingerprint} AIDL interface.
*/
class FingerprintAuthenticationClient extends AuthenticationClient<AidlSession>
class FingerprintAuthenticationClient
extends AuthenticationClient<AidlSession, FingerprintAuthenticateOptions>
implements Udfps, LockoutConsumer, PowerPressHandler {
private static final String TAG = "FingerprintAuthenticationClient";
private static final int MESSAGE_AUTH_SUCCESS = 2;
@@ -97,13 +99,11 @@ class FingerprintAuthenticationClient extends AuthenticationClient<AidlSession>
@NonNull IBinder token,
long requestId,
@NonNull ClientMonitorCallbackConverter listener,
int targetUserId,
long operationId,
boolean restricted,
@NonNull String owner,
@NonNull FingerprintAuthenticateOptions options,
int cookie,
boolean requireConfirmation,
int sensorId,
@NonNull BiometricLogger biometricLogger,
@NonNull BiometricContext biometricContext,
boolean isStrongBiometric,
@@ -122,13 +122,11 @@ class FingerprintAuthenticationClient extends AuthenticationClient<AidlSession>
lazyDaemon,
token,
listener,
targetUserId,
operationId,
restricted,
owner,
options,
cookie,
requireConfirmation,
sensorId,
biometricLogger,
biometricContext,
isStrongBiometric,

View File

@@ -21,6 +21,7 @@ import android.annotation.Nullable;
import android.content.Context;
import android.hardware.biometrics.BiometricOverlayConstants;
import android.hardware.biometrics.common.ICancellationSignal;
import android.hardware.fingerprint.FingerprintAuthenticateOptions;
import android.hardware.fingerprint.IUdfpsOverlay;
import android.hardware.fingerprint.IUdfpsOverlayController;
import android.os.IBinder;
@@ -52,13 +53,14 @@ class FingerprintDetectClient extends AcquisitionClient<AidlSession> implements
FingerprintDetectClient(@NonNull Context context, @NonNull Supplier<AidlSession> lazyDaemon,
@NonNull IBinder token, long requestId,
@NonNull ClientMonitorCallbackConverter listener, int userId,
@NonNull String owner, int sensorId,
@NonNull ClientMonitorCallbackConverter listener,
@NonNull FingerprintAuthenticateOptions options,
@NonNull BiometricLogger biometricLogger, @NonNull BiometricContext biometricContext,
@Nullable IUdfpsOverlayController udfpsOverlayController,
@Nullable IUdfpsOverlay udfpsOverlay,
boolean isStrongBiometric) {
super(context, lazyDaemon, token, listener, userId, owner, 0 /* cookie */, sensorId,
super(context, lazyDaemon, token, listener, options.getUserId(),
options.getOpPackageName(), 0 /* cookie */, options.getSensorId(),
true /* shouldVibrate */, biometricLogger, biometricContext);
setRequestId(requestId);
mIsStrongBiometric = isStrongBiometric;

View File

@@ -37,6 +37,7 @@ import android.hardware.biometrics.fingerprint.IFingerprint;
import android.hardware.biometrics.fingerprint.PointerContext;
import android.hardware.biometrics.fingerprint.SensorProps;
import android.hardware.fingerprint.Fingerprint;
import android.hardware.fingerprint.FingerprintAuthenticateOptions;
import android.hardware.fingerprint.FingerprintManager;
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
import android.hardware.fingerprint.IFingerprintServiceReceiver;
@@ -422,15 +423,17 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi
}
@Override
public long scheduleFingerDetect(int sensorId, @NonNull IBinder token, int userId,
@NonNull ClientMonitorCallbackConverter callback, @NonNull String opPackageName,
public long scheduleFingerDetect(@NonNull IBinder token,
@NonNull ClientMonitorCallbackConverter callback,
@NonNull FingerprintAuthenticateOptions options,
int statsClient) {
final long id = mRequestCounter.incrementAndGet();
mHandler.post(() -> {
final int sensorId = options.getSensorId();
final boolean isStrongBiometric = Utils.isStrongBiometric(sensorId);
final FingerprintDetectClient client = new FingerprintDetectClient(mContext,
mSensors.get(sensorId).getLazySession(), token, id, callback, userId,
opPackageName, sensorId,
mSensors.get(sensorId).getLazySession(), token, id, callback,
options,
createLogger(BiometricsProtoEnums.ACTION_AUTHENTICATE, statsClient),
mBiometricContext,
mUdfpsOverlayController, mUdfpsOverlay, isStrongBiometric);
@@ -441,16 +444,19 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi
}
@Override
public 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,
public void scheduleAuthenticate(@NonNull IBinder token, long operationId,
int cookie, @NonNull ClientMonitorCallbackConverter callback,
@NonNull FingerprintAuthenticateOptions options,
long requestId, boolean restricted, int statsClient,
boolean allowBackgroundAuthentication) {
mHandler.post(() -> {
final int userId = options.getUserId();
final int sensorId = options.getSensorId();
final boolean isStrongBiometric = Utils.isStrongBiometric(sensorId);
final FingerprintAuthenticationClient client = new FingerprintAuthenticationClient(
mContext, mSensors.get(sensorId).getLazySession(), token, requestId, callback,
userId, operationId, restricted, opPackageName, cookie,
false /* requireConfirmation */, sensorId,
operationId, restricted, options, cookie,
false /* requireConfirmation */,
createLogger(BiometricsProtoEnums.ACTION_AUTHENTICATE, statsClient),
mBiometricContext, isStrongBiometric,
mTaskStackListener, mSensors.get(sensorId).getLockoutCache(),
@@ -485,14 +491,14 @@ 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,
public long scheduleAuthenticate(@NonNull IBinder token, long operationId,
int cookie, @NonNull ClientMonitorCallbackConverter callback,
@NonNull FingerprintAuthenticateOptions options, boolean restricted, int statsClient,
boolean allowBackgroundAuthentication) {
final long id = mRequestCounter.incrementAndGet();
scheduleAuthenticate(sensorId, token, operationId, userId, cookie, callback,
opPackageName, id, restricted, statsClient, allowBackgroundAuthentication);
scheduleAuthenticate(token, operationId, cookie, callback,
options, id, restricted, statsClient, allowBackgroundAuthentication);
return id;
}

View File

@@ -34,6 +34,7 @@ import android.hardware.biometrics.fingerprint.PointerContext;
import android.hardware.biometrics.fingerprint.V2_1.IBiometricsFingerprint;
import android.hardware.biometrics.fingerprint.V2_2.IBiometricsFingerprintClientCallback;
import android.hardware.fingerprint.Fingerprint;
import android.hardware.fingerprint.FingerprintAuthenticateOptions;
import android.hardware.fingerprint.FingerprintManager;
import android.hardware.fingerprint.FingerprintSensorProperties;
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
@@ -631,17 +632,17 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider
}
@Override
public long scheduleFingerDetect(int sensorId, @NonNull IBinder token, int userId,
@NonNull ClientMonitorCallbackConverter listener, @NonNull String opPackageName,
public long scheduleFingerDetect(@NonNull IBinder token,
@NonNull ClientMonitorCallbackConverter listener,
@NonNull FingerprintAuthenticateOptions options,
int statsClient) {
final long id = mRequestCounter.incrementAndGet();
mHandler.post(() -> {
scheduleUpdateActiveUserWithoutHandler(userId);
scheduleUpdateActiveUserWithoutHandler(options.getUserId());
final boolean isStrongBiometric = Utils.isStrongBiometric(mSensorProperties.sensorId);
final FingerprintDetectClient client = new FingerprintDetectClient(mContext,
mLazyDaemon, token, id, listener, userId, opPackageName,
mSensorProperties.sensorId,
mLazyDaemon, token, id, listener, options,
createLogger(BiometricsProtoEnums.ACTION_AUTHENTICATE, statsClient),
mBiometricContext, mUdfpsOverlayController, mUdfpsOverlay,
isStrongBiometric);
@@ -652,18 +653,18 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider
}
@Override
public void scheduleAuthenticate(int sensorId, @NonNull IBinder token, long operationId,
int userId, int cookie, @NonNull ClientMonitorCallbackConverter listener,
@NonNull String opPackageName, long requestId, boolean restricted, int statsClient,
public void scheduleAuthenticate(@NonNull IBinder token, long operationId,
int cookie, @NonNull ClientMonitorCallbackConverter listener,
@NonNull FingerprintAuthenticateOptions options,
long requestId, boolean restricted, int statsClient,
boolean allowBackgroundAuthentication) {
mHandler.post(() -> {
scheduleUpdateActiveUserWithoutHandler(userId);
scheduleUpdateActiveUserWithoutHandler(options.getUserId());
final boolean isStrongBiometric = Utils.isStrongBiometric(mSensorProperties.sensorId);
final FingerprintAuthenticationClient client = new FingerprintAuthenticationClient(
mContext, mLazyDaemon, token, requestId, listener, userId, operationId,
restricted, opPackageName, cookie, false /* requireConfirmation */,
mSensorProperties.sensorId,
mContext, mLazyDaemon, token, requestId, listener, operationId,
restricted, options, cookie, false /* requireConfirmation */,
createLogger(BiometricsProtoEnums.ACTION_AUTHENTICATE, statsClient),
mBiometricContext, isStrongBiometric,
mTaskStackListener, mLockoutTracker,
@@ -675,14 +676,14 @@ 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,
public long scheduleAuthenticate(@NonNull IBinder token, long operationId,
int cookie, @NonNull ClientMonitorCallbackConverter listener,
@NonNull FingerprintAuthenticateOptions options, boolean restricted, int statsClient,
boolean allowBackgroundAuthentication) {
final long id = mRequestCounter.incrementAndGet();
scheduleAuthenticate(sensorId, token, operationId, userId, cookie, listener,
opPackageName, id, restricted, statsClient, allowBackgroundAuthentication);
scheduleAuthenticate(token, operationId, cookie, listener,
options, id, restricted, statsClient, allowBackgroundAuthentication);
return id;
}

View File

@@ -22,6 +22,7 @@ import android.app.trust.TrustManager;
import android.content.ContentResolver;
import android.content.Context;
import android.hardware.biometrics.fingerprint.PointerContext;
import android.hardware.fingerprint.FingerprintAuthenticateOptions;
import android.hardware.fingerprint.FingerprintManager;
import android.hardware.fingerprint.FingerprintManager.AuthenticationCallback;
import android.hardware.fingerprint.FingerprintManager.AuthenticationResult;
@@ -362,13 +363,16 @@ public class Fingerprint21UdfpsMock extends Fingerprint21 implements TrustManage
// Store the authClient parameters so it can be rescheduled
final IBinder token = client.getToken();
final long operationId = authClient.getOperationId();
final int user = client.getTargetUserId();
final int cookie = client.getCookie();
final ClientMonitorCallbackConverter listener = client.getListener();
final String opPackageName = client.getOwnerString();
final boolean restricted = authClient.isRestricted();
final int statsClient = client.getLogger().getStatsClient();
final boolean isKeyguard = authClient.isKeyguard();
final FingerprintAuthenticateOptions options =
new FingerprintAuthenticateOptions.Builder()
.setUserId(client.getTargetUserId())
.setOpPackageName(client.getOwnerString())
.build();
// Don't actually send cancel() to the HAL, since successful auth already finishes
// HAL authenticate() lifecycle. Just
@@ -376,8 +380,8 @@ public class Fingerprint21UdfpsMock extends Fingerprint21 implements TrustManage
// Schedule this only after we invoke onClientFinished for the previous client, so that
// internal preemption logic is not run.
mFingerprint21.scheduleAuthenticate(mFingerprint21.mSensorProperties.sensorId, token,
operationId, user, cookie, listener, opPackageName, restricted, statsClient,
mFingerprint21.scheduleAuthenticate(token,
operationId, cookie, listener, options, restricted, statsClient,
isKeyguard);
}
}

View File

@@ -26,6 +26,7 @@ import android.hardware.biometrics.BiometricFingerprintConstants;
import android.hardware.biometrics.BiometricManager.Authenticators;
import android.hardware.biometrics.fingerprint.PointerContext;
import android.hardware.biometrics.fingerprint.V2_1.IBiometricsFingerprint;
import android.hardware.fingerprint.FingerprintAuthenticateOptions;
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
import android.hardware.fingerprint.ISidefpsController;
import android.hardware.fingerprint.IUdfpsOverlay;
@@ -57,7 +58,8 @@ import java.util.function.Supplier;
* {@link android.hardware.biometrics.fingerprint.V2_1} and
* {@link android.hardware.biometrics.fingerprint.V2_2} HIDL interfaces.
*/
class FingerprintAuthenticationClient extends AuthenticationClient<IBiometricsFingerprint>
class FingerprintAuthenticationClient
extends AuthenticationClient<IBiometricsFingerprint, FingerprintAuthenticateOptions>
implements Udfps {
private static final String TAG = "Biometrics/FingerprintAuthClient";
@@ -72,9 +74,9 @@ class FingerprintAuthenticationClient extends AuthenticationClient<IBiometricsFi
FingerprintAuthenticationClient(@NonNull Context context,
@NonNull Supplier<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, @NonNull BiometricLogger logger,
@NonNull ClientMonitorCallbackConverter listener, long operationId,
boolean restricted, @NonNull FingerprintAuthenticateOptions options,
int cookie, boolean requireConfirmation, @NonNull BiometricLogger logger,
@NonNull BiometricContext biometricContext, boolean isStrongBiometric,
@NonNull TaskStackListener taskStackListener,
@NonNull LockoutFrameworkImpl lockoutTracker,
@@ -84,8 +86,8 @@ class FingerprintAuthenticationClient extends AuthenticationClient<IBiometricsFi
boolean allowBackgroundAuthentication,
@NonNull FingerprintSensorPropertiesInternal sensorProps,
@Authenticators.Types int sensorStrength) {
super(context, lazyDaemon, token, listener, targetUserId, operationId, restricted,
owner, cookie, requireConfirmation, sensorId, logger, biometricContext,
super(context, lazyDaemon, token, listener, operationId, restricted,
options, cookie, requireConfirmation, logger, biometricContext,
isStrongBiometric, taskStackListener, lockoutTracker, allowBackgroundAuthentication,
false /* shouldVibrate */, sensorStrength);
setRequestId(requestId);

View File

@@ -24,6 +24,7 @@ import android.hardware.biometrics.BiometricFingerprintConstants;
import android.hardware.biometrics.BiometricOverlayConstants;
import android.hardware.biometrics.fingerprint.PointerContext;
import android.hardware.biometrics.fingerprint.V2_1.IBiometricsFingerprint;
import android.hardware.fingerprint.FingerprintAuthenticateOptions;
import android.hardware.fingerprint.IUdfpsOverlay;
import android.hardware.fingerprint.IUdfpsOverlayController;
import android.os.IBinder;
@@ -61,12 +62,13 @@ class FingerprintDetectClient extends AcquisitionClient<IBiometricsFingerprint>
public FingerprintDetectClient(@NonNull Context context,
@NonNull Supplier<IBiometricsFingerprint> lazyDaemon,
@NonNull IBinder token, long requestId,
@NonNull ClientMonitorCallbackConverter listener, int userId, @NonNull String owner,
int sensorId,
@NonNull ClientMonitorCallbackConverter listener,
@NonNull FingerprintAuthenticateOptions options,
@NonNull BiometricLogger biometricLogger, @NonNull BiometricContext biometricContext,
@Nullable IUdfpsOverlayController udfpsOverlayController,
@Nullable IUdfpsOverlay udfpsOverlay, boolean isStrongBiometric) {
super(context, lazyDaemon, token, listener, userId, owner, 0 /* cookie */, sensorId,
super(context, lazyDaemon, token, listener, options.getUserId(),
options.getOpPackageName(), 0 /* cookie */, options.getSensorId(),
true /* shouldVibrate */, biometricLogger, biometricContext);
setRequestId(requestId);
mSensorOverlays = new SensorOverlays(udfpsOverlayController,

View File

@@ -37,6 +37,7 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.Context;
import android.hardware.biometrics.AuthenticateOptions;
import android.hardware.biometrics.BiometricAuthenticator;
import android.hardware.biometrics.BiometricConstants;
import android.hardware.biometrics.IBiometricService;
@@ -681,7 +682,37 @@ public class BiometricSchedulerTest {
TestableLooper.get(this).processAllMessages();
}
private static class TestAuthenticationClient extends AuthenticationClient<Object> {
private static class TestAuthenticateOptions implements AuthenticateOptions {
@Override
public int getUserId() {
return 0;
}
@Override
public int getSensorId() {
return TEST_SENSOR_ID;
}
@Override
public int getDisplayState() {
return DISPLAY_STATE_UNKNOWN;
}
@NonNull
@Override
public String getOpPackageName() {
return "some.test.name";
}
@Nullable
@Override
public String getAttributionTag() {
return null;
}
}
private static class TestAuthenticationClient
extends AuthenticationClient<Object, TestAuthenticateOptions> {
boolean mStartedHal = false;
boolean mStoppedHal = false;
boolean mDestroyed = false;
@@ -700,9 +731,10 @@ public class BiometricSchedulerTest {
@NonNull Supplier<Object> lazyDaemon, @NonNull IBinder token,
@NonNull ClientMonitorCallbackConverter listener, int cookie,
@NonNull BiometricContext biometricContext) {
super(context, lazyDaemon, token, listener, 0 /* targetUserId */, 0 /* operationId */,
false /* restricted */, TAG, cookie, false /* requireConfirmation */,
TEST_SENSOR_ID, mock(BiometricLogger.class), biometricContext,
super(context, lazyDaemon, token, listener, 0 /* operationId */,
false /* restricted */, new TestAuthenticateOptions(), cookie,
false /* requireConfirmation */,
mock(BiometricLogger.class), biometricContext,
true /* isStrongBiometric */, null /* taskStackListener */,
null /* lockoutTracker */, false /* isKeyguard */,
true /* shouldVibrate */,

View File

@@ -33,6 +33,7 @@ import android.content.ComponentName;
import android.hardware.biometrics.common.ICancellationSignal;
import android.hardware.biometrics.face.ISession;
import android.hardware.face.Face;
import android.hardware.face.FaceAuthenticateOptions;
import android.os.IBinder;
import android.os.RemoteException;
import android.platform.test.annotations.Presubmit;
@@ -153,14 +154,18 @@ public class FaceAuthenticationClientTest {
when(mHal.getInterfaceVersion()).thenReturn(version);
final AidlSession aidl = new AidlSession(version, mHal, USER_ID, mHalSessionCallback);
final FaceAuthenticateOptions options = new FaceAuthenticateOptions.Builder()
.setOpPackageName("test-owner")
.setUserId(5)
.setSensorId(9)
.build();
return new FaceAuthenticationClient(mContext, () -> aidl, mToken,
2 /* requestId */, mClientMonitorCallbackConverter, 5 /* targetUserId */, OP_ID,
false /* restricted */, "test-owner", 4 /* cookie */,
false /* requireConfirmation */, 9 /* sensorId */,
2 /* requestId */, mClientMonitorCallbackConverter, OP_ID,
false /* restricted */, options, 4 /* cookie */,
false /* requireConfirmation */,
mBiometricLogger, mBiometricContext, true /* isStrongBiometric */,
mUsageStats, null /* mLockoutCache */, false /* allowBackgroundAuthentication */,
null /* sensorPrivacyManager */,
0 /* biometricStrength */) {
null /* sensorPrivacyManager */, 0 /* biometricStrength */) {
@Override
protected ActivityTaskManager getActivityTaskManager() {
return mActivityTaskManager;

View File

@@ -25,6 +25,7 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.hardware.biometrics.face.ISession;
import android.hardware.face.FaceAuthenticateOptions;
import android.os.IBinder;
import android.os.RemoteException;
import android.platform.test.annotations.Presubmit;
@@ -112,8 +113,13 @@ public class FaceDetectClientTest {
final AidlSession aidl = new AidlSession(version, mHal, USER_ID, mHalSessionCallback);
return new FaceDetectClient(mContext, () -> aidl, mToken,
99 /* requestId */, mClientMonitorCallbackConverter, USER_ID,
"own-it", 5 /* sensorId */, mBiometricLogger, mBiometricContext,
99 /* requestId */, mClientMonitorCallbackConverter,
new FaceAuthenticateOptions.Builder()
.setUserId(USER_ID)
.setSensorId(5)
.setOpPackageName("own-it")
.build(),
mBiometricLogger, mBiometricContext,
false /* isStrongBiometric */, null /* sensorPrivacyManager */);
}
}

View File

@@ -144,7 +144,7 @@ public class BiometricStateCallbackTest {
@Test
public void testAuthentication_enrollmentCallbackNeverNotified() {
AuthenticationClient<?> client = mock(AuthenticationClient.class);
AuthenticationClient<?, ?> client = mock(AuthenticationClient.class);
mCallback.onClientFinished(client, true /* success */);
verify(mBiometricStateListener, never()).onEnrollmentsChanged(anyInt(), anyInt(),
anyBoolean());

View File

@@ -16,24 +16,35 @@
package com.android.server.biometrics.sensors.fingerprint;
import static android.Manifest.permission.USE_BIOMETRIC;
import static android.Manifest.permission.USE_BIOMETRIC_INTERNAL;
import static android.app.AppOpsManager.OP_USE_BIOMETRIC;
import static android.app.AppOpsManager.OP_USE_FINGERPRINT;
import static android.hardware.biometrics.SensorProperties.STRENGTH_STRONG;
import static android.hardware.fingerprint.FingerprintManager.SENSOR_ID_ANY;
import static android.hardware.fingerprint.FingerprintSensorProperties.TYPE_REAR;
import static android.hardware.fingerprint.FingerprintSensorProperties.TYPE_UDFPS_OPTICAL;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.AppOpsManager;
import android.content.pm.PackageManager;
import android.hardware.biometrics.IBiometricService;
import android.hardware.biometrics.common.CommonProps;
import android.hardware.biometrics.common.SensorStrength;
import android.hardware.biometrics.fingerprint.FingerprintSensorType;
import android.hardware.biometrics.fingerprint.IFingerprint;
import android.hardware.biometrics.fingerprint.SensorLocation;
import android.hardware.biometrics.fingerprint.SensorProps;
import android.hardware.fingerprint.FingerprintAuthenticateOptions;
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
import android.hardware.fingerprint.IFingerprintAuthenticatorsRegisteredCallback;
import android.hardware.fingerprint.IFingerprintServiceReceiver;
import android.os.IBinder;
import android.platform.test.annotations.Presubmit;
import android.provider.Settings;
import android.testing.TestableContext;
@@ -44,10 +55,13 @@ import androidx.test.platform.app.InstrumentationRegistry;
import com.android.internal.util.test.FakeSettingsProvider;
import com.android.internal.util.test.FakeSettingsProviderRule;
import com.android.server.biometrics.log.BiometricContext;
import com.android.server.biometrics.sensors.fingerprint.aidl.FingerprintProvider;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
@@ -64,6 +78,8 @@ public class FingerprintServiceTest {
private static final int ID_VIRTUAL = 6;
private static final String NAME_DEFAULT = "default";
private static final String NAME_VIRTUAL = "virtual";
private static final List<FingerprintSensorPropertiesInternal> HIDL_AUTHENTICATORS =
List.of();
@Rule
public final MockitoRule mMockito = MockitoJUnit.rule();
@@ -73,48 +89,81 @@ public class FingerprintServiceTest {
@Rule
public final FakeSettingsProviderRule mSettingsRule = FakeSettingsProvider.rule();
@Mock
private AppOpsManager mAppOpsManager;
@Mock
private BiometricContext mBiometricContext;
@Mock
private IBiometricService mIBiometricService;
@Mock
private IFingerprint mIFingerprintDefault;
private FingerprintProvider mFingerprintDefault;
@Mock
private IFingerprint mIFingerprintVirtual;
private FingerprintProvider mFingerprintVirtual;
@Mock
private IFingerprintServiceReceiver mServiceReceiver;
@Mock
private IBinder mToken;
private final SensorProps mSensorPropsDefault = createProps(ID_DEFAULT,
SensorStrength.STRONG, FingerprintSensorType.POWER_BUTTON);
private final SensorProps mSensorPropsVirtual = createProps(ID_VIRTUAL,
SensorStrength.STRONG, FingerprintSensorType.UNDER_DISPLAY_OPTICAL);
@Captor
private ArgumentCaptor<FingerprintAuthenticateOptions> mAuthenticateOptionsCaptor;
private final FingerprintSensorPropertiesInternal mSensorPropsDefault =
new FingerprintSensorPropertiesInternal(ID_DEFAULT, STRENGTH_STRONG,
2 /* maxEnrollmentsPerUser */,
List.of(),
TYPE_REAR,
false /* resetLockoutRequiresHardwareAuthToken */);
private final FingerprintSensorPropertiesInternal mSensorPropsVirtual =
new FingerprintSensorPropertiesInternal(ID_VIRTUAL, STRENGTH_STRONG,
2 /* maxEnrollmentsPerUser */,
List.of(),
TYPE_UDFPS_OPTICAL,
false /* resetLockoutRequiresHardwareAuthToken */);
private FingerprintService mService;
@Before
public void setup() throws Exception {
when(mIFingerprintDefault.getSensorProps()).thenReturn(
new SensorProps[]{mSensorPropsDefault});
when(mIFingerprintVirtual.getSensorProps()).thenReturn(
new SensorProps[]{mSensorPropsVirtual});
when(mFingerprintDefault.getSensorProperties()).thenReturn(List.of(mSensorPropsDefault));
when(mFingerprintVirtual.getSensorProperties()).thenReturn(List.of(mSensorPropsVirtual));
when(mFingerprintDefault.containsSensor(anyInt()))
.thenAnswer(i -> i.getArguments()[0].equals(ID_DEFAULT));
when(mFingerprintVirtual.containsSensor(anyInt()))
.thenAnswer(i -> i.getArguments()[0].equals(ID_VIRTUAL));
mContext.getTestablePermissions().setPermission(
USE_BIOMETRIC_INTERNAL, PackageManager.PERMISSION_GRANTED);
mContext.addMockSystemService(AppOpsManager.class, mAppOpsManager);
for (int permission : List.of(OP_USE_BIOMETRIC, OP_USE_FINGERPRINT)) {
when(mAppOpsManager.noteOp(eq(permission), anyInt(), any(), any(), any()))
.thenReturn(AppOpsManager.MODE_ALLOWED);
}
for (String permission : List.of(USE_BIOMETRIC, USE_BIOMETRIC_INTERNAL)) {
mContext.getTestablePermissions().setPermission(
permission, PackageManager.PERMISSION_GRANTED);
}
}
private void initServiceWith(String... aidlInstances) {
mService = new FingerprintService(mContext, mBiometricContext,
() -> mIBiometricService,
() -> aidlInstances,
(fqName) -> {
if (fqName.endsWith(NAME_DEFAULT)) return mIFingerprintDefault;
if (fqName.endsWith(NAME_VIRTUAL)) return mIFingerprintVirtual;
(name) -> {
if (NAME_DEFAULT.equals(name)) return mFingerprintDefault;
if (NAME_VIRTUAL.equals(name)) return mFingerprintVirtual;
return null;
});
}
private void initServiceWithAndWait(String... aidlInstances) throws Exception {
initServiceWith(aidlInstances);
mService.mServiceWrapper.registerAuthenticators(HIDL_AUTHENTICATORS);
waitForRegistration();
}
@Test
public void registerAuthenticators_defaultOnly() throws Exception {
initServiceWith(NAME_DEFAULT, NAME_VIRTUAL);
mService.mServiceWrapper.registerAuthenticators(List.of());
mService.mServiceWrapper.registerAuthenticators(HIDL_AUTHENTICATORS);
waitForRegistration();
verify(mIBiometricService).registerAuthenticator(eq(ID_DEFAULT), anyInt(), anyInt(), any());
@@ -126,7 +175,7 @@ public class FingerprintServiceTest {
Settings.Secure.putInt(mSettingsRule.mockContentResolver(mContext),
Settings.Secure.BIOMETRIC_VIRTUAL_ENABLED, 1);
mService.mServiceWrapper.registerAuthenticators(List.of());
mService.mServiceWrapper.registerAuthenticators(HIDL_AUTHENTICATORS);
waitForRegistration();
verify(mIBiometricService).registerAuthenticator(eq(ID_VIRTUAL), anyInt(), anyInt(), any());
@@ -136,7 +185,7 @@ public class FingerprintServiceTest {
public void registerAuthenticators_virtualAlwaysWhenNoOther() throws Exception {
initServiceWith(NAME_VIRTUAL);
mService.mServiceWrapper.registerAuthenticators(List.of());
mService.mServiceWrapper.registerAuthenticators(HIDL_AUTHENTICATORS);
waitForRegistration();
verify(mIBiometricService).registerAuthenticator(eq(ID_VIRTUAL), anyInt(), anyInt(), any());
@@ -155,13 +204,47 @@ public class FingerprintServiceTest {
latch.await(5, TimeUnit.SECONDS);
}
private static SensorProps createProps(int id, byte strength, byte type) {
final SensorProps props = new SensorProps();
props.commonProps = new CommonProps();
props.commonProps.sensorId = id;
props.commonProps.sensorStrength = strength;
props.sensorType = type;
props.sensorLocations = new SensorLocation[]{new SensorLocation()};
return props;
@Test
public void authenticateWithDefaultSensorId() throws Exception {
initServiceWithAndWait(NAME_DEFAULT, NAME_VIRTUAL);
final long operationId = 2;
mService.mServiceWrapper.authenticate(mToken, operationId, mServiceReceiver,
new FingerprintAuthenticateOptions.Builder()
.setSensorId(SENSOR_ID_ANY)
.build());
final FingerprintAuthenticateOptions options =
verifyAuthenticateWithNewRequestId(mFingerprintDefault, operationId);
assertThat(options.getSensorId()).isEqualTo(ID_DEFAULT);
verifyNoAuthenticate(mFingerprintVirtual);
}
private FingerprintAuthenticateOptions verifyAuthenticateWithNewRequestId(
FingerprintProvider provider, long operationId) {
return verifyAuthenticateWithNewRequestId(
provider, operationId, true /* shouldSchedule */);
}
private void verifyNoAuthenticate(FingerprintProvider provider) {
verifyAuthenticateWithNewRequestId(
provider, 0 /* operationId */, false /* shouldSchedule */);
}
private FingerprintAuthenticateOptions verifyAuthenticateWithNewRequestId(
FingerprintProvider provider, long operationId, boolean shouldSchedule) {
verify(provider, shouldSchedule ? times(1) : never())
.scheduleAuthenticate(eq(mToken), eq(operationId), anyInt(), any(),
mAuthenticateOptionsCaptor.capture(), anyBoolean(), anyInt(),
anyBoolean());
verify(provider, never()).scheduleAuthenticate(eq(mToken), anyLong(),
anyInt(), any(), mAuthenticateOptionsCaptor.capture(), anyLong(),
anyBoolean(), anyInt(), anyBoolean());
if (shouldSchedule) {
return mAuthenticateOptionsCaptor.getValue();
}
return null;
}
}

View File

@@ -41,6 +41,7 @@ import android.hardware.biometrics.common.OperationContext;
import android.hardware.biometrics.fingerprint.ISession;
import android.hardware.biometrics.fingerprint.PointerContext;
import android.hardware.fingerprint.Fingerprint;
import android.hardware.fingerprint.FingerprintAuthenticateOptions;
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
import android.hardware.fingerprint.ISidefpsController;
import android.hardware.fingerprint.IUdfpsOverlayController;
@@ -414,11 +415,16 @@ public class FingerprintAuthenticationClientTest {
when(mHal.getInterfaceVersion()).thenReturn(version);
final AidlSession aidl = new AidlSession(version, mHal, USER_ID, mHalSessionCallback);
final FingerprintAuthenticateOptions options = new FingerprintAuthenticateOptions.Builder()
.setOpPackageName("test-owner")
.setUserId(5)
.setSensorId(9)
.build();
return new FingerprintAuthenticationClient(mContext, () -> aidl, mToken,
REQUEST_ID, mClientMonitorCallbackConverter, 5 /* targetUserId */, OP_ID,
false /* restricted */, "test-owner", 4 /* cookie */,
REQUEST_ID, mClientMonitorCallbackConverter, OP_ID,
false /* restricted */, options, 4 /* cookie */,
false /* requireConfirmation */,
9 /* sensorId */, mBiometricLogger, mBiometricContext,
mBiometricLogger, mBiometricContext,
true /* isStrongBiometric */,
null /* taskStackListener */, null /* lockoutCache */,
mUdfpsOverlayController, mSideFpsController, null, allowBackgroundAuthentication,

View File

@@ -25,6 +25,7 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.hardware.biometrics.fingerprint.ISession;
import android.hardware.fingerprint.FingerprintAuthenticateOptions;
import android.hardware.fingerprint.IUdfpsOverlayController;
import android.os.IBinder;
import android.os.RemoteException;
@@ -117,8 +118,13 @@ public class FingerprintDetectClientTest {
final AidlSession aidl = new AidlSession(version, mHal, USER_ID, mHalSessionCallback);
return new FingerprintDetectClient(mContext, () -> aidl, mToken,
6 /* requestId */, mClientMonitorCallbackConverter, 2 /* userId */,
"a-test", 1 /* sensorId */, mBiometricLogger, mBiometricContext,
6 /* requestId */, mClientMonitorCallbackConverter,
new FingerprintAuthenticateOptions.Builder()
.setUserId(2)
.setSensorId(1)
.setOpPackageName("a-test")
.build(),
mBiometricLogger, mBiometricContext,
mUdfpsOverlayController, null, true /* isStrongBiometric */);
}
}