Send AoD context changed notification to HAL.
Bug: 204585936 Bug: 204584403 Test: atest FingerprintAuthenticationClientTest FingerprintDetectClientTest FingerprintEnrollClientTest Change-Id: Idcccba362a151d0454d4070475073d07803e4e2a
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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()) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
|
||||
Reference in New Issue
Block a user