Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit eeca918a authored by Kevin Chyn's avatar Kevin Chyn
Browse files

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
parent 44427259
Loading
Loading
Loading
Loading
+21 −3
Original line number Diff line number Diff line
@@ -16,19 +16,21 @@

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;
@@ -40,6 +42,8 @@ import java.util.concurrent.Executor;
 */
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;
@@ -48,7 +52,6 @@ public class BiometricFragment extends InstrumentedFragment {
    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;
@@ -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()}
     * @return
@@ -123,6 +140,7 @@ public class BiometricFragment extends InstrumentedFragment {
        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(
@@ -135,7 +153,7 @@ public class BiometricFragment extends InstrumentedFragment {

        // TODO: CC doesn't use crypto for now
        mBiometricPrompt.authenticateUser(mCancellationSignal, mClientExecutor,
                mAuthenticationCallback, mUserId);
                mAuthenticationCallback, mUserId, mCancelCallback);
    }

    @Override
+14 −6
Original line number Diff line number Diff line
@@ -106,13 +106,11 @@ public class ConfirmDeviceCredentialActivity extends FragmentActivity {
    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 {
@@ -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
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
@@ -178,7 +187,6 @@ public class ConfirmDeviceCredentialActivity extends FragmentActivity {
                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 {
+11 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.settings.password;
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;
@@ -51,6 +52,15 @@ public abstract class ConfirmDeviceCredentialBaseActivity extends SettingsActivi
    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);
@@ -81,6 +91,7 @@ public abstract class ConfirmDeviceCredentialBaseActivity extends SettingsActivi
        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