diff options
| author | 2023-03-06 23:01:14 +0000 | |
|---|---|---|
| committer | 2023-03-06 23:09:32 +0000 | |
| commit | 357c36564230a91533db7e2f4771f9de1e4c3dd5 (patch) | |
| tree | 20d22c291d28bcb06785df1b664e0d5a7a6b9a66 | |
| parent | c6bbc387dbf68164fe92126e0015d863f1cd5063 (diff) | |
Propagate wake reason and face auth reason from SysUI to HAL.
Bug: 242628816
Bug: 268216312
Test: atest FaceAuthenticationClientTest FaceDetectClientTest FingerprintAuthenticationClientTest FingerprintDetectClientTest
Change-Id: Ie956b06346efcda042715a192cfbc82294bbb960
10 files changed, 190 insertions, 14 deletions
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 42be95b7377a..ecb7e7ca08fb 100644 --- a/services/core/java/com/android/server/biometrics/log/OperationContextExt.java +++ b/services/core/java/com/android/server/biometrics/log/OperationContextExt.java @@ -20,8 +20,13 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Intent; import android.hardware.biometrics.IBiometricContextListener; +import android.hardware.biometrics.common.AuthenticateReason; import android.hardware.biometrics.common.OperationContext; import android.hardware.biometrics.common.OperationReason; +import android.hardware.biometrics.common.WakeReason; +import android.hardware.face.FaceAuthenticateOptions; +import android.hardware.fingerprint.FingerprintAuthenticateOptions; +import android.os.PowerManager; import android.view.Surface; /** @@ -50,12 +55,127 @@ public class OperationContextExt { mAidlContext = context; } - /** Gets the subset of the context that can be shared with the HAL. */ + /** + * Gets the subset of the context that can be shared with the HAL. + * + * When starting a new operation use methods like to update & fetch the context: + * <ul> + * <li>{@link #toAidlContext(FaceAuthenticateOptions)} + * <li>{@link #toAidlContext(FingerprintAuthenticateOptions)} + * </ul> + * + * Use this method for any subsequent calls to the HAL or for operations that do + * not accept any options. + * + * @return the underlying AIDL context + */ @NonNull public OperationContext toAidlContext() { return mAidlContext; } + /** + * 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)); + mAidlContext.wakeReason = getWakeReason(options); + + return mAidlContext; + } + + /** + * 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 FingerprintAuthenticateOptions options) { + mAidlContext.authenticateReason = AuthenticateReason + .fingerprintAuthenticateReason(getAuthReason(options)); + mAidlContext.wakeReason = getWakeReason(options); + + return mAidlContext; + } + + @AuthenticateReason.Face + private int getAuthReason(@NonNull FaceAuthenticateOptions options) { + switch (options.getAuthenticateReason()) { + case FaceAuthenticateOptions.AUTHENTICATE_REASON_STARTED_WAKING_UP: + return AuthenticateReason.Face.STARTED_WAKING_UP; + case FaceAuthenticateOptions.AUTHENTICATE_REASON_PRIMARY_BOUNCER_SHOWN: + return AuthenticateReason.Face.PRIMARY_BOUNCER_SHOWN; + case FaceAuthenticateOptions.AUTHENTICATE_REASON_ASSISTANT_VISIBLE: + return AuthenticateReason.Face.ASSISTANT_VISIBLE; + case FaceAuthenticateOptions.AUTHENTICATE_REASON_ALTERNATE_BIOMETRIC_BOUNCER_SHOWN: + return AuthenticateReason.Face.ALTERNATE_BIOMETRIC_BOUNCER_SHOWN; + case FaceAuthenticateOptions.AUTHENTICATE_REASON_NOTIFICATION_PANEL_CLICKED: + return AuthenticateReason.Face.NOTIFICATION_PANEL_CLICKED; + case FaceAuthenticateOptions.AUTHENTICATE_REASON_OCCLUDING_APP_REQUESTED: + return AuthenticateReason.Face.OCCLUDING_APP_REQUESTED; + case FaceAuthenticateOptions.AUTHENTICATE_REASON_PICK_UP_GESTURE_TRIGGERED: + return AuthenticateReason.Face.PICK_UP_GESTURE_TRIGGERED; + case FaceAuthenticateOptions.AUTHENTICATE_REASON_QS_EXPANDED: + return AuthenticateReason.Face.QS_EXPANDED; + case FaceAuthenticateOptions.AUTHENTICATE_REASON_SWIPE_UP_ON_BOUNCER: + return AuthenticateReason.Face.SWIPE_UP_ON_BOUNCER; + case FaceAuthenticateOptions.AUTHENTICATE_REASON_UDFPS_POINTER_DOWN: + return AuthenticateReason.Face.UDFPS_POINTER_DOWN; + default: + return AuthenticateReason.Face.UNKNOWN; + } + } + + @WakeReason + private int getWakeReason(@NonNull FaceAuthenticateOptions options) { + switch (options.getWakeReason()) { + case PowerManager.WAKE_REASON_POWER_BUTTON: + return WakeReason.POWER_BUTTON; + case PowerManager.WAKE_REASON_GESTURE: + return WakeReason.GESTURE; + case PowerManager.WAKE_REASON_WAKE_KEY: + return WakeReason.WAKE_KEY; + case PowerManager.WAKE_REASON_WAKE_MOTION: + return WakeReason.WAKE_MOTION; + case PowerManager.WAKE_REASON_DISPLAY_GROUP_ADDED: + return WakeReason.DISPLAY_GROUP_ADDED; + case PowerManager.WAKE_REASON_TAP: + return WakeReason.TAP; + case PowerManager.WAKE_REASON_LIFT: + return WakeReason.LIFT; + case PowerManager.WAKE_REASON_BIOMETRIC: + return WakeReason.BIOMETRIC; + case PowerManager.WAKE_REASON_CAMERA_LAUNCH: + case PowerManager.WAKE_REASON_HDMI: + case PowerManager.WAKE_REASON_DISPLAY_GROUP_TURNED_ON: + case PowerManager.WAKE_REASON_UNFOLD_DEVICE: + case PowerManager.WAKE_REASON_DREAM_FINISHED: + case PowerManager.WAKE_REASON_TILT: + case PowerManager.WAKE_REASON_APPLICATION: + case PowerManager.WAKE_REASON_PLUGGED_IN: + default: + return WakeReason.UNKNOWN; + } + } + + @AuthenticateReason.Fingerprint + private int getAuthReason(@NonNull FingerprintAuthenticateOptions options) { + return AuthenticateReason.Fingerprint.UNKNOWN; + } + + @WakeReason + private int getWakeReason(@NonNull FingerprintAuthenticateOptions options) { + return WakeReason.UNKNOWN; + } + /** {@link OperationContext#id}. */ public int getId() { return mAidlContext.id; 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 005ad20a2d48..7b9fc36e8d61 100644 --- a/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java @@ -74,6 +74,7 @@ public abstract class AuthenticationClient<T, O extends AuthenticateOptions> @Nullable private final TaskStackListener mTaskStackListener; private final LockoutTracker mLockoutTracker; + private final O mOptions; private final boolean mIsRestricted; private final boolean mAllowBackgroundAuthentication; // TODO: This is currently hard to maintain, as each AuthenticationClient subclass must update @@ -110,6 +111,7 @@ public abstract class AuthenticationClient<T, O extends AuthenticateOptions> mAllowBackgroundAuthentication = allowBackgroundAuthentication; mShouldUseLockoutTracker = lockoutTracker != null; mSensorStrength = sensorStrength; + mOptions = options; } @LockoutTracker.LockoutMode @@ -151,6 +153,11 @@ public abstract class AuthenticationClient<T, O extends AuthenticateOptions> return Utils.isSettings(getContext(), getOwnerString()); } + /** The options requested at the start of the operation. */ + protected O getOptions() { + return mOptions; + } + @Override protected boolean isCryptoOperation() { return mOperationId != 0; 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 976f1cbe1e5c..84e2fb4a5966 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 @@ -166,7 +166,7 @@ class FaceAuthenticationClient extends AuthenticationClient<AidlSession, FaceAut if (session.hasContextMethods()) { return session.getSession().authenticateWithContext( - mOperationId, getOperationContext().toAidlContext()); + mOperationId, getOperationContext().toAidlContext(getOptions())); } else { return session.getSession().authenticate(mOperationId); } 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 e65202dca5cd..fa23ccd482fb 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 @@ -47,6 +47,7 @@ public class FaceDetectClient extends AcquisitionClient<AidlSession> implements private static final String TAG = "FaceDetectClient"; private final boolean mIsStrongBiometric; + private final FaceAuthenticateOptions mOptions; @Nullable private ICancellationSignal mCancellationSignal; @Nullable private SensorPrivacyManager mSensorPrivacyManager; @@ -74,6 +75,7 @@ public class FaceDetectClient extends AcquisitionClient<AidlSession> implements setRequestId(requestId); mIsStrongBiometric = isStrongBiometric; mSensorPrivacyManager = sensorPrivacyManager; + mOptions = options; } @Override @@ -118,7 +120,7 @@ public class FaceDetectClient extends AcquisitionClient<AidlSession> implements if (session.hasContextMethods()) { return session.getSession().detectInteractionWithContext( - getOperationContext().toAidlContext()); + getOperationContext().toAidlContext(mOptions)); } else { return session.getSession().detectInteraction(); } 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 0f81f9f2660e..435e81d688bd 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 @@ -285,7 +285,7 @@ class FingerprintAuthenticationClient if (session.hasContextMethods()) { return session.getSession().authenticateWithContext( - mOperationId, opContext.toAidlContext()); + mOperationId, opContext.toAidlContext(getOptions())); } else { return session.getSession().authenticate(mOperationId); } 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 376d23187fb8..16d16fc95c5b 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 @@ -48,6 +48,7 @@ class FingerprintDetectClient extends AcquisitionClient<AidlSession> implements private static final String TAG = "FingerprintDetectClient"; private final boolean mIsStrongBiometric; + private final FingerprintAuthenticateOptions mOptions; @NonNull private final SensorOverlays mSensorOverlays; @Nullable private ICancellationSignal mCancellationSignal; @@ -66,6 +67,7 @@ class FingerprintDetectClient extends AcquisitionClient<AidlSession> implements mIsStrongBiometric = isStrongBiometric; mSensorOverlays = new SensorOverlays(udfpsOverlayController, null /* sideFpsController*/, udfpsOverlay); + mOptions = options; } @Override @@ -105,7 +107,7 @@ class FingerprintDetectClient extends AcquisitionClient<AidlSession> implements if (session.hasContextMethods()) { return session.getSession().detectInteractionWithContext( - getOperationContext().toAidlContext()); + getOperationContext().toAidlContext(mOptions)); } else { return session.getSession().detectInteraction(); } 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 3ff802c0125c..6b0e33037af8 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 @@ -16,6 +16,8 @@ package com.android.server.biometrics.sensors.face.aidl; +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; @@ -30,11 +32,15 @@ import static org.mockito.Mockito.when; import android.app.ActivityManager; import android.app.ActivityTaskManager; import android.content.ComponentName; +import android.hardware.biometrics.common.AuthenticateReason; import android.hardware.biometrics.common.ICancellationSignal; +import android.hardware.biometrics.common.OperationContext; +import android.hardware.biometrics.common.WakeReason; import android.hardware.biometrics.face.ISession; import android.hardware.face.Face; import android.hardware.face.FaceAuthenticateOptions; import android.os.IBinder; +import android.os.PowerManager; import android.os.RemoteException; import android.platform.test.annotations.Presubmit; import android.testing.TestableContext; @@ -69,6 +75,8 @@ public class FaceAuthenticationClientTest { private static final int USER_ID = 12; private static final long OP_ID = 32; + private static final int WAKE_REASON = WakeReason.LIFT; + private static final int AUTH_REASON = AuthenticateReason.Face.ASSISTANT_VISIBLE; @Rule public final TestableContext mContext = new TestableContext( @@ -126,8 +134,13 @@ public class FaceAuthenticationClientTest { InOrder order = inOrder(mHal, mBiometricContext); order.verify(mBiometricContext).updateContext( mOperationContextCaptor.capture(), anyBoolean()); - order.verify(mHal).authenticateWithContext( - eq(OP_ID), same(mOperationContextCaptor.getValue().toAidlContext())); + + final OperationContext aidlContext = mOperationContextCaptor.getValue().toAidlContext(); + order.verify(mHal).authenticateWithContext(eq(OP_ID), same(aidlContext)); + assertThat(aidlContext.wakeReason).isEqualTo(WAKE_REASON); + assertThat(aidlContext.authenticateReason.getFaceAuthenticateReason()) + .isEqualTo(AUTH_REASON); + verify(mHal, never()).authenticate(anyLong()); } @@ -156,8 +169,11 @@ public class FaceAuthenticationClientTest { final AidlSession aidl = new AidlSession(version, mHal, USER_ID, mHalSessionCallback); final FaceAuthenticateOptions options = new FaceAuthenticateOptions.Builder() .setOpPackageName("test-owner") - .setUserId(5) + .setUserId(USER_ID) .setSensorId(9) + .setWakeReason(PowerManager.WAKE_REASON_LIFT) + .setAuthenticateReason( + FaceAuthenticateOptions.AUTHENTICATE_REASON_ASSISTANT_VISIBLE) .build(); return new FaceAuthenticationClient(mContext, () -> aidl, mToken, 2 /* requestId */, mClientMonitorCallbackConverter, OP_ID, 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 c4c550549f73..0abfa7e6546d 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 @@ -16,6 +16,8 @@ package com.android.server.biometrics.sensors.face.aidl; +import static com.google.common.truth.Truth.assertThat; + import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.Mockito.inOrder; @@ -24,9 +26,13 @@ import static org.mockito.Mockito.same; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import android.hardware.biometrics.common.AuthenticateReason; +import android.hardware.biometrics.common.OperationContext; +import android.hardware.biometrics.common.WakeReason; import android.hardware.biometrics.face.ISession; import android.hardware.face.FaceAuthenticateOptions; import android.os.IBinder; +import android.os.PowerManager; import android.os.RemoteException; import android.platform.test.annotations.Presubmit; import android.testing.TestableContext; @@ -55,6 +61,8 @@ import org.mockito.junit.MockitoRule; public class FaceDetectClientTest { private static final int USER_ID = 12; + private static final int WAKE_REASON = WakeReason.POWER_BUTTON; + private static final int AUTH_REASON = AuthenticateReason.Face.OCCLUDING_APP_REQUESTED; @Rule public final TestableContext mContext = new TestableContext( @@ -103,8 +111,13 @@ public class FaceDetectClientTest { InOrder order = inOrder(mHal, mBiometricContext); order.verify(mBiometricContext).updateContext( mOperationContextCaptor.capture(), anyBoolean()); - order.verify(mHal).detectInteractionWithContext( - same(mOperationContextCaptor.getValue().toAidlContext())); + + final OperationContext aidlContext = mOperationContextCaptor.getValue().toAidlContext(); + order.verify(mHal).detectInteractionWithContext(same(aidlContext)); + assertThat(aidlContext.wakeReason).isEqualTo(WAKE_REASON); + assertThat(aidlContext.authenticateReason.getFaceAuthenticateReason()) + .isEqualTo(AUTH_REASON); + verify(mHal, never()).detectInteraction(); } @@ -118,6 +131,9 @@ public class FaceDetectClientTest { .setUserId(USER_ID) .setSensorId(5) .setOpPackageName("own-it") + .setWakeReason(PowerManager.WAKE_REASON_POWER_BUTTON) + .setAuthenticateReason( + FaceAuthenticateOptions.AUTHENTICATE_REASON_OCCLUDING_APP_REQUESTED) .build(), mBiometricLogger, mBiometricContext, false /* isStrongBiometric */, null /* sensorPrivacyManager */); 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 f0f975ccf5ff..c6645003c7e2 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 @@ -36,6 +36,7 @@ import android.app.ActivityManager; import android.app.ActivityTaskManager; import android.content.ComponentName; import android.hardware.biometrics.BiometricManager; +import android.hardware.biometrics.common.AuthenticateReason; import android.hardware.biometrics.common.ICancellationSignal; import android.hardware.biometrics.common.OperationContext; import android.hardware.biometrics.fingerprint.ISession; @@ -165,8 +166,12 @@ public class FingerprintAuthenticationClientTest { InOrder order = inOrder(mHal, mBiometricContext); order.verify(mBiometricContext).updateContext( mOperationContextCaptor.capture(), anyBoolean()); - order.verify(mHal).authenticateWithContext( - eq(OP_ID), same(mOperationContextCaptor.getValue().toAidlContext())); + + final OperationContext aidlContext = mOperationContextCaptor.getValue().toAidlContext(); + order.verify(mHal).authenticateWithContext(eq(OP_ID), same(aidlContext)); + assertThat(aidlContext.authenticateReason.getFingerprintAuthenticateReason()) + .isEqualTo(AuthenticateReason.Fingerprint.UNKNOWN); + verify(mHal, never()).authenticate(anyLong()); } 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 e741e446da85..c20cc392f5c0 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 @@ -16,6 +16,8 @@ package com.android.server.biometrics.sensors.fingerprint.aidl; +import static com.google.common.truth.Truth.assertThat; + import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.Mockito.any; import static org.mockito.Mockito.inOrder; @@ -24,6 +26,8 @@ import static org.mockito.Mockito.same; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import android.hardware.biometrics.common.AuthenticateReason; +import android.hardware.biometrics.common.OperationContext; import android.hardware.biometrics.fingerprint.ISession; import android.hardware.fingerprint.FingerprintAuthenticateOptions; import android.hardware.fingerprint.IUdfpsOverlayController; @@ -108,8 +112,12 @@ public class FingerprintDetectClientTest { InOrder order = inOrder(mHal, mBiometricContext); order.verify(mBiometricContext).updateContext( mOperationContextCaptor.capture(), anyBoolean()); - order.verify(mHal).detectInteractionWithContext( - same(mOperationContextCaptor.getValue().toAidlContext())); + + final OperationContext aidlContext = mOperationContextCaptor.getValue().toAidlContext(); + order.verify(mHal).detectInteractionWithContext(same(aidlContext)); + assertThat(aidlContext.authenticateReason.getFingerprintAuthenticateReason()) + .isEqualTo(AuthenticateReason.Fingerprint.UNKNOWN); + verify(mHal, never()).detectInteraction(); } |