Merge "Move ALS auth logging triggers to wakefullness events." into tm-qpr-dev am: 40db12e7c7

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/19775212

Change-Id: I773e5885a49273e1d335165fba8afecbcb157410
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Joe Bolinger
2022-09-01 20:14:06 +00:00
committed by Automerger Merge Worker
10 changed files with 189 additions and 69 deletions

View File

@@ -23,5 +23,8 @@ package android.hardware.biometrics;
* @hide * @hide
*/ */
oneway interface IBiometricContextListener { oneway interface IBiometricContextListener {
void onDozeChanged(boolean isDozing); // Called when doze or awake (screen on) status changes.
// These may be called while the device is still transitioning to the new state
// (i.e. about to become awake or enter doze)
void onDozeChanged(boolean isDozing, boolean isAwake);
} }

View File

@@ -19,6 +19,9 @@ package com.android.systemui.biometrics;
import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FACE; import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FACE;
import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT; import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT;
import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_AWAKE;
import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_GOING_TO_SLEEP;
import android.annotation.NonNull; import android.annotation.NonNull;
import android.annotation.Nullable; import android.annotation.Nullable;
import android.app.ActivityManager; import android.app.ActivityManager;
@@ -655,7 +658,6 @@ public class AuthController extends CoreStartable implements CommandQueue.Callba
@Background DelayableExecutor bgExecutor) { @Background DelayableExecutor bgExecutor) {
super(context); super(context);
mExecution = execution; mExecution = execution;
mWakefulnessLifecycle = wakefulnessLifecycle;
mUserManager = userManager; mUserManager = userManager;
mLockPatternUtils = lockPatternUtils; mLockPatternUtils = lockPatternUtils;
mHandler = handler; mHandler = handler;
@@ -681,11 +683,24 @@ public class AuthController extends CoreStartable implements CommandQueue.Callba
return Unit.INSTANCE; return Unit.INSTANCE;
}); });
mWakefulnessLifecycle = wakefulnessLifecycle;
mWakefulnessLifecycle.addObserver(new WakefulnessLifecycle.Observer() {
@Override
public void onFinishedWakingUp() {
notifyDozeChanged(mStatusBarStateController.isDozing(), WAKEFULNESS_AWAKE);
}
@Override
public void onStartedGoingToSleep() {
notifyDozeChanged(mStatusBarStateController.isDozing(), WAKEFULNESS_GOING_TO_SLEEP);
}
});
mStatusBarStateController = statusBarStateController; mStatusBarStateController = statusBarStateController;
mStatusBarStateController.addCallback(new StatusBarStateController.StateListener() { mStatusBarStateController.addCallback(new StatusBarStateController.StateListener() {
@Override @Override
public void onDozingChanged(boolean isDozing) { public void onDozingChanged(boolean isDozing) {
notifyDozeChanged(isDozing); notifyDozeChanged(isDozing, wakefulnessLifecycle.getWakefulness());
} }
}); });
@@ -763,13 +778,16 @@ public class AuthController extends CoreStartable implements CommandQueue.Callba
@Override @Override
public void setBiometicContextListener(IBiometricContextListener listener) { public void setBiometicContextListener(IBiometricContextListener listener) {
mBiometricContextListener = listener; mBiometricContextListener = listener;
notifyDozeChanged(mStatusBarStateController.isDozing()); notifyDozeChanged(mStatusBarStateController.isDozing(),
mWakefulnessLifecycle.getWakefulness());
} }
private void notifyDozeChanged(boolean isDozing) { private void notifyDozeChanged(boolean isDozing,
@WakefulnessLifecycle.Wakefulness int wakefullness) {
if (mBiometricContextListener != null) { if (mBiometricContextListener != null) {
try { try {
mBiometricContextListener.onDozeChanged(isDozing); final boolean isAwake = wakefullness == WAKEFULNESS_AWAKE;
mBiometricContextListener.onDozeChanged(isDozing, isAwake);
} catch (RemoteException e) { } catch (RemoteException e) {
Log.w(TAG, "failed to notify initial doze state"); Log.w(TAG, "failed to notify initial doze state");
} }

View File

@@ -20,6 +20,8 @@ import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRIN
import static android.hardware.biometrics.BiometricManager.Authenticators; import static android.hardware.biometrics.BiometricManager.Authenticators;
import static android.hardware.biometrics.BiometricManager.BIOMETRIC_MULTI_SENSOR_FINGERPRINT_AND_FACE; import static android.hardware.biometrics.BiometricManager.BIOMETRIC_MULTI_SENSOR_FINGERPRINT_AND_FACE;
import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_AWAKE;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertEquals;
@@ -156,11 +158,13 @@ public class AuthControllerTest extends SysuiTestCase {
@Mock @Mock
private InteractionJankMonitor mInteractionJankMonitor; private InteractionJankMonitor mInteractionJankMonitor;
@Captor @Captor
ArgumentCaptor<IFingerprintAuthenticatorsRegisteredCallback> mAuthenticatorsRegisteredCaptor; private ArgumentCaptor<IFingerprintAuthenticatorsRegisteredCallback> mAuthenticatorsRegisteredCaptor;
@Captor @Captor
ArgumentCaptor<BiometricStateListener> mBiometricStateCaptor; private ArgumentCaptor<BiometricStateListener> mBiometricStateCaptor;
@Captor @Captor
ArgumentCaptor<StatusBarStateController.StateListener> mStatusBarStateListenerCaptor; private ArgumentCaptor<StatusBarStateController.StateListener> mStatusBarStateListenerCaptor;
@Captor
private ArgumentCaptor<WakefulnessLifecycle.Observer> mWakefullnessObserverCaptor;
private TestableContext mContextSpy; private TestableContext mContextSpy;
private Execution mExecution; private Execution mExecution;
@@ -224,7 +228,9 @@ public class AuthControllerTest extends SysuiTestCase {
mAuthenticatorsRegisteredCaptor.capture()); mAuthenticatorsRegisteredCaptor.capture());
when(mStatusBarStateController.isDozing()).thenReturn(false); when(mStatusBarStateController.isDozing()).thenReturn(false);
when(mWakefulnessLifecycle.getWakefulness()).thenReturn(WAKEFULNESS_AWAKE);
verify(mStatusBarStateController).addCallback(mStatusBarStateListenerCaptor.capture()); verify(mStatusBarStateController).addCallback(mStatusBarStateListenerCaptor.capture());
verify(mWakefulnessLifecycle).addObserver(mWakefullnessObserverCaptor.capture());
mAuthenticatorsRegisteredCaptor.getValue().onAllAuthenticatorsRegistered(props); mAuthenticatorsRegisteredCaptor.getValue().onAllAuthenticatorsRegistered(props);
@@ -721,16 +727,37 @@ public class AuthControllerTest extends SysuiTestCase {
} }
@Test @Test
public void testForwardsDozeEvent() throws RemoteException { public void testForwardsDozeEvents() throws RemoteException {
when(mStatusBarStateController.isDozing()).thenReturn(true);
when(mWakefulnessLifecycle.getWakefulness()).thenReturn(WAKEFULNESS_AWAKE);
mAuthController.setBiometicContextListener(mContextListener); mAuthController.setBiometicContextListener(mContextListener);
mStatusBarStateListenerCaptor.getValue().onDozingChanged(false);
mStatusBarStateListenerCaptor.getValue().onDozingChanged(true); mStatusBarStateListenerCaptor.getValue().onDozingChanged(true);
mStatusBarStateListenerCaptor.getValue().onDozingChanged(false);
InOrder order = inOrder(mContextListener); InOrder order = inOrder(mContextListener);
// invoked twice since the initial state is false order.verify(mContextListener, times(2)).onDozeChanged(eq(true), eq(true));
order.verify(mContextListener, times(2)).onDozeChanged(eq(false)); order.verify(mContextListener).onDozeChanged(eq(false), eq(true));
order.verify(mContextListener).onDozeChanged(eq(true)); order.verifyNoMoreInteractions();
}
@Test
public void testForwardsWakeEvents() throws RemoteException {
when(mStatusBarStateController.isDozing()).thenReturn(false);
when(mWakefulnessLifecycle.getWakefulness()).thenReturn(WAKEFULNESS_AWAKE);
mAuthController.setBiometicContextListener(mContextListener);
mWakefullnessObserverCaptor.getValue().onStartedGoingToSleep();
mWakefullnessObserverCaptor.getValue().onFinishedGoingToSleep();
mWakefullnessObserverCaptor.getValue().onStartedWakingUp();
mWakefullnessObserverCaptor.getValue().onFinishedWakingUp();
mWakefullnessObserverCaptor.getValue().onPostFinishedWakingUp();
InOrder order = inOrder(mContextListener);
order.verify(mContextListener).onDozeChanged(eq(false), eq(true));
order.verify(mContextListener).onDozeChanged(eq(false), eq(false));
order.verify(mContextListener).onDozeChanged(eq(false), eq(true));
order.verifyNoMoreInteractions();
} }
@Test @Test

View File

@@ -46,6 +46,9 @@ public interface BiometricContext {
/** If the display is in AOD. */ /** If the display is in AOD. */
boolean isAod(); boolean isAod();
/** If the device is awake or is becoming awake. */
boolean isAwake();
/** /**
* Subscribe to context changes. * Subscribe to context changes.
* *

View File

@@ -43,7 +43,7 @@ import java.util.function.Consumer;
/** /**
* A default provider for {@link BiometricContext}. * A default provider for {@link BiometricContext}.
*/ */
class BiometricContextProvider implements BiometricContext { final class BiometricContextProvider implements BiometricContext {
private static final String TAG = "BiometricContextProvider"; private static final String TAG = "BiometricContextProvider";
@@ -76,7 +76,8 @@ class BiometricContextProvider implements BiometricContext {
private final Map<Integer, InstanceId> mSession = new ConcurrentHashMap<>(); private final Map<Integer, InstanceId> mSession = new ConcurrentHashMap<>();
private final AmbientDisplayConfiguration mAmbientDisplayConfiguration; private final AmbientDisplayConfiguration mAmbientDisplayConfiguration;
private boolean mIsDozing = false; private boolean mIsAod = false;
private boolean mIsAwake = false;
@VisibleForTesting @VisibleForTesting
BiometricContextProvider(@NonNull AmbientDisplayConfiguration ambientDisplayConfiguration, BiometricContextProvider(@NonNull AmbientDisplayConfiguration ambientDisplayConfiguration,
@@ -85,9 +86,14 @@ class BiometricContextProvider implements BiometricContext {
try { try {
service.setBiometicContextListener(new IBiometricContextListener.Stub() { service.setBiometicContextListener(new IBiometricContextListener.Stub() {
@Override @Override
public void onDozeChanged(boolean isDozing) { public void onDozeChanged(boolean isDozing, boolean isAwake) {
mIsDozing = isDozing; isDozing = isDozing && isAodEnabled();
notifyChanged(); final boolean changed = (mIsAod != isDozing) || (mIsAwake != isAwake);
if (changed) {
mIsAod = isDozing;
mIsAwake = isAwake;
notifyChanged();
}
} }
private void notifyChanged() { private void notifyChanged() {
@@ -97,6 +103,10 @@ class BiometricContextProvider implements BiometricContext {
notifySubscribers(); notifySubscribers();
} }
} }
private boolean isAodEnabled() {
return mAmbientDisplayConfiguration.alwaysOnEnabled(UserHandle.USER_CURRENT);
}
}); });
service.registerSessionListener(SESSION_TYPES, new ISessionListener.Stub() { service.registerSessionListener(SESSION_TYPES, new ISessionListener.Stub() {
@Override @Override
@@ -161,7 +171,12 @@ class BiometricContextProvider implements BiometricContext {
@Override @Override
public boolean isAod() { public boolean isAod() {
return mIsDozing && mAmbientDisplayConfiguration.alwaysOnEnabled(UserHandle.USER_CURRENT); return mIsAod;
}
@Override
public boolean isAwake() {
return mIsAwake;
} }
@Override @Override

View File

@@ -315,21 +315,27 @@ class FingerprintAuthenticationClient extends AuthenticationClient<AidlSession>
private ICancellationSignal doAuthenticate() throws RemoteException { private ICancellationSignal doAuthenticate() throws RemoteException {
final AidlSession session = getFreshDaemon(); final AidlSession session = getFreshDaemon();
final OperationContext opContext = getOperationContext();
getBiometricContext().subscribe(opContext, ctx -> {
if (session.hasContextMethods()) {
try {
session.getSession().onContextChanged(ctx);
} catch (RemoteException e) {
Slog.e(TAG, "Unable to notify context changed", e);
}
}
// TODO(b/243836005): this should come via ctx
final boolean isAwake = getBiometricContext().isAwake();
if (isAwake) {
mALSProbeCallback.getProbe().enable();
} else {
mALSProbeCallback.getProbe().disable();
}
});
if (session.hasContextMethods()) { if (session.hasContextMethods()) {
final OperationContext opContext = getOperationContext(); return session.getSession().authenticateWithContext(mOperationId, opContext);
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 { } else {
return session.getSession().authenticate(mOperationId); return session.getSession().authenticate(mOperationId);
} }
@@ -360,7 +366,6 @@ class FingerprintAuthenticationClient extends AuthenticationClient<AidlSession>
try { try {
mIsPointerDown = true; mIsPointerDown = true;
mState = STATE_STARTED; mState = STATE_STARTED;
mALSProbeCallback.getProbe().enable();
final AidlSession session = getFreshDaemon(); final AidlSession session = getFreshDaemon();
if (session.hasContextMethods()) { if (session.hasContextMethods()) {
@@ -389,7 +394,6 @@ class FingerprintAuthenticationClient extends AuthenticationClient<AidlSession>
try { try {
mIsPointerDown = false; mIsPointerDown = false;
mState = STATE_STARTED_PAUSED_ATTEMPTED; mState = STATE_STARTED_PAUSED_ATTEMPTED;
mALSProbeCallback.getProbe().disable();
final AidlSession session = getFreshDaemon(); final AidlSession session = getFreshDaemon();
if (session.hasContextMethods()) { if (session.hasContextMethods()) {

View File

@@ -94,7 +94,7 @@ class FingerprintEnrollClient extends EnrollClient<AidlSession> implements Udfps
mSensorOverlays = new SensorOverlays(udfpsOverlayController, sidefpsController); mSensorOverlays = new SensorOverlays(udfpsOverlayController, sidefpsController);
mMaxTemplatesPerUser = maxTemplatesPerUser; mMaxTemplatesPerUser = maxTemplatesPerUser;
mALSProbeCallback = getLogger().getAmbientLightProbe(false /* startWithClient */); mALSProbeCallback = getLogger().getAmbientLightProbe(true /* startWithClient */);
mEnrollReason = enrollReason; mEnrollReason = enrollReason;
if (enrollReason == FingerprintManager.ENROLL_FIND_SENSOR) { if (enrollReason == FingerprintManager.ENROLL_FIND_SENSOR) {
@@ -216,7 +216,6 @@ class FingerprintEnrollClient extends EnrollClient<AidlSession> implements Udfps
public void onPointerDown(int x, int y, float minor, float major) { public void onPointerDown(int x, int y, float minor, float major) {
try { try {
mIsPointerDown = true; mIsPointerDown = true;
mALSProbeCallback.getProbe().enable();
final AidlSession session = getFreshDaemon(); final AidlSession session = getFreshDaemon();
if (session.hasContextMethods()) { if (session.hasContextMethods()) {
@@ -240,7 +239,6 @@ class FingerprintEnrollClient extends EnrollClient<AidlSession> implements Udfps
public void onPointerUp() { public void onPointerUp() {
try { try {
mIsPointerDown = false; mIsPointerDown = false;
mALSProbeCallback.getProbe().disable();
final AidlSession session = getFreshDaemon(); final AidlSession session = getFreshDaemon();
if (session.hasContextMethods()) { if (session.hasContextMethods()) {

View File

@@ -40,8 +40,6 @@ import com.android.internal.logging.InstanceId;
import com.android.internal.statusbar.ISessionListener; import com.android.internal.statusbar.ISessionListener;
import com.android.internal.statusbar.IStatusBarService; import com.android.internal.statusbar.IStatusBarService;
import com.google.common.collect.ImmutableList;
import org.junit.Before; import org.junit.Before;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
@@ -89,33 +87,64 @@ public class BiometricContextProviderTest {
@Test @Test
public void testIsAod() throws RemoteException { public void testIsAod() throws RemoteException {
mListener.onDozeChanged(true); mListener.onDozeChanged(true /* isDozing */, false /* isAwake */);
assertThat(mProvider.isAod()).isTrue(); assertThat(mProvider.isAod()).isTrue();
mListener.onDozeChanged(false); mListener.onDozeChanged(false /* isDozing */, false /* isAwake */);
assertThat(mProvider.isAod()).isFalse(); assertThat(mProvider.isAod()).isFalse();
when(mAmbientDisplayConfiguration.alwaysOnEnabled(anyInt())).thenReturn(false); when(mAmbientDisplayConfiguration.alwaysOnEnabled(anyInt())).thenReturn(false);
mListener.onDozeChanged(true); mListener.onDozeChanged(true /* isDozing */, false /* isAwake */);
assertThat(mProvider.isAod()).isFalse(); assertThat(mProvider.isAod()).isFalse();
mListener.onDozeChanged(false); mListener.onDozeChanged(false /* isDozing */, false /* isAwake */);
assertThat(mProvider.isAod()).isFalse(); assertThat(mProvider.isAod()).isFalse();
} }
@Test
public void testIsAwake() throws RemoteException {
mListener.onDozeChanged(false /* isDozing */, true /* isAwake */);
assertThat(mProvider.isAwake()).isTrue();
mListener.onDozeChanged(false /* isDozing */, false /* isAwake */);
assertThat(mProvider.isAwake()).isFalse();
mListener.onDozeChanged(true /* isDozing */, true /* isAwake */);
assertThat(mProvider.isAwake()).isTrue();
mListener.onDozeChanged(true /* isDozing */, false /* isAwake */);
assertThat(mProvider.isAwake()).isFalse();
}
@Test @Test
public void testSubscribesToAod() throws RemoteException { public void testSubscribesToAod() throws RemoteException {
final List<Boolean> expected = ImmutableList.of(true, false, true, true, false);
final List<Boolean> actual = new ArrayList<>(); final List<Boolean> actual = new ArrayList<>();
mProvider.subscribe(mOpContext, ctx -> { mProvider.subscribe(mOpContext, ctx -> {
assertThat(ctx).isSameInstanceAs(mOpContext); assertThat(ctx).isSameInstanceAs(mOpContext);
assertThat(mProvider.isAod()).isEqualTo(ctx.isAod);
assertThat(mProvider.isAwake()).isFalse();
actual.add(ctx.isAod); actual.add(ctx.isAod);
}); });
for (boolean v : expected) { for (boolean v : List.of(true, false, true, true, false, false)) {
mListener.onDozeChanged(v); mListener.onDozeChanged(v /* isDozing */, false /* isAwake */);
} }
assertThat(actual).containsExactlyElementsIn(expected).inOrder(); assertThat(actual).containsExactly(true, false, true, false).inOrder();
}
@Test
public void testSubscribesToAwake() throws RemoteException {
final List<Boolean> actual = new ArrayList<>();
mProvider.subscribe(mOpContext, ctx -> {
assertThat(ctx).isSameInstanceAs(mOpContext);
assertThat(ctx.isAod).isFalse();
assertThat(mProvider.isAod()).isFalse();
actual.add(mProvider.isAwake());
});
for (boolean v : List.of(true, false, true, true, false, false)) {
mListener.onDozeChanged(false /* isDozing */, v /* isAwake */);
}
assertThat(actual).containsExactly(true, false, true, false).inOrder();
} }
@Test @Test
@@ -124,13 +153,13 @@ public class BiometricContextProviderTest {
mProvider.subscribe(mOpContext, emptyConsumer); mProvider.subscribe(mOpContext, emptyConsumer);
mProvider.unsubscribe(mOpContext); mProvider.unsubscribe(mOpContext);
mListener.onDozeChanged(true); mListener.onDozeChanged(true /* isDozing */, false /* isAwake */);
final Consumer<OperationContext> nonEmptyConsumer = mock(Consumer.class); final Consumer<OperationContext> nonEmptyConsumer = mock(Consumer.class);
mProvider.subscribe(mOpContext, nonEmptyConsumer); mProvider.subscribe(mOpContext, nonEmptyConsumer);
mListener.onDozeChanged(false); mListener.onDozeChanged(false /* isDozing */, false /* isAwake */);
mProvider.unsubscribe(mOpContext); mProvider.unsubscribe(mOpContext);
mListener.onDozeChanged(true); mListener.onDozeChanged(true /* isDozing */, false /* isAwake */);
verify(emptyConsumer, never()).accept(any()); verify(emptyConsumer, never()).accept(any());
verify(nonEmptyConsumer).accept(same(mOpContext)); verify(nonEmptyConsumer).accept(same(mOpContext));
@@ -171,7 +200,7 @@ public class BiometricContextProviderTest {
@Test @Test
public void testUpdate() throws RemoteException { public void testUpdate() throws RemoteException {
mListener.onDozeChanged(false); mListener.onDozeChanged(false /* isDozing */, false /* isAwake */);
OperationContext context = mProvider.updateContext(mOpContext, false /* crypto */); OperationContext context = mProvider.updateContext(mOpContext, false /* crypto */);
// default state when nothing has been set // default state when nothing has been set
@@ -186,7 +215,7 @@ public class BiometricContextProviderTest {
final int id = 40 + type; final int id = 40 + type;
final boolean aod = (type & 1) == 0; final boolean aod = (type & 1) == 0;
mListener.onDozeChanged(aod); mListener.onDozeChanged(aod /* isDozing */, false /* isAwake */);
mSessionListener.onSessionStarted(type, InstanceId.fakeInstanceId(id)); mSessionListener.onSessionStarted(type, InstanceId.fakeInstanceId(id));
context = mProvider.updateContext(mOpContext, false /* crypto */); context = mProvider.updateContext(mOpContext, false /* crypto */);
assertThat(context).isSameInstanceAs(mOpContext); assertThat(context).isSameInstanceAs(mOpContext);

View File

@@ -26,8 +26,8 @@ import static org.mockito.Mockito.anyLong;
import static org.mockito.Mockito.eq; import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.inOrder; import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.never; import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.same; import static org.mockito.Mockito.same;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
@@ -96,6 +96,7 @@ public class FingerprintAuthenticationClientTest {
InstrumentationRegistry.getInstrumentation().getTargetContext(), null); InstrumentationRegistry.getInstrumentation().getTargetContext(), null);
@Rule @Rule
public final MockitoRule mockito = MockitoJUnit.rule(); public final MockitoRule mockito = MockitoJUnit.rule();
@Mock @Mock
private ISession mHal; private ISession mHal;
@Mock @Mock
@@ -213,21 +214,41 @@ public class FingerprintAuthenticationClientTest {
} }
@Test @Test
public void luxProbeWhenFingerDown() throws RemoteException { public void luxProbeWhenAwake() throws RemoteException {
when(mBiometricContext.isAwake()).thenReturn(false, true, false);
when(mBiometricContext.isAod()).thenReturn(false);
final FingerprintAuthenticationClient client = createClient(); final FingerprintAuthenticationClient client = createClient();
client.start(mCallback); client.start(mCallback);
client.onPointerDown(TOUCH_X, TOUCH_Y, TOUCH_MAJOR, TOUCH_MINOR); verify(mHal).authenticateWithContext(eq(OP_ID), mOperationContextCaptor.capture());
verify(mLuxProbe).enable(); OperationContext opContext = mOperationContextCaptor.getValue();
verify(mBiometricContext).subscribe(eq(opContext), mContextInjector.capture());
client.onAcquired(2, 0); mContextInjector.getValue().accept(opContext);
verify(mLuxProbe, never()).enable();
reset(mLuxProbe);
mContextInjector.getValue().accept(opContext);
verify(mLuxProbe).enable();
verify(mLuxProbe, never()).disable(); verify(mLuxProbe, never()).disable();
client.onPointerUp(); mContextInjector.getValue().accept(opContext);
verify(mLuxProbe).disable(); verify(mLuxProbe).disable();
}
client.onPointerDown(TOUCH_X, TOUCH_Y, TOUCH_MAJOR, TOUCH_MINOR); @Test
verify(mLuxProbe, times(2)).enable(); public void luxProbeDisabledOnAod() throws RemoteException {
when(mBiometricContext.isAwake()).thenReturn(false);
when(mBiometricContext.isAod()).thenReturn(true);
final FingerprintAuthenticationClient client = createClient();
client.start(mCallback);
verify(mHal).authenticateWithContext(eq(OP_ID), mOperationContextCaptor.capture());
OperationContext opContext = mOperationContextCaptor.getValue();
verify(mBiometricContext).subscribe(eq(opContext), mContextInjector.capture());
mContextInjector.getValue().accept(opContext);
verify(mLuxProbe, never()).enable();
} }
@Test @Test

View File

@@ -64,6 +64,7 @@ import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule; import org.mockito.junit.MockitoRule;
import java.util.ArrayList;
import java.util.function.Consumer; import java.util.function.Consumer;
@Presubmit @Presubmit
@@ -196,21 +197,22 @@ public class FingerprintEnrollClientTest {
} }
@Test @Test
public void luxProbeWhenFingerDown() throws RemoteException { public void luxProbeWhenStarted() throws RemoteException {
final FingerprintEnrollClient client = createClient(); final FingerprintEnrollClient client = createClient();
client.start(mCallback); client.start(mCallback);
client.onPointerDown(TOUCH_X, TOUCH_Y, TOUCH_MAJOR, TOUCH_MINOR);
verify(mLuxProbe).enable(); verify(mLuxProbe).enable();
client.onAcquired(2, 0); client.onAcquired(2, 0);
verify(mLuxProbe, never()).disable();
client.onPointerUp(); client.onPointerUp();
verify(mLuxProbe).disable();
client.onPointerDown(TOUCH_X, TOUCH_Y, TOUCH_MAJOR, TOUCH_MINOR); client.onPointerDown(TOUCH_X, TOUCH_Y, TOUCH_MAJOR, TOUCH_MINOR);
verify(mLuxProbe, times(2)).enable(); verify(mLuxProbe, never()).disable();
verify(mLuxProbe, never()).destroy();
client.onEnrollResult(new Fingerprint("f", 30 /* fingerId */, 14 /* deviceId */),
0 /* remaining */);
verify(mLuxProbe).destroy();
} }
@Test @Test