Merge "Fix fingerprint unlock stuck after renaming" into udc-qpr-dev

This commit is contained in:
Wenhui Yang
2023-06-13 01:02:42 +00:00
committed by Android (Google) Code Review
2 changed files with 54 additions and 3 deletions

View File

@@ -21,6 +21,7 @@ import android.hardware.fingerprint.FingerprintManager;
import android.hardware.fingerprint.FingerprintManager.AuthenticationResult; import android.hardware.fingerprint.FingerprintManager.AuthenticationResult;
import android.os.CancellationSignal; import android.os.CancellationSignal;
import com.android.internal.annotations.VisibleForTesting;
import com.android.settings.core.InstrumentedFragment; import com.android.settings.core.InstrumentedFragment;
/** /**
@@ -80,7 +81,6 @@ public class FingerprintAuthenticateSidecar extends InstrumentedFragment {
@Override @Override
public void onAuthenticationError(int errMsgId, CharSequence errString) { public void onAuthenticationError(int errMsgId, CharSequence errString) {
mCancellationSignal = null;
if (mListener != null) { if (mListener != null) {
mListener.onAuthenticationError(errMsgId, errString); mListener.onAuthenticationError(errMsgId, errString);
} else { } else {
@@ -108,11 +108,13 @@ public class FingerprintAuthenticateSidecar extends InstrumentedFragment {
} }
public void stopAuthentication() { public void stopAuthentication() {
if (mCancellationSignal != null && !mCancellationSignal.isCanceled()) { if (mCancellationSignal != null) {
// This will automatically check if the cancel has been sent and if so
// it won't send it again.
mCancellationSignal.cancel(); mCancellationSignal.cancel();
}
mCancellationSignal = null; mCancellationSignal = null;
} }
}
public void setListener(Listener listener) { public void setListener(Listener listener) {
if (mListener == null && listener != null) { if (mListener == null && listener != null) {
@@ -129,4 +131,9 @@ public class FingerprintAuthenticateSidecar extends InstrumentedFragment {
} }
mListener = listener; mListener = listener;
} }
@VisibleForTesting
boolean isCancelled() {
return mCancellationSignal == null || mCancellationSignal.isCanceled();
}
} }

View File

@@ -44,6 +44,7 @@ import android.hardware.biometrics.SensorProperties;
import android.hardware.fingerprint.FingerprintManager; import android.hardware.fingerprint.FingerprintManager;
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal; import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
import android.os.Bundle; import android.os.Bundle;
import android.os.CancellationSignal;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.ViewGroup; import android.view.ViewGroup;
@@ -68,6 +69,7 @@ import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor; import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule; import org.mockito.junit.MockitoRule;
@@ -92,6 +94,16 @@ public class FingerprintSettingsFragmentTest {
@Mock @Mock
private FragmentTransaction mFragmentTransaction; private FragmentTransaction mFragmentTransaction;
@Captor
private ArgumentCaptor<CancellationSignal> mCancellationSignalArgumentCaptor =
ArgumentCaptor.forClass(CancellationSignal.class);
@Captor
private ArgumentCaptor<FingerprintManager.AuthenticationCallback>
mAuthenticationCallbackArgumentCaptor = ArgumentCaptor.forClass(
FingerprintManager.AuthenticationCallback.class);
private FingerprintAuthenticateSidecar mFingerprintAuthenticateSidecar;
@Before @Before
public void setUp() { public void setUp() {
doReturn(true).when(mFingerprintManager).isHardwareDetected(); doReturn(true).when(mFingerprintManager).isHardwareDetected();
@@ -146,6 +158,34 @@ public class FingerprintSettingsFragmentTest {
false)).isTrue(); false)).isTrue();
} }
// Test the case when FingerprintAuthenticateSidecar receives an error callback from the
// framework or from another authentication client. The cancellation signal should not be set
// to null because there may exist a running authentication client.
// The signal can only be cancelled from the caller in FingerprintSettings.
@Test
public void testCancellationSignalLifeCycle() {
setUpFragment(false);
mFingerprintAuthenticateSidecar.setFingerprintManager(mFingerprintManager);
doNothing().when(mFingerprintManager).authenticate(any(),
mCancellationSignalArgumentCaptor.capture(),
mAuthenticationCallbackArgumentCaptor.capture(), any(), anyInt());
mFingerprintAuthenticateSidecar.startAuthentication(1);
assertThat(mAuthenticationCallbackArgumentCaptor.getValue()).isNotNull();
assertThat(mCancellationSignalArgumentCaptor.getValue()).isNotNull();
// Authentication error callback should not cancel the signal.
mAuthenticationCallbackArgumentCaptor.getValue().onAuthenticationError(0, "");
assertThat(mFingerprintAuthenticateSidecar.isCancelled()).isFalse();
// The signal should be cancelled when caller stops the authentication.
mFingerprintAuthenticateSidecar.stopAuthentication();
assertThat(mFingerprintAuthenticateSidecar.isCancelled()).isTrue();
}
private void setUpFragment(boolean showChooseLock) { private void setUpFragment(boolean showChooseLock) {
Intent intent = new Intent(); Intent intent = new Intent();
if (!showChooseLock) { if (!showChooseLock) {
@@ -166,6 +206,10 @@ public class FingerprintSettingsFragmentTest {
doReturn(fragmentManager).when(mFragment).getFragmentManager(); doReturn(fragmentManager).when(mFragment).getFragmentManager();
doReturn(fragmentManager).when(mActivity).getSupportFragmentManager(); doReturn(fragmentManager).when(mActivity).getSupportFragmentManager();
mFingerprintAuthenticateSidecar = new FingerprintAuthenticateSidecar();
doReturn(mFingerprintAuthenticateSidecar).when(fragmentManager).findFragmentByTag(
"authenticate_sidecar");
doNothing().when(mFragment).startActivityForResult(any(Intent.class), anyInt()); doNothing().when(mFragment).startActivityForResult(any(Intent.class), anyInt());
setSensor(); setSensor();