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. */ /** The sensor id for this operation. */
private final int mSensorId; private int mSensorId;
private static int defaultSensorId() { private static int defaultSensorId() {
return -1; return -1;
} }
@@ -298,6 +298,15 @@ public class FaceAuthenticateOptions implements AuthenticateOptions, Parcelable
return mAttributionTag; 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 * The package name for that operation that should be used for
* {@link android.app.AppOpsManager} verification. * {@link android.app.AppOpsManager} verification.
@@ -610,10 +619,10 @@ public class FaceAuthenticateOptions implements AuthenticateOptions, Parcelable
} }
@DataClass.Generated( @DataClass.Generated(
time = 1676508211385L, time = 1677119626034L,
codegenVersion = "1.0.23", codegenVersion = "1.0.23",
sourceFile = "frameworks/base/core/java/android/hardware/face/FaceAuthenticateOptions.java", 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 @Deprecated
private void __metadata() {} private void __metadata() {}

View File

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

View File

@@ -46,7 +46,7 @@ public final class FingerprintAuthenticateOptions implements AuthenticateOptions
} }
/** The sensor id for this operation. */ /** The sensor id for this operation. */
private final int mSensorId; private int mSensorId;
private static int defaultSensorId() { private static int defaultSensorId() {
return SENSOR_ID_ANY; return SENSOR_ID_ANY;
} }
@@ -175,6 +175,15 @@ public final class FingerprintAuthenticateOptions implements AuthenticateOptions
return mAttributionTag; 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 * The package name for that operation that should be used for
* {@link android.app.AppOpsManager} verification. * {@link android.app.AppOpsManager} verification.
@@ -433,10 +442,10 @@ public final class FingerprintAuthenticateOptions implements AuthenticateOptions
} }
@DataClass.Generated( @DataClass.Generated(
time = 1676508212083L, time = 1677119626721L,
codegenVersion = "1.0.23", codegenVersion = "1.0.23",
sourceFile = "frameworks/base/core/java/android/hardware/fingerprint/FingerprintAuthenticateOptions.java", 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 @Deprecated
private void __metadata() {} private void __metadata() {}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -25,6 +25,7 @@ import android.hardware.biometrics.BiometricConstants;
import android.hardware.biometrics.BiometricFaceConstants; import android.hardware.biometrics.BiometricFaceConstants;
import android.hardware.biometrics.BiometricManager.Authenticators; import android.hardware.biometrics.BiometricManager.Authenticators;
import android.hardware.biometrics.face.V1_0.IBiometricsFace; import android.hardware.biometrics.face.V1_0.IBiometricsFace;
import android.hardware.face.FaceAuthenticateOptions;
import android.hardware.face.FaceManager; import android.hardware.face.FaceManager;
import android.os.IBinder; import android.os.IBinder;
import android.os.RemoteException; 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} * Face-specific authentication client supporting the {@link android.hardware.biometrics.face.V1_0}
* HIDL interface. * HIDL interface.
*/ */
class FaceAuthenticationClient extends AuthenticationClient<IBiometricsFace> { class FaceAuthenticationClient
extends AuthenticationClient<IBiometricsFace, FaceAuthenticateOptions> {
private static final String TAG = "FaceAuthenticationClient"; private static final String TAG = "FaceAuthenticationClient";
@@ -67,17 +69,18 @@ class FaceAuthenticationClient extends AuthenticationClient<IBiometricsFace> {
FaceAuthenticationClient(@NonNull Context context, FaceAuthenticationClient(@NonNull Context context,
@NonNull Supplier<IBiometricsFace> lazyDaemon, @NonNull Supplier<IBiometricsFace> lazyDaemon,
@NonNull IBinder token, long requestId, @NonNull IBinder token, long requestId,
@NonNull ClientMonitorCallbackConverter listener, int targetUserId, long operationId, @NonNull ClientMonitorCallbackConverter listener, long operationId,
boolean restricted, String owner, int cookie, boolean requireConfirmation, int sensorId, boolean restricted, @NonNull FaceAuthenticateOptions options, int cookie,
boolean requireConfirmation,
@NonNull BiometricLogger logger, @NonNull BiometricContext biometricContext, @NonNull BiometricLogger logger, @NonNull BiometricContext biometricContext,
boolean isStrongBiometric, @NonNull LockoutTracker lockoutTracker, boolean isStrongBiometric, @NonNull LockoutTracker lockoutTracker,
@NonNull UsageStats usageStats, boolean allowBackgroundAuthentication, @NonNull UsageStats usageStats, boolean allowBackgroundAuthentication,
@Authenticators.Types int sensorStrength) { @Authenticators.Types int sensorStrength) {
super(context, lazyDaemon, token, listener, targetUserId, operationId, restricted, super(context, lazyDaemon, token, listener, operationId, restricted,
owner, cookie, requireConfirmation, sensorId, logger, biometricContext, options, cookie, requireConfirmation, logger, biometricContext,
isStrongBiometric, null /* taskStackListener */, isStrongBiometric, null /* taskStackListener */,
lockoutTracker, allowBackgroundAuthentication, false /* shouldVibrate */, lockoutTracker, allowBackgroundAuthentication, false /* shouldVibrate */,
sensorStrength); sensorStrength);
setRequestId(requestId); setRequestId(requestId);
mUsageStats = usageStats; mUsageStats = usageStats;
mSensorPrivacyManager = context.getSystemService(SensorPrivacyManager.class); 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.ITestSession;
import android.hardware.biometrics.ITestSessionCallback; import android.hardware.biometrics.ITestSessionCallback;
import android.hardware.biometrics.SensorPropertiesInternal; import android.hardware.biometrics.SensorPropertiesInternal;
import android.hardware.fingerprint.FingerprintAuthenticateOptions;
import android.hardware.fingerprint.IFingerprintService; import android.hardware.fingerprint.IFingerprintService;
import android.os.IBinder; import android.os.IBinder;
import android.os.RemoteException; import android.os.RemoteException;
@@ -63,8 +64,13 @@ public final class FingerprintAuthenticator extends IBiometricAuthenticator.Stub
long operationId, int userId, IBiometricSensorReceiver sensorReceiver, long operationId, int userId, IBiometricSensorReceiver sensorReceiver,
String opPackageName, long requestId, int cookie, boolean allowBackgroundAuthentication) String opPackageName, long requestId, int cookie, boolean allowBackgroundAuthentication)
throws RemoteException { throws RemoteException {
mFingerprintService.prepareForAuthentication(mSensorId, token, operationId, userId, mFingerprintService.prepareForAuthentication(token, operationId, sensorReceiver,
sensorReceiver, opPackageName, requestId, cookie, allowBackgroundAuthentication); new FingerprintAuthenticateOptions.Builder()
.setSensorId(mSensorId)
.setUserId(userId)
.setOpPackageName(opPackageName)
.build(),
requestId, cookie, allowBackgroundAuthentication);
} }
@Override @Override

View File

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

View File

@@ -23,6 +23,7 @@ import android.hardware.biometrics.ITestSession;
import android.hardware.biometrics.ITestSessionCallback; import android.hardware.biometrics.ITestSessionCallback;
import android.hardware.biometrics.fingerprint.PointerContext; import android.hardware.biometrics.fingerprint.PointerContext;
import android.hardware.fingerprint.Fingerprint; import android.hardware.fingerprint.Fingerprint;
import android.hardware.fingerprint.FingerprintAuthenticateOptions;
import android.hardware.fingerprint.FingerprintManager; import android.hardware.fingerprint.FingerprintManager;
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal; import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
import android.hardware.fingerprint.IFingerprintServiceReceiver; import android.hardware.fingerprint.IFingerprintServiceReceiver;
@@ -78,19 +79,21 @@ public interface ServiceProvider extends
void cancelEnrollment(int sensorId, @NonNull IBinder token, long requestId); void cancelEnrollment(int sensorId, @NonNull IBinder token, long requestId);
long scheduleFingerDetect(int sensorId, @NonNull IBinder token, int userId, long scheduleFingerDetect(@NonNull IBinder token,
@NonNull ClientMonitorCallbackConverter callback, @NonNull String opPackageName, @NonNull ClientMonitorCallbackConverter callback,
@NonNull FingerprintAuthenticateOptions options,
int statsClient); 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, 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); 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, int cookie, @NonNull ClientMonitorCallbackConverter callback,
@NonNull String opPackageName, boolean restricted, int statsClient, @NonNull FingerprintAuthenticateOptions options,
boolean allowBackgroundAuthentication); boolean restricted, int statsClient, boolean allowBackgroundAuthentication);
void startPreparedClient(int sensorId, int cookie); 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.BiometricManager.Authenticators;
import android.hardware.biometrics.common.ICancellationSignal; import android.hardware.biometrics.common.ICancellationSignal;
import android.hardware.biometrics.fingerprint.PointerContext; import android.hardware.biometrics.fingerprint.PointerContext;
import android.hardware.fingerprint.FingerprintAuthenticateOptions;
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal; import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
import android.hardware.fingerprint.ISidefpsController; import android.hardware.fingerprint.ISidefpsController;
import android.hardware.fingerprint.IUdfpsOverlay; import android.hardware.fingerprint.IUdfpsOverlay;
@@ -65,7 +66,8 @@ import java.util.function.Supplier;
* Fingerprint-specific authentication client supporting the {@link * Fingerprint-specific authentication client supporting the {@link
* android.hardware.biometrics.fingerprint.IFingerprint} AIDL interface. * android.hardware.biometrics.fingerprint.IFingerprint} AIDL interface.
*/ */
class FingerprintAuthenticationClient extends AuthenticationClient<AidlSession> class FingerprintAuthenticationClient
extends AuthenticationClient<AidlSession, FingerprintAuthenticateOptions>
implements Udfps, LockoutConsumer, PowerPressHandler { implements Udfps, LockoutConsumer, PowerPressHandler {
private static final String TAG = "FingerprintAuthenticationClient"; private static final String TAG = "FingerprintAuthenticationClient";
private static final int MESSAGE_AUTH_SUCCESS = 2; private static final int MESSAGE_AUTH_SUCCESS = 2;
@@ -97,13 +99,11 @@ class FingerprintAuthenticationClient extends AuthenticationClient<AidlSession>
@NonNull IBinder token, @NonNull IBinder token,
long requestId, long requestId,
@NonNull ClientMonitorCallbackConverter listener, @NonNull ClientMonitorCallbackConverter listener,
int targetUserId,
long operationId, long operationId,
boolean restricted, boolean restricted,
@NonNull String owner, @NonNull FingerprintAuthenticateOptions options,
int cookie, int cookie,
boolean requireConfirmation, boolean requireConfirmation,
int sensorId,
@NonNull BiometricLogger biometricLogger, @NonNull BiometricLogger biometricLogger,
@NonNull BiometricContext biometricContext, @NonNull BiometricContext biometricContext,
boolean isStrongBiometric, boolean isStrongBiometric,
@@ -122,13 +122,11 @@ class FingerprintAuthenticationClient extends AuthenticationClient<AidlSession>
lazyDaemon, lazyDaemon,
token, token,
listener, listener,
targetUserId,
operationId, operationId,
restricted, restricted,
owner, options,
cookie, cookie,
requireConfirmation, requireConfirmation,
sensorId,
biometricLogger, biometricLogger,
biometricContext, biometricContext,
isStrongBiometric, isStrongBiometric,

View File

@@ -21,6 +21,7 @@ import android.annotation.Nullable;
import android.content.Context; import android.content.Context;
import android.hardware.biometrics.BiometricOverlayConstants; import android.hardware.biometrics.BiometricOverlayConstants;
import android.hardware.biometrics.common.ICancellationSignal; import android.hardware.biometrics.common.ICancellationSignal;
import android.hardware.fingerprint.FingerprintAuthenticateOptions;
import android.hardware.fingerprint.IUdfpsOverlay; import android.hardware.fingerprint.IUdfpsOverlay;
import android.hardware.fingerprint.IUdfpsOverlayController; import android.hardware.fingerprint.IUdfpsOverlayController;
import android.os.IBinder; import android.os.IBinder;
@@ -52,13 +53,14 @@ class FingerprintDetectClient extends AcquisitionClient<AidlSession> implements
FingerprintDetectClient(@NonNull Context context, @NonNull Supplier<AidlSession> lazyDaemon, FingerprintDetectClient(@NonNull Context context, @NonNull Supplier<AidlSession> lazyDaemon,
@NonNull IBinder token, long requestId, @NonNull IBinder token, long requestId,
@NonNull ClientMonitorCallbackConverter listener, int userId, @NonNull ClientMonitorCallbackConverter listener,
@NonNull String owner, int sensorId, @NonNull FingerprintAuthenticateOptions options,
@NonNull BiometricLogger biometricLogger, @NonNull BiometricContext biometricContext, @NonNull BiometricLogger biometricLogger, @NonNull BiometricContext biometricContext,
@Nullable IUdfpsOverlayController udfpsOverlayController, @Nullable IUdfpsOverlayController udfpsOverlayController,
@Nullable IUdfpsOverlay udfpsOverlay, @Nullable IUdfpsOverlay udfpsOverlay,
boolean isStrongBiometric) { 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); true /* shouldVibrate */, biometricLogger, biometricContext);
setRequestId(requestId); setRequestId(requestId);
mIsStrongBiometric = isStrongBiometric; 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.PointerContext;
import android.hardware.biometrics.fingerprint.SensorProps; import android.hardware.biometrics.fingerprint.SensorProps;
import android.hardware.fingerprint.Fingerprint; import android.hardware.fingerprint.Fingerprint;
import android.hardware.fingerprint.FingerprintAuthenticateOptions;
import android.hardware.fingerprint.FingerprintManager; import android.hardware.fingerprint.FingerprintManager;
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal; import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
import android.hardware.fingerprint.IFingerprintServiceReceiver; import android.hardware.fingerprint.IFingerprintServiceReceiver;
@@ -422,15 +423,17 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi
} }
@Override @Override
public long scheduleFingerDetect(int sensorId, @NonNull IBinder token, int userId, public long scheduleFingerDetect(@NonNull IBinder token,
@NonNull ClientMonitorCallbackConverter callback, @NonNull String opPackageName, @NonNull ClientMonitorCallbackConverter callback,
@NonNull FingerprintAuthenticateOptions options,
int statsClient) { int statsClient) {
final long id = mRequestCounter.incrementAndGet(); final long id = mRequestCounter.incrementAndGet();
mHandler.post(() -> { mHandler.post(() -> {
final int sensorId = options.getSensorId();
final boolean isStrongBiometric = Utils.isStrongBiometric(sensorId); final boolean isStrongBiometric = Utils.isStrongBiometric(sensorId);
final FingerprintDetectClient client = new FingerprintDetectClient(mContext, final FingerprintDetectClient client = new FingerprintDetectClient(mContext,
mSensors.get(sensorId).getLazySession(), token, id, callback, userId, mSensors.get(sensorId).getLazySession(), token, id, callback,
opPackageName, sensorId, options,
createLogger(BiometricsProtoEnums.ACTION_AUTHENTICATE, statsClient), createLogger(BiometricsProtoEnums.ACTION_AUTHENTICATE, statsClient),
mBiometricContext, mBiometricContext,
mUdfpsOverlayController, mUdfpsOverlay, isStrongBiometric); mUdfpsOverlayController, mUdfpsOverlay, isStrongBiometric);
@@ -441,16 +444,19 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi
} }
@Override @Override
public void scheduleAuthenticate(int sensorId, @NonNull IBinder token, long operationId, public void scheduleAuthenticate(@NonNull IBinder token, long operationId,
int userId, int cookie, @NonNull ClientMonitorCallbackConverter callback, 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) { boolean allowBackgroundAuthentication) {
mHandler.post(() -> { mHandler.post(() -> {
final int userId = options.getUserId();
final int sensorId = options.getSensorId();
final boolean isStrongBiometric = Utils.isStrongBiometric(sensorId); final boolean isStrongBiometric = Utils.isStrongBiometric(sensorId);
final FingerprintAuthenticationClient client = new FingerprintAuthenticationClient( final FingerprintAuthenticationClient client = new FingerprintAuthenticationClient(
mContext, mSensors.get(sensorId).getLazySession(), token, requestId, callback, mContext, mSensors.get(sensorId).getLazySession(), token, requestId, callback,
userId, operationId, restricted, opPackageName, cookie, operationId, restricted, options, cookie,
false /* requireConfirmation */, sensorId, false /* requireConfirmation */,
createLogger(BiometricsProtoEnums.ACTION_AUTHENTICATE, statsClient), createLogger(BiometricsProtoEnums.ACTION_AUTHENTICATE, statsClient),
mBiometricContext, isStrongBiometric, mBiometricContext, isStrongBiometric,
mTaskStackListener, mSensors.get(sensorId).getLockoutCache(), mTaskStackListener, mSensors.get(sensorId).getLockoutCache(),
@@ -485,14 +491,14 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi
} }
@Override @Override
public long scheduleAuthenticate(int sensorId, @NonNull IBinder token, long operationId, public long scheduleAuthenticate(@NonNull IBinder token, long operationId,
int userId, int cookie, @NonNull ClientMonitorCallbackConverter callback, int cookie, @NonNull ClientMonitorCallbackConverter callback,
@NonNull String opPackageName, boolean restricted, int statsClient, @NonNull FingerprintAuthenticateOptions options, boolean restricted, int statsClient,
boolean allowBackgroundAuthentication) { boolean allowBackgroundAuthentication) {
final long id = mRequestCounter.incrementAndGet(); final long id = mRequestCounter.incrementAndGet();
scheduleAuthenticate(sensorId, token, operationId, userId, cookie, callback, scheduleAuthenticate(token, operationId, cookie, callback,
opPackageName, id, restricted, statsClient, allowBackgroundAuthentication); options, id, restricted, statsClient, allowBackgroundAuthentication);
return id; 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_1.IBiometricsFingerprint;
import android.hardware.biometrics.fingerprint.V2_2.IBiometricsFingerprintClientCallback; import android.hardware.biometrics.fingerprint.V2_2.IBiometricsFingerprintClientCallback;
import android.hardware.fingerprint.Fingerprint; import android.hardware.fingerprint.Fingerprint;
import android.hardware.fingerprint.FingerprintAuthenticateOptions;
import android.hardware.fingerprint.FingerprintManager; import android.hardware.fingerprint.FingerprintManager;
import android.hardware.fingerprint.FingerprintSensorProperties; import android.hardware.fingerprint.FingerprintSensorProperties;
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal; import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
@@ -631,17 +632,17 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider
} }
@Override @Override
public long scheduleFingerDetect(int sensorId, @NonNull IBinder token, int userId, public long scheduleFingerDetect(@NonNull IBinder token,
@NonNull ClientMonitorCallbackConverter listener, @NonNull String opPackageName, @NonNull ClientMonitorCallbackConverter listener,
@NonNull FingerprintAuthenticateOptions options,
int statsClient) { int statsClient) {
final long id = mRequestCounter.incrementAndGet(); final long id = mRequestCounter.incrementAndGet();
mHandler.post(() -> { mHandler.post(() -> {
scheduleUpdateActiveUserWithoutHandler(userId); scheduleUpdateActiveUserWithoutHandler(options.getUserId());
final boolean isStrongBiometric = Utils.isStrongBiometric(mSensorProperties.sensorId); final boolean isStrongBiometric = Utils.isStrongBiometric(mSensorProperties.sensorId);
final FingerprintDetectClient client = new FingerprintDetectClient(mContext, final FingerprintDetectClient client = new FingerprintDetectClient(mContext,
mLazyDaemon, token, id, listener, userId, opPackageName, mLazyDaemon, token, id, listener, options,
mSensorProperties.sensorId,
createLogger(BiometricsProtoEnums.ACTION_AUTHENTICATE, statsClient), createLogger(BiometricsProtoEnums.ACTION_AUTHENTICATE, statsClient),
mBiometricContext, mUdfpsOverlayController, mUdfpsOverlay, mBiometricContext, mUdfpsOverlayController, mUdfpsOverlay,
isStrongBiometric); isStrongBiometric);
@@ -652,18 +653,18 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider
} }
@Override @Override
public void scheduleAuthenticate(int sensorId, @NonNull IBinder token, long operationId, public void scheduleAuthenticate(@NonNull IBinder token, long operationId,
int userId, int cookie, @NonNull ClientMonitorCallbackConverter listener, int cookie, @NonNull ClientMonitorCallbackConverter listener,
@NonNull String opPackageName, long requestId, boolean restricted, int statsClient, @NonNull FingerprintAuthenticateOptions options,
long requestId, boolean restricted, int statsClient,
boolean allowBackgroundAuthentication) { boolean allowBackgroundAuthentication) {
mHandler.post(() -> { mHandler.post(() -> {
scheduleUpdateActiveUserWithoutHandler(userId); scheduleUpdateActiveUserWithoutHandler(options.getUserId());
final boolean isStrongBiometric = Utils.isStrongBiometric(mSensorProperties.sensorId); final boolean isStrongBiometric = Utils.isStrongBiometric(mSensorProperties.sensorId);
final FingerprintAuthenticationClient client = new FingerprintAuthenticationClient( final FingerprintAuthenticationClient client = new FingerprintAuthenticationClient(
mContext, mLazyDaemon, token, requestId, listener, userId, operationId, mContext, mLazyDaemon, token, requestId, listener, operationId,
restricted, opPackageName, cookie, false /* requireConfirmation */, restricted, options, cookie, false /* requireConfirmation */,
mSensorProperties.sensorId,
createLogger(BiometricsProtoEnums.ACTION_AUTHENTICATE, statsClient), createLogger(BiometricsProtoEnums.ACTION_AUTHENTICATE, statsClient),
mBiometricContext, isStrongBiometric, mBiometricContext, isStrongBiometric,
mTaskStackListener, mLockoutTracker, mTaskStackListener, mLockoutTracker,
@@ -675,14 +676,14 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider
} }
@Override @Override
public long scheduleAuthenticate(int sensorId, @NonNull IBinder token, long operationId, public long scheduleAuthenticate(@NonNull IBinder token, long operationId,
int userId, int cookie, @NonNull ClientMonitorCallbackConverter listener, int cookie, @NonNull ClientMonitorCallbackConverter listener,
@NonNull String opPackageName, boolean restricted, int statsClient, @NonNull FingerprintAuthenticateOptions options, boolean restricted, int statsClient,
boolean allowBackgroundAuthentication) { boolean allowBackgroundAuthentication) {
final long id = mRequestCounter.incrementAndGet(); final long id = mRequestCounter.incrementAndGet();
scheduleAuthenticate(sensorId, token, operationId, userId, cookie, listener, scheduleAuthenticate(token, operationId, cookie, listener,
opPackageName, id, restricted, statsClient, allowBackgroundAuthentication); options, id, restricted, statsClient, allowBackgroundAuthentication);
return id; return id;
} }

View File

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

View File

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

View File

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

View File

@@ -37,6 +37,7 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import android.content.Context; import android.content.Context;
import android.hardware.biometrics.AuthenticateOptions;
import android.hardware.biometrics.BiometricAuthenticator; import android.hardware.biometrics.BiometricAuthenticator;
import android.hardware.biometrics.BiometricConstants; import android.hardware.biometrics.BiometricConstants;
import android.hardware.biometrics.IBiometricService; import android.hardware.biometrics.IBiometricService;
@@ -681,7 +682,37 @@ public class BiometricSchedulerTest {
TestableLooper.get(this).processAllMessages(); 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 mStartedHal = false;
boolean mStoppedHal = false; boolean mStoppedHal = false;
boolean mDestroyed = false; boolean mDestroyed = false;
@@ -700,9 +731,10 @@ public class BiometricSchedulerTest {
@NonNull Supplier<Object> lazyDaemon, @NonNull IBinder token, @NonNull Supplier<Object> lazyDaemon, @NonNull IBinder token,
@NonNull ClientMonitorCallbackConverter listener, int cookie, @NonNull ClientMonitorCallbackConverter listener, int cookie,
@NonNull BiometricContext biometricContext) { @NonNull BiometricContext biometricContext) {
super(context, lazyDaemon, token, listener, 0 /* targetUserId */, 0 /* operationId */, super(context, lazyDaemon, token, listener, 0 /* operationId */,
false /* restricted */, TAG, cookie, false /* requireConfirmation */, false /* restricted */, new TestAuthenticateOptions(), cookie,
TEST_SENSOR_ID, mock(BiometricLogger.class), biometricContext, false /* requireConfirmation */,
mock(BiometricLogger.class), biometricContext,
true /* isStrongBiometric */, null /* taskStackListener */, true /* isStrongBiometric */, null /* taskStackListener */,
null /* lockoutTracker */, false /* isKeyguard */, null /* lockoutTracker */, false /* isKeyguard */,
true /* shouldVibrate */, true /* shouldVibrate */,

View File

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

View File

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

View File

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

View File

@@ -16,24 +16,35 @@
package com.android.server.biometrics.sensors.fingerprint; 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.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.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.eq; 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.verify;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import android.app.AppOpsManager;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.hardware.biometrics.IBiometricService; import android.hardware.biometrics.IBiometricService;
import android.hardware.biometrics.common.CommonProps; import android.hardware.fingerprint.FingerprintAuthenticateOptions;
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.FingerprintSensorPropertiesInternal; import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
import android.hardware.fingerprint.IFingerprintAuthenticatorsRegisteredCallback; import android.hardware.fingerprint.IFingerprintAuthenticatorsRegisteredCallback;
import android.hardware.fingerprint.IFingerprintServiceReceiver;
import android.os.IBinder;
import android.platform.test.annotations.Presubmit; import android.platform.test.annotations.Presubmit;
import android.provider.Settings; import android.provider.Settings;
import android.testing.TestableContext; 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.FakeSettingsProvider;
import com.android.internal.util.test.FakeSettingsProviderRule; import com.android.internal.util.test.FakeSettingsProviderRule;
import com.android.server.biometrics.log.BiometricContext; import com.android.server.biometrics.log.BiometricContext;
import com.android.server.biometrics.sensors.fingerprint.aidl.FingerprintProvider;
import org.junit.Before; import org.junit.Before;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule; import org.mockito.junit.MockitoRule;
@@ -64,6 +78,8 @@ public class FingerprintServiceTest {
private static final int ID_VIRTUAL = 6; private static final int ID_VIRTUAL = 6;
private static final String NAME_DEFAULT = "default"; private static final String NAME_DEFAULT = "default";
private static final String NAME_VIRTUAL = "virtual"; private static final String NAME_VIRTUAL = "virtual";
private static final List<FingerprintSensorPropertiesInternal> HIDL_AUTHENTICATORS =
List.of();
@Rule @Rule
public final MockitoRule mMockito = MockitoJUnit.rule(); public final MockitoRule mMockito = MockitoJUnit.rule();
@@ -73,48 +89,81 @@ public class FingerprintServiceTest {
@Rule @Rule
public final FakeSettingsProviderRule mSettingsRule = FakeSettingsProvider.rule(); public final FakeSettingsProviderRule mSettingsRule = FakeSettingsProvider.rule();
@Mock
private AppOpsManager mAppOpsManager;
@Mock @Mock
private BiometricContext mBiometricContext; private BiometricContext mBiometricContext;
@Mock @Mock
private IBiometricService mIBiometricService; private IBiometricService mIBiometricService;
@Mock @Mock
private IFingerprint mIFingerprintDefault; private FingerprintProvider mFingerprintDefault;
@Mock @Mock
private IFingerprint mIFingerprintVirtual; private FingerprintProvider mFingerprintVirtual;
@Mock
private IFingerprintServiceReceiver mServiceReceiver;
@Mock
private IBinder mToken;
private final SensorProps mSensorPropsDefault = createProps(ID_DEFAULT, @Captor
SensorStrength.STRONG, FingerprintSensorType.POWER_BUTTON); private ArgumentCaptor<FingerprintAuthenticateOptions> mAuthenticateOptionsCaptor;
private final SensorProps mSensorPropsVirtual = createProps(ID_VIRTUAL,
SensorStrength.STRONG, FingerprintSensorType.UNDER_DISPLAY_OPTICAL); 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; private FingerprintService mService;
@Before @Before
public void setup() throws Exception { public void setup() throws Exception {
when(mIFingerprintDefault.getSensorProps()).thenReturn( when(mFingerprintDefault.getSensorProperties()).thenReturn(List.of(mSensorPropsDefault));
new SensorProps[]{mSensorPropsDefault}); when(mFingerprintVirtual.getSensorProperties()).thenReturn(List.of(mSensorPropsVirtual));
when(mIFingerprintVirtual.getSensorProps()).thenReturn( when(mFingerprintDefault.containsSensor(anyInt()))
new SensorProps[]{mSensorPropsVirtual}); .thenAnswer(i -> i.getArguments()[0].equals(ID_DEFAULT));
when(mFingerprintVirtual.containsSensor(anyInt()))
.thenAnswer(i -> i.getArguments()[0].equals(ID_VIRTUAL));
mContext.getTestablePermissions().setPermission( mContext.addMockSystemService(AppOpsManager.class, mAppOpsManager);
USE_BIOMETRIC_INTERNAL, PackageManager.PERMISSION_GRANTED); 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) { private void initServiceWith(String... aidlInstances) {
mService = new FingerprintService(mContext, mBiometricContext, mService = new FingerprintService(mContext, mBiometricContext,
() -> mIBiometricService, () -> mIBiometricService,
() -> aidlInstances, () -> aidlInstances,
(fqName) -> { (name) -> {
if (fqName.endsWith(NAME_DEFAULT)) return mIFingerprintDefault; if (NAME_DEFAULT.equals(name)) return mFingerprintDefault;
if (fqName.endsWith(NAME_VIRTUAL)) return mIFingerprintVirtual; if (NAME_VIRTUAL.equals(name)) return mFingerprintVirtual;
return null; return null;
}); });
} }
private void initServiceWithAndWait(String... aidlInstances) throws Exception {
initServiceWith(aidlInstances);
mService.mServiceWrapper.registerAuthenticators(HIDL_AUTHENTICATORS);
waitForRegistration();
}
@Test @Test
public void registerAuthenticators_defaultOnly() throws Exception { public void registerAuthenticators_defaultOnly() throws Exception {
initServiceWith(NAME_DEFAULT, NAME_VIRTUAL); initServiceWith(NAME_DEFAULT, NAME_VIRTUAL);
mService.mServiceWrapper.registerAuthenticators(List.of()); mService.mServiceWrapper.registerAuthenticators(HIDL_AUTHENTICATORS);
waitForRegistration(); waitForRegistration();
verify(mIBiometricService).registerAuthenticator(eq(ID_DEFAULT), anyInt(), anyInt(), any()); verify(mIBiometricService).registerAuthenticator(eq(ID_DEFAULT), anyInt(), anyInt(), any());
@@ -126,7 +175,7 @@ public class FingerprintServiceTest {
Settings.Secure.putInt(mSettingsRule.mockContentResolver(mContext), Settings.Secure.putInt(mSettingsRule.mockContentResolver(mContext),
Settings.Secure.BIOMETRIC_VIRTUAL_ENABLED, 1); Settings.Secure.BIOMETRIC_VIRTUAL_ENABLED, 1);
mService.mServiceWrapper.registerAuthenticators(List.of()); mService.mServiceWrapper.registerAuthenticators(HIDL_AUTHENTICATORS);
waitForRegistration(); waitForRegistration();
verify(mIBiometricService).registerAuthenticator(eq(ID_VIRTUAL), anyInt(), anyInt(), any()); verify(mIBiometricService).registerAuthenticator(eq(ID_VIRTUAL), anyInt(), anyInt(), any());
@@ -136,7 +185,7 @@ public class FingerprintServiceTest {
public void registerAuthenticators_virtualAlwaysWhenNoOther() throws Exception { public void registerAuthenticators_virtualAlwaysWhenNoOther() throws Exception {
initServiceWith(NAME_VIRTUAL); initServiceWith(NAME_VIRTUAL);
mService.mServiceWrapper.registerAuthenticators(List.of()); mService.mServiceWrapper.registerAuthenticators(HIDL_AUTHENTICATORS);
waitForRegistration(); waitForRegistration();
verify(mIBiometricService).registerAuthenticator(eq(ID_VIRTUAL), anyInt(), anyInt(), any()); verify(mIBiometricService).registerAuthenticator(eq(ID_VIRTUAL), anyInt(), anyInt(), any());
@@ -155,13 +204,47 @@ public class FingerprintServiceTest {
latch.await(5, TimeUnit.SECONDS); latch.await(5, TimeUnit.SECONDS);
} }
private static SensorProps createProps(int id, byte strength, byte type) { @Test
final SensorProps props = new SensorProps(); public void authenticateWithDefaultSensorId() throws Exception {
props.commonProps = new CommonProps(); initServiceWithAndWait(NAME_DEFAULT, NAME_VIRTUAL);
props.commonProps.sensorId = id;
props.commonProps.sensorStrength = strength; final long operationId = 2;
props.sensorType = type; mService.mServiceWrapper.authenticate(mToken, operationId, mServiceReceiver,
props.sensorLocations = new SensorLocation[]{new SensorLocation()}; new FingerprintAuthenticateOptions.Builder()
return props; .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.ISession;
import android.hardware.biometrics.fingerprint.PointerContext; import android.hardware.biometrics.fingerprint.PointerContext;
import android.hardware.fingerprint.Fingerprint; import android.hardware.fingerprint.Fingerprint;
import android.hardware.fingerprint.FingerprintAuthenticateOptions;
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal; import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
import android.hardware.fingerprint.ISidefpsController; import android.hardware.fingerprint.ISidefpsController;
import android.hardware.fingerprint.IUdfpsOverlayController; import android.hardware.fingerprint.IUdfpsOverlayController;
@@ -414,11 +415,16 @@ public class FingerprintAuthenticationClientTest {
when(mHal.getInterfaceVersion()).thenReturn(version); when(mHal.getInterfaceVersion()).thenReturn(version);
final AidlSession aidl = new AidlSession(version, mHal, USER_ID, mHalSessionCallback); 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, return new FingerprintAuthenticationClient(mContext, () -> aidl, mToken,
REQUEST_ID, mClientMonitorCallbackConverter, 5 /* targetUserId */, OP_ID, REQUEST_ID, mClientMonitorCallbackConverter, OP_ID,
false /* restricted */, "test-owner", 4 /* cookie */, false /* restricted */, options, 4 /* cookie */,
false /* requireConfirmation */, false /* requireConfirmation */,
9 /* sensorId */, mBiometricLogger, mBiometricContext, mBiometricLogger, mBiometricContext,
true /* isStrongBiometric */, true /* isStrongBiometric */,
null /* taskStackListener */, null /* lockoutCache */, null /* taskStackListener */, null /* lockoutCache */,
mUdfpsOverlayController, mSideFpsController, null, allowBackgroundAuthentication, mUdfpsOverlayController, mSideFpsController, null, allowBackgroundAuthentication,

View File

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