Merge "Updated keyguard to be robust against fpm" into tm-qpr-dev

This commit is contained in:
Joshua Mccloskey
2022-08-08 17:44:41 +00:00
committed by Android (Google) Code Review
2 changed files with 65 additions and 9 deletions

View File

@@ -214,7 +214,8 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
* If no cancel signal has been received after this amount of time, set the biometric running
* state to stopped to allow Keyguard to retry authentication.
*/
private static final int DEFAULT_CANCEL_SIGNAL_TIMEOUT = 3000;
@VisibleForTesting
protected static final int DEFAULT_CANCEL_SIGNAL_TIMEOUT = 3000;
private static final ComponentName FALLBACK_HOME_COMPONENT = new ComponentName(
"com.android.settings", "com.android.settings.FallbackHome");
@@ -332,10 +333,15 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
private static final int HAL_ERROR_RETRY_TIMEOUT = 500; // ms
private static final int HAL_ERROR_RETRY_MAX = 20;
private final Runnable mFpCancelNotReceived = this::onFingerprintCancelNotReceived;
@VisibleForTesting
protected final Runnable mFpCancelNotReceived = this::onFingerprintCancelNotReceived;
private final Runnable mFaceCancelNotReceived = this::onFaceCancelNotReceived;
@VisibleForTesting
protected Handler getHandler() {
return mHandler;
}
private final Handler mHandler;
private SparseBooleanArray mBiometricEnabledForUser = new SparseBooleanArray();
@@ -723,6 +729,11 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
private void handleFingerprintAuthFailed() {
Assert.isMainThread();
if (mHandler.hasCallbacks(mFpCancelNotReceived)) {
Log.d(TAG, "handleFingerprintAuthFailed()"
+ " triggered while waiting for cancellation, removing watchdog");
mHandler.removeCallbacks(mFpCancelNotReceived);
}
for (int i = 0; i < mCallbacks.size(); i++) {
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
if (cb != null) {
@@ -753,6 +764,11 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
private void handleFingerprintAuthenticated(int authUserId, boolean isStrongBiometric) {
Trace.beginSection("KeyGuardUpdateMonitor#handlerFingerPrintAuthenticated");
if (mHandler.hasCallbacks(mFpCancelNotReceived)) {
Log.d(TAG, "handleFingerprintAuthenticated()"
+ " triggered while waiting for cancellation, removing watchdog");
mHandler.removeCallbacks(mFpCancelNotReceived);
}
try {
final int userId;
try {

View File

@@ -22,6 +22,7 @@ import static android.telephony.SubscriptionManager.NAME_SOURCE_CARRIER_ID;
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_USER_REQUEST;
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT;
import static com.android.keyguard.KeyguardUpdateMonitor.DEFAULT_CANCEL_SIGNAL_TIMEOUT;
import static com.google.common.truth.Truth.assertThat;
@@ -109,6 +110,7 @@ import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.MockitoSession;
import org.mockito.internal.util.reflection.FieldSetter;
import java.util.ArrayList;
import java.util.Arrays;
@@ -200,9 +202,10 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
private ArgumentCaptor<CancellationSignal> mCancellationSignalCaptor;
// Direct executor
private Executor mBackgroundExecutor = Runnable::run;
private Executor mMainExecutor = Runnable::run;
private final Executor mBackgroundExecutor = Runnable::run;
private final Executor mMainExecutor = Runnable::run;
private TestableLooper mTestableLooper;
private Handler mHandler;
private TestableKeyguardUpdateMonitor mKeyguardUpdateMonitor;
private TestableContext mSpiedContext;
private MockitoSession mMockitoSession;
@@ -291,6 +294,13 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
mBiometricEnabledOnKeyguardCallback = mBiometricEnabledCallbackArgCaptor.getValue();
biometricsEnabledForCurrentUser();
mHandler = spy(mKeyguardUpdateMonitor.getHandler());
try {
FieldSetter.setField(mKeyguardUpdateMonitor,
KeyguardUpdateMonitor.class.getDeclaredField("mHandler"), mHandler);
} catch (NoSuchFieldException e) {
}
verify(mStatusBarStateController).addCallback(mStatusBarStateListenerCaptor.capture());
mStatusBarStateListener = mStatusBarStateListenerCaptor.getValue();
mKeyguardUpdateMonitor.registerCallback(mTestCallback);
@@ -330,7 +340,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
when(mTelephonyManager.getActiveModemCount()).thenReturn(1);
when(mTelephonyManager.getSimState(anyInt())).thenReturn(state);
when(mSubscriptionManager.getSubscriptionIds(anyInt())).thenReturn(new int[] { subId });
when(mSubscriptionManager.getSubscriptionIds(anyInt())).thenReturn(new int[]{subId});
KeyguardUpdateMonitor testKUM = new TestableKeyguardUpdateMonitor(mSpiedContext);
@@ -505,7 +515,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
// Even SimState Loaded, still need ACTION_SERVICE_STATE turn on mTelephonyCapable
assertThat(mKeyguardUpdateMonitor.mTelephonyCapable).isFalse();
Intent intentServiceState = new Intent(Intent.ACTION_SERVICE_STATE);
Intent intentServiceState = new Intent(Intent.ACTION_SERVICE_STATE);
intentSimState.putExtra(Intent.EXTRA_SIM_STATE
, Intent.SIM_STATE_LOADED);
mKeyguardUpdateMonitor.mBroadcastReceiver.onReceive(getContext()
@@ -520,7 +530,7 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
mTestableLooper.processAllMessages();
verify(mFingerprintManager).authenticate(any(), any(), any(), any(), anyInt(), anyInt(),
anyInt());
anyInt());
verify(mFingerprintManager, never()).detectFingerprint(any(), any(), anyInt());
}
@@ -791,7 +801,8 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
public void testBiometricsCleared_whenUserSwitches() throws Exception {
final IRemoteCallback reply = new IRemoteCallback.Stub() {
@Override
public void sendResult(Bundle data) {} // do nothing
public void sendResult(Bundle data) {
} // do nothing
};
final BiometricAuthenticated dummyAuthentication =
new BiometricAuthenticated(true /* authenticated */, true /* strong */);
@@ -809,7 +820,8 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
public void testMultiUserJankMonitor_whenUserSwitches() throws Exception {
final IRemoteCallback reply = new IRemoteCallback.Stub() {
@Override
public void sendResult(Bundle data) {} // do nothing
public void sendResult(Bundle data) {
} // do nothing
};
mKeyguardUpdateMonitor.handleUserSwitchComplete(10 /* user */);
verify(mInteractionJankMonitor).end(InteractionJankMonitor.CUJ_USER_SWITCH);
@@ -1499,6 +1511,34 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
assertThat(cancelSignal.isCanceled()).isTrue();
}
@Test
public void testFingerprintCanAuth_whenCancellationNotReceivedAndAuthFailed() {
mKeyguardUpdateMonitor.dispatchStartedWakingUp();
mTestableLooper.processAllMessages();
mKeyguardUpdateMonitor.onKeyguardVisibilityChanged(true);
verify(mFaceManager).authenticate(any(), any(), any(), any(), anyInt(), anyBoolean());
verify(mFingerprintManager).authenticate(any(), any(), any(), any(), anyInt(), anyInt(),
anyInt());
mKeyguardUpdateMonitor.onFaceAuthenticated(0, false);
// Make sure keyguard is going away after face auth attempt, and that it calls
// updateBiometricStateListeningState.
mKeyguardUpdateMonitor.onKeyguardVisibilityChanged(false);
mTestableLooper.processAllMessages();
verify(mHandler).postDelayed(mKeyguardUpdateMonitor.mFpCancelNotReceived,
DEFAULT_CANCEL_SIGNAL_TIMEOUT);
mKeyguardUpdateMonitor.onFingerprintAuthenticated(0, true);
mTestableLooper.processAllMessages();
verify(mHandler, times(1)).removeCallbacks(mKeyguardUpdateMonitor.mFpCancelNotReceived);
mKeyguardUpdateMonitor.dispatchStartedGoingToSleep(0 /* why */);
mTestableLooper.processAllMessages();
assertThat(mKeyguardUpdateMonitor.shouldListenForFingerprint(anyBoolean())).isEqualTo(true);
}
private void fingerprintIsNotEnrolled() {
when(mFingerprintManager.hasEnrolledTemplates(mCurrentUserId)).thenReturn(false);
}