Propagate wake reason and face auth reason from SysUI to HAL.

Bug: 242628816
Bug: 268216312
Test: atest FaceAuthenticationClientTest FaceDetectClientTest FingerprintAuthenticationClientTest FingerprintDetectClientTest
Change-Id: Ie956b06346efcda042715a192cfbc82294bbb960
This commit is contained in:
Joe Bolinger
2023-03-06 23:01:14 +00:00
parent c6bbc387db
commit 357c365642
10 changed files with 190 additions and 14 deletions

View File

@@ -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;

View File

@@ -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;

View File

@@ -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);
}

View File

@@ -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();
}

View File

@@ -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);
}

View File

@@ -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();
}

View File

@@ -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,

View File

@@ -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 */);

View File

@@ -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());
}

View File

@@ -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();
}