Improve delete fingerprint UI.
- Make fingerprint preference use two_target preference - And add a delete button as secondary target - Remove delete fingerint code from RenameDeleteDialog, and move to new DeleteFingerprintDialog - Some code cleanup - Tests Change-Id: I49d9c7d1d03497f07c7e20a805f23e6da934f587 Fix: 37783186 Test: make RunSettingsRoboTests
This commit is contained in:
@@ -36,6 +36,7 @@ import android.os.CancellationSignal;
|
||||
import android.os.Handler;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.support.annotation.VisibleForTesting;
|
||||
import android.support.v7.preference.Preference;
|
||||
import android.support.v7.preference.Preference.OnPreferenceChangeListener;
|
||||
import android.support.v7.preference.Preference.OnPreferenceClickListener;
|
||||
@@ -48,7 +49,6 @@ import android.text.SpannableStringBuilder;
|
||||
import android.text.TextPaint;
|
||||
import android.text.TextUtils;
|
||||
import android.text.style.URLSpan;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
@@ -66,6 +66,7 @@ import com.android.settings.password.ChooseLockSettingsHelper;
|
||||
import com.android.settingslib.HelpUtils;
|
||||
import com.android.settingslib.RestrictedLockUtils;
|
||||
import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
|
||||
import com.android.settingslib.TwoTargetPreference;
|
||||
import com.android.settingslib.widget.FooterPreference;
|
||||
|
||||
import java.util.HashMap;
|
||||
@@ -127,7 +128,7 @@ public class FingerprintSettings extends SubSettings {
|
||||
}
|
||||
|
||||
public static class FingerprintSettingsFragment extends SettingsPreferenceFragment
|
||||
implements OnPreferenceChangeListener {
|
||||
implements OnPreferenceChangeListener, FingerprintPreference.OnDeleteClickListener {
|
||||
private static final int MAX_RETRY_ATTEMPTS = 20;
|
||||
private static final int RESET_HIGHLIGHT_DELAY_MS = 500;
|
||||
|
||||
@@ -173,7 +174,7 @@ public class FingerprintSettings extends SubSettings {
|
||||
@Override
|
||||
public void onAuthenticationFailed() {
|
||||
mHandler.obtainMessage(MSG_FINGER_AUTH_FAIL).sendToTarget();
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAuthenticationError(int errMsgId, CharSequence errString) {
|
||||
@@ -195,6 +196,7 @@ public class FingerprintSettings extends SubSettings {
|
||||
fingerprint.getFingerId(), 0).sendToTarget();
|
||||
updateDialog();
|
||||
}
|
||||
|
||||
public void onRemovalError(Fingerprint fp, int errMsgId, CharSequence errString) {
|
||||
final Activity activity = getActivity();
|
||||
if (activity != null) {
|
||||
@@ -202,11 +204,12 @@ public class FingerprintSettings extends SubSettings {
|
||||
}
|
||||
updateDialog();
|
||||
}
|
||||
|
||||
private void updateDialog() {
|
||||
RenameDeleteDialog renameDeleteDialog = (RenameDeleteDialog)getFragmentManager().
|
||||
findFragmentByTag(RenameDeleteDialog.class.getName());
|
||||
if (renameDeleteDialog != null) {
|
||||
renameDeleteDialog.enableDelete();
|
||||
RenameDialog renameDialog = (RenameDialog) getFragmentManager().
|
||||
findFragmentByTag(RenameDialog.class.getName());
|
||||
if (renameDialog != null) {
|
||||
renameDialog.enableDelete();
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -236,7 +239,7 @@ public class FingerprintSettings extends SubSettings {
|
||||
}
|
||||
break;
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
private void stopFingerprint() {
|
||||
@@ -310,10 +313,10 @@ public class FingerprintSettings extends SubSettings {
|
||||
mRemovalSidecar.setFingerprintManager(mFingerprintManager);
|
||||
mRemovalSidecar.setListener(mRemovalListener);
|
||||
|
||||
RenameDeleteDialog renameDeleteDialog = (RenameDeleteDialog)getFragmentManager().
|
||||
findFragmentByTag(RenameDeleteDialog.class.getName());
|
||||
if (renameDeleteDialog != null) {
|
||||
renameDeleteDialog.setDeleteInProgress(mRemovalSidecar.inProgress());
|
||||
RenameDialog renameDialog = (RenameDialog) getFragmentManager().
|
||||
findFragmentByTag(RenameDialog.class.getName());
|
||||
if (renameDialog != null) {
|
||||
renameDialog.setDeleteInProgress(mRemovalSidecar.inProgress());
|
||||
}
|
||||
|
||||
mFingerprintsRenaming = new HashMap<Integer, String>();
|
||||
@@ -380,7 +383,8 @@ public class FingerprintSettings extends SubSettings {
|
||||
final int fingerprintCount = items.size();
|
||||
for (int i = 0; i < fingerprintCount; i++) {
|
||||
final Fingerprint item = items.get(i);
|
||||
FingerprintPreference pref = new FingerprintPreference(root.getContext());
|
||||
FingerprintPreference pref = new FingerprintPreference(root.getContext(),
|
||||
this /* onDeleteClickListener */);
|
||||
pref.setKey(genKey(item.getFingerId()));
|
||||
pref.setTitle(item.getName());
|
||||
pref.setFingerprint(item);
|
||||
@@ -471,14 +475,40 @@ public class FingerprintSettings extends SubSettings {
|
||||
} else if (pref instanceof FingerprintPreference) {
|
||||
FingerprintPreference fpref = (FingerprintPreference) pref;
|
||||
final Fingerprint fp = fpref.getFingerprint();
|
||||
showRenameDeleteDialog(fp);
|
||||
return super.onPreferenceTreeClick(pref);
|
||||
showRenameDialog(fp);
|
||||
}
|
||||
return true;
|
||||
return super.onPreferenceTreeClick(pref);
|
||||
}
|
||||
|
||||
private void showRenameDeleteDialog(final Fingerprint fp) {
|
||||
RenameDeleteDialog renameDeleteDialog = new RenameDeleteDialog();
|
||||
@Override
|
||||
public void onDeleteClick(FingerprintPreference p) {
|
||||
final boolean hasMultipleFingerprint =
|
||||
mFingerprintManager.getEnrolledFingerprints(mUserId).size() > 1;
|
||||
final Fingerprint fp = p.getFingerprint();
|
||||
|
||||
if (hasMultipleFingerprint) {
|
||||
if (mRemovalSidecar.inProgress()) {
|
||||
Log.d(TAG, "Fingerprint delete in progress, skipping");
|
||||
return;
|
||||
}
|
||||
DeleteFingerprintDialog.newInstance(fp, this /* target */)
|
||||
.show(getFragmentManager(), DeleteFingerprintDialog.class.getName());
|
||||
} else {
|
||||
ConfirmLastDeleteDialog lastDeleteDialog = new ConfirmLastDeleteDialog();
|
||||
final boolean isProfileChallengeUser =
|
||||
UserManager.get(getContext()).isManagedProfile(mUserId);
|
||||
final Bundle args = new Bundle();
|
||||
args.putParcelable("fingerprint", fp);
|
||||
args.putBoolean("isProfileChallengeUser", isProfileChallengeUser);
|
||||
lastDeleteDialog.setArguments(args);
|
||||
lastDeleteDialog.setTargetFragment(this, 0);
|
||||
lastDeleteDialog.show(getFragmentManager(),
|
||||
ConfirmLastDeleteDialog.class.getName());
|
||||
}
|
||||
}
|
||||
|
||||
private void showRenameDialog(final Fingerprint fp) {
|
||||
RenameDialog renameDialog = new RenameDialog();
|
||||
Bundle args = new Bundle();
|
||||
if (mFingerprintsRenaming.containsKey(fp.getFingerId())) {
|
||||
final Fingerprint f = new Fingerprint(mFingerprintsRenaming.get(fp.getFingerId()),
|
||||
@@ -487,10 +517,10 @@ public class FingerprintSettings extends SubSettings {
|
||||
} else {
|
||||
args.putParcelable("fingerprint", fp);
|
||||
}
|
||||
renameDeleteDialog.setDeleteInProgress(mRemovalSidecar.inProgress());
|
||||
renameDeleteDialog.setArguments(args);
|
||||
renameDeleteDialog.setTargetFragment(this, 0);
|
||||
renameDeleteDialog.show(getFragmentManager(), RenameDeleteDialog.class.getName());
|
||||
renameDialog.setDeleteInProgress(mRemovalSidecar.inProgress());
|
||||
renameDialog.setArguments(args);
|
||||
renameDialog.setTargetFragment(this, 0);
|
||||
renameDialog.show(getFragmentManager(), RenameDialog.class.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -598,7 +628,8 @@ public class FingerprintSettings extends SubSettings {
|
||||
}
|
||||
}
|
||||
|
||||
private void deleteFingerPrint(Fingerprint fingerPrint) {
|
||||
@VisibleForTesting
|
||||
void deleteFingerPrint(Fingerprint fingerPrint) {
|
||||
mRemovalSidecar.startRemove(fingerPrint, mUserId);
|
||||
String name = genKey(fingerPrint.getFingerId());
|
||||
Preference prefToRemove = findPreference(name);
|
||||
@@ -622,7 +653,60 @@ public class FingerprintSettings extends SubSettings {
|
||||
}
|
||||
};
|
||||
|
||||
public static class RenameDeleteDialog extends InstrumentedDialogFragment {
|
||||
public static class DeleteFingerprintDialog extends InstrumentedDialogFragment
|
||||
implements DialogInterface.OnClickListener {
|
||||
|
||||
private static final String KEY_FINGERPRINT = "fingerprint";
|
||||
private Fingerprint mFp;
|
||||
private AlertDialog mAlertDialog;
|
||||
|
||||
public static DeleteFingerprintDialog newInstance(Fingerprint fp,
|
||||
FingerprintSettingsFragment target) {
|
||||
final DeleteFingerprintDialog dialog = new DeleteFingerprintDialog();
|
||||
final Bundle bundle = new Bundle();
|
||||
bundle.putParcelable(KEY_FINGERPRINT, fp);
|
||||
dialog.setArguments(bundle);
|
||||
dialog.setTargetFragment(target, 0 /* requestCode */);
|
||||
return dialog;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMetricsCategory() {
|
||||
return MetricsEvent.DIALOG_FINGERPINT_EDIT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
mFp = getArguments().getParcelable(KEY_FINGERPRINT);
|
||||
final String title = getString(R.string.fingerprint_delete_title, mFp.getName());
|
||||
|
||||
mAlertDialog = new AlertDialog.Builder(getActivity())
|
||||
.setTitle(title)
|
||||
.setMessage(R.string.fingerprint_delete_message)
|
||||
.setPositiveButton(
|
||||
R.string.security_settings_fingerprint_enroll_dialog_delete,
|
||||
this /* onClickListener */)
|
||||
.setNegativeButton(R.string.cancel, null /* onClickListener */)
|
||||
.create();
|
||||
return mAlertDialog;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
if (which == DialogInterface.BUTTON_POSITIVE) {
|
||||
final int fingerprintId = mFp.getFingerId();
|
||||
Log.v(TAG, "Removing fpId=" + fingerprintId);
|
||||
mMetricsFeatureProvider.action(getContext(),
|
||||
MetricsEvent.ACTION_FINGERPRINT_DELETE,
|
||||
fingerprintId);
|
||||
FingerprintSettingsFragment parent
|
||||
= (FingerprintSettingsFragment) getTargetFragment();
|
||||
parent.deleteFingerPrint(mFp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class RenameDialog extends InstrumentedDialogFragment {
|
||||
|
||||
private Fingerprint mFp;
|
||||
private EditText mDialogTextField;
|
||||
@@ -636,6 +720,7 @@ public class FingerprintSettings extends SubSettings {
|
||||
public void setDeleteInProgress(boolean deleteInProgress) {
|
||||
mDeleteInProgress = deleteInProgress;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
mFp = getArguments().getParcelable("fingerprint");
|
||||
@@ -654,10 +739,8 @@ public class FingerprintSettings extends SubSettings {
|
||||
final String newName =
|
||||
mDialogTextField.getText().toString();
|
||||
final CharSequence name = mFp.getName();
|
||||
if (!newName.equals(name)) {
|
||||
if (DEBUG) {
|
||||
Log.v(TAG, "rename " + name + " to " + newName);
|
||||
}
|
||||
if (!TextUtils.equals(newName, name)) {
|
||||
Log.d(TAG, "rename " + name + " to " + newName);
|
||||
mMetricsFeatureProvider.action(getContext(),
|
||||
MetricsEvent.ACTION_FINGERPRINT_RENAME,
|
||||
mFp.getFingerId());
|
||||
@@ -670,14 +753,6 @@ public class FingerprintSettings extends SubSettings {
|
||||
dialog.dismiss();
|
||||
}
|
||||
})
|
||||
.setNegativeButton(
|
||||
R.string.security_settings_fingerprint_enroll_dialog_delete,
|
||||
new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
onDeleteClick(dialog);
|
||||
}
|
||||
})
|
||||
.create();
|
||||
mAlertDialog.setOnShowListener(new DialogInterface.OnShowListener() {
|
||||
@Override
|
||||
@@ -711,29 +786,6 @@ public class FingerprintSettings extends SubSettings {
|
||||
}
|
||||
}
|
||||
|
||||
private void onDeleteClick(DialogInterface dialog) {
|
||||
if (DEBUG) Log.v(TAG, "Removing fpId=" + mFp.getFingerId());
|
||||
mMetricsFeatureProvider.action(getContext(), MetricsEvent.ACTION_FINGERPRINT_DELETE,
|
||||
mFp.getFingerId());
|
||||
FingerprintSettingsFragment parent
|
||||
= (FingerprintSettingsFragment) getTargetFragment();
|
||||
final boolean isProfileChallengeUser =
|
||||
UserManager.get(getContext()).isManagedProfile(parent.mUserId);
|
||||
if (parent.mFingerprintManager.getEnrolledFingerprints(parent.mUserId).size() > 1) {
|
||||
parent.deleteFingerPrint(mFp);
|
||||
} else {
|
||||
ConfirmLastDeleteDialog lastDeleteDialog = new ConfirmLastDeleteDialog();
|
||||
Bundle args = new Bundle();
|
||||
args.putParcelable("fingerprint", mFp);
|
||||
args.putBoolean("isProfileChallengeUser", isProfileChallengeUser);
|
||||
lastDeleteDialog.setArguments(args);
|
||||
lastDeleteDialog.setTargetFragment(getTargetFragment(), 0);
|
||||
lastDeleteDialog.show(getFragmentManager(),
|
||||
ConfirmLastDeleteDialog.class.getName());
|
||||
}
|
||||
dialog.dismiss();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
@@ -794,27 +846,26 @@ public class FingerprintSettings extends SubSettings {
|
||||
}
|
||||
}
|
||||
|
||||
public static class FingerprintPreference extends Preference {
|
||||
public static class FingerprintPreference extends TwoTargetPreference {
|
||||
|
||||
private final OnDeleteClickListener mOnDeleteClickListener;
|
||||
|
||||
private Fingerprint mFingerprint;
|
||||
private View mView;
|
||||
private View mDeleteView;
|
||||
|
||||
public FingerprintPreference(Context context, AttributeSet attrs, int defStyleAttr,
|
||||
int defStyleRes) {
|
||||
super(context, attrs, defStyleAttr, defStyleRes);
|
||||
}
|
||||
public FingerprintPreference(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
public interface OnDeleteClickListener {
|
||||
void onDeleteClick(FingerprintPreference p);
|
||||
}
|
||||
|
||||
public FingerprintPreference(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public FingerprintPreference(Context context) {
|
||||
public FingerprintPreference(Context context, OnDeleteClickListener onDeleteClickListener) {
|
||||
super(context);
|
||||
mOnDeleteClickListener = onDeleteClickListener;
|
||||
}
|
||||
|
||||
public View getView() { return mView; }
|
||||
public View getView() {
|
||||
return mView;
|
||||
}
|
||||
|
||||
public void setFingerprint(Fingerprint item) {
|
||||
mFingerprint = item;
|
||||
@@ -824,12 +875,26 @@ public class FingerprintSettings extends SubSettings {
|
||||
return mFingerprint;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getSecondTargetResId() {
|
||||
return R.layout.preference_widget_delete;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(PreferenceViewHolder view) {
|
||||
super.onBindViewHolder(view);
|
||||
mView = view.itemView;
|
||||
mDeleteView = view.itemView.findViewById(R.id.delete_button);
|
||||
mDeleteView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (mOnDeleteClickListener != null) {
|
||||
mOnDeleteClickListener.onDeleteClick(FingerprintPreference.this);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static class LearnMoreSpan extends URLSpan {
|
||||
|
||||
|
Reference in New Issue
Block a user