ConfirmDeviceCredential should respond to cancel when launched through BP
Fixes: 128747871 Test: BiometricPrompt launched by ConfirmDeviceCredential is canceled Test: ConfirmLock* can also now be canceled Test: No effect on non-biometric related paths Change-Id: I237de136e63d523fece87fad7a93f4ecd66d800b
This commit is contained in:
@@ -16,19 +16,21 @@
|
|||||||
|
|
||||||
package com.android.settings.password;
|
package com.android.settings.password;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
import android.app.settings.SettingsEnums;
|
import android.app.settings.SettingsEnums;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.hardware.biometrics.BiometricConstants;
|
import android.hardware.biometrics.BiometricConstants;
|
||||||
import android.hardware.biometrics.BiometricPrompt;
|
import android.hardware.biometrics.BiometricPrompt;
|
||||||
import android.hardware.biometrics.BiometricPrompt.AuthenticationCallback;
|
import android.hardware.biometrics.BiometricPrompt.AuthenticationCallback;
|
||||||
import android.hardware.biometrics.BiometricPrompt.AuthenticationResult;
|
import android.hardware.biometrics.BiometricPrompt.AuthenticationResult;
|
||||||
|
import android.hardware.biometrics.IBiometricConfirmDeviceCredentialCallback;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.CancellationSignal;
|
import android.os.CancellationSignal;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
|
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
import com.android.settings.core.InstrumentedFragment;
|
import com.android.settings.core.InstrumentedFragment;
|
||||||
@@ -40,6 +42,8 @@ import java.util.concurrent.Executor;
|
|||||||
*/
|
*/
|
||||||
public class BiometricFragment extends 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
|
// Re-set by the application. Should be done upon orientation changes, etc
|
||||||
private Executor mClientExecutor;
|
private Executor mClientExecutor;
|
||||||
private AuthenticationCallback mClientCallback;
|
private AuthenticationCallback mClientCallback;
|
||||||
@@ -48,7 +52,6 @@ public class BiometricFragment extends InstrumentedFragment {
|
|||||||
private int mUserId;
|
private int mUserId;
|
||||||
|
|
||||||
// Created/Initialized once and retained
|
// Created/Initialized once and retained
|
||||||
private final Handler mHandler = new Handler(Looper.getMainLooper());
|
|
||||||
private Bundle mBundle;
|
private Bundle mBundle;
|
||||||
private BiometricPrompt mBiometricPrompt;
|
private BiometricPrompt mBiometricPrompt;
|
||||||
private CancellationSignal mCancellationSignal;
|
private CancellationSignal mCancellationSignal;
|
||||||
@@ -82,6 +85,20 @@ public class BiometricFragment extends InstrumentedFragment {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 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()}
|
* @param bundle Bundle passed from {@link BiometricPrompt.Builder#buildIntent()}
|
||||||
* @return
|
* @return
|
||||||
@@ -123,6 +140,7 @@ public class BiometricFragment extends InstrumentedFragment {
|
|||||||
mBiometricPrompt = new BiometricPrompt.Builder(getContext())
|
mBiometricPrompt = new BiometricPrompt.Builder(getContext())
|
||||||
.setTitle(mBundle.getString(BiometricPrompt.KEY_TITLE))
|
.setTitle(mBundle.getString(BiometricPrompt.KEY_TITLE))
|
||||||
.setUseDefaultTitle() // use default title if title is null/empty
|
.setUseDefaultTitle() // use default title if title is null/empty
|
||||||
|
.setFromConfirmDeviceCredential()
|
||||||
.setSubtitle(mBundle.getString(BiometricPrompt.KEY_SUBTITLE))
|
.setSubtitle(mBundle.getString(BiometricPrompt.KEY_SUBTITLE))
|
||||||
.setDescription(mBundle.getString(BiometricPrompt.KEY_DESCRIPTION))
|
.setDescription(mBundle.getString(BiometricPrompt.KEY_DESCRIPTION))
|
||||||
.setConfirmationRequired(
|
.setConfirmationRequired(
|
||||||
@@ -135,7 +153,7 @@ public class BiometricFragment extends InstrumentedFragment {
|
|||||||
|
|
||||||
// TODO: CC doesn't use crypto for now
|
// TODO: CC doesn't use crypto for now
|
||||||
mBiometricPrompt.authenticateUser(mCancellationSignal, mClientExecutor,
|
mBiometricPrompt.authenticateUser(mCancellationSignal, mClientExecutor,
|
||||||
mAuthenticationCallback, mUserId);
|
mAuthenticationCallback, mUserId, mCancelCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@@ -106,13 +106,11 @@ public class ConfirmDeviceCredentialActivity extends FragmentActivity {
|
|||||||
private AuthenticationCallback mAuthenticationCallback = new AuthenticationCallback() {
|
private AuthenticationCallback mAuthenticationCallback = new AuthenticationCallback() {
|
||||||
public void onAuthenticationError(int errorCode, @NonNull CharSequence errString) {
|
public void onAuthenticationError(int errorCode, @NonNull CharSequence errString) {
|
||||||
if (!mGoingToBackground) {
|
if (!mGoingToBackground) {
|
||||||
if (errorCode == BiometricPrompt.BIOMETRIC_ERROR_USER_CANCELED) {
|
if (errorCode == BiometricPrompt.BIOMETRIC_ERROR_USER_CANCELED
|
||||||
|
|| errorCode == BiometricPrompt.BIOMETRIC_ERROR_CANCELED) {
|
||||||
if (mIsFallback) {
|
if (mIsFallback) {
|
||||||
mBiometricManager.onConfirmDeviceCredentialError(
|
mBiometricManager.onConfirmDeviceCredentialError(
|
||||||
BiometricConstants.BIOMETRIC_ERROR_USER_CANCELED,
|
errorCode, getStringForError(errorCode));
|
||||||
getString(
|
|
||||||
com.android.internal.R.string
|
|
||||||
.biometric_error_user_canceled));
|
|
||||||
}
|
}
|
||||||
finish();
|
finish();
|
||||||
} else {
|
} else {
|
||||||
@@ -139,6 +137,17 @@ public class ConfirmDeviceCredentialActivity extends FragmentActivity {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
@@ -178,7 +187,6 @@ public class ConfirmDeviceCredentialActivity extends FragmentActivity {
|
|||||||
intent.getBundleExtra(KeyguardManager.EXTRA_BIOMETRIC_PROMPT_BUNDLE);
|
intent.getBundleExtra(KeyguardManager.EXTRA_BIOMETRIC_PROMPT_BUNDLE);
|
||||||
if (bpBundle != null) {
|
if (bpBundle != null) {
|
||||||
mIsFallback = true;
|
mIsFallback = true;
|
||||||
// TODO: CDC maybe should show description as well.
|
|
||||||
mTitle = bpBundle.getString(BiometricPrompt.KEY_TITLE);
|
mTitle = bpBundle.getString(BiometricPrompt.KEY_TITLE);
|
||||||
mDetails = bpBundle.getString(BiometricPrompt.KEY_SUBTITLE);
|
mDetails = bpBundle.getString(BiometricPrompt.KEY_SUBTITLE);
|
||||||
} else {
|
} else {
|
||||||
|
@@ -19,6 +19,7 @@ package com.android.settings.password;
|
|||||||
import android.app.KeyguardManager;
|
import android.app.KeyguardManager;
|
||||||
import android.hardware.biometrics.BiometricConstants;
|
import android.hardware.biometrics.BiometricConstants;
|
||||||
import android.hardware.biometrics.BiometricManager;
|
import android.hardware.biometrics.BiometricManager;
|
||||||
|
import android.hardware.biometrics.IBiometricConfirmDeviceCredentialCallback;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.UserManager;
|
import android.os.UserManager;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
@@ -51,6 +52,15 @@ public abstract class ConfirmDeviceCredentialBaseActivity extends SettingsActivi
|
|||||||
private ConfirmCredentialTheme mConfirmCredentialTheme;
|
private ConfirmCredentialTheme mConfirmCredentialTheme;
|
||||||
private BiometricManager mBiometricManager;
|
private BiometricManager mBiometricManager;
|
||||||
|
|
||||||
|
// TODO(b/123378871): Remove when moved.
|
||||||
|
private final IBiometricConfirmDeviceCredentialCallback mCancelCallback
|
||||||
|
= new IBiometricConfirmDeviceCredentialCallback.Stub() {
|
||||||
|
@Override
|
||||||
|
public void cancel() {
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
private boolean isInternalActivity() {
|
private boolean isInternalActivity() {
|
||||||
return (this instanceof ConfirmLockPassword.InternalActivity)
|
return (this instanceof ConfirmLockPassword.InternalActivity)
|
||||||
|| (this instanceof ConfirmLockPattern.InternalActivity);
|
|| (this instanceof ConfirmLockPattern.InternalActivity);
|
||||||
@@ -81,6 +91,7 @@ public abstract class ConfirmDeviceCredentialBaseActivity extends SettingsActivi
|
|||||||
super.onCreate(savedState);
|
super.onCreate(savedState);
|
||||||
|
|
||||||
mBiometricManager = getSystemService(BiometricManager.class);
|
mBiometricManager = getSystemService(BiometricManager.class);
|
||||||
|
mBiometricManager.registerCancellationCallback(mCancelCallback);
|
||||||
|
|
||||||
if (mConfirmCredentialTheme == ConfirmCredentialTheme.NORMAL) {
|
if (mConfirmCredentialTheme == ConfirmCredentialTheme.NORMAL) {
|
||||||
// Prevent the content parent from consuming the window insets because GlifLayout uses
|
// Prevent the content parent from consuming the window insets because GlifLayout uses
|
||||||
|
Reference in New Issue
Block a user