Merge "Refresh templates when fp removal fails" into main
diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintRemoveSidecar.java b/src/com/android/settings/biometrics/fingerprint/FingerprintRemoveSidecar.java
index 73eccdc..2737d38 100644
--- a/src/com/android/settings/biometrics/fingerprint/FingerprintRemoveSidecar.java
+++ b/src/com/android/settings/biometrics/fingerprint/FingerprintRemoveSidecar.java
@@ -23,6 +23,7 @@
import android.util.Log;
import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
import com.android.settings.core.InstrumentedFragment;
@@ -51,7 +52,8 @@
}
}
- private FingerprintManager.RemovalCallback
+ @VisibleForTesting
+ FingerprintManager.RemovalCallback
mRemoveCallback = new FingerprintManager.RemovalCallback() {
@Override
public void onRemovalSucceeded(Fingerprint fingerprint, int remaining) {
diff --git a/src/com/android/settings/biometrics/fingerprint/FingerprintSettings.java b/src/com/android/settings/biometrics/fingerprint/FingerprintSettings.java
index cb7d617..9a4e657 100644
--- a/src/com/android/settings/biometrics/fingerprint/FingerprintSettings.java
+++ b/src/com/android/settings/biometrics/fingerprint/FingerprintSettings.java
@@ -226,6 +226,7 @@
private static final int MSG_FINGER_AUTH_FAIL = 1002;
private static final int MSG_FINGER_AUTH_ERROR = 1003;
private static final int MSG_FINGER_AUTH_HELP = 1004;
+ private static final int MSG_RELOAD_FINGERPRINT_TEMPLATES = 1005;
private static final int CONFIRM_REQUEST = 101;
@VisibleForTesting
@@ -313,6 +314,8 @@
if (activity != null) {
Toast.makeText(activity, errString, Toast.LENGTH_SHORT);
}
+ mHandler.obtainMessage(MSG_RELOAD_FINGERPRINT_TEMPLATES)
+ .sendToTarget();
updateDialog();
}
@@ -331,11 +334,7 @@
switch (msg.what) {
case MSG_REFRESH_FINGERPRINT_TEMPLATES:
removeFingerprintPreference(msg.arg1);
- updateAddPreference();
- if (isSfps()) {
- updateFingerprintUnlockCategoryVisibility();
- }
- updatePreferences();
+ updatePreferencesAfterFingerprintRemoved();
break;
case MSG_FINGER_AUTH_SUCCESS:
highlightFingerprintItem(msg.arg1);
@@ -347,6 +346,9 @@
case MSG_FINGER_AUTH_ERROR:
handleError(msg.arg1 /* errMsgId */, (CharSequence) msg.obj /* errStr */);
break;
+ case MSG_RELOAD_FINGERPRINT_TEMPLATES:
+ updatePreferencesAfterFingerprintRemoved();
+ break;
case MSG_FINGER_AUTH_HELP: {
// Not used
}
@@ -568,6 +570,7 @@
protected void removeFingerprintPreference(int fingerprintId) {
String name = genKey(fingerprintId);
+ Log.e(TAG, "removeFingerprintPreference : " + fingerprintId);
Preference prefToRemove = findPreference(name);
if (prefToRemove != null) {
if (!getPreferenceScreen().removePreference(prefToRemove)) {
@@ -692,6 +695,13 @@
});
}
+ private void updatePreferencesAfterFingerprintRemoved() {
+ updateAddPreference();
+ if (isSfps()) {
+ updateFingerprintUnlockCategoryVisibility();
+ }
+ }
+
private void updateAddPreference() {
if (getActivity() == null) {
return; // Activity went away
diff --git a/tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintSettingsFragmentTest.java b/tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintSettingsFragmentTest.java
index 4ef3223..a34b6de 100644
--- a/tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintSettingsFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/biometrics/fingerprint/FingerprintSettingsFragmentTest.java
@@ -36,6 +36,7 @@
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import static org.robolectric.Shadows.shadowOf;
import android.content.Context;
import android.content.Intent;
@@ -44,11 +45,13 @@
import android.hardware.biometrics.ComponentInfoInternal;
import android.hardware.biometrics.Flags;
import android.hardware.biometrics.SensorProperties;
+import android.hardware.fingerprint.Fingerprint;
import android.hardware.fingerprint.FingerprintManager;
import android.hardware.fingerprint.FingerprintSensorProperties;
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
import android.os.Bundle;
import android.os.CancellationSignal;
+import android.os.Looper;
import android.os.UserHandle;
import android.platform.test.annotations.EnableFlags;
import android.platform.test.flag.junit.SetFlagsRule;
@@ -59,6 +62,7 @@
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
+import androidx.preference.Preference;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.password.ChooseLockSettingsHelper;
@@ -87,6 +91,7 @@
import org.robolectric.annotation.Config;
import java.util.ArrayList;
+import java.util.List;
@RunWith(RobolectricTestRunner.class)
@Config(shadows = {ShadowSettingsPreferenceFragment.class, ShadowUtils.class, ShadowFragment.class,
@@ -120,6 +125,7 @@
FingerprintManager.AuthenticationCallback.class);
private FingerprintAuthenticateSidecar mFingerprintAuthenticateSidecar;
+ private FingerprintRemoveSidecar mFingerprintRemoveSidecar;
@Before
public void setUp() {
@@ -216,7 +222,7 @@
1,
UserHandle.of(GUEST_USER_ID).getIdentifier());
- setUpFragment(false, GUEST_USER_ID, TYPE_POWER_BUTTON);
+ setUpFragment(false, GUEST_USER_ID, TYPE_POWER_BUTTON, 1);
final RestrictedSwitchPreference requireScreenOnToAuthPreference = mFragment.findPreference(
KEY_REQUIRE_SCREEN_ON_TO_AUTH);
@@ -224,11 +230,15 @@
}
private void setUpFragment(boolean showChooseLock) {
- setUpFragment(showChooseLock, PRIMARY_USER_ID, TYPE_UDFPS_OPTICAL);
+ setUpFragment(showChooseLock, PRIMARY_USER_ID, TYPE_UDFPS_OPTICAL, 1);
+ }
+
+ private void setUpFragment(boolean showChooseLock, int maxFingerprints) {
+ setUpFragment(showChooseLock, PRIMARY_USER_ID, TYPE_UDFPS_OPTICAL, maxFingerprints);
}
private void setUpFragment(boolean showChooseLock, int userId,
- @FingerprintSensorProperties.SensorType int sensorType) {
+ @FingerprintSensorProperties.SensorType int sensorType, int maxFingerprints) {
ShadowUserManager.getShadow().addProfile(new UserInfo(userId, "", 0));
Intent intent = new Intent();
@@ -250,9 +260,13 @@
doReturn(mFingerprintAuthenticateSidecar).when(fragmentManager).findFragmentByTag(
"authenticate_sidecar");
+ mFingerprintRemoveSidecar = new FingerprintRemoveSidecar();
+ doReturn(mFingerprintRemoveSidecar).when(fragmentManager).findFragmentByTag(
+ "removal_sidecar");
+
doNothing().when(mFragment).startActivityForResult(any(Intent.class), anyInt());
- setSensor(sensorType);
+ setSensor(sensorType, maxFingerprints);
// Start fragment
mFragment.onAttach(mContext);
@@ -269,12 +283,38 @@
assertThat(mFragment.isVisible()).isTrue();
}
- private void setSensor(@FingerprintSensorProperties.SensorType int sensorType) {
+ @Ignore("b/353726774")
+ @Test
+ public void testAddButtonWorksAfterRemovalError() {
+ final Fingerprint fingerprint = new Fingerprint("Test", 0, 0);
+ doReturn(List.of(fingerprint)).when(mFingerprintManager).getEnrolledFingerprints(anyInt());
+ setUpFragment(false, 5);
+ shadowOf(Looper.getMainLooper()).idle();
+ final Preference addPref = mFragment.findPreference("key_fingerprint_add");
+ final FingerprintSettings.FingerprintPreference fpPref =
+ mFragment.findPreference("key_fingerprint_item_0");
+ assertThat(fpPref).isNotNull();
+ assertThat(addPref).isNotNull();
+ assertThat(addPref.isEnabled()).isTrue();
+
+ mFingerprintRemoveSidecar.setListener(mFragment.mRemovalListener);
+ mFragment.deleteFingerPrint(fingerprint);
+ verify(mFingerprintManager).remove(any(), anyInt(), any());
+ assertThat(addPref.isEnabled()).isFalse();
+
+ mFingerprintRemoveSidecar.mRemoveCallback.onRemovalError(fingerprint, 0, "failure");
+
+ shadowOf(Looper.getMainLooper()).idle();
+ assertThat(addPref.isEnabled()).isTrue();
+ }
+
+ private void setSensor(@FingerprintSensorProperties.SensorType int sensorType,
+ int maxFingerprints) {
final ArrayList<FingerprintSensorPropertiesInternal> props = new ArrayList<>();
props.add(new FingerprintSensorPropertiesInternal(
0 /* sensorId */,
SensorProperties.STRENGTH_STRONG,
- 1 /* maxEnrollmentsPerUser */,
+ maxFingerprints /* maxEnrollmentsPerUser */,
new ArrayList<ComponentInfoInternal>(),
sensorType,
true /* resetLockoutRequiresHardwareAuthToken */));