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

Commit 4584d88d authored by Curtis Belmonte's avatar Curtis Belmonte
Browse files

Add internal API for credential text in BiometricPrompt

Adds a hidden API behind an internal permission check that allows the
Settings app to use specific text to BiometricPrompt for credential
auth. This allows the work authentication prompt to use work-specific
language when verifying work credentials, while retaining more generic
language when authenticating with biometrics.

Test: Work lock prompt shows "Enter your work ___" for credential
Test: Work lock prompt now shows "Verify it's you" for face

Bug: 149003660
Change-Id: Idf06f7e008f4bdb448b0d539522efd2e9290a3bb
parent 5cf71d71
Loading
Loading
Loading
Loading
+36 −0
Original line number Original line Diff line number Diff line
@@ -72,6 +72,18 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan
     * @hide
     * @hide
     */
     */
    public static final String KEY_DESCRIPTION = "description";
    public static final String KEY_DESCRIPTION = "description";
    /**
     * @hide
     */
    public static final String KEY_DEVICE_CREDENTIAL_TITLE = "device_credential_title";
    /**
     * @hide
     */
    public static final String KEY_DEVICE_CREDENTIAL_SUBTITLE = "device_credential_subtitle";
    /**
     * @hide
     */
    public static final String KEY_DEVICE_CREDENTIAL_DESCRIPTION = "device_credential_description";
    /**
    /**
     * @hide
     * @hide
     */
     */
@@ -220,6 +232,30 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan
            return this;
            return this;
        }
        }


        /**
         * Sets an optional title, subtitle, and/or description that will override other text when
         * the user is authenticating with PIN/pattern/password. Currently for internal use only.
         * @return This builder.
         * @hide
         */
        @RequiresPermission(USE_BIOMETRIC_INTERNAL)
        @NonNull
        public Builder setTextForDeviceCredential(
                @Nullable CharSequence title,
                @Nullable CharSequence subtitle,
                @Nullable CharSequence description) {
            if (title != null) {
                mBundle.putCharSequence(KEY_DEVICE_CREDENTIAL_TITLE, title);
            }
            if (subtitle != null) {
                mBundle.putCharSequence(KEY_DEVICE_CREDENTIAL_SUBTITLE, subtitle);
            }
            if (description != null) {
                mBundle.putCharSequence(KEY_DEVICE_CREDENTIAL_DESCRIPTION, description);
            }
            return this;
        }

        /**
        /**
         * Required: Sets the text, executor, and click listener for the negative button on the
         * Required: Sets the text, executor, and click listener for the negative button on the
         * prompt. This is typically a cancel button, but may be also used to show an alternative
         * prompt. This is typically a cancel button, but may be also used to show an alternative
+35 −10
Original line number Original line Diff line number Diff line
@@ -16,6 +16,7 @@


package com.android.systemui.biometrics;
package com.android.systemui.biometrics;


import android.annotation.NonNull;
import android.content.Context;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Drawable;
import android.hardware.biometrics.BiometricPrompt;
import android.hardware.biometrics.BiometricPrompt;
@@ -33,6 +34,8 @@ import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.TextView;


import androidx.annotation.Nullable;

import com.android.internal.widget.LockPatternUtils;
import com.android.internal.widget.LockPatternUtils;
import com.android.systemui.Interpolators;
import com.android.systemui.Interpolators;
import com.android.systemui.R;
import com.android.systemui.R;
@@ -126,18 +129,18 @@ public abstract class AuthCredentialView extends LinearLayout {
        mHandler.postDelayed(mClearErrorRunnable, ERROR_DURATION_MS);
        mHandler.postDelayed(mClearErrorRunnable, ERROR_DURATION_MS);
    }
    }


    private void setTextOrHide(TextView view, String string) {
    private void setTextOrHide(TextView view, CharSequence text) {
        if (TextUtils.isEmpty(string)) {
        if (TextUtils.isEmpty(text)) {
            view.setVisibility(View.GONE);
            view.setVisibility(View.GONE);
        } else {
        } else {
            view.setText(string);
            view.setText(text);
        }
        }


        Utils.notifyAccessibilityContentChanged(mAccessibilityManager, this);
        Utils.notifyAccessibilityContentChanged(mAccessibilityManager, this);
    }
    }


    private void setText(TextView view, String string) {
    private void setText(TextView view, CharSequence text) {
        view.setText(string);
        view.setText(text);
    }
    }


    void setEffectiveUserId(int effectiveUserId) {
    void setEffectiveUserId(int effectiveUserId) {
@@ -173,11 +176,9 @@ public abstract class AuthCredentialView extends LinearLayout {
    protected void onAttachedToWindow() {
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        super.onAttachedToWindow();


        setText(mTitleView, mBiometricPromptBundle.getString(BiometricPrompt.KEY_TITLE));
        setText(mTitleView, getTitle(mBiometricPromptBundle));
        setTextOrHide(mSubtitleView,
        setTextOrHide(mSubtitleView, getSubtitle(mBiometricPromptBundle));
                mBiometricPromptBundle.getString(BiometricPrompt.KEY_SUBTITLE));
        setTextOrHide(mDescriptionView, getDescription(mBiometricPromptBundle));
        setTextOrHide(mDescriptionView,
                mBiometricPromptBundle.getString(BiometricPrompt.KEY_DESCRIPTION));


        final boolean isManagedProfile = Utils.isManagedProfile(mContext, mEffectiveUserId);
        final boolean isManagedProfile = Utils.isManagedProfile(mContext, mEffectiveUserId);
        final Drawable image;
        final Drawable image;
@@ -279,4 +280,28 @@ public abstract class AuthCredentialView extends LinearLayout {
            }
            }
        }
        }
    }
    }

    @Nullable
    private static CharSequence getTitle(@NonNull Bundle bundle) {
        final CharSequence credentialTitle =
                bundle.getCharSequence(BiometricPrompt.KEY_DEVICE_CREDENTIAL_TITLE);
        return credentialTitle != null ? credentialTitle
                : bundle.getCharSequence(BiometricPrompt.KEY_TITLE);
    }

    @Nullable
    private static CharSequence getSubtitle(@NonNull Bundle bundle) {
        final CharSequence credentialSubtitle =
                bundle.getCharSequence(BiometricPrompt.KEY_DEVICE_CREDENTIAL_SUBTITLE);
        return credentialSubtitle != null ? credentialSubtitle
                : bundle.getCharSequence(BiometricPrompt.KEY_SUBTITLE);
    }

    @Nullable
    private static CharSequence getDescription(@NonNull Bundle bundle) {
        final CharSequence credentialDescription =
                bundle.getCharSequence(BiometricPrompt.KEY_DEVICE_CREDENTIAL_DESCRIPTION);
        return credentialDescription != null ? credentialDescription
                : bundle.getCharSequence(BiometricPrompt.KEY_DESCRIPTION);
    }
}
}
+6 −1
Original line number Original line Diff line number Diff line
@@ -153,7 +153,12 @@ public class AuthService extends SystemService {


            // Only allow internal clients to enable non-public options.
            // Only allow internal clients to enable non-public options.
            if (bundle.getBoolean(BiometricPrompt.EXTRA_DISALLOW_BIOMETRICS_IF_POLICY_EXISTS)
            if (bundle.getBoolean(BiometricPrompt.EXTRA_DISALLOW_BIOMETRICS_IF_POLICY_EXISTS)
                    || bundle.getBoolean(BiometricPrompt.KEY_USE_DEFAULT_TITLE, false)) {
                    || bundle.getBoolean(BiometricPrompt.KEY_USE_DEFAULT_TITLE, false)
                    || bundle.getCharSequence(BiometricPrompt.KEY_DEVICE_CREDENTIAL_TITLE) != null
                    || bundle.getCharSequence(
                            BiometricPrompt.KEY_DEVICE_CREDENTIAL_SUBTITLE) != null
                    || bundle.getCharSequence(
                            BiometricPrompt.KEY_DEVICE_CREDENTIAL_DESCRIPTION) != null) {
                checkInternalPermission();
                checkInternalPermission();
            }
            }