package com.android.settings.password;
+import android.app.Activity;
import android.app.settings.SettingsEnums;
import android.content.DialogInterface;
import android.hardware.biometrics.BiometricConstants;
import android.hardware.biometrics.BiometricPrompt;
import android.hardware.biometrics.BiometricPrompt.AuthenticationCallback;
import android.hardware.biometrics.BiometricPrompt.AuthenticationResult;
+import android.hardware.biometrics.IBiometricConfirmDeviceCredentialCallback;
import android.os.Bundle;
import android.os.CancellationSignal;
import android.os.Handler;
import android.os.Looper;
+import android.util.Log;
import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
import com.android.settings.R;
import com.android.settings.core.InstrumentedFragment;
*/
public class BiometricFragment extends InstrumentedFragment {
+ private static final String TAG = "ConfirmDeviceCredential/BiometricFragment";
+
// Re-set by the application. Should be done upon orientation changes, etc
private Executor mClientExecutor;
private AuthenticationCallback mClientCallback;
private int mUserId;
// Created/Initialized once and retained
- private final Handler mHandler = new Handler(Looper.getMainLooper());
private Bundle mBundle;
private BiometricPrompt mBiometricPrompt;
private CancellationSignal mCancellationSignal;
}
};
+ // TODO(b/123378871): Remove when moved.
+ private final IBiometricConfirmDeviceCredentialCallback mCancelCallback
+ = new IBiometricConfirmDeviceCredentialCallback.Stub() {
+ @Override
+ public void cancel() {
+ final Activity activity = getActivity();
+ if (activity != null) {
+ activity.finish();
+ } else {
+ Log.e(TAG, "Activity null!");
+ }
+ }
+ };
+
/**
* @param bundle Bundle passed from {@link BiometricPrompt.Builder#buildIntent()}
* @return
mBiometricPrompt = new BiometricPrompt.Builder(getContext())
.setTitle(mBundle.getString(BiometricPrompt.KEY_TITLE))
.setUseDefaultTitle() // use default title if title is null/empty
+ .setFromConfirmDeviceCredential()
.setSubtitle(mBundle.getString(BiometricPrompt.KEY_SUBTITLE))
.setDescription(mBundle.getString(BiometricPrompt.KEY_DESCRIPTION))
.setConfirmationRequired(
// TODO: CC doesn't use crypto for now
mBiometricPrompt.authenticateUser(mCancellationSignal, mClientExecutor,
- mAuthenticationCallback, mUserId);
+ mAuthenticationCallback, mUserId, mCancelCallback);
}
@Override
private AuthenticationCallback mAuthenticationCallback = new AuthenticationCallback() {
public void onAuthenticationError(int errorCode, @NonNull CharSequence errString) {
if (!mGoingToBackground) {
- if (errorCode == BiometricPrompt.BIOMETRIC_ERROR_USER_CANCELED) {
+ if (errorCode == BiometricPrompt.BIOMETRIC_ERROR_USER_CANCELED
+ || errorCode == BiometricPrompt.BIOMETRIC_ERROR_CANCELED) {
if (mIsFallback) {
mBiometricManager.onConfirmDeviceCredentialError(
- BiometricConstants.BIOMETRIC_ERROR_USER_CANCELED,
- getString(
- com.android.internal.R.string
- .biometric_error_user_canceled));
+ errorCode, getStringForError(errorCode));
}
finish();
} else {
}
};
+ private String getStringForError(int errorCode) {
+ switch (errorCode) {
+ case BiometricConstants.BIOMETRIC_ERROR_USER_CANCELED:
+ return getString(com.android.internal.R.string.biometric_error_user_canceled);
+ case BiometricConstants.BIOMETRIC_ERROR_CANCELED:
+ return getString(com.android.internal.R.string.biometric_error_canceled);
+ default:
+ return null;
+ }
+ }
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
intent.getBundleExtra(KeyguardManager.EXTRA_BIOMETRIC_PROMPT_BUNDLE);
if (bpBundle != null) {
mIsFallback = true;
- // TODO: CDC maybe should show description as well.
mTitle = bpBundle.getString(BiometricPrompt.KEY_TITLE);
mDetails = bpBundle.getString(BiometricPrompt.KEY_SUBTITLE);
} else {
import android.app.KeyguardManager;
import android.hardware.biometrics.BiometricConstants;
import android.hardware.biometrics.BiometricManager;
+import android.hardware.biometrics.IBiometricConfirmDeviceCredentialCallback;
import android.os.Bundle;
import android.os.UserManager;
import android.util.Log;
private ConfirmCredentialTheme mConfirmCredentialTheme;
private BiometricManager mBiometricManager;
+ // TODO(b/123378871): Remove when moved.
+ private final IBiometricConfirmDeviceCredentialCallback mCancelCallback
+ = new IBiometricConfirmDeviceCredentialCallback.Stub() {
+ @Override
+ public void cancel() {
+ finish();
+ }
+ };
+
private boolean isInternalActivity() {
return (this instanceof ConfirmLockPassword.InternalActivity)
|| (this instanceof ConfirmLockPattern.InternalActivity);
super.onCreate(savedState);
mBiometricManager = getSystemService(BiometricManager.class);
+ mBiometricManager.registerCancellationCallback(mCancelCallback);
if (mConfirmCredentialTheme == ConfirmCredentialTheme.NORMAL) {
// Prevent the content parent from consuming the window insets because GlifLayout uses