summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/biometrics/log/BiometricContext.java20
-rw-r--r--services/core/java/com/android/server/biometrics/log/BiometricContextProvider.java13
-rw-r--r--services/core/java/com/android/server/biometrics/log/OperationContextExt.java18
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/HalClientMonitor.java4
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceAuthenticationClient.java34
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceDetectClient.java31
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceEnrollClient.java49
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintAuthenticationClient.java52
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintDetectClient.java33
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java36
-rw-r--r--services/tests/servicestests/src/com/android/server/biometrics/log/BiometricContextProviderTest.java39
11 files changed, 323 insertions, 6 deletions
diff --git a/services/core/java/com/android/server/biometrics/log/BiometricContext.java b/services/core/java/com/android/server/biometrics/log/BiometricContext.java
index 3dcea19b6077..337745c43e80 100644
--- a/services/core/java/com/android/server/biometrics/log/BiometricContext.java
+++ b/services/core/java/com/android/server/biometrics/log/BiometricContext.java
@@ -84,10 +84,30 @@ public interface BiometricContext {
*
* @param context context that will be modified when changed
* @param consumer callback when the context is modified
+ *
+ * @deprecated instead use {@link BiometricContext#subscribe(OperationContextExt, Consumer,
+ * Consumer, AuthenticateOptions)}
+ * TODO (b/294161627): Delete this API once Flags.DE_HIDL is removed.
*/
+ @Deprecated
void subscribe(@NonNull OperationContextExt context,
@NonNull Consumer<OperationContext> consumer);
+ /**
+ * Subscribe to context changes and start the HAL operation.
+ *
+ * Note that this method only notifies for properties that are visible to the HAL.
+ *
+ * @param context context that will be modified when changed
+ * @param startHalConsumer callback to start HAL operation after subscription is done
+ * @param updateContextConsumer callback when the context is modified
+ * @param options authentication options for updating the context
+ */
+ void subscribe(@NonNull OperationContextExt context,
+ @NonNull Consumer<OperationContext> startHalConsumer,
+ @NonNull Consumer<OperationContext> updateContextConsumer,
+ @Nullable AuthenticateOptions options);
+
/** Unsubscribe from context changes. */
void unsubscribe(@NonNull OperationContextExt context);
diff --git a/services/core/java/com/android/server/biometrics/log/BiometricContextProvider.java b/services/core/java/com/android/server/biometrics/log/BiometricContextProvider.java
index 95a047faef07..ddcd4292b7b5 100644
--- a/services/core/java/com/android/server/biometrics/log/BiometricContextProvider.java
+++ b/services/core/java/com/android/server/biometrics/log/BiometricContextProvider.java
@@ -225,6 +225,19 @@ public final class BiometricContextProvider implements BiometricContext {
}
@Override
+ public void subscribe(@NonNull OperationContextExt context,
+ @NonNull Consumer<OperationContext> startHalConsumer,
+ @NonNull Consumer<OperationContext> updateContextConsumer,
+ @Nullable AuthenticateOptions options) {
+ mSubscribers.put(updateContext(context, context.isCrypto()), updateContextConsumer);
+ if (options != null) {
+ startHalConsumer.accept(context.toAidlContext(options));
+ } else {
+ startHalConsumer.accept(context.toAidlContext());
+ }
+ }
+
+ @Override
public void unsubscribe(@NonNull OperationContextExt context) {
mSubscribers.remove(context);
}
diff --git a/services/core/java/com/android/server/biometrics/log/OperationContextExt.java b/services/core/java/com/android/server/biometrics/log/OperationContextExt.java
index b4e0dff615f5..9c86cecd6331 100644
--- a/services/core/java/com/android/server/biometrics/log/OperationContextExt.java
+++ b/services/core/java/com/android/server/biometrics/log/OperationContextExt.java
@@ -87,6 +87,24 @@ public class OperationContextExt {
* @return the underlying AIDL context
*/
@NonNull
+ public OperationContext toAidlContext(@NonNull AuthenticateOptions options) {
+ if (options instanceof FaceAuthenticateOptions) {
+ return toAidlContext((FaceAuthenticateOptions) options);
+ }
+ if (options instanceof FingerprintAuthenticateOptions) {
+ return toAidlContext((FingerprintAuthenticateOptions) options);
+ }
+ throw new IllegalStateException("Authenticate options are invalid.");
+ }
+
+ /**
+ * Gets the subset of the context that can be shared with the HAL and updates
+ * it with the given options.
+ *
+ * @param options authenticate options
+ * @return the underlying AIDL context
+ */
+ @NonNull
public OperationContext toAidlContext(@NonNull FaceAuthenticateOptions options) {
mAidlContext.authenticateReason = AuthenticateReason
.faceAuthenticateReason(getAuthReason(options));
diff --git a/services/core/java/com/android/server/biometrics/sensors/HalClientMonitor.java b/services/core/java/com/android/server/biometrics/sensors/HalClientMonitor.java
index 03658ce21fc2..139b745daef2 100644
--- a/services/core/java/com/android/server/biometrics/sensors/HalClientMonitor.java
+++ b/services/core/java/com/android/server/biometrics/sensors/HalClientMonitor.java
@@ -21,6 +21,7 @@ import android.annotation.Nullable;
import android.content.Context;
import android.os.IBinder;
+import com.android.server.biometrics.Flags;
import com.android.server.biometrics.log.BiometricContext;
import com.android.server.biometrics.log.BiometricLogger;
import com.android.server.biometrics.log.OperationContextExt;
@@ -91,6 +92,9 @@ public abstract class HalClientMonitor<T> extends BaseClientMonitor {
}
protected OperationContextExt getOperationContext() {
+ if (Flags.deHidl()) {
+ return mOperationContext;
+ }
return getBiometricContext().updateContext(mOperationContext, isCryptoOperation());
}
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 470dc4b7172c..22e399c6747b 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
@@ -37,6 +37,7 @@ import android.util.Slog;
import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.biometrics.Flags;
import com.android.server.biometrics.Utils;
import com.android.server.biometrics.log.BiometricContext;
import com.android.server.biometrics.log.BiometricLogger;
@@ -153,7 +154,11 @@ public class FaceAuthenticationClient
0 /* vendorCode */);
mCallback.onClientFinished(this, false /* success */);
} else {
- mCancellationSignal = doAuthenticate();
+ if (Flags.deHidl()) {
+ startAuthenticate();
+ } else {
+ mCancellationSignal = doAuthenticate();
+ }
}
} catch (RemoteException e) {
Slog.e(TAG, "Remote exception when requesting auth", e);
@@ -182,6 +187,33 @@ public class FaceAuthenticationClient
}
}
+ private void startAuthenticate() throws RemoteException {
+ final AidlSession session = getFreshDaemon();
+
+ if (session.hasContextMethods()) {
+ final OperationContextExt opContext = getOperationContext();
+ getBiometricContext().subscribe(opContext, ctx -> {
+ try {
+ mCancellationSignal = session.getSession().authenticateWithContext(
+ mOperationId, ctx);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Remote exception when requesting auth", e);
+ onError(BiometricFaceConstants.FACE_ERROR_HW_UNAVAILABLE,
+ 0 /* vendorCode */);
+ mCallback.onClientFinished(this, false /* success */);
+ }
+ }, ctx -> {
+ try {
+ session.getSession().onContextChanged(ctx);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Unable to notify context changed", e);
+ }
+ }, getOptions());
+ } else {
+ mCancellationSignal = session.getSession().authenticate(mOperationId);
+ }
+ }
+
@Override
protected void stopHalOperation() {
unsubscribeBiometricContext();
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 a529fb9779a7..5ddddda4e201 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
@@ -29,6 +29,7 @@ import android.util.Slog;
import com.android.internal.annotations.VisibleForTesting;
import com.android.server.biometrics.BiometricsProto;
+import com.android.server.biometrics.Flags;
import com.android.server.biometrics.log.BiometricContext;
import com.android.server.biometrics.log.BiometricLogger;
import com.android.server.biometrics.log.OperationContextExt;
@@ -111,7 +112,11 @@ public class FaceDetectClient extends AcquisitionClient<AidlSession> implements
}
try {
- mCancellationSignal = doDetectInteraction();
+ if (Flags.deHidl()) {
+ startDetect();
+ } else {
+ mCancellationSignal = doDetectInteraction();
+ }
} catch (RemoteException e) {
Slog.e(TAG, "Remote exception when requesting face detect", e);
mCallback.onClientFinished(this, false /* success */);
@@ -138,6 +143,30 @@ public class FaceDetectClient extends AcquisitionClient<AidlSession> implements
}
}
+ private void startDetect() throws RemoteException {
+ final AidlSession session = getFreshDaemon();
+
+ if (session.hasContextMethods()) {
+ final OperationContextExt opContext = getOperationContext();
+ getBiometricContext().subscribe(opContext, ctx -> {
+ try {
+ mCancellationSignal = session.getSession().detectInteractionWithContext(ctx);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Remote exception when requesting face detect", e);
+ mCallback.onClientFinished(this, false /* success */);
+ }
+ }, ctx -> {
+ try {
+ session.getSession().onContextChanged(ctx);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Unable to notify context changed", e);
+ }
+ }, mOptions);
+ } else {
+ mCancellationSignal = session.getSession().detectInteraction();
+ }
+ }
+
@Override
public void onInteractionDetected() {
vibrateSuccess();
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceEnrollClient.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceEnrollClient.java
index 0af6e40434ef..f5c452992674 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceEnrollClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceEnrollClient.java
@@ -36,6 +36,7 @@ import android.util.Slog;
import android.view.Surface;
import com.android.internal.R;
+import com.android.server.biometrics.Flags;
import com.android.server.biometrics.HardwareAuthTokenUtils;
import com.android.server.biometrics.Utils;
import com.android.server.biometrics.log.BiometricContext;
@@ -187,7 +188,11 @@ public class FaceEnrollClient extends EnrollClient<AidlSession> {
features[i] = featureList.get(i);
}
- mCancellationSignal = doEnroll(features);
+ if (Flags.deHidl()) {
+ startEnroll(features);
+ } else {
+ mCancellationSignal = doEnroll(features);
+ }
} catch (RemoteException | IllegalArgumentException e) {
Slog.e(TAG, "Exception when requesting enroll", e);
onError(BiometricFaceConstants.FACE_ERROR_UNABLE_TO_PROCESS, 0 /* vendorCode */);
@@ -231,6 +236,48 @@ public class FaceEnrollClient extends EnrollClient<AidlSession> {
}
}
+ private void startEnroll(byte[] features) throws RemoteException {
+ final AidlSession session = getFreshDaemon();
+ final HardwareAuthToken hat =
+ HardwareAuthTokenUtils.toHardwareAuthToken(mHardwareAuthToken);
+
+ if (session.hasContextMethods()) {
+ final OperationContextExt opContext = getOperationContext();
+ getBiometricContext().subscribe(opContext, ctx -> {
+ try {
+ if (session.supportsFaceEnrollOptions()) {
+ FaceEnrollOptions options = new FaceEnrollOptions();
+ options.hardwareAuthToken = hat;
+ options.enrollmentType = EnrollmentType.DEFAULT;
+ options.features = features;
+ options.nativeHandlePreview = null;
+ options.context = ctx;
+ options.surfacePreview = mPreviewSurface;
+ mCancellationSignal = session.getSession().enrollWithOptions(options);
+ } else {
+ mCancellationSignal = session.getSession().enrollWithContext(
+ hat, EnrollmentType.DEFAULT, features, mHwPreviewHandle, ctx);
+ }
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Exception when requesting enroll", e);
+ onError(BiometricFaceConstants.FACE_ERROR_UNABLE_TO_PROCESS,
+ 0 /* vendorCode */);
+ mCallback.onClientFinished(this, false /* success */);
+ }
+ }, ctx -> {
+ try {
+ session.getSession().onContextChanged(ctx);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Unable to notify context changed", e);
+ }
+ }, null /* options */);
+ } else {
+ mCancellationSignal = session.getSession().enroll(hat, EnrollmentType.DEFAULT, features,
+ mHwPreviewHandle);
+ }
+ }
+
+
@Override
protected void stopHalOperation() {
unsubscribeBiometricContext();
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 29c5a3de3a80..2755ab50debb 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
@@ -43,6 +43,7 @@ import android.provider.Settings;
import android.util.Slog;
import com.android.internal.R;
+import com.android.server.biometrics.Flags;
import com.android.server.biometrics.log.BiometricContext;
import com.android.server.biometrics.log.BiometricLogger;
import com.android.server.biometrics.log.CallbackWithProbe;
@@ -296,7 +297,11 @@ public class FingerprintAuthenticationClient
}
try {
- mCancellationSignal = doAuthenticate();
+ if (Flags.deHidl()) {
+ startAuthentication();
+ } else {
+ mCancellationSignal = doAuthenticate();
+ }
} catch (RemoteException e) {
Slog.e(TAG, "Remote exception", e);
onError(
@@ -346,6 +351,51 @@ public class FingerprintAuthenticationClient
return cancel;
}
+ private void startAuthentication() {
+ final AidlSession session = getFreshDaemon();
+ final OperationContextExt opContext = getOperationContext();
+
+ getBiometricContext().subscribe(opContext, ctx -> {
+ try {
+ if (session.hasContextMethods()) {
+ mCancellationSignal = session.getSession().authenticateWithContext(mOperationId,
+ ctx);
+ } else {
+ mCancellationSignal = session.getSession().authenticate(mOperationId);
+ }
+
+ if (getBiometricContext().isAwake()) {
+ mALSProbeCallback.getProbe().enable();
+ }
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Remote exception", e);
+ onError(
+ BiometricFingerprintConstants.FINGERPRINT_ERROR_HW_UNAVAILABLE,
+ 0 /* vendorCode */);
+ mSensorOverlays.hide(getSensorId());
+ if (sidefpsControllerRefactor()) {
+ mAuthenticationStateListeners.onAuthenticationStopped();
+ }
+ mCallback.onClientFinished(this, false /* success */);
+ }
+ }, ctx -> {
+ if (session.hasContextMethods()) {
+ try {
+ session.getSession().onContextChanged(ctx);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Unable to notify context changed", e);
+ }
+ }
+
+ final boolean isAwake = getBiometricContext().isAwake();
+ if (isAwake) {
+ mALSProbeCallback.getProbe().enable();
+ } else {
+ mALSProbeCallback.getProbe().disable();
+ }
+ }, getOptions());
+ }
+
@Override
protected void stopHalOperation() {
mSensorOverlays.hide(getSensorId());
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 e58e5ae117b5..e9a1c23c148e 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
@@ -30,6 +30,7 @@ import android.os.RemoteException;
import android.util.Slog;
import com.android.server.biometrics.BiometricsProto;
+import com.android.server.biometrics.Flags;
import com.android.server.biometrics.log.BiometricContext;
import com.android.server.biometrics.log.BiometricLogger;
import com.android.server.biometrics.log.OperationContextExt;
@@ -104,7 +105,11 @@ public class FingerprintDetectClient extends AcquisitionClient<AidlSession>
this);
try {
- mCancellationSignal = doDetectInteraction();
+ if (Flags.deHidl()) {
+ startDetectInteraction();
+ } else {
+ mCancellationSignal = doDetectInteraction();
+ }
} catch (RemoteException e) {
Slog.e(TAG, "Remote exception when requesting finger detect", e);
mSensorOverlays.hide(getSensorId());
@@ -132,6 +137,32 @@ public class FingerprintDetectClient extends AcquisitionClient<AidlSession>
}
}
+ private void startDetectInteraction() throws RemoteException {
+ final AidlSession session = getFreshDaemon();
+
+ if (session.hasContextMethods()) {
+ final OperationContextExt opContext = getOperationContext();
+ getBiometricContext().subscribe(opContext, ctx -> {
+ try {
+ mCancellationSignal = session.getSession().detectInteractionWithContext(
+ ctx);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Unable to start detect interaction", e);
+ mSensorOverlays.hide(getSensorId());
+ mCallback.onClientFinished(this, false /* success */);
+ }
+ }, ctx -> {
+ try {
+ session.getSession().onContextChanged(ctx);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Unable to notify context changed", e);
+ }
+ }, mOptions);
+ } else {
+ mCancellationSignal = session.getSession().detectInteraction();
+ }
+ }
+
@Override
public void onInteractionDetected() {
vibrateSuccess();
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java
index c0761ed8f32b..9d0c67b8f911 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java
@@ -38,6 +38,7 @@ import android.os.RemoteException;
import android.util.Slog;
import android.view.accessibility.AccessibilityManager;
+import com.android.server.biometrics.Flags;
import com.android.server.biometrics.HardwareAuthTokenUtils;
import com.android.server.biometrics.log.BiometricContext;
import com.android.server.biometrics.log.BiometricLogger;
@@ -199,7 +200,11 @@ public class FingerprintEnrollClient extends EnrollClient<AidlSession> implement
BiometricNotificationUtils.cancelBadCalibrationNotification(getContext());
try {
- mCancellationSignal = doEnroll();
+ if (Flags.deHidl()) {
+ startEnroll();
+ } else {
+ mCancellationSignal = doEnroll();
+ }
} catch (RemoteException e) {
Slog.e(TAG, "Remote exception when requesting enroll", e);
onError(BiometricFingerprintConstants.FINGERPRINT_ERROR_UNABLE_TO_PROCESS,
@@ -230,6 +235,35 @@ public class FingerprintEnrollClient extends EnrollClient<AidlSession> implement
}
}
+ private void startEnroll() throws RemoteException {
+ final AidlSession session = getFreshDaemon();
+ final HardwareAuthToken hat =
+ HardwareAuthTokenUtils.toHardwareAuthToken(mHardwareAuthToken);
+
+ if (session.hasContextMethods()) {
+ final OperationContextExt opContext = getOperationContext();
+ getBiometricContext().subscribe(opContext, ctx -> {
+ try {
+ mCancellationSignal = session.getSession().enrollWithContext(
+ hat, ctx);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Remote exception when requesting enroll", e);
+ onError(BiometricFingerprintConstants.FINGERPRINT_ERROR_UNABLE_TO_PROCESS,
+ 0 /* vendorCode */);
+ mCallback.onClientFinished(this, false /* success */);
+ }
+ }, ctx -> {
+ try {
+ session.getSession().onContextChanged(ctx);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Unable to notify context changed", e);
+ }
+ }, null /* options */);
+ } else {
+ mCancellationSignal = session.getSession().enroll(hat);
+ }
+ }
+
@Override
protected void stopHalOperation() {
mSensorOverlays.hide(getSensorId());
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/log/BiometricContextProviderTest.java b/services/tests/servicestests/src/com/android/server/biometrics/log/BiometricContextProviderTest.java
index 1b9e6fb6e247..1c35f08a9ffe 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/log/BiometricContextProviderTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/log/BiometricContextProviderTest.java
@@ -20,6 +20,7 @@ import static android.view.DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS;
import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.assertThrows;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.mock;
@@ -33,11 +34,15 @@ import android.content.Intent;
import android.hardware.biometrics.AuthenticateOptions;
import android.hardware.biometrics.IBiometricContextListener;
import android.hardware.biometrics.IBiometricContextListener.FoldState;
+import android.hardware.biometrics.common.DisplayState;
import android.hardware.biometrics.common.OperationContext;
import android.hardware.biometrics.common.OperationReason;
import android.hardware.display.DisplayManagerGlobal;
+import android.hardware.fingerprint.FingerprintAuthenticateOptions;
import android.os.RemoteException;
import android.platform.test.annotations.Presubmit;
+import android.platform.test.flag.junit.CheckFlagsRule;
+import android.platform.test.flag.junit.DeviceFlagsValueProvider;
import android.testing.TestableContext;
import android.view.Display;
import android.view.DisplayInfo;
@@ -72,6 +77,9 @@ public class BiometricContextProviderTest {
@Rule
public TestableContext mContext = new TestableContext(
InstrumentationRegistry.getInstrumentation().getContext());
+ @Rule
+ public final CheckFlagsRule mCheckFlagsRule =
+ DeviceFlagsValueProvider.createCheckFlagsRule();
@Mock
private IStatusBarService mStatusBarService;
@@ -386,6 +394,37 @@ public class BiometricContextProviderTest {
}
}
+ @Test
+ public void testSubscribe_thenStartHal() throws RemoteException {
+ Consumer<OperationContext> updateConsumer = mock(Consumer.class);
+ Consumer<OperationContext> startHalConsumer = mock(Consumer.class);
+ AuthenticateOptions options = new FingerprintAuthenticateOptions.Builder().build();
+ OperationContextExt context = mProvider.updateContext(mOpContext, false /* crypto */);
+
+ assertThat(context.getDisplayState()).isEqualTo(DisplayState.UNKNOWN);
+ assertThat(context.getFoldState()).isEqualTo(IBiometricContextListener.FoldState.UNKNOWN);
+
+ mListener.onDisplayStateChanged(DisplayState.LOCKSCREEN);
+ mListener.onFoldChanged(FoldState.FULLY_CLOSED);
+ mProvider.subscribe(context, startHalConsumer, updateConsumer, options);
+
+ assertThat(context.getDisplayState()).isEqualTo(DisplayState.LOCKSCREEN);
+ assertThat(context.getFoldState()).isEqualTo(FoldState.FULLY_CLOSED);
+ verify(updateConsumer, never()).accept(context.toAidlContext());
+ verify(startHalConsumer).accept(context.toAidlContext(options));
+ }
+
+ @Test
+ public void testSubscribe_withInvalidOptions() {
+ Consumer<OperationContext> updateConsumer = mock(Consumer.class);
+ Consumer<OperationContext> startHalConsumer = mock(Consumer.class);
+ AuthenticateOptions options = mock(AuthenticateOptions.class);
+ OperationContextExt context = mProvider.updateContext(mOpContext, false /* crypto */);
+
+ assertThrows(IllegalStateException.class, () -> mProvider.subscribe(
+ context, startHalConsumer, updateConsumer, options));
+ }
+
private static byte reason(int type) {
if (type == StatusBarManager.SESSION_BIOMETRIC_PROMPT) {
return OperationReason.BIOMETRIC_PROMPT;