Propogate face/fingerprint authenticate options to detect and authenticate clients.
Bug: 246363169 Bug: 268216312 Bug: 242628816 Test: atest FingerprintServiceTest FaceAuthenticationClientTest FaceDetectClientTest FingerprintAuthenticationClientTest FingerprintDetectClientTest Change-Id: I2fa1c7d39d2e93de387c16892cb47064d193a73d
This commit is contained in:
@@ -52,7 +52,7 @@ public class FaceAuthenticateOptions implements AuthenticateOptions, Parcelable
|
||||
}
|
||||
|
||||
/** The sensor id for this operation. */
|
||||
private final int mSensorId;
|
||||
private int mSensorId;
|
||||
private static int defaultSensorId() {
|
||||
return -1;
|
||||
}
|
||||
@@ -298,6 +298,15 @@ public class FaceAuthenticateOptions implements AuthenticateOptions, Parcelable
|
||||
return mAttributionTag;
|
||||
}
|
||||
|
||||
/**
|
||||
* The sensor id for this operation.
|
||||
*/
|
||||
@DataClass.Generated.Member
|
||||
public @NonNull FaceAuthenticateOptions setSensorId( int value) {
|
||||
mSensorId = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* The package name for that operation that should be used for
|
||||
* {@link android.app.AppOpsManager} verification.
|
||||
@@ -610,10 +619,10 @@ public class FaceAuthenticateOptions implements AuthenticateOptions, Parcelable
|
||||
}
|
||||
|
||||
@DataClass.Generated(
|
||||
time = 1676508211385L,
|
||||
time = 1677119626034L,
|
||||
codegenVersion = "1.0.23",
|
||||
sourceFile = "frameworks/base/core/java/android/hardware/face/FaceAuthenticateOptions.java",
|
||||
inputSignatures = "private final int mUserId\nprivate final int mSensorId\nprivate final @android.hardware.biometrics.AuthenticateOptions.DisplayState int mDisplayState\npublic static final int AUTHENTICATE_REASON_UNKNOWN\npublic static final int AUTHENTICATE_REASON_STARTED_WAKING_UP\npublic static final int AUTHENTICATE_REASON_PRIMARY_BOUNCER_SHOWN\npublic static final int AUTHENTICATE_REASON_ASSISTANT_VISIBLE\npublic static final int AUTHENTICATE_REASON_ALTERNATE_BIOMETRIC_BOUNCER_SHOWN\npublic static final int AUTHENTICATE_REASON_NOTIFICATION_PANEL_CLICKED\npublic static final int AUTHENTICATE_REASON_OCCLUDING_APP_REQUESTED\npublic static final int AUTHENTICATE_REASON_PICK_UP_GESTURE_TRIGGERED\npublic static final int AUTHENTICATE_REASON_QS_EXPANDED\npublic static final int AUTHENTICATE_REASON_SWIPE_UP_ON_BOUNCER\npublic static final int AUTHENTICATE_REASON_UDFPS_POINTER_DOWN\nprivate final @android.hardware.face.FaceAuthenticateOptions.AuthenticateReason int mAuthenticateReason\nprivate final @android.os.PowerManager.WakeReason int mWakeReason\nprivate @android.annotation.NonNull java.lang.String mOpPackageName\nprivate @android.annotation.Nullable java.lang.String mAttributionTag\nprivate static int defaultUserId()\nprivate static int defaultSensorId()\nprivate static int defaultDisplayState()\nprivate static int defaultAuthenticateReason()\nprivate static int defaultWakeReason()\nprivate static java.lang.String defaultOpPackageName()\nprivate static java.lang.String defaultAttributionTag()\nclass FaceAuthenticateOptions extends java.lang.Object implements [android.hardware.biometrics.AuthenticateOptions, android.os.Parcelable]\n@com.android.internal.util.DataClass(genParcelable=true, genAidl=true, genBuilder=true, genSetters=true, genEqualsHashCode=true)")
|
||||
inputSignatures = "private final int mUserId\nprivate int mSensorId\nprivate final @android.hardware.biometrics.AuthenticateOptions.DisplayState int mDisplayState\npublic static final int AUTHENTICATE_REASON_UNKNOWN\npublic static final int AUTHENTICATE_REASON_STARTED_WAKING_UP\npublic static final int AUTHENTICATE_REASON_PRIMARY_BOUNCER_SHOWN\npublic static final int AUTHENTICATE_REASON_ASSISTANT_VISIBLE\npublic static final int AUTHENTICATE_REASON_ALTERNATE_BIOMETRIC_BOUNCER_SHOWN\npublic static final int AUTHENTICATE_REASON_NOTIFICATION_PANEL_CLICKED\npublic static final int AUTHENTICATE_REASON_OCCLUDING_APP_REQUESTED\npublic static final int AUTHENTICATE_REASON_PICK_UP_GESTURE_TRIGGERED\npublic static final int AUTHENTICATE_REASON_QS_EXPANDED\npublic static final int AUTHENTICATE_REASON_SWIPE_UP_ON_BOUNCER\npublic static final int AUTHENTICATE_REASON_UDFPS_POINTER_DOWN\nprivate final @android.hardware.face.FaceAuthenticateOptions.AuthenticateReason int mAuthenticateReason\nprivate final @android.os.PowerManager.WakeReason int mWakeReason\nprivate @android.annotation.NonNull java.lang.String mOpPackageName\nprivate @android.annotation.Nullable java.lang.String mAttributionTag\nprivate static int defaultUserId()\nprivate static int defaultSensorId()\nprivate static int defaultDisplayState()\nprivate static int defaultAuthenticateReason()\nprivate static int defaultWakeReason()\nprivate static java.lang.String defaultOpPackageName()\nprivate static java.lang.String defaultAttributionTag()\nclass FaceAuthenticateOptions extends java.lang.Object implements [android.hardware.biometrics.AuthenticateOptions, android.os.Parcelable]\n@com.android.internal.util.DataClass(genParcelable=true, genAidl=true, genBuilder=true, genSetters=true, genEqualsHashCode=true)")
|
||||
@Deprecated
|
||||
private void __metadata() {}
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ interface IFaceService {
|
||||
// by BiometricService. To start authentication after the clients are ready, use
|
||||
// startPreparedClient().
|
||||
@EnforcePermission("USE_BIOMETRIC_INTERNAL")
|
||||
void prepareForAuthentication(int sensorId, boolean requireConfirmation, IBinder token,
|
||||
void prepareForAuthentication(boolean requireConfirmation, IBinder token,
|
||||
long operationId, IBiometricSensorReceiver sensorReceiver,
|
||||
in FaceAuthenticateOptions options, long requestId, int cookie,
|
||||
boolean allowBackgroundAuthentication);
|
||||
|
||||
@@ -46,7 +46,7 @@ public final class FingerprintAuthenticateOptions implements AuthenticateOptions
|
||||
}
|
||||
|
||||
/** The sensor id for this operation. */
|
||||
private final int mSensorId;
|
||||
private int mSensorId;
|
||||
private static int defaultSensorId() {
|
||||
return SENSOR_ID_ANY;
|
||||
}
|
||||
@@ -175,6 +175,15 @@ public final class FingerprintAuthenticateOptions implements AuthenticateOptions
|
||||
return mAttributionTag;
|
||||
}
|
||||
|
||||
/**
|
||||
* The sensor id for this operation.
|
||||
*/
|
||||
@DataClass.Generated.Member
|
||||
public @NonNull FingerprintAuthenticateOptions setSensorId( int value) {
|
||||
mSensorId = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* The package name for that operation that should be used for
|
||||
* {@link android.app.AppOpsManager} verification.
|
||||
@@ -433,10 +442,10 @@ public final class FingerprintAuthenticateOptions implements AuthenticateOptions
|
||||
}
|
||||
|
||||
@DataClass.Generated(
|
||||
time = 1676508212083L,
|
||||
time = 1677119626721L,
|
||||
codegenVersion = "1.0.23",
|
||||
sourceFile = "frameworks/base/core/java/android/hardware/fingerprint/FingerprintAuthenticateOptions.java",
|
||||
inputSignatures = "private final int mUserId\nprivate final int mSensorId\nprivate final boolean mIgnoreEnrollmentState\nprivate final @android.hardware.biometrics.AuthenticateOptions.DisplayState int mDisplayState\nprivate @android.annotation.NonNull java.lang.String mOpPackageName\nprivate @android.annotation.Nullable java.lang.String mAttributionTag\nprivate static int defaultUserId()\nprivate static int defaultSensorId()\nprivate static boolean defaultIgnoreEnrollmentState()\nprivate static int defaultDisplayState()\nprivate static java.lang.String defaultOpPackageName()\nprivate static java.lang.String defaultAttributionTag()\nclass FingerprintAuthenticateOptions extends java.lang.Object implements [android.hardware.biometrics.AuthenticateOptions, android.os.Parcelable]\n@com.android.internal.util.DataClass(genParcelable=true, genAidl=true, genBuilder=true, genSetters=true, genEqualsHashCode=true)")
|
||||
inputSignatures = "private final int mUserId\nprivate int mSensorId\nprivate final boolean mIgnoreEnrollmentState\nprivate final @android.hardware.biometrics.AuthenticateOptions.DisplayState int mDisplayState\nprivate @android.annotation.NonNull java.lang.String mOpPackageName\nprivate @android.annotation.Nullable java.lang.String mAttributionTag\nprivate static int defaultUserId()\nprivate static int defaultSensorId()\nprivate static boolean defaultIgnoreEnrollmentState()\nprivate static int defaultDisplayState()\nprivate static java.lang.String defaultOpPackageName()\nprivate static java.lang.String defaultAttributionTag()\nclass FingerprintAuthenticateOptions extends java.lang.Object implements [android.hardware.biometrics.AuthenticateOptions, android.os.Parcelable]\n@com.android.internal.util.DataClass(genParcelable=true, genAidl=true, genBuilder=true, genSetters=true, genEqualsHashCode=true)")
|
||||
@Deprecated
|
||||
private void __metadata() {}
|
||||
|
||||
|
||||
@@ -73,8 +73,8 @@ interface IFingerprintService {
|
||||
// by BiometricService. To start authentication after the clients are ready, use
|
||||
// startPreparedClient().
|
||||
@EnforcePermission("MANAGE_BIOMETRIC")
|
||||
void prepareForAuthentication(int sensorId, IBinder token, long operationId, int userId,
|
||||
IBiometricSensorReceiver sensorReceiver, String opPackageName, long requestId,
|
||||
void prepareForAuthentication(IBinder token, long operationId,
|
||||
IBiometricSensorReceiver sensorReceiver, in FingerprintAuthenticateOptions options, long requestId,
|
||||
int cookie, boolean allowBackgroundAuthentication);
|
||||
|
||||
// Starts authentication with the previously prepared client.
|
||||
|
||||
@@ -23,6 +23,7 @@ import android.app.ActivityTaskManager;
|
||||
import android.app.TaskStackListener;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.hardware.biometrics.AuthenticateOptions;
|
||||
import android.hardware.biometrics.BiometricAuthenticator;
|
||||
import android.hardware.biometrics.BiometricConstants;
|
||||
import android.hardware.biometrics.BiometricManager;
|
||||
@@ -44,8 +45,8 @@ import java.util.function.Supplier;
|
||||
/**
|
||||
* A class to keep track of the authentication state for a given client.
|
||||
*/
|
||||
public abstract class AuthenticationClient<T> extends AcquisitionClient<T>
|
||||
implements AuthenticationConsumer {
|
||||
public abstract class AuthenticationClient<T, O extends AuthenticateOptions>
|
||||
extends AcquisitionClient<T> implements AuthenticationConsumer {
|
||||
|
||||
// New, has not started yet
|
||||
public static final int STATE_NEW = 0;
|
||||
@@ -89,14 +90,15 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T>
|
||||
|
||||
public AuthenticationClient(@NonNull Context context, @NonNull Supplier<T> lazyDaemon,
|
||||
@NonNull IBinder token, @NonNull ClientMonitorCallbackConverter listener,
|
||||
int targetUserId, long operationId, boolean restricted, @NonNull String owner,
|
||||
int cookie, boolean requireConfirmation, int sensorId,
|
||||
long operationId, boolean restricted, @NonNull O options,
|
||||
int cookie, boolean requireConfirmation,
|
||||
@NonNull BiometricLogger biometricLogger, @NonNull BiometricContext biometricContext,
|
||||
boolean isStrongBiometric, @Nullable TaskStackListener taskStackListener,
|
||||
@NonNull LockoutTracker lockoutTracker, boolean allowBackgroundAuthentication,
|
||||
boolean shouldVibrate, int sensorStrength) {
|
||||
super(context, lazyDaemon, token, listener, targetUserId, owner, cookie, sensorId,
|
||||
shouldVibrate, biometricLogger, biometricContext);
|
||||
super(context, lazyDaemon, token, listener, options.getUserId(),
|
||||
options.getOpPackageName(), cookie, options.getSensorId(), shouldVibrate,
|
||||
biometricLogger, biometricContext);
|
||||
mIsStrongBiometric = isStrongBiometric;
|
||||
mOperationId = operationId;
|
||||
mRequireConfirmation = requireConfirmation;
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.android.server.biometrics.sensors;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.hardware.biometrics.SensorPropertiesInternal;
|
||||
import android.util.proto.ProtoOutputStream;
|
||||
|
||||
@@ -39,7 +40,7 @@ public interface BiometricServiceProvider<T extends SensorPropertiesInternal> {
|
||||
List<T> getSensorProperties();
|
||||
|
||||
/** Properties for the given sensor id. */
|
||||
@NonNull
|
||||
@Nullable
|
||||
T getSensorProperties(int sensorId);
|
||||
|
||||
boolean isHardwareDetected(int sensorId);
|
||||
|
||||
@@ -92,7 +92,7 @@ public class BiometricStateCallback<T extends BiometricServiceProvider<P>,
|
||||
final int previousBiometricState = mBiometricState;
|
||||
|
||||
if (client instanceof AuthenticationClient) {
|
||||
final AuthenticationClient<?> authClient = (AuthenticationClient<?>) client;
|
||||
final AuthenticationClient<?, ?> authClient = (AuthenticationClient<?, ?>) client;
|
||||
if (authClient.isKeyguard()) {
|
||||
mBiometricState = STATE_KEYGUARD_AUTH;
|
||||
} else if (authClient.isBiometricPrompt()) {
|
||||
|
||||
@@ -64,9 +64,10 @@ public final class FaceAuthenticator extends IBiometricAuthenticator.Stub {
|
||||
long operationId, int userId, IBiometricSensorReceiver sensorReceiver,
|
||||
String opPackageName, long requestId, int cookie, boolean allowBackgroundAuthentication)
|
||||
throws RemoteException {
|
||||
mFaceService.prepareForAuthentication(mSensorId, requireConfirmation, token, operationId,
|
||||
mFaceService.prepareForAuthentication(requireConfirmation, token, operationId,
|
||||
sensorReceiver, new FaceAuthenticateOptions.Builder()
|
||||
.setUserId(userId)
|
||||
.setSensorId(mSensorId)
|
||||
.setOpPackageName(opPackageName)
|
||||
.build(),
|
||||
requestId, cookie, allowBackgroundAuthentication);
|
||||
|
||||
@@ -246,7 +246,6 @@ public class FaceService extends SystemService {
|
||||
|
||||
super.authenticate_enforcePermission();
|
||||
|
||||
final int userId = options.getUserId();
|
||||
final String opPackageName = options.getOpPackageName();
|
||||
final boolean restricted = false; // Face APIs are private
|
||||
final int statsClient = Utils.isKeyguard(getContext(), opPackageName)
|
||||
@@ -261,9 +260,11 @@ public class FaceService extends SystemService {
|
||||
if (provider == null) {
|
||||
Slog.w(TAG, "Null provider for authenticate");
|
||||
return -1;
|
||||
} else {
|
||||
options.setSensorId(provider.first);
|
||||
}
|
||||
|
||||
return provider.second.scheduleAuthenticate(provider.first, token, operationId,
|
||||
return provider.second.scheduleAuthenticate(token, operationId,
|
||||
0 /* cookie */, new ClientMonitorCallbackConverter(receiver), options,
|
||||
restricted, statsClient, isKeyguard);
|
||||
}
|
||||
@@ -286,28 +287,27 @@ public class FaceService extends SystemService {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return provider.second.scheduleFaceDetect(provider.first, token, options.getUserId(),
|
||||
new ClientMonitorCallbackConverter(receiver), opPackageName,
|
||||
return provider.second.scheduleFaceDetect(token,
|
||||
new ClientMonitorCallbackConverter(receiver), options,
|
||||
BiometricsProtoEnums.CLIENT_KEYGUARD);
|
||||
}
|
||||
|
||||
@android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
|
||||
@Override // Binder call
|
||||
public void prepareForAuthentication(int sensorId, boolean requireConfirmation,
|
||||
public void prepareForAuthentication(boolean requireConfirmation,
|
||||
IBinder token, long operationId, IBiometricSensorReceiver sensorReceiver,
|
||||
FaceAuthenticateOptions options, long requestId, int cookie,
|
||||
boolean allowBackgroundAuthentication) {
|
||||
super.prepareForAuthentication_enforcePermission();
|
||||
|
||||
final ServiceProvider provider = mRegistry.getProviderForSensor(sensorId);
|
||||
final ServiceProvider provider = mRegistry.getProviderForSensor(options.getSensorId());
|
||||
if (provider == null) {
|
||||
Slog.w(TAG, "Null provider for prepareForAuthentication");
|
||||
return;
|
||||
}
|
||||
|
||||
final boolean isKeyguardBypassEnabled = false; // only valid for keyguard clients
|
||||
final boolean restricted = true; // BiometricPrompt is always restricted
|
||||
provider.scheduleAuthenticate(sensorId, token, operationId, cookie,
|
||||
provider.scheduleAuthenticate(token, operationId, cookie,
|
||||
new ClientMonitorCallbackConverter(sensorReceiver), options, requestId,
|
||||
restricted, BiometricsProtoEnums.CLIENT_BIOMETRIC_PROMPT,
|
||||
allowBackgroundAuthentication);
|
||||
|
||||
@@ -83,18 +83,19 @@ public interface ServiceProvider extends BiometricServiceProvider<FaceSensorProp
|
||||
|
||||
void cancelEnrollment(int sensorId, @NonNull IBinder token, long requestId);
|
||||
|
||||
long scheduleFaceDetect(int sensorId, @NonNull IBinder token, int userId,
|
||||
@NonNull ClientMonitorCallbackConverter callback, @NonNull String opPackageName,
|
||||
long scheduleFaceDetect(@NonNull IBinder token,
|
||||
@NonNull ClientMonitorCallbackConverter callback,
|
||||
@NonNull FaceAuthenticateOptions options,
|
||||
int statsClient);
|
||||
|
||||
void cancelFaceDetect(int sensorId, @NonNull IBinder token, long requestId);
|
||||
|
||||
long scheduleAuthenticate(int sensorId, @NonNull IBinder token, long operationId,
|
||||
long scheduleAuthenticate(@NonNull IBinder token, long operationId,
|
||||
int cookie, @NonNull ClientMonitorCallbackConverter callback,
|
||||
@NonNull FaceAuthenticateOptions options,
|
||||
boolean restricted, int statsClient, boolean allowBackgroundAuthentication);
|
||||
|
||||
void scheduleAuthenticate(int sensorId, @NonNull IBinder token, long operationId,
|
||||
void scheduleAuthenticate(@NonNull IBinder token, long operationId,
|
||||
int cookie, @NonNull ClientMonitorCallbackConverter callback,
|
||||
@NonNull FaceAuthenticateOptions options, long requestId,
|
||||
boolean restricted, int statsClient, boolean allowBackgroundAuthentication);
|
||||
|
||||
@@ -28,6 +28,7 @@ import android.hardware.biometrics.BiometricFaceConstants;
|
||||
import android.hardware.biometrics.BiometricManager.Authenticators;
|
||||
import android.hardware.biometrics.common.ICancellationSignal;
|
||||
import android.hardware.biometrics.face.IFace;
|
||||
import android.hardware.face.FaceAuthenticateOptions;
|
||||
import android.hardware.face.FaceAuthenticationFrame;
|
||||
import android.hardware.face.FaceManager;
|
||||
import android.os.IBinder;
|
||||
@@ -56,7 +57,7 @@ import java.util.function.Supplier;
|
||||
/**
|
||||
* Face-specific authentication client for the {@link IFace} AIDL HAL interface.
|
||||
*/
|
||||
class FaceAuthenticationClient extends AuthenticationClient<AidlSession>
|
||||
class FaceAuthenticationClient extends AuthenticationClient<AidlSession, FaceAuthenticateOptions>
|
||||
implements LockoutConsumer {
|
||||
private static final String TAG = "FaceAuthenticationClient";
|
||||
|
||||
@@ -80,16 +81,16 @@ class FaceAuthenticationClient extends AuthenticationClient<AidlSession>
|
||||
FaceAuthenticationClient(@NonNull Context context,
|
||||
@NonNull Supplier<AidlSession> lazyDaemon,
|
||||
@NonNull IBinder token, long requestId,
|
||||
@NonNull ClientMonitorCallbackConverter listener, int targetUserId, long operationId,
|
||||
boolean restricted, String owner, int cookie, boolean requireConfirmation, int sensorId,
|
||||
@NonNull ClientMonitorCallbackConverter listener, long operationId,
|
||||
boolean restricted, @NonNull FaceAuthenticateOptions options, int cookie,
|
||||
boolean requireConfirmation,
|
||||
@NonNull BiometricLogger logger, @NonNull BiometricContext biometricContext,
|
||||
boolean isStrongBiometric, @NonNull UsageStats usageStats,
|
||||
@NonNull LockoutCache lockoutCache, boolean allowBackgroundAuthentication,
|
||||
@Authenticators.Types int sensorStrength) {
|
||||
this(context, lazyDaemon, token, requestId, listener, targetUserId, operationId,
|
||||
restricted, owner, cookie, requireConfirmation, sensorId, logger, biometricContext,
|
||||
isStrongBiometric, usageStats, lockoutCache /* lockoutCache */,
|
||||
allowBackgroundAuthentication,
|
||||
this(context, lazyDaemon, token, requestId, listener, operationId,
|
||||
restricted, options, cookie, requireConfirmation, logger, biometricContext,
|
||||
isStrongBiometric, usageStats, lockoutCache, allowBackgroundAuthentication,
|
||||
context.getSystemService(SensorPrivacyManager.class), sensorStrength);
|
||||
}
|
||||
|
||||
@@ -97,15 +98,16 @@ class FaceAuthenticationClient extends AuthenticationClient<AidlSession>
|
||||
FaceAuthenticationClient(@NonNull Context context,
|
||||
@NonNull Supplier<AidlSession> lazyDaemon,
|
||||
@NonNull IBinder token, long requestId,
|
||||
@NonNull ClientMonitorCallbackConverter listener, int targetUserId, long operationId,
|
||||
boolean restricted, String owner, int cookie, boolean requireConfirmation, int sensorId,
|
||||
@NonNull ClientMonitorCallbackConverter listener, long operationId,
|
||||
boolean restricted, @NonNull FaceAuthenticateOptions options, int cookie,
|
||||
boolean requireConfirmation,
|
||||
@NonNull BiometricLogger logger, @NonNull BiometricContext biometricContext,
|
||||
boolean isStrongBiometric, @NonNull UsageStats usageStats,
|
||||
@NonNull LockoutCache lockoutCache, boolean allowBackgroundAuthentication,
|
||||
SensorPrivacyManager sensorPrivacyManager,
|
||||
@Authenticators.Types int biometricStrength) {
|
||||
super(context, lazyDaemon, token, listener, targetUserId, operationId, restricted,
|
||||
owner, cookie, requireConfirmation, sensorId, logger, biometricContext,
|
||||
super(context, lazyDaemon, token, listener, operationId, restricted,
|
||||
options, cookie, requireConfirmation, logger, biometricContext,
|
||||
isStrongBiometric, null /* taskStackListener */, null /* lockoutCache */,
|
||||
allowBackgroundAuthentication, false /* shouldVibrate */,
|
||||
biometricStrength);
|
||||
|
||||
@@ -22,6 +22,7 @@ import android.content.Context;
|
||||
import android.hardware.SensorPrivacyManager;
|
||||
import android.hardware.biometrics.BiometricConstants;
|
||||
import android.hardware.biometrics.common.ICancellationSignal;
|
||||
import android.hardware.face.FaceAuthenticateOptions;
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Slog;
|
||||
@@ -51,11 +52,11 @@ public class FaceDetectClient extends AcquisitionClient<AidlSession> implements
|
||||
|
||||
FaceDetectClient(@NonNull Context context, @NonNull Supplier<AidlSession> lazyDaemon,
|
||||
@NonNull IBinder token, long requestId,
|
||||
@NonNull ClientMonitorCallbackConverter listener, int userId,
|
||||
@NonNull String owner, int sensorId,
|
||||
@NonNull ClientMonitorCallbackConverter listener,
|
||||
@NonNull FaceAuthenticateOptions options,
|
||||
@NonNull BiometricLogger logger, @NonNull BiometricContext biometricContext,
|
||||
boolean isStrongBiometric) {
|
||||
this(context, lazyDaemon, token, requestId, listener, userId, owner, sensorId,
|
||||
this(context, lazyDaemon, token, requestId, listener, options,
|
||||
logger, biometricContext, isStrongBiometric,
|
||||
context.getSystemService(SensorPrivacyManager.class));
|
||||
}
|
||||
@@ -63,11 +64,12 @@ public class FaceDetectClient extends AcquisitionClient<AidlSession> implements
|
||||
@VisibleForTesting
|
||||
FaceDetectClient(@NonNull Context context, @NonNull Supplier<AidlSession> lazyDaemon,
|
||||
@NonNull IBinder token, long requestId,
|
||||
@NonNull ClientMonitorCallbackConverter listener, int userId,
|
||||
@NonNull String owner, int sensorId,
|
||||
@NonNull ClientMonitorCallbackConverter listener,
|
||||
@NonNull FaceAuthenticateOptions options,
|
||||
@NonNull BiometricLogger logger, @NonNull BiometricContext biometricContext,
|
||||
boolean isStrongBiometric, SensorPrivacyManager sensorPrivacyManager) {
|
||||
super(context, lazyDaemon, token, listener, userId, owner, 0 /* cookie */, sensorId,
|
||||
super(context, lazyDaemon, token, listener, options.getUserId(),
|
||||
options.getOpPackageName(), 0 /* cookie */, options.getSensorId(),
|
||||
true /* shouldVibrate */, logger, biometricContext);
|
||||
setRequestId(requestId);
|
||||
mIsStrongBiometric = isStrongBiometric;
|
||||
|
||||
@@ -410,16 +410,17 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
public long scheduleFaceDetect(int sensorId, @NonNull IBinder token,
|
||||
int userId, @NonNull ClientMonitorCallbackConverter callback,
|
||||
@NonNull String opPackageName, int statsClient) {
|
||||
public long scheduleFaceDetect(@NonNull IBinder token,
|
||||
@NonNull ClientMonitorCallbackConverter callback,
|
||||
@NonNull FaceAuthenticateOptions options, int statsClient) {
|
||||
final long id = mRequestCounter.incrementAndGet();
|
||||
final int sensorId = options.getSensorId();
|
||||
|
||||
mHandler.post(() -> {
|
||||
final boolean isStrongBiometric = Utils.isStrongBiometric(sensorId);
|
||||
final FaceDetectClient client = new FaceDetectClient(mContext,
|
||||
mSensors.get(sensorId).getLazySession(),
|
||||
token, id, callback, userId, opPackageName, sensorId,
|
||||
token, id, callback, options,
|
||||
createLogger(BiometricsProtoEnums.ACTION_AUTHENTICATE, statsClient),
|
||||
mBiometricContext, isStrongBiometric);
|
||||
scheduleForSensor(sensorId, client, mBiometricStateCallback);
|
||||
@@ -435,18 +436,19 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void scheduleAuthenticate(int sensorId, @NonNull IBinder token, long operationId,
|
||||
public void scheduleAuthenticate(@NonNull IBinder token, long operationId,
|
||||
int cookie, @NonNull ClientMonitorCallbackConverter callback,
|
||||
@NonNull FaceAuthenticateOptions options,
|
||||
long requestId, boolean restricted, int statsClient,
|
||||
boolean allowBackgroundAuthentication) {
|
||||
mHandler.post(() -> {
|
||||
final int userId = options.getUserId();
|
||||
final int sensorId = options.getSensorId();
|
||||
final boolean isStrongBiometric = Utils.isStrongBiometric(sensorId);
|
||||
final FaceAuthenticationClient client = new FaceAuthenticationClient(
|
||||
mContext, mSensors.get(sensorId).getLazySession(), token, requestId, callback,
|
||||
userId, operationId, restricted, options.getOpPackageName(), cookie,
|
||||
false /* requireConfirmation */, sensorId,
|
||||
operationId, restricted, options, cookie,
|
||||
false /* requireConfirmation */,
|
||||
createLogger(BiometricsProtoEnums.ACTION_AUTHENTICATE, statsClient),
|
||||
mBiometricContext, isStrongBiometric,
|
||||
mUsageStats, mSensors.get(sensorId).getLockoutCache(),
|
||||
@@ -470,13 +472,13 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
public long scheduleAuthenticate(int sensorId, @NonNull IBinder token, long operationId,
|
||||
public long scheduleAuthenticate(@NonNull IBinder token, long operationId,
|
||||
int cookie, @NonNull ClientMonitorCallbackConverter callback,
|
||||
@NonNull FaceAuthenticateOptions options, boolean restricted, int statsClient,
|
||||
boolean allowBackgroundAuthentication) {
|
||||
final long id = mRequestCounter.incrementAndGet();
|
||||
|
||||
scheduleAuthenticate(sensorId, token, operationId, cookie, callback,
|
||||
scheduleAuthenticate(token, operationId, cookie, callback,
|
||||
options, id, restricted, statsClient, allowBackgroundAuthentication);
|
||||
|
||||
return id;
|
||||
|
||||
@@ -651,9 +651,9 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
public long scheduleFaceDetect(int sensorId, @NonNull IBinder token,
|
||||
int userId, @NonNull ClientMonitorCallbackConverter callback,
|
||||
@NonNull String opPackageName, int statsClient) {
|
||||
public long scheduleFaceDetect(@NonNull IBinder token,
|
||||
@NonNull ClientMonitorCallbackConverter callback,
|
||||
@NonNull FaceAuthenticateOptions options, int statsClient) {
|
||||
throw new IllegalStateException("Face detect not supported by IBiometricsFace@1.0. Did you"
|
||||
+ "forget to check the supportsFaceDetection flag?");
|
||||
}
|
||||
@@ -665,7 +665,7 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void scheduleAuthenticate(int sensorId, @NonNull IBinder token, long operationId,
|
||||
public void scheduleAuthenticate(@NonNull IBinder token, long operationId,
|
||||
int cookie, @NonNull ClientMonitorCallbackConverter receiver,
|
||||
@NonNull FaceAuthenticateOptions options, long requestId, boolean restricted,
|
||||
int statsClient, boolean allowBackgroundAuthentication) {
|
||||
@@ -675,8 +675,8 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider {
|
||||
|
||||
final boolean isStrongBiometric = Utils.isStrongBiometric(mSensorId);
|
||||
final FaceAuthenticationClient client = new FaceAuthenticationClient(mContext,
|
||||
mLazyDaemon, token, requestId, receiver, userId, operationId, restricted,
|
||||
options.getOpPackageName(), cookie, false /* requireConfirmation */, mSensorId,
|
||||
mLazyDaemon, token, requestId, receiver, operationId, restricted,
|
||||
options, cookie, false /* requireConfirmation */,
|
||||
createLogger(BiometricsProtoEnums.ACTION_AUTHENTICATE, statsClient),
|
||||
mBiometricContext, isStrongBiometric, mLockoutTracker,
|
||||
mUsageStats, allowBackgroundAuthentication,
|
||||
@@ -686,13 +686,13 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
public long scheduleAuthenticate(int sensorId, @NonNull IBinder token, long operationId,
|
||||
public long scheduleAuthenticate(@NonNull IBinder token, long operationId,
|
||||
int cookie, @NonNull ClientMonitorCallbackConverter receiver,
|
||||
@NonNull FaceAuthenticateOptions options, boolean restricted, int statsClient,
|
||||
boolean allowBackgroundAuthentication) {
|
||||
final long id = mRequestCounter.incrementAndGet();
|
||||
|
||||
scheduleAuthenticate(sensorId, token, operationId, cookie, receiver,
|
||||
scheduleAuthenticate(token, operationId, cookie, receiver,
|
||||
options, id, restricted, statsClient, allowBackgroundAuthentication);
|
||||
|
||||
return id;
|
||||
|
||||
@@ -25,6 +25,7 @@ import android.hardware.biometrics.BiometricConstants;
|
||||
import android.hardware.biometrics.BiometricFaceConstants;
|
||||
import android.hardware.biometrics.BiometricManager.Authenticators;
|
||||
import android.hardware.biometrics.face.V1_0.IBiometricsFace;
|
||||
import android.hardware.face.FaceAuthenticateOptions;
|
||||
import android.hardware.face.FaceManager;
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
@@ -50,7 +51,8 @@ import java.util.function.Supplier;
|
||||
* Face-specific authentication client supporting the {@link android.hardware.biometrics.face.V1_0}
|
||||
* HIDL interface.
|
||||
*/
|
||||
class FaceAuthenticationClient extends AuthenticationClient<IBiometricsFace> {
|
||||
class FaceAuthenticationClient
|
||||
extends AuthenticationClient<IBiometricsFace, FaceAuthenticateOptions> {
|
||||
|
||||
private static final String TAG = "FaceAuthenticationClient";
|
||||
|
||||
@@ -67,17 +69,18 @@ class FaceAuthenticationClient extends AuthenticationClient<IBiometricsFace> {
|
||||
FaceAuthenticationClient(@NonNull Context context,
|
||||
@NonNull Supplier<IBiometricsFace> lazyDaemon,
|
||||
@NonNull IBinder token, long requestId,
|
||||
@NonNull ClientMonitorCallbackConverter listener, int targetUserId, long operationId,
|
||||
boolean restricted, String owner, int cookie, boolean requireConfirmation, int sensorId,
|
||||
@NonNull ClientMonitorCallbackConverter listener, long operationId,
|
||||
boolean restricted, @NonNull FaceAuthenticateOptions options, int cookie,
|
||||
boolean requireConfirmation,
|
||||
@NonNull BiometricLogger logger, @NonNull BiometricContext biometricContext,
|
||||
boolean isStrongBiometric, @NonNull LockoutTracker lockoutTracker,
|
||||
@NonNull UsageStats usageStats, boolean allowBackgroundAuthentication,
|
||||
@Authenticators.Types int sensorStrength) {
|
||||
super(context, lazyDaemon, token, listener, targetUserId, operationId, restricted,
|
||||
owner, cookie, requireConfirmation, sensorId, logger, biometricContext,
|
||||
super(context, lazyDaemon, token, listener, operationId, restricted,
|
||||
options, cookie, requireConfirmation, logger, biometricContext,
|
||||
isStrongBiometric, null /* taskStackListener */,
|
||||
lockoutTracker, allowBackgroundAuthentication, false /* shouldVibrate */,
|
||||
sensorStrength);
|
||||
sensorStrength);
|
||||
setRequestId(requestId);
|
||||
mUsageStats = usageStats;
|
||||
mSensorPrivacyManager = context.getSystemService(SensorPrivacyManager.class);
|
||||
|
||||
@@ -23,6 +23,7 @@ import android.hardware.biometrics.IInvalidationCallback;
|
||||
import android.hardware.biometrics.ITestSession;
|
||||
import android.hardware.biometrics.ITestSessionCallback;
|
||||
import android.hardware.biometrics.SensorPropertiesInternal;
|
||||
import android.hardware.fingerprint.FingerprintAuthenticateOptions;
|
||||
import android.hardware.fingerprint.IFingerprintService;
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
@@ -63,8 +64,13 @@ public final class FingerprintAuthenticator extends IBiometricAuthenticator.Stub
|
||||
long operationId, int userId, IBiometricSensorReceiver sensorReceiver,
|
||||
String opPackageName, long requestId, int cookie, boolean allowBackgroundAuthentication)
|
||||
throws RemoteException {
|
||||
mFingerprintService.prepareForAuthentication(mSensorId, token, operationId, userId,
|
||||
sensorReceiver, opPackageName, requestId, cookie, allowBackgroundAuthentication);
|
||||
mFingerprintService.prepareForAuthentication(token, operationId, sensorReceiver,
|
||||
new FingerprintAuthenticateOptions.Builder()
|
||||
.setSensorId(mSensorId)
|
||||
.setUserId(userId)
|
||||
.setOpPackageName(opPackageName)
|
||||
.build(),
|
||||
requestId, cookie, allowBackgroundAuthentication);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -119,7 +119,7 @@ public class FingerprintService extends SystemService {
|
||||
@NonNull
|
||||
private final Supplier<String[]> mAidlInstanceNameSupplier;
|
||||
@NonNull
|
||||
private final Function<String, IFingerprint> mIFingerprintProvider;
|
||||
private final Function<String, FingerprintProvider> mFingerprintProvider;
|
||||
@NonNull
|
||||
private final BiometricStateCallback<ServiceProvider, FingerprintSensorPropertiesInternal>
|
||||
mBiometricStateCallback;
|
||||
@@ -307,6 +307,8 @@ public class FingerprintService extends SystemService {
|
||||
if (provider == null) {
|
||||
Slog.w(TAG, "Null provider for authenticate");
|
||||
return -1;
|
||||
} else {
|
||||
options.setSensorId(provider.first);
|
||||
}
|
||||
|
||||
final FingerprintSensorPropertiesInternal sensorProps =
|
||||
@@ -322,8 +324,8 @@ public class FingerprintService extends SystemService {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return provider.second.scheduleAuthenticate(provider.first, token, operationId, userId,
|
||||
0 /* cookie */, new ClientMonitorCallbackConverter(receiver), opPackageName,
|
||||
return provider.second.scheduleAuthenticate(token, operationId,
|
||||
0 /* cookie */, new ClientMonitorCallbackConverter(receiver), options,
|
||||
restricted, statsClient, isKeyguard);
|
||||
}
|
||||
|
||||
@@ -436,29 +438,32 @@ public class FingerprintService extends SystemService {
|
||||
if (provider == null) {
|
||||
Slog.w(TAG, "Null provider for detectFingerprint");
|
||||
return -1;
|
||||
} else {
|
||||
options.setSensorId(provider.first);
|
||||
}
|
||||
|
||||
return provider.second.scheduleFingerDetect(provider.first, token, options.getUserId(),
|
||||
new ClientMonitorCallbackConverter(receiver), opPackageName,
|
||||
return provider.second.scheduleFingerDetect(token,
|
||||
new ClientMonitorCallbackConverter(receiver), options,
|
||||
BiometricsProtoEnums.CLIENT_KEYGUARD);
|
||||
}
|
||||
|
||||
@android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_BIOMETRIC)
|
||||
@Override // Binder call
|
||||
public void prepareForAuthentication(int sensorId, IBinder token, long operationId,
|
||||
int userId, IBiometricSensorReceiver sensorReceiver, String opPackageName,
|
||||
public void prepareForAuthentication(IBinder token, long operationId,
|
||||
IBiometricSensorReceiver sensorReceiver,
|
||||
@NonNull FingerprintAuthenticateOptions options,
|
||||
long requestId, int cookie, boolean allowBackgroundAuthentication) {
|
||||
super.prepareForAuthentication_enforcePermission();
|
||||
|
||||
final ServiceProvider provider = mRegistry.getProviderForSensor(sensorId);
|
||||
final ServiceProvider provider = mRegistry.getProviderForSensor(options.getSensorId());
|
||||
if (provider == null) {
|
||||
Slog.w(TAG, "Null provider for prepareForAuthentication");
|
||||
return;
|
||||
}
|
||||
|
||||
final boolean restricted = true; // BiometricPrompt is always restricted
|
||||
provider.scheduleAuthenticate(sensorId, token, operationId, userId, cookie,
|
||||
new ClientMonitorCallbackConverter(sensorReceiver), opPackageName, requestId,
|
||||
provider.scheduleAuthenticate(token, operationId, cookie,
|
||||
new ClientMonitorCallbackConverter(sensorReceiver), options, requestId,
|
||||
restricted, BiometricsProtoEnums.CLIENT_BIOMETRIC_PROMPT,
|
||||
allowBackgroundAuthentication);
|
||||
}
|
||||
@@ -982,8 +987,7 @@ public class FingerprintService extends SystemService {
|
||||
() -> IBiometricService.Stub.asInterface(
|
||||
ServiceManager.getService(Context.BIOMETRIC_SERVICE)),
|
||||
() -> ServiceManager.getDeclaredInstances(IFingerprint.DESCRIPTOR),
|
||||
(fqName) -> IFingerprint.Stub.asInterface(
|
||||
Binder.allowBlocking(ServiceManager.waitForDeclaredService(fqName))));
|
||||
null /* fingerprintProvider */);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
@@ -991,16 +995,35 @@ public class FingerprintService extends SystemService {
|
||||
BiometricContext biometricContext,
|
||||
Supplier<IBiometricService> biometricServiceSupplier,
|
||||
Supplier<String[]> aidlInstanceNameSupplier,
|
||||
Function<String, IFingerprint> fingerprintProvider) {
|
||||
Function<String, FingerprintProvider> fingerprintProvider) {
|
||||
super(context);
|
||||
mBiometricContext = biometricContext;
|
||||
mAidlInstanceNameSupplier = aidlInstanceNameSupplier;
|
||||
mIFingerprintProvider = fingerprintProvider;
|
||||
mAppOps = context.getSystemService(AppOpsManager.class);
|
||||
mGestureAvailabilityDispatcher = new GestureAvailabilityDispatcher();
|
||||
mLockoutResetDispatcher = new LockoutResetDispatcher(context);
|
||||
mLockPatternUtils = new LockPatternUtils(context);
|
||||
mBiometricStateCallback = new BiometricStateCallback<>(UserManager.get(context));
|
||||
mFingerprintProvider = fingerprintProvider != null ? fingerprintProvider :
|
||||
(name) -> {
|
||||
final String fqName = IFingerprint.DESCRIPTOR + "/" + name;
|
||||
final IFingerprint fp = IFingerprint.Stub.asInterface(
|
||||
Binder.allowBlocking(ServiceManager.waitForDeclaredService(fqName)));
|
||||
if (fp != null) {
|
||||
try {
|
||||
return new FingerprintProvider(getContext(),
|
||||
mBiometricStateCallback, fp.getSensorProps(), name,
|
||||
mLockoutResetDispatcher, mGestureAvailabilityDispatcher,
|
||||
mBiometricContext);
|
||||
} catch (RemoteException e) {
|
||||
Slog.e(TAG, "Remote exception in getSensorProps: " + fqName);
|
||||
}
|
||||
} else {
|
||||
Slog.e(TAG, "Unable to get declared service: " + fqName);
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
mHandler = new Handler(Looper.getMainLooper());
|
||||
mRegistry = new FingerprintServiceRegistry(mServiceWrapper, biometricServiceSupplier);
|
||||
mRegistry.addAllRegisteredCallback(new IFingerprintAuthenticatorsRegisteredCallback.Stub() {
|
||||
@@ -1044,23 +1067,9 @@ public class FingerprintService extends SystemService {
|
||||
final List<ServiceProvider> providers = new ArrayList<>();
|
||||
|
||||
for (String instance : instances) {
|
||||
final String fqName = IFingerprint.DESCRIPTOR + "/" + instance;
|
||||
final IFingerprint fp = mIFingerprintProvider.apply(fqName);
|
||||
|
||||
if (fp != null) {
|
||||
try {
|
||||
final FingerprintProvider provider = new FingerprintProvider(getContext(),
|
||||
mBiometricStateCallback, fp.getSensorProps(), instance,
|
||||
mLockoutResetDispatcher, mGestureAvailabilityDispatcher,
|
||||
mBiometricContext);
|
||||
Slog.i(TAG, "Adding AIDL provider: " + fqName);
|
||||
providers.add(provider);
|
||||
} catch (RemoteException e) {
|
||||
Slog.e(TAG, "Remote exception in getSensorProps: " + fqName);
|
||||
}
|
||||
} else {
|
||||
Slog.e(TAG, "Unable to get declared service: " + fqName);
|
||||
}
|
||||
final FingerprintProvider provider = mFingerprintProvider.apply(instance);
|
||||
Slog.i(TAG, "Adding AIDL provider: " + instance);
|
||||
providers.add(provider);
|
||||
}
|
||||
|
||||
return providers;
|
||||
|
||||
@@ -23,6 +23,7 @@ import android.hardware.biometrics.ITestSession;
|
||||
import android.hardware.biometrics.ITestSessionCallback;
|
||||
import android.hardware.biometrics.fingerprint.PointerContext;
|
||||
import android.hardware.fingerprint.Fingerprint;
|
||||
import android.hardware.fingerprint.FingerprintAuthenticateOptions;
|
||||
import android.hardware.fingerprint.FingerprintManager;
|
||||
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
|
||||
import android.hardware.fingerprint.IFingerprintServiceReceiver;
|
||||
@@ -78,19 +79,21 @@ public interface ServiceProvider extends
|
||||
|
||||
void cancelEnrollment(int sensorId, @NonNull IBinder token, long requestId);
|
||||
|
||||
long scheduleFingerDetect(int sensorId, @NonNull IBinder token, int userId,
|
||||
@NonNull ClientMonitorCallbackConverter callback, @NonNull String opPackageName,
|
||||
long scheduleFingerDetect(@NonNull IBinder token,
|
||||
@NonNull ClientMonitorCallbackConverter callback,
|
||||
@NonNull FingerprintAuthenticateOptions options,
|
||||
int statsClient);
|
||||
|
||||
void scheduleAuthenticate(int sensorId, @NonNull IBinder token, long operationId, int userId,
|
||||
void scheduleAuthenticate(@NonNull IBinder token, long operationId,
|
||||
int cookie, @NonNull ClientMonitorCallbackConverter callback,
|
||||
@NonNull String opPackageName, long requestId, boolean restricted, int statsClient,
|
||||
@NonNull FingerprintAuthenticateOptions options,
|
||||
long requestId, boolean restricted, int statsClient,
|
||||
boolean allowBackgroundAuthentication);
|
||||
|
||||
long scheduleAuthenticate(int sensorId, @NonNull IBinder token, long operationId, int userId,
|
||||
long scheduleAuthenticate(@NonNull IBinder token, long operationId,
|
||||
int cookie, @NonNull ClientMonitorCallbackConverter callback,
|
||||
@NonNull String opPackageName, boolean restricted, int statsClient,
|
||||
boolean allowBackgroundAuthentication);
|
||||
@NonNull FingerprintAuthenticateOptions options,
|
||||
boolean restricted, int statsClient, boolean allowBackgroundAuthentication);
|
||||
|
||||
void startPreparedClient(int sensorId, int cookie);
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ import android.hardware.biometrics.BiometricFingerprintConstants.FingerprintAcqu
|
||||
import android.hardware.biometrics.BiometricManager.Authenticators;
|
||||
import android.hardware.biometrics.common.ICancellationSignal;
|
||||
import android.hardware.biometrics.fingerprint.PointerContext;
|
||||
import android.hardware.fingerprint.FingerprintAuthenticateOptions;
|
||||
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
|
||||
import android.hardware.fingerprint.ISidefpsController;
|
||||
import android.hardware.fingerprint.IUdfpsOverlay;
|
||||
@@ -65,7 +66,8 @@ import java.util.function.Supplier;
|
||||
* Fingerprint-specific authentication client supporting the {@link
|
||||
* android.hardware.biometrics.fingerprint.IFingerprint} AIDL interface.
|
||||
*/
|
||||
class FingerprintAuthenticationClient extends AuthenticationClient<AidlSession>
|
||||
class FingerprintAuthenticationClient
|
||||
extends AuthenticationClient<AidlSession, FingerprintAuthenticateOptions>
|
||||
implements Udfps, LockoutConsumer, PowerPressHandler {
|
||||
private static final String TAG = "FingerprintAuthenticationClient";
|
||||
private static final int MESSAGE_AUTH_SUCCESS = 2;
|
||||
@@ -97,13 +99,11 @@ class FingerprintAuthenticationClient extends AuthenticationClient<AidlSession>
|
||||
@NonNull IBinder token,
|
||||
long requestId,
|
||||
@NonNull ClientMonitorCallbackConverter listener,
|
||||
int targetUserId,
|
||||
long operationId,
|
||||
boolean restricted,
|
||||
@NonNull String owner,
|
||||
@NonNull FingerprintAuthenticateOptions options,
|
||||
int cookie,
|
||||
boolean requireConfirmation,
|
||||
int sensorId,
|
||||
@NonNull BiometricLogger biometricLogger,
|
||||
@NonNull BiometricContext biometricContext,
|
||||
boolean isStrongBiometric,
|
||||
@@ -122,13 +122,11 @@ class FingerprintAuthenticationClient extends AuthenticationClient<AidlSession>
|
||||
lazyDaemon,
|
||||
token,
|
||||
listener,
|
||||
targetUserId,
|
||||
operationId,
|
||||
restricted,
|
||||
owner,
|
||||
options,
|
||||
cookie,
|
||||
requireConfirmation,
|
||||
sensorId,
|
||||
biometricLogger,
|
||||
biometricContext,
|
||||
isStrongBiometric,
|
||||
|
||||
@@ -21,6 +21,7 @@ import android.annotation.Nullable;
|
||||
import android.content.Context;
|
||||
import android.hardware.biometrics.BiometricOverlayConstants;
|
||||
import android.hardware.biometrics.common.ICancellationSignal;
|
||||
import android.hardware.fingerprint.FingerprintAuthenticateOptions;
|
||||
import android.hardware.fingerprint.IUdfpsOverlay;
|
||||
import android.hardware.fingerprint.IUdfpsOverlayController;
|
||||
import android.os.IBinder;
|
||||
@@ -52,13 +53,14 @@ class FingerprintDetectClient extends AcquisitionClient<AidlSession> implements
|
||||
|
||||
FingerprintDetectClient(@NonNull Context context, @NonNull Supplier<AidlSession> lazyDaemon,
|
||||
@NonNull IBinder token, long requestId,
|
||||
@NonNull ClientMonitorCallbackConverter listener, int userId,
|
||||
@NonNull String owner, int sensorId,
|
||||
@NonNull ClientMonitorCallbackConverter listener,
|
||||
@NonNull FingerprintAuthenticateOptions options,
|
||||
@NonNull BiometricLogger biometricLogger, @NonNull BiometricContext biometricContext,
|
||||
@Nullable IUdfpsOverlayController udfpsOverlayController,
|
||||
@Nullable IUdfpsOverlay udfpsOverlay,
|
||||
boolean isStrongBiometric) {
|
||||
super(context, lazyDaemon, token, listener, userId, owner, 0 /* cookie */, sensorId,
|
||||
super(context, lazyDaemon, token, listener, options.getUserId(),
|
||||
options.getOpPackageName(), 0 /* cookie */, options.getSensorId(),
|
||||
true /* shouldVibrate */, biometricLogger, biometricContext);
|
||||
setRequestId(requestId);
|
||||
mIsStrongBiometric = isStrongBiometric;
|
||||
|
||||
@@ -37,6 +37,7 @@ import android.hardware.biometrics.fingerprint.IFingerprint;
|
||||
import android.hardware.biometrics.fingerprint.PointerContext;
|
||||
import android.hardware.biometrics.fingerprint.SensorProps;
|
||||
import android.hardware.fingerprint.Fingerprint;
|
||||
import android.hardware.fingerprint.FingerprintAuthenticateOptions;
|
||||
import android.hardware.fingerprint.FingerprintManager;
|
||||
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
|
||||
import android.hardware.fingerprint.IFingerprintServiceReceiver;
|
||||
@@ -422,15 +423,17 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi
|
||||
}
|
||||
|
||||
@Override
|
||||
public long scheduleFingerDetect(int sensorId, @NonNull IBinder token, int userId,
|
||||
@NonNull ClientMonitorCallbackConverter callback, @NonNull String opPackageName,
|
||||
public long scheduleFingerDetect(@NonNull IBinder token,
|
||||
@NonNull ClientMonitorCallbackConverter callback,
|
||||
@NonNull FingerprintAuthenticateOptions options,
|
||||
int statsClient) {
|
||||
final long id = mRequestCounter.incrementAndGet();
|
||||
mHandler.post(() -> {
|
||||
final int sensorId = options.getSensorId();
|
||||
final boolean isStrongBiometric = Utils.isStrongBiometric(sensorId);
|
||||
final FingerprintDetectClient client = new FingerprintDetectClient(mContext,
|
||||
mSensors.get(sensorId).getLazySession(), token, id, callback, userId,
|
||||
opPackageName, sensorId,
|
||||
mSensors.get(sensorId).getLazySession(), token, id, callback,
|
||||
options,
|
||||
createLogger(BiometricsProtoEnums.ACTION_AUTHENTICATE, statsClient),
|
||||
mBiometricContext,
|
||||
mUdfpsOverlayController, mUdfpsOverlay, isStrongBiometric);
|
||||
@@ -441,16 +444,19 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi
|
||||
}
|
||||
|
||||
@Override
|
||||
public void scheduleAuthenticate(int sensorId, @NonNull IBinder token, long operationId,
|
||||
int userId, int cookie, @NonNull ClientMonitorCallbackConverter callback,
|
||||
@NonNull String opPackageName, long requestId, boolean restricted, int statsClient,
|
||||
public void scheduleAuthenticate(@NonNull IBinder token, long operationId,
|
||||
int cookie, @NonNull ClientMonitorCallbackConverter callback,
|
||||
@NonNull FingerprintAuthenticateOptions options,
|
||||
long requestId, boolean restricted, int statsClient,
|
||||
boolean allowBackgroundAuthentication) {
|
||||
mHandler.post(() -> {
|
||||
final int userId = options.getUserId();
|
||||
final int sensorId = options.getSensorId();
|
||||
final boolean isStrongBiometric = Utils.isStrongBiometric(sensorId);
|
||||
final FingerprintAuthenticationClient client = new FingerprintAuthenticationClient(
|
||||
mContext, mSensors.get(sensorId).getLazySession(), token, requestId, callback,
|
||||
userId, operationId, restricted, opPackageName, cookie,
|
||||
false /* requireConfirmation */, sensorId,
|
||||
operationId, restricted, options, cookie,
|
||||
false /* requireConfirmation */,
|
||||
createLogger(BiometricsProtoEnums.ACTION_AUTHENTICATE, statsClient),
|
||||
mBiometricContext, isStrongBiometric,
|
||||
mTaskStackListener, mSensors.get(sensorId).getLockoutCache(),
|
||||
@@ -485,14 +491,14 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi
|
||||
}
|
||||
|
||||
@Override
|
||||
public long scheduleAuthenticate(int sensorId, @NonNull IBinder token, long operationId,
|
||||
int userId, int cookie, @NonNull ClientMonitorCallbackConverter callback,
|
||||
@NonNull String opPackageName, boolean restricted, int statsClient,
|
||||
public long scheduleAuthenticate(@NonNull IBinder token, long operationId,
|
||||
int cookie, @NonNull ClientMonitorCallbackConverter callback,
|
||||
@NonNull FingerprintAuthenticateOptions options, boolean restricted, int statsClient,
|
||||
boolean allowBackgroundAuthentication) {
|
||||
final long id = mRequestCounter.incrementAndGet();
|
||||
|
||||
scheduleAuthenticate(sensorId, token, operationId, userId, cookie, callback,
|
||||
opPackageName, id, restricted, statsClient, allowBackgroundAuthentication);
|
||||
scheduleAuthenticate(token, operationId, cookie, callback,
|
||||
options, id, restricted, statsClient, allowBackgroundAuthentication);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ import android.hardware.biometrics.fingerprint.PointerContext;
|
||||
import android.hardware.biometrics.fingerprint.V2_1.IBiometricsFingerprint;
|
||||
import android.hardware.biometrics.fingerprint.V2_2.IBiometricsFingerprintClientCallback;
|
||||
import android.hardware.fingerprint.Fingerprint;
|
||||
import android.hardware.fingerprint.FingerprintAuthenticateOptions;
|
||||
import android.hardware.fingerprint.FingerprintManager;
|
||||
import android.hardware.fingerprint.FingerprintSensorProperties;
|
||||
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
|
||||
@@ -631,17 +632,17 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider
|
||||
}
|
||||
|
||||
@Override
|
||||
public long scheduleFingerDetect(int sensorId, @NonNull IBinder token, int userId,
|
||||
@NonNull ClientMonitorCallbackConverter listener, @NonNull String opPackageName,
|
||||
public long scheduleFingerDetect(@NonNull IBinder token,
|
||||
@NonNull ClientMonitorCallbackConverter listener,
|
||||
@NonNull FingerprintAuthenticateOptions options,
|
||||
int statsClient) {
|
||||
final long id = mRequestCounter.incrementAndGet();
|
||||
mHandler.post(() -> {
|
||||
scheduleUpdateActiveUserWithoutHandler(userId);
|
||||
scheduleUpdateActiveUserWithoutHandler(options.getUserId());
|
||||
|
||||
final boolean isStrongBiometric = Utils.isStrongBiometric(mSensorProperties.sensorId);
|
||||
final FingerprintDetectClient client = new FingerprintDetectClient(mContext,
|
||||
mLazyDaemon, token, id, listener, userId, opPackageName,
|
||||
mSensorProperties.sensorId,
|
||||
mLazyDaemon, token, id, listener, options,
|
||||
createLogger(BiometricsProtoEnums.ACTION_AUTHENTICATE, statsClient),
|
||||
mBiometricContext, mUdfpsOverlayController, mUdfpsOverlay,
|
||||
isStrongBiometric);
|
||||
@@ -652,18 +653,18 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider
|
||||
}
|
||||
|
||||
@Override
|
||||
public void scheduleAuthenticate(int sensorId, @NonNull IBinder token, long operationId,
|
||||
int userId, int cookie, @NonNull ClientMonitorCallbackConverter listener,
|
||||
@NonNull String opPackageName, long requestId, boolean restricted, int statsClient,
|
||||
public void scheduleAuthenticate(@NonNull IBinder token, long operationId,
|
||||
int cookie, @NonNull ClientMonitorCallbackConverter listener,
|
||||
@NonNull FingerprintAuthenticateOptions options,
|
||||
long requestId, boolean restricted, int statsClient,
|
||||
boolean allowBackgroundAuthentication) {
|
||||
mHandler.post(() -> {
|
||||
scheduleUpdateActiveUserWithoutHandler(userId);
|
||||
scheduleUpdateActiveUserWithoutHandler(options.getUserId());
|
||||
|
||||
final boolean isStrongBiometric = Utils.isStrongBiometric(mSensorProperties.sensorId);
|
||||
final FingerprintAuthenticationClient client = new FingerprintAuthenticationClient(
|
||||
mContext, mLazyDaemon, token, requestId, listener, userId, operationId,
|
||||
restricted, opPackageName, cookie, false /* requireConfirmation */,
|
||||
mSensorProperties.sensorId,
|
||||
mContext, mLazyDaemon, token, requestId, listener, operationId,
|
||||
restricted, options, cookie, false /* requireConfirmation */,
|
||||
createLogger(BiometricsProtoEnums.ACTION_AUTHENTICATE, statsClient),
|
||||
mBiometricContext, isStrongBiometric,
|
||||
mTaskStackListener, mLockoutTracker,
|
||||
@@ -675,14 +676,14 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider
|
||||
}
|
||||
|
||||
@Override
|
||||
public long scheduleAuthenticate(int sensorId, @NonNull IBinder token, long operationId,
|
||||
int userId, int cookie, @NonNull ClientMonitorCallbackConverter listener,
|
||||
@NonNull String opPackageName, boolean restricted, int statsClient,
|
||||
public long scheduleAuthenticate(@NonNull IBinder token, long operationId,
|
||||
int cookie, @NonNull ClientMonitorCallbackConverter listener,
|
||||
@NonNull FingerprintAuthenticateOptions options, boolean restricted, int statsClient,
|
||||
boolean allowBackgroundAuthentication) {
|
||||
final long id = mRequestCounter.incrementAndGet();
|
||||
|
||||
scheduleAuthenticate(sensorId, token, operationId, userId, cookie, listener,
|
||||
opPackageName, id, restricted, statsClient, allowBackgroundAuthentication);
|
||||
scheduleAuthenticate(token, operationId, cookie, listener,
|
||||
options, id, restricted, statsClient, allowBackgroundAuthentication);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import android.app.trust.TrustManager;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.hardware.biometrics.fingerprint.PointerContext;
|
||||
import android.hardware.fingerprint.FingerprintAuthenticateOptions;
|
||||
import android.hardware.fingerprint.FingerprintManager;
|
||||
import android.hardware.fingerprint.FingerprintManager.AuthenticationCallback;
|
||||
import android.hardware.fingerprint.FingerprintManager.AuthenticationResult;
|
||||
@@ -362,13 +363,16 @@ public class Fingerprint21UdfpsMock extends Fingerprint21 implements TrustManage
|
||||
// Store the authClient parameters so it can be rescheduled
|
||||
final IBinder token = client.getToken();
|
||||
final long operationId = authClient.getOperationId();
|
||||
final int user = client.getTargetUserId();
|
||||
final int cookie = client.getCookie();
|
||||
final ClientMonitorCallbackConverter listener = client.getListener();
|
||||
final String opPackageName = client.getOwnerString();
|
||||
final boolean restricted = authClient.isRestricted();
|
||||
final int statsClient = client.getLogger().getStatsClient();
|
||||
final boolean isKeyguard = authClient.isKeyguard();
|
||||
final FingerprintAuthenticateOptions options =
|
||||
new FingerprintAuthenticateOptions.Builder()
|
||||
.setUserId(client.getTargetUserId())
|
||||
.setOpPackageName(client.getOwnerString())
|
||||
.build();
|
||||
|
||||
// Don't actually send cancel() to the HAL, since successful auth already finishes
|
||||
// HAL authenticate() lifecycle. Just
|
||||
@@ -376,8 +380,8 @@ public class Fingerprint21UdfpsMock extends Fingerprint21 implements TrustManage
|
||||
|
||||
// Schedule this only after we invoke onClientFinished for the previous client, so that
|
||||
// internal preemption logic is not run.
|
||||
mFingerprint21.scheduleAuthenticate(mFingerprint21.mSensorProperties.sensorId, token,
|
||||
operationId, user, cookie, listener, opPackageName, restricted, statsClient,
|
||||
mFingerprint21.scheduleAuthenticate(token,
|
||||
operationId, cookie, listener, options, restricted, statsClient,
|
||||
isKeyguard);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ import android.hardware.biometrics.BiometricFingerprintConstants;
|
||||
import android.hardware.biometrics.BiometricManager.Authenticators;
|
||||
import android.hardware.biometrics.fingerprint.PointerContext;
|
||||
import android.hardware.biometrics.fingerprint.V2_1.IBiometricsFingerprint;
|
||||
import android.hardware.fingerprint.FingerprintAuthenticateOptions;
|
||||
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
|
||||
import android.hardware.fingerprint.ISidefpsController;
|
||||
import android.hardware.fingerprint.IUdfpsOverlay;
|
||||
@@ -57,7 +58,8 @@ import java.util.function.Supplier;
|
||||
* {@link android.hardware.biometrics.fingerprint.V2_1} and
|
||||
* {@link android.hardware.biometrics.fingerprint.V2_2} HIDL interfaces.
|
||||
*/
|
||||
class FingerprintAuthenticationClient extends AuthenticationClient<IBiometricsFingerprint>
|
||||
class FingerprintAuthenticationClient
|
||||
extends AuthenticationClient<IBiometricsFingerprint, FingerprintAuthenticateOptions>
|
||||
implements Udfps {
|
||||
|
||||
private static final String TAG = "Biometrics/FingerprintAuthClient";
|
||||
@@ -72,9 +74,9 @@ class FingerprintAuthenticationClient extends AuthenticationClient<IBiometricsFi
|
||||
FingerprintAuthenticationClient(@NonNull Context context,
|
||||
@NonNull Supplier<IBiometricsFingerprint> lazyDaemon,
|
||||
@NonNull IBinder token, long requestId,
|
||||
@NonNull ClientMonitorCallbackConverter listener, int targetUserId, long operationId,
|
||||
boolean restricted, @NonNull String owner, int cookie, boolean requireConfirmation,
|
||||
int sensorId, @NonNull BiometricLogger logger,
|
||||
@NonNull ClientMonitorCallbackConverter listener, long operationId,
|
||||
boolean restricted, @NonNull FingerprintAuthenticateOptions options,
|
||||
int cookie, boolean requireConfirmation, @NonNull BiometricLogger logger,
|
||||
@NonNull BiometricContext biometricContext, boolean isStrongBiometric,
|
||||
@NonNull TaskStackListener taskStackListener,
|
||||
@NonNull LockoutFrameworkImpl lockoutTracker,
|
||||
@@ -84,8 +86,8 @@ class FingerprintAuthenticationClient extends AuthenticationClient<IBiometricsFi
|
||||
boolean allowBackgroundAuthentication,
|
||||
@NonNull FingerprintSensorPropertiesInternal sensorProps,
|
||||
@Authenticators.Types int sensorStrength) {
|
||||
super(context, lazyDaemon, token, listener, targetUserId, operationId, restricted,
|
||||
owner, cookie, requireConfirmation, sensorId, logger, biometricContext,
|
||||
super(context, lazyDaemon, token, listener, operationId, restricted,
|
||||
options, cookie, requireConfirmation, logger, biometricContext,
|
||||
isStrongBiometric, taskStackListener, lockoutTracker, allowBackgroundAuthentication,
|
||||
false /* shouldVibrate */, sensorStrength);
|
||||
setRequestId(requestId);
|
||||
|
||||
@@ -24,6 +24,7 @@ import android.hardware.biometrics.BiometricFingerprintConstants;
|
||||
import android.hardware.biometrics.BiometricOverlayConstants;
|
||||
import android.hardware.biometrics.fingerprint.PointerContext;
|
||||
import android.hardware.biometrics.fingerprint.V2_1.IBiometricsFingerprint;
|
||||
import android.hardware.fingerprint.FingerprintAuthenticateOptions;
|
||||
import android.hardware.fingerprint.IUdfpsOverlay;
|
||||
import android.hardware.fingerprint.IUdfpsOverlayController;
|
||||
import android.os.IBinder;
|
||||
@@ -61,12 +62,13 @@ class FingerprintDetectClient extends AcquisitionClient<IBiometricsFingerprint>
|
||||
public FingerprintDetectClient(@NonNull Context context,
|
||||
@NonNull Supplier<IBiometricsFingerprint> lazyDaemon,
|
||||
@NonNull IBinder token, long requestId,
|
||||
@NonNull ClientMonitorCallbackConverter listener, int userId, @NonNull String owner,
|
||||
int sensorId,
|
||||
@NonNull ClientMonitorCallbackConverter listener,
|
||||
@NonNull FingerprintAuthenticateOptions options,
|
||||
@NonNull BiometricLogger biometricLogger, @NonNull BiometricContext biometricContext,
|
||||
@Nullable IUdfpsOverlayController udfpsOverlayController,
|
||||
@Nullable IUdfpsOverlay udfpsOverlay, boolean isStrongBiometric) {
|
||||
super(context, lazyDaemon, token, listener, userId, owner, 0 /* cookie */, sensorId,
|
||||
super(context, lazyDaemon, token, listener, options.getUserId(),
|
||||
options.getOpPackageName(), 0 /* cookie */, options.getSensorId(),
|
||||
true /* shouldVibrate */, biometricLogger, biometricContext);
|
||||
setRequestId(requestId);
|
||||
mSensorOverlays = new SensorOverlays(udfpsOverlayController,
|
||||
|
||||
@@ -37,6 +37,7 @@ import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.content.Context;
|
||||
import android.hardware.biometrics.AuthenticateOptions;
|
||||
import android.hardware.biometrics.BiometricAuthenticator;
|
||||
import android.hardware.biometrics.BiometricConstants;
|
||||
import android.hardware.biometrics.IBiometricService;
|
||||
@@ -681,7 +682,37 @@ public class BiometricSchedulerTest {
|
||||
TestableLooper.get(this).processAllMessages();
|
||||
}
|
||||
|
||||
private static class TestAuthenticationClient extends AuthenticationClient<Object> {
|
||||
private static class TestAuthenticateOptions implements AuthenticateOptions {
|
||||
@Override
|
||||
public int getUserId() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSensorId() {
|
||||
return TEST_SENSOR_ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDisplayState() {
|
||||
return DISPLAY_STATE_UNKNOWN;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String getOpPackageName() {
|
||||
return "some.test.name";
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getAttributionTag() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static class TestAuthenticationClient
|
||||
extends AuthenticationClient<Object, TestAuthenticateOptions> {
|
||||
boolean mStartedHal = false;
|
||||
boolean mStoppedHal = false;
|
||||
boolean mDestroyed = false;
|
||||
@@ -700,9 +731,10 @@ public class BiometricSchedulerTest {
|
||||
@NonNull Supplier<Object> lazyDaemon, @NonNull IBinder token,
|
||||
@NonNull ClientMonitorCallbackConverter listener, int cookie,
|
||||
@NonNull BiometricContext biometricContext) {
|
||||
super(context, lazyDaemon, token, listener, 0 /* targetUserId */, 0 /* operationId */,
|
||||
false /* restricted */, TAG, cookie, false /* requireConfirmation */,
|
||||
TEST_SENSOR_ID, mock(BiometricLogger.class), biometricContext,
|
||||
super(context, lazyDaemon, token, listener, 0 /* operationId */,
|
||||
false /* restricted */, new TestAuthenticateOptions(), cookie,
|
||||
false /* requireConfirmation */,
|
||||
mock(BiometricLogger.class), biometricContext,
|
||||
true /* isStrongBiometric */, null /* taskStackListener */,
|
||||
null /* lockoutTracker */, false /* isKeyguard */,
|
||||
true /* shouldVibrate */,
|
||||
|
||||
@@ -33,6 +33,7 @@ import android.content.ComponentName;
|
||||
import android.hardware.biometrics.common.ICancellationSignal;
|
||||
import android.hardware.biometrics.face.ISession;
|
||||
import android.hardware.face.Face;
|
||||
import android.hardware.face.FaceAuthenticateOptions;
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
import android.platform.test.annotations.Presubmit;
|
||||
@@ -153,14 +154,18 @@ public class FaceAuthenticationClientTest {
|
||||
when(mHal.getInterfaceVersion()).thenReturn(version);
|
||||
|
||||
final AidlSession aidl = new AidlSession(version, mHal, USER_ID, mHalSessionCallback);
|
||||
final FaceAuthenticateOptions options = new FaceAuthenticateOptions.Builder()
|
||||
.setOpPackageName("test-owner")
|
||||
.setUserId(5)
|
||||
.setSensorId(9)
|
||||
.build();
|
||||
return new FaceAuthenticationClient(mContext, () -> aidl, mToken,
|
||||
2 /* requestId */, mClientMonitorCallbackConverter, 5 /* targetUserId */, OP_ID,
|
||||
false /* restricted */, "test-owner", 4 /* cookie */,
|
||||
false /* requireConfirmation */, 9 /* sensorId */,
|
||||
2 /* requestId */, mClientMonitorCallbackConverter, OP_ID,
|
||||
false /* restricted */, options, 4 /* cookie */,
|
||||
false /* requireConfirmation */,
|
||||
mBiometricLogger, mBiometricContext, true /* isStrongBiometric */,
|
||||
mUsageStats, null /* mLockoutCache */, false /* allowBackgroundAuthentication */,
|
||||
null /* sensorPrivacyManager */,
|
||||
0 /* biometricStrength */) {
|
||||
null /* sensorPrivacyManager */, 0 /* biometricStrength */) {
|
||||
@Override
|
||||
protected ActivityTaskManager getActivityTaskManager() {
|
||||
return mActivityTaskManager;
|
||||
|
||||
@@ -25,6 +25,7 @@ import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.hardware.biometrics.face.ISession;
|
||||
import android.hardware.face.FaceAuthenticateOptions;
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
import android.platform.test.annotations.Presubmit;
|
||||
@@ -112,8 +113,13 @@ public class FaceDetectClientTest {
|
||||
|
||||
final AidlSession aidl = new AidlSession(version, mHal, USER_ID, mHalSessionCallback);
|
||||
return new FaceDetectClient(mContext, () -> aidl, mToken,
|
||||
99 /* requestId */, mClientMonitorCallbackConverter, USER_ID,
|
||||
"own-it", 5 /* sensorId */, mBiometricLogger, mBiometricContext,
|
||||
99 /* requestId */, mClientMonitorCallbackConverter,
|
||||
new FaceAuthenticateOptions.Builder()
|
||||
.setUserId(USER_ID)
|
||||
.setSensorId(5)
|
||||
.setOpPackageName("own-it")
|
||||
.build(),
|
||||
mBiometricLogger, mBiometricContext,
|
||||
false /* isStrongBiometric */, null /* sensorPrivacyManager */);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,7 +144,7 @@ public class BiometricStateCallbackTest {
|
||||
|
||||
@Test
|
||||
public void testAuthentication_enrollmentCallbackNeverNotified() {
|
||||
AuthenticationClient<?> client = mock(AuthenticationClient.class);
|
||||
AuthenticationClient<?, ?> client = mock(AuthenticationClient.class);
|
||||
mCallback.onClientFinished(client, true /* success */);
|
||||
verify(mBiometricStateListener, never()).onEnrollmentsChanged(anyInt(), anyInt(),
|
||||
anyBoolean());
|
||||
|
||||
@@ -16,24 +16,35 @@
|
||||
|
||||
package com.android.server.biometrics.sensors.fingerprint;
|
||||
|
||||
import static android.Manifest.permission.USE_BIOMETRIC;
|
||||
import static android.Manifest.permission.USE_BIOMETRIC_INTERNAL;
|
||||
import static android.app.AppOpsManager.OP_USE_BIOMETRIC;
|
||||
import static android.app.AppOpsManager.OP_USE_FINGERPRINT;
|
||||
import static android.hardware.biometrics.SensorProperties.STRENGTH_STRONG;
|
||||
import static android.hardware.fingerprint.FingerprintManager.SENSOR_ID_ANY;
|
||||
import static android.hardware.fingerprint.FingerprintSensorProperties.TYPE_REAR;
|
||||
import static android.hardware.fingerprint.FingerprintSensorProperties.TYPE_UDFPS_OPTICAL;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.anyLong;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.app.AppOpsManager;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.hardware.biometrics.IBiometricService;
|
||||
import android.hardware.biometrics.common.CommonProps;
|
||||
import android.hardware.biometrics.common.SensorStrength;
|
||||
import android.hardware.biometrics.fingerprint.FingerprintSensorType;
|
||||
import android.hardware.biometrics.fingerprint.IFingerprint;
|
||||
import android.hardware.biometrics.fingerprint.SensorLocation;
|
||||
import android.hardware.biometrics.fingerprint.SensorProps;
|
||||
import android.hardware.fingerprint.FingerprintAuthenticateOptions;
|
||||
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
|
||||
import android.hardware.fingerprint.IFingerprintAuthenticatorsRegisteredCallback;
|
||||
import android.hardware.fingerprint.IFingerprintServiceReceiver;
|
||||
import android.os.IBinder;
|
||||
import android.platform.test.annotations.Presubmit;
|
||||
import android.provider.Settings;
|
||||
import android.testing.TestableContext;
|
||||
@@ -44,10 +55,13 @@ import androidx.test.platform.app.InstrumentationRegistry;
|
||||
import com.android.internal.util.test.FakeSettingsProvider;
|
||||
import com.android.internal.util.test.FakeSettingsProviderRule;
|
||||
import com.android.server.biometrics.log.BiometricContext;
|
||||
import com.android.server.biometrics.sensors.fingerprint.aidl.FingerprintProvider;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Captor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnit;
|
||||
import org.mockito.junit.MockitoRule;
|
||||
@@ -64,6 +78,8 @@ public class FingerprintServiceTest {
|
||||
private static final int ID_VIRTUAL = 6;
|
||||
private static final String NAME_DEFAULT = "default";
|
||||
private static final String NAME_VIRTUAL = "virtual";
|
||||
private static final List<FingerprintSensorPropertiesInternal> HIDL_AUTHENTICATORS =
|
||||
List.of();
|
||||
|
||||
@Rule
|
||||
public final MockitoRule mMockito = MockitoJUnit.rule();
|
||||
@@ -73,48 +89,81 @@ public class FingerprintServiceTest {
|
||||
@Rule
|
||||
public final FakeSettingsProviderRule mSettingsRule = FakeSettingsProvider.rule();
|
||||
|
||||
@Mock
|
||||
private AppOpsManager mAppOpsManager;
|
||||
@Mock
|
||||
private BiometricContext mBiometricContext;
|
||||
@Mock
|
||||
private IBiometricService mIBiometricService;
|
||||
@Mock
|
||||
private IFingerprint mIFingerprintDefault;
|
||||
private FingerprintProvider mFingerprintDefault;
|
||||
@Mock
|
||||
private IFingerprint mIFingerprintVirtual;
|
||||
private FingerprintProvider mFingerprintVirtual;
|
||||
@Mock
|
||||
private IFingerprintServiceReceiver mServiceReceiver;
|
||||
@Mock
|
||||
private IBinder mToken;
|
||||
|
||||
private final SensorProps mSensorPropsDefault = createProps(ID_DEFAULT,
|
||||
SensorStrength.STRONG, FingerprintSensorType.POWER_BUTTON);
|
||||
private final SensorProps mSensorPropsVirtual = createProps(ID_VIRTUAL,
|
||||
SensorStrength.STRONG, FingerprintSensorType.UNDER_DISPLAY_OPTICAL);
|
||||
@Captor
|
||||
private ArgumentCaptor<FingerprintAuthenticateOptions> mAuthenticateOptionsCaptor;
|
||||
|
||||
private final FingerprintSensorPropertiesInternal mSensorPropsDefault =
|
||||
new FingerprintSensorPropertiesInternal(ID_DEFAULT, STRENGTH_STRONG,
|
||||
2 /* maxEnrollmentsPerUser */,
|
||||
List.of(),
|
||||
TYPE_REAR,
|
||||
false /* resetLockoutRequiresHardwareAuthToken */);
|
||||
private final FingerprintSensorPropertiesInternal mSensorPropsVirtual =
|
||||
new FingerprintSensorPropertiesInternal(ID_VIRTUAL, STRENGTH_STRONG,
|
||||
2 /* maxEnrollmentsPerUser */,
|
||||
List.of(),
|
||||
TYPE_UDFPS_OPTICAL,
|
||||
false /* resetLockoutRequiresHardwareAuthToken */);
|
||||
private FingerprintService mService;
|
||||
|
||||
@Before
|
||||
public void setup() throws Exception {
|
||||
when(mIFingerprintDefault.getSensorProps()).thenReturn(
|
||||
new SensorProps[]{mSensorPropsDefault});
|
||||
when(mIFingerprintVirtual.getSensorProps()).thenReturn(
|
||||
new SensorProps[]{mSensorPropsVirtual});
|
||||
when(mFingerprintDefault.getSensorProperties()).thenReturn(List.of(mSensorPropsDefault));
|
||||
when(mFingerprintVirtual.getSensorProperties()).thenReturn(List.of(mSensorPropsVirtual));
|
||||
when(mFingerprintDefault.containsSensor(anyInt()))
|
||||
.thenAnswer(i -> i.getArguments()[0].equals(ID_DEFAULT));
|
||||
when(mFingerprintVirtual.containsSensor(anyInt()))
|
||||
.thenAnswer(i -> i.getArguments()[0].equals(ID_VIRTUAL));
|
||||
|
||||
mContext.getTestablePermissions().setPermission(
|
||||
USE_BIOMETRIC_INTERNAL, PackageManager.PERMISSION_GRANTED);
|
||||
mContext.addMockSystemService(AppOpsManager.class, mAppOpsManager);
|
||||
for (int permission : List.of(OP_USE_BIOMETRIC, OP_USE_FINGERPRINT)) {
|
||||
when(mAppOpsManager.noteOp(eq(permission), anyInt(), any(), any(), any()))
|
||||
.thenReturn(AppOpsManager.MODE_ALLOWED);
|
||||
}
|
||||
|
||||
for (String permission : List.of(USE_BIOMETRIC, USE_BIOMETRIC_INTERNAL)) {
|
||||
mContext.getTestablePermissions().setPermission(
|
||||
permission, PackageManager.PERMISSION_GRANTED);
|
||||
}
|
||||
}
|
||||
|
||||
private void initServiceWith(String... aidlInstances) {
|
||||
mService = new FingerprintService(mContext, mBiometricContext,
|
||||
() -> mIBiometricService,
|
||||
() -> aidlInstances,
|
||||
(fqName) -> {
|
||||
if (fqName.endsWith(NAME_DEFAULT)) return mIFingerprintDefault;
|
||||
if (fqName.endsWith(NAME_VIRTUAL)) return mIFingerprintVirtual;
|
||||
(name) -> {
|
||||
if (NAME_DEFAULT.equals(name)) return mFingerprintDefault;
|
||||
if (NAME_VIRTUAL.equals(name)) return mFingerprintVirtual;
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
private void initServiceWithAndWait(String... aidlInstances) throws Exception {
|
||||
initServiceWith(aidlInstances);
|
||||
mService.mServiceWrapper.registerAuthenticators(HIDL_AUTHENTICATORS);
|
||||
waitForRegistration();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void registerAuthenticators_defaultOnly() throws Exception {
|
||||
initServiceWith(NAME_DEFAULT, NAME_VIRTUAL);
|
||||
|
||||
mService.mServiceWrapper.registerAuthenticators(List.of());
|
||||
mService.mServiceWrapper.registerAuthenticators(HIDL_AUTHENTICATORS);
|
||||
waitForRegistration();
|
||||
|
||||
verify(mIBiometricService).registerAuthenticator(eq(ID_DEFAULT), anyInt(), anyInt(), any());
|
||||
@@ -126,7 +175,7 @@ public class FingerprintServiceTest {
|
||||
Settings.Secure.putInt(mSettingsRule.mockContentResolver(mContext),
|
||||
Settings.Secure.BIOMETRIC_VIRTUAL_ENABLED, 1);
|
||||
|
||||
mService.mServiceWrapper.registerAuthenticators(List.of());
|
||||
mService.mServiceWrapper.registerAuthenticators(HIDL_AUTHENTICATORS);
|
||||
waitForRegistration();
|
||||
|
||||
verify(mIBiometricService).registerAuthenticator(eq(ID_VIRTUAL), anyInt(), anyInt(), any());
|
||||
@@ -136,7 +185,7 @@ public class FingerprintServiceTest {
|
||||
public void registerAuthenticators_virtualAlwaysWhenNoOther() throws Exception {
|
||||
initServiceWith(NAME_VIRTUAL);
|
||||
|
||||
mService.mServiceWrapper.registerAuthenticators(List.of());
|
||||
mService.mServiceWrapper.registerAuthenticators(HIDL_AUTHENTICATORS);
|
||||
waitForRegistration();
|
||||
|
||||
verify(mIBiometricService).registerAuthenticator(eq(ID_VIRTUAL), anyInt(), anyInt(), any());
|
||||
@@ -155,13 +204,47 @@ public class FingerprintServiceTest {
|
||||
latch.await(5, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
private static SensorProps createProps(int id, byte strength, byte type) {
|
||||
final SensorProps props = new SensorProps();
|
||||
props.commonProps = new CommonProps();
|
||||
props.commonProps.sensorId = id;
|
||||
props.commonProps.sensorStrength = strength;
|
||||
props.sensorType = type;
|
||||
props.sensorLocations = new SensorLocation[]{new SensorLocation()};
|
||||
return props;
|
||||
@Test
|
||||
public void authenticateWithDefaultSensorId() throws Exception {
|
||||
initServiceWithAndWait(NAME_DEFAULT, NAME_VIRTUAL);
|
||||
|
||||
final long operationId = 2;
|
||||
mService.mServiceWrapper.authenticate(mToken, operationId, mServiceReceiver,
|
||||
new FingerprintAuthenticateOptions.Builder()
|
||||
.setSensorId(SENSOR_ID_ANY)
|
||||
.build());
|
||||
|
||||
final FingerprintAuthenticateOptions options =
|
||||
verifyAuthenticateWithNewRequestId(mFingerprintDefault, operationId);
|
||||
assertThat(options.getSensorId()).isEqualTo(ID_DEFAULT);
|
||||
verifyNoAuthenticate(mFingerprintVirtual);
|
||||
}
|
||||
|
||||
|
||||
private FingerprintAuthenticateOptions verifyAuthenticateWithNewRequestId(
|
||||
FingerprintProvider provider, long operationId) {
|
||||
return verifyAuthenticateWithNewRequestId(
|
||||
provider, operationId, true /* shouldSchedule */);
|
||||
}
|
||||
|
||||
private void verifyNoAuthenticate(FingerprintProvider provider) {
|
||||
verifyAuthenticateWithNewRequestId(
|
||||
provider, 0 /* operationId */, false /* shouldSchedule */);
|
||||
}
|
||||
|
||||
private FingerprintAuthenticateOptions verifyAuthenticateWithNewRequestId(
|
||||
FingerprintProvider provider, long operationId, boolean shouldSchedule) {
|
||||
verify(provider, shouldSchedule ? times(1) : never())
|
||||
.scheduleAuthenticate(eq(mToken), eq(operationId), anyInt(), any(),
|
||||
mAuthenticateOptionsCaptor.capture(), anyBoolean(), anyInt(),
|
||||
anyBoolean());
|
||||
verify(provider, never()).scheduleAuthenticate(eq(mToken), anyLong(),
|
||||
anyInt(), any(), mAuthenticateOptionsCaptor.capture(), anyLong(),
|
||||
anyBoolean(), anyInt(), anyBoolean());
|
||||
|
||||
if (shouldSchedule) {
|
||||
return mAuthenticateOptionsCaptor.getValue();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,6 +41,7 @@ import android.hardware.biometrics.common.OperationContext;
|
||||
import android.hardware.biometrics.fingerprint.ISession;
|
||||
import android.hardware.biometrics.fingerprint.PointerContext;
|
||||
import android.hardware.fingerprint.Fingerprint;
|
||||
import android.hardware.fingerprint.FingerprintAuthenticateOptions;
|
||||
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
|
||||
import android.hardware.fingerprint.ISidefpsController;
|
||||
import android.hardware.fingerprint.IUdfpsOverlayController;
|
||||
@@ -414,11 +415,16 @@ public class FingerprintAuthenticationClientTest {
|
||||
when(mHal.getInterfaceVersion()).thenReturn(version);
|
||||
|
||||
final AidlSession aidl = new AidlSession(version, mHal, USER_ID, mHalSessionCallback);
|
||||
final FingerprintAuthenticateOptions options = new FingerprintAuthenticateOptions.Builder()
|
||||
.setOpPackageName("test-owner")
|
||||
.setUserId(5)
|
||||
.setSensorId(9)
|
||||
.build();
|
||||
return new FingerprintAuthenticationClient(mContext, () -> aidl, mToken,
|
||||
REQUEST_ID, mClientMonitorCallbackConverter, 5 /* targetUserId */, OP_ID,
|
||||
false /* restricted */, "test-owner", 4 /* cookie */,
|
||||
REQUEST_ID, mClientMonitorCallbackConverter, OP_ID,
|
||||
false /* restricted */, options, 4 /* cookie */,
|
||||
false /* requireConfirmation */,
|
||||
9 /* sensorId */, mBiometricLogger, mBiometricContext,
|
||||
mBiometricLogger, mBiometricContext,
|
||||
true /* isStrongBiometric */,
|
||||
null /* taskStackListener */, null /* lockoutCache */,
|
||||
mUdfpsOverlayController, mSideFpsController, null, allowBackgroundAuthentication,
|
||||
|
||||
@@ -25,6 +25,7 @@ import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.hardware.biometrics.fingerprint.ISession;
|
||||
import android.hardware.fingerprint.FingerprintAuthenticateOptions;
|
||||
import android.hardware.fingerprint.IUdfpsOverlayController;
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
@@ -117,8 +118,13 @@ public class FingerprintDetectClientTest {
|
||||
|
||||
final AidlSession aidl = new AidlSession(version, mHal, USER_ID, mHalSessionCallback);
|
||||
return new FingerprintDetectClient(mContext, () -> aidl, mToken,
|
||||
6 /* requestId */, mClientMonitorCallbackConverter, 2 /* userId */,
|
||||
"a-test", 1 /* sensorId */, mBiometricLogger, mBiometricContext,
|
||||
6 /* requestId */, mClientMonitorCallbackConverter,
|
||||
new FingerprintAuthenticateOptions.Builder()
|
||||
.setUserId(2)
|
||||
.setSensorId(1)
|
||||
.setOpPackageName("a-test")
|
||||
.build(),
|
||||
mBiometricLogger, mBiometricContext,
|
||||
mUdfpsOverlayController, null, true /* isStrongBiometric */);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user