Merge "Propogate face/fingerprint authenticate options to detect and authenticate clients." into udc-dev
diff --git a/core/java/android/hardware/face/FaceAuthenticateOptions.java b/core/java/android/hardware/face/FaceAuthenticateOptions.java
index 4009fa7..1c6de04 100644
--- a/core/java/android/hardware/face/FaceAuthenticateOptions.java
+++ b/core/java/android/hardware/face/FaceAuthenticateOptions.java
@@ -52,7 +52,7 @@
     }
 
     /** The sensor id for this operation. */
-    private final int mSensorId;
+    private int mSensorId;
     private static int defaultSensorId() {
         return -1;
     }
@@ -299,6 +299,15 @@
     }
 
     /**
+     * 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 @@
     }
 
     @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() {}
 
diff --git a/core/java/android/hardware/face/IFaceService.aidl b/core/java/android/hardware/face/IFaceService.aidl
index 2857627..9d5073e 100644
--- a/core/java/android/hardware/face/IFaceService.aidl
+++ b/core/java/android/hardware/face/IFaceService.aidl
@@ -68,7 +68,7 @@
     // 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);
diff --git a/core/java/android/hardware/fingerprint/FingerprintAuthenticateOptions.java b/core/java/android/hardware/fingerprint/FingerprintAuthenticateOptions.java
index cecb317..763246e 100644
--- a/core/java/android/hardware/fingerprint/FingerprintAuthenticateOptions.java
+++ b/core/java/android/hardware/fingerprint/FingerprintAuthenticateOptions.java
@@ -46,7 +46,7 @@
     }
 
     /** The sensor id for this operation. */
-    private final int mSensorId;
+    private int mSensorId;
     private static int defaultSensorId() {
         return SENSOR_ID_ANY;
     }
@@ -176,6 +176,15 @@
     }
 
     /**
+     * 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 @@
     }
 
     @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() {}
 
diff --git a/core/java/android/hardware/fingerprint/IFingerprintService.aidl b/core/java/android/hardware/fingerprint/IFingerprintService.aidl
index e3ae299..ec5749e 100644
--- a/core/java/android/hardware/fingerprint/IFingerprintService.aidl
+++ b/core/java/android/hardware/fingerprint/IFingerprintService.aidl
@@ -73,8 +73,8 @@
     // 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.
diff --git a/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java
index dce88da..005ad20 100644
--- a/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java
@@ -23,6 +23,7 @@
 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 @@
 /**
  * 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 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;
diff --git a/services/core/java/com/android/server/biometrics/sensors/BiometricServiceProvider.java b/services/core/java/com/android/server/biometrics/sensors/BiometricServiceProvider.java
index 0f1fe68..25651fa28 100644
--- a/services/core/java/com/android/server/biometrics/sensors/BiometricServiceProvider.java
+++ b/services/core/java/com/android/server/biometrics/sensors/BiometricServiceProvider.java
@@ -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 @@
     List<T> getSensorProperties();
 
     /** Properties for the given sensor id. */
-    @NonNull
+    @Nullable
     T getSensorProperties(int sensorId);
 
     boolean isHardwareDetected(int sensorId);
diff --git a/services/core/java/com/android/server/biometrics/sensors/BiometricStateCallback.java b/services/core/java/com/android/server/biometrics/sensors/BiometricStateCallback.java
index 2263e80..a4b0a0e 100644
--- a/services/core/java/com/android/server/biometrics/sensors/BiometricStateCallback.java
+++ b/services/core/java/com/android/server/biometrics/sensors/BiometricStateCallback.java
@@ -92,7 +92,7 @@
         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()) {
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/FaceAuthenticator.java b/services/core/java/com/android/server/biometrics/sensors/face/FaceAuthenticator.java
index 5182968..fb64bcc 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/FaceAuthenticator.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/FaceAuthenticator.java
@@ -64,9 +64,10 @@
             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);
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java b/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java
index 1ee9f53..6d7b2cb 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java
@@ -246,7 +246,6 @@
 
             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 @@
             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 @@
                 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);
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/ServiceProvider.java b/services/core/java/com/android/server/biometrics/sensors/face/ServiceProvider.java
index 609c6a7..2cf64b7 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/ServiceProvider.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/ServiceProvider.java
@@ -83,18 +83,19 @@
 
     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);
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClient.java
index 29dd707..976f1cb 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClient.java
@@ -28,6 +28,7 @@
 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 @@
 /**
  * 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 @@
     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 @@
     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);
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceDetectClient.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceDetectClient.java
index 506b2bc..e65202d 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceDetectClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceDetectClient.java
@@ -22,6 +22,7 @@
 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 @@
 
     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 @@
     @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;
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java
index 41e0269..cf8ea86 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java
@@ -410,16 +410,17 @@
     }
 
     @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 @@
     }
 
     @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 @@
     }
 
     @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;
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java b/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java
index 7e575bc..0f22296 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java
@@ -651,9 +651,9 @@
     }
 
     @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 @@
     }
 
     @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 @@
 
             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 @@
     }
 
     @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;
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceAuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceAuthenticationClient.java
index 1c1f56c..8ab8892 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceAuthenticationClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceAuthenticationClient.java
@@ -25,6 +25,7 @@
 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 @@
  * 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 @@
     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);
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintAuthenticator.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintAuthenticator.java
index 52d887a..d47a57a 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintAuthenticator.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintAuthenticator.java
@@ -23,6 +23,7 @@
 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 @@
             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
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
index affc496e..8a33f22 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
@@ -119,7 +119,7 @@
     @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 @@
             if (provider == null) {
                 Slog.w(TAG, "Null provider for authenticate");
                 return -1;
+            } else {
+                options.setSensorId(provider.first);
             }
 
             final FingerprintSensorPropertiesInternal sensorProps =
@@ -322,8 +324,8 @@
                     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 @@
             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 @@
                 () -> 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 @@
             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 @@
         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;
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/ServiceProvider.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/ServiceProvider.java
index 5b6f14d..004af2c 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/ServiceProvider.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/ServiceProvider.java
@@ -23,6 +23,7 @@
 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 @@
 
     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);
 
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java
index d1a7b13..0f81f9f 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java
@@ -26,6 +26,7 @@
 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 @@
  * 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 @@
             @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 @@
                 lazyDaemon,
                 token,
                 listener,
-                targetUserId,
                 operationId,
                 restricted,
-                owner,
+                options,
                 cookie,
                 requireConfirmation,
-                sensorId,
                 biometricLogger,
                 biometricContext,
                 isStrongBiometric,
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintDetectClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintDetectClient.java
index f6911ea..376d231 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintDetectClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintDetectClient.java
@@ -21,6 +21,7 @@
 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 @@
 
     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;
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java
index 776d331..a833278 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java
@@ -37,6 +37,7 @@
 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 @@
     }
 
     @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 @@
     }
 
     @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 @@
     }
 
     @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;
     }
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java
index 4567addc..99c491a 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java
@@ -34,6 +34,7 @@
 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 @@
     }
 
     @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 @@
     }
 
     @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 @@
     }
 
     @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;
     }
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21UdfpsMock.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21UdfpsMock.java
index 73b1288..0a47c12 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21UdfpsMock.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21UdfpsMock.java
@@ -22,6 +22,7 @@
 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 @@
             // 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 @@
 
             // 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);
         }
     }
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintAuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintAuthenticationClient.java
index 957005a..d22aef8 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintAuthenticationClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintAuthenticationClient.java
@@ -26,6 +26,7 @@
 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 @@
  * {@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 @@
     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 @@
             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);
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintDetectClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintDetectClient.java
index cfa9fb4..362c820 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintDetectClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintDetectClient.java
@@ -24,6 +24,7 @@
 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 @@
     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,
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerTest.java
index b0c3a6e..cf650d2 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerTest.java
@@ -37,6 +37,7 @@
 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 @@
         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 @@
                 @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 */,
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClientTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClientTest.java
index 184a556..3ff802c 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClientTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClientTest.java
@@ -33,6 +33,7 @@
 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 @@
         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;
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceDetectClientTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceDetectClientTest.java
index e0fdb8c..c4c5505 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceDetectClientTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceDetectClientTest.java
@@ -25,6 +25,7 @@
 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 @@
 
         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 */);
     }
 }
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/BiometricStateCallbackTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/BiometricStateCallbackTest.java
index 3b66eab..54d6478 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/BiometricStateCallbackTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/BiometricStateCallbackTest.java
@@ -144,7 +144,7 @@
 
     @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());
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/FingerprintServiceTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/FingerprintServiceTest.java
index a4048a2..25a700a 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/FingerprintServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/FingerprintServiceTest.java
@@ -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 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 @@
     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();
@@ -74,47 +90,80 @@
     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 @@
         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 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 @@
         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;
     }
 }
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClientTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClientTest.java
index 99f7905..f0f975c 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClientTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClientTest.java
@@ -41,6 +41,7 @@
 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 @@
         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,
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintDetectClientTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintDetectClientTest.java
index 2dbd8f6..e741e44 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintDetectClientTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintDetectClientTest.java
@@ -25,6 +25,7 @@
 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 @@
 
         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 */);
     }
 }