Send AoD context changed notification to HAL.

Bug: 204585936
Bug: 204584403
Test: atest FingerprintAuthenticationClientTest FingerprintDetectClientTest FingerprintEnrollClientTest
Change-Id: Idcccba362a151d0454d4070475073d07803e4e2a
This commit is contained in:
Joe Bolinger
2022-01-28 13:35:30 -08:00
parent 16f0d3494e
commit 0b8634d243
7 changed files with 139 additions and 27 deletions

View File

@@ -82,10 +82,23 @@ public abstract class HalClientMonitor<T> extends BaseClientMonitor {
super.destroy();
// subclasses should do this earlier in most cases, but ensure it happens now
getBiometricContext().unsubscribe(mOperationContext);
unsubscribeBiometricContext();
}
protected OperationContext getOperationContext() {
return getBiometricContext().updateContext(mOperationContext, isCryptoOperation());
}
protected ClientMonitorCallback getBiometricContextUnsubscriber() {
return new ClientMonitorCallback() {
@Override
public void onClientFinished(@NonNull BaseClientMonitor monitor, boolean success) {
unsubscribeBiometricContext();
}
};
}
protected void unsubscribeBiometricContext() {
getBiometricContext().unsubscribe(mOperationContext);
}
}

View File

@@ -24,6 +24,7 @@ import android.hardware.biometrics.BiometricAuthenticator;
import android.hardware.biometrics.BiometricFingerprintConstants;
import android.hardware.biometrics.BiometricFingerprintConstants.FingerprintAcquired;
import android.hardware.biometrics.common.ICancellationSignal;
import android.hardware.biometrics.common.OperationContext;
import android.hardware.biometrics.fingerprint.PointerContext;
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
import android.hardware.fingerprint.ISidefpsController;
@@ -107,7 +108,8 @@ class FingerprintAuthenticationClient extends AuthenticationClient<AidlSession>
@NonNull
@Override
protected ClientMonitorCallback wrapCallbackForStart(@NonNull ClientMonitorCallback callback) {
return new ClientMonitorCompositeCallback(mALSProbeCallback, callback);
return new ClientMonitorCompositeCallback(mALSProbeCallback,
getBiometricContextUnsubscriber(), callback);
}
@Override
@@ -177,8 +179,17 @@ class FingerprintAuthenticationClient extends AuthenticationClient<AidlSession>
final AidlSession session = getFreshDaemon();
if (session.hasContextMethods()) {
return session.getSession().authenticateWithContext(
mOperationId, getOperationContext());
final OperationContext opContext = getOperationContext();
final ICancellationSignal cancel = session.getSession().authenticateWithContext(
mOperationId, opContext);
getBiometricContext().subscribe(opContext, ctx -> {
try {
session.getSession().onContextChanged(ctx);
} catch (RemoteException e) {
Slog.e(TAG, "Unable to notify context changed", e);
}
});
return cancel;
} else {
return session.getSession().authenticate(mOperationId);
}
@@ -187,6 +198,8 @@ class FingerprintAuthenticationClient extends AuthenticationClient<AidlSession>
@Override
protected void stopHalOperation() {
mSensorOverlays.hide(getSensorId());
unsubscribeBiometricContext();
if (mCancellationSignal != null) {
try {
mCancellationSignal.cancel();
@@ -216,7 +229,7 @@ class FingerprintAuthenticationClient extends AuthenticationClient<AidlSession>
context.y = y;
context.minor = minor;
context.major = major;
context.isAoD = false; // TODO; get value
context.isAoD = getBiometricContext().isAoD();
session.getSession().onPointerDownWithContext(context);
} else {
session.getSession().onPointerDown(0 /* pointerId */, x, y, minor, major);

View File

@@ -23,6 +23,7 @@ import android.hardware.biometrics.BiometricAuthenticator;
import android.hardware.biometrics.BiometricFingerprintConstants;
import android.hardware.biometrics.BiometricFingerprintConstants.FingerprintAcquired;
import android.hardware.biometrics.common.ICancellationSignal;
import android.hardware.biometrics.common.OperationContext;
import android.hardware.biometrics.fingerprint.PointerContext;
import android.hardware.fingerprint.Fingerprint;
import android.hardware.fingerprint.FingerprintManager;
@@ -37,6 +38,8 @@ import android.util.Slog;
import com.android.server.biometrics.HardwareAuthTokenUtils;
import com.android.server.biometrics.log.BiometricContext;
import com.android.server.biometrics.log.BiometricLogger;
import com.android.server.biometrics.log.CallbackWithProbe;
import com.android.server.biometrics.log.Probe;
import com.android.server.biometrics.sensors.BiometricNotificationUtils;
import com.android.server.biometrics.sensors.BiometricUtils;
import com.android.server.biometrics.sensors.ClientMonitorCallback;
@@ -56,6 +59,7 @@ class FingerprintEnrollClient extends EnrollClient<AidlSession> implements Udfps
@NonNull private final FingerprintSensorPropertiesInternal mSensorProps;
@NonNull private final SensorOverlays mSensorOverlays;
@NonNull private final CallbackWithProbe<Probe> mALSProbeCallback;
private final @FingerprintManager.EnrollReason int mEnrollReason;
@Nullable private ICancellationSignal mCancellationSignal;
@@ -81,6 +85,8 @@ class FingerprintEnrollClient extends EnrollClient<AidlSession> implements Udfps
mSensorOverlays = new SensorOverlays(udfpsOverlayController, sidefpsController);
mMaxTemplatesPerUser = maxTemplatesPerUser;
mALSProbeCallback = getLogger().createALSCallback(false /* startWithClient */);
mEnrollReason = enrollReason;
if (enrollReason == FingerprintManager.ENROLL_FIND_SENSOR) {
getLogger().disableMetrics();
@@ -90,8 +96,8 @@ class FingerprintEnrollClient extends EnrollClient<AidlSession> implements Udfps
@NonNull
@Override
protected ClientMonitorCallback wrapCallbackForStart(@NonNull ClientMonitorCallback callback) {
return new ClientMonitorCompositeCallback(
getLogger().createALSCallback(true /* startWithClient */), callback);
return new ClientMonitorCompositeCallback(mALSProbeCallback,
getBiometricContextUnsubscriber(), callback);
}
@Override
@@ -139,22 +145,6 @@ class FingerprintEnrollClient extends EnrollClient<AidlSession> implements Udfps
>= mMaxTemplatesPerUser;
}
@Override
protected void stopHalOperation() {
mSensorOverlays.hide(getSensorId());
if (mCancellationSignal != null) {
try {
mCancellationSignal.cancel();
} catch (RemoteException e) {
Slog.e(TAG, "Remote exception when requesting cancel", e);
onError(BiometricFingerprintConstants.FINGERPRINT_ERROR_HW_UNAVAILABLE,
0 /* vendorCode */);
mCallback.onClientFinished(this, false /* success */);
}
}
}
@Override
protected void startHalOperation() {
mSensorOverlays.show(getSensorId(), getOverlayReasonFromEnrollReason(mEnrollReason), this);
@@ -176,16 +166,44 @@ class FingerprintEnrollClient extends EnrollClient<AidlSession> implements Udfps
HardwareAuthTokenUtils.toHardwareAuthToken(mHardwareAuthToken);
if (session.hasContextMethods()) {
return session.getSession().enrollWithContext(hat, getOperationContext());
final OperationContext opContext = getOperationContext();
final ICancellationSignal cancel = session.getSession().enrollWithContext(
hat, opContext);
getBiometricContext().subscribe(opContext, ctx -> {
try {
session.getSession().onContextChanged(ctx);
} catch (RemoteException e) {
Slog.e(TAG, "Unable to notify context changed", e);
}
});
return cancel;
} else {
return session.getSession().enroll(hat);
}
}
@Override
protected void stopHalOperation() {
mSensorOverlays.hide(getSensorId());
unsubscribeBiometricContext();
if (mCancellationSignal != null) {
try {
mCancellationSignal.cancel();
} catch (RemoteException e) {
Slog.e(TAG, "Remote exception when requesting cancel", e);
onError(BiometricFingerprintConstants.FINGERPRINT_ERROR_HW_UNAVAILABLE,
0 /* vendorCode */);
mCallback.onClientFinished(this, false /* success */);
}
}
}
@Override
public void onPointerDown(int x, int y, float minor, float major) {
try {
mIsPointerDown = true;
mALSProbeCallback.getProbe().enable();
final AidlSession session = getFreshDaemon();
if (session.hasContextMethods()) {
@@ -195,7 +213,7 @@ class FingerprintEnrollClient extends EnrollClient<AidlSession> implements Udfps
context.y = y;
context.minor = minor;
context.major = major;
context.isAoD = false;
context.isAoD = getBiometricContext().isAoD();
session.getSession().onPointerDownWithContext(context);
} else {
session.getSession().onPointerDown(0 /* pointerId */, x, y, minor, major);
@@ -209,6 +227,7 @@ class FingerprintEnrollClient extends EnrollClient<AidlSession> implements Udfps
public void onPointerUp() {
try {
mIsPointerDown = false;
mALSProbeCallback.getProbe().disable();
final AidlSession session = getFreshDaemon();
if (session.hasContextMethods()) {

View File

@@ -158,6 +158,8 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D
private final SparseArray<UiState> mDisplayUiState = new SparseArray<>();
@GuardedBy("mLock")
private IUdfpsHbmListener mUdfpsHbmListener;
@GuardedBy("mLock")
private IBiometricContextListener mBiometricContextListener;
@GuardedBy("mCurrentRequestAddTilePackages")
private final ArrayMap<String, Long> mCurrentRequestAddTilePackages = new ArrayMap<>();
@@ -897,6 +899,9 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D
@Override
public void setBiometicContextListener(IBiometricContextListener listener) {
enforceStatusBarService();
synchronized (mLock) {
mBiometricContextListener = listener;
}
if (mBar != null) {
try {
mBar.setBiometicContextListener(listener);
@@ -1327,6 +1332,7 @@ public class StatusBarManagerService extends IStatusBarService.Stub implements D
mHandler.post(() -> {
synchronized (mLock) {
setUdfpsHbmListener(mUdfpsHbmListener);
setBiometicContextListener(mBiometricContextListener);
}
});
}

View File

@@ -109,6 +109,8 @@ public class FingerprintAuthenticationClientTest {
private ArgumentCaptor<OperationContext> mOperationContextCaptor;
@Captor
private ArgumentCaptor<PointerContext> mPointerContextCaptor;
@Captor
private ArgumentCaptor<Consumer<OperationContext>> mContextInjector;
@Rule
public final MockitoRule mockito = MockitoJUnit.rule();
@@ -208,6 +210,23 @@ public class FingerprintAuthenticationClientTest {
verify(mLuxProbe, times(2)).enable();
}
@Test
public void notifyHalWhenContextChanges() throws RemoteException {
final FingerprintAuthenticationClient client = createClient();
client.start(mCallback);
verify(mHal).authenticateWithContext(eq(OP_ID), mOperationContextCaptor.capture());
OperationContext opContext = mOperationContextCaptor.getValue();
// fake an update to the context
verify(mBiometricContext).subscribe(eq(opContext), mContextInjector.capture());
mContextInjector.getValue().accept(opContext);
verify(mHal).onContextChanged(eq(opContext));
client.stopHalOperation();
verify(mBiometricContext).unsubscribe(same(opContext));
}
@Test
public void showHideOverlay_cancel() throws RemoteException {
showHideOverlay(c -> c.cancel());

View File

@@ -55,7 +55,6 @@ import org.mockito.junit.MockitoRule;
public class FingerprintDetectClientTest {
private static final int USER_ID = 8;
private static final boolean HAS_AOD = true;
@Rule
public final TestableContext mContext = new TestableContext(
@@ -85,7 +84,6 @@ public class FingerprintDetectClientTest {
@Before
public void setup() {
when(mBiometricContext.isAoD()).thenReturn(HAS_AOD);
when(mBiometricContext.updateContext(any(), anyBoolean())).thenAnswer(
i -> i.getArgument(0));
}

View File

@@ -26,6 +26,7 @@ import static org.mockito.Mockito.any;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.same;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -47,6 +48,8 @@ import androidx.test.platform.app.InstrumentationRegistry;
import com.android.server.biometrics.log.BiometricContext;
import com.android.server.biometrics.log.BiometricLogger;
import com.android.server.biometrics.log.CallbackWithProbe;
import com.android.server.biometrics.log.Probe;
import com.android.server.biometrics.sensors.BiometricUtils;
import com.android.server.biometrics.sensors.ClientMonitorCallback;
import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
@@ -101,16 +104,22 @@ public class FingerprintEnrollClientTest {
private ClientMonitorCallback mCallback;
@Mock
private Sensor.HalSessionCallback mHalSessionCallback;
@Mock
private Probe mLuxProbe;
@Captor
private ArgumentCaptor<OperationContext> mOperationContextCaptor;
@Captor
private ArgumentCaptor<PointerContext> mPointerContextCaptor;
@Captor
private ArgumentCaptor<Consumer<OperationContext>> mContextInjector;
@Rule
public final MockitoRule mockito = MockitoJUnit.rule();
@Before
public void setup() {
when(mBiometricLogger.createALSCallback(anyBoolean())).thenAnswer(i ->
new CallbackWithProbe<>(mLuxProbe, i.getArgument(0)));
when(mBiometricContext.updateContext(any(), anyBoolean())).thenAnswer(
i -> i.getArgument(0));
}
@@ -185,6 +194,41 @@ public class FingerprintEnrollClientTest {
assertThat(pContext.pointerId).isEqualTo(POINTER_ID);
}
@Test
public void luxProbeWhenFingerDown() throws RemoteException {
final FingerprintEnrollClient client = createClient();
client.start(mCallback);
client.onPointerDown(TOUCH_X, TOUCH_Y, TOUCH_MAJOR, TOUCH_MINOR);
verify(mLuxProbe).enable();
client.onAcquired(2, 0);
verify(mLuxProbe, never()).disable();
client.onPointerUp();
verify(mLuxProbe).disable();
client.onPointerDown(TOUCH_X, TOUCH_Y, TOUCH_MAJOR, TOUCH_MINOR);
verify(mLuxProbe, times(2)).enable();
}
@Test
public void notifyHalWhenContextChanges() throws RemoteException {
final FingerprintEnrollClient client = createClient();
client.start(mCallback);
verify(mHal).enrollWithContext(any(), mOperationContextCaptor.capture());
OperationContext opContext = mOperationContextCaptor.getValue();
// fake an update to the context
verify(mBiometricContext).subscribe(eq(opContext), mContextInjector.capture());
mContextInjector.getValue().accept(opContext);
verify(mHal).onContextChanged(eq(opContext));
client.stopHalOperation();
verify(mBiometricContext).unsubscribe(same(opContext));
}
@Test
public void showHideOverlay_cancel() throws RemoteException {
showHideOverlay(c -> c.cancel());