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

Commit 0cf243ea authored by Joshua Mccloskey's avatar Joshua Mccloskey Committed by Android (Google) Code Review
Browse files

Merge "Add builder method to check DevicePolicyManager"

parents 73b4b64b 15c0a441
Loading
Loading
Loading
Loading
+32 −0
Original line number Diff line number Diff line
@@ -117,6 +117,16 @@ public class KeyguardManager {
     */
    public static final int RESULT_ALTERNATE = 1;

    /**
     *
     * If this is set, check device policy for allowed biometrics when the user is authenticating.
     * This should only be used in the context of managed profiles.
     *
     * @hide
     */
    public static final String EXTRA_DISALLOW_BIOMETRICS_IF_POLICY_EXISTS = "check_dpm";


    /**
     * Get an intent to prompt the user to confirm credentials (pin, pattern, password or biometrics
     * if enrolled) for the current user of the device. The caller is expected to launch this
@@ -164,6 +174,28 @@ public class KeyguardManager {
        return intent;
    }

    /**
     * Get an intent to prompt the user to confirm credentials (pin, pattern or password)
     * for the given user. The caller is expected to launch this activity using
     * {@link android.app.Activity#startActivityForResult(Intent, int)} and check for
     * {@link android.app.Activity#RESULT_OK} if the user successfully completes the challenge.
     *
     * @param disallowBiometricsIfPolicyExists If true check if the Device Policy Manager has
     * disabled biometrics on the device. If biometrics are disabled, fall back to PIN/pattern/pass.
     *
     * @return the intent for launching the activity or null if no password is required.
     *
     * @hide
     */
    public Intent createConfirmDeviceCredentialIntent(
            CharSequence title, CharSequence description, int userId,
            boolean disallowBiometricsIfPolicyExists) {
        Intent intent = this.createConfirmDeviceCredentialIntent(title, description, userId);
        intent.putExtra(EXTRA_DISALLOW_BIOMETRICS_IF_POLICY_EXISTS,
                disallowBiometricsIfPolicyExists);
        return intent;
    }

    /**
     * Get an intent to prompt the user to confirm credentials (pin, pattern or password)
     * for the previous owner of the device. The caller is expected to launch this activity using
+19 −0
Original line number Diff line number Diff line
@@ -87,6 +87,11 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan
     * @hide
     */
    public static final String KEY_AUTHENTICATORS_ALLOWED = "authenticators_allowed";
    /**
     * If this is set, check the Device Policy Manager for allowed biometrics.
     * @hide
     */
    public static final String EXTRA_DISALLOW_BIOMETRICS_IF_POLICY_EXISTS = "check_dpm";

    /**
     * Error/help message will show for this amount of time.
@@ -325,6 +330,20 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan
            return this;
        }

        /**
         * If set check the Device Policy Manager for disabled biometrics.
         *
         * @param checkDevicePolicyManager
         * @return This builder.
         * @hide
         */
        @NonNull
        public Builder setDisallowBiometricsIfPolicyExists(boolean checkDevicePolicyManager) {
            mBundle.putBoolean(EXTRA_DISALLOW_BIOMETRICS_IF_POLICY_EXISTS,
                    checkDevicePolicyManager);
            return this;
        }

        /**
         * Creates a {@link BiometricPrompt}.
         *
+2 −8
Original line number Diff line number Diff line
@@ -51,12 +51,6 @@ import javax.inject.Inject;
public class WorkLockActivity extends Activity {
    private static final String TAG = "WorkLockActivity";

    /**
     * Add additional extra {@link com.android.settings.password.ConfirmDeviceCredentialActivity} to
     * enable device policy management enforcement from systemui.
     */
    public static final String EXTRA_FROM_WORK_LOCK_ACTIVITY = "from_work_lock_activity";

    /**
     * Contains a {@link TaskDescription} for the activity being covered.
     */
@@ -156,7 +150,8 @@ public class WorkLockActivity extends Activity {
        }

        final Intent credential = getKeyguardManager()
                .createConfirmDeviceCredentialIntent(null, null, getTargetUserId());
                .createConfirmDeviceCredentialIntent(null, null, getTargetUserId(),
                true /* disallowBiometricsIfPolicyExists */);
        if (credential == null) {
            return;
        }
@@ -172,7 +167,6 @@ public class WorkLockActivity extends Activity {

        if (target != null) {
            credential.putExtra(Intent.EXTRA_INTENT, target.getIntentSender());
            credential.putExtra(EXTRA_FROM_WORK_LOCK_ACTIVITY, true);
        }

        final ActivityOptions launchOptions = ActivityOptions.makeBasic();
+56 −4
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import static android.hardware.biometrics.BiometricManager.Authenticators;
import android.app.ActivityManager;
import android.app.IActivityManager;
import android.app.UserSwitchObserver;
import android.app.admin.DevicePolicyManager;
import android.app.trust.ITrustManager;
import android.content.ContentResolver;
import android.content.Context;
@@ -210,6 +211,7 @@ public class BiometricService extends SystemService {
    }

    private final Injector mInjector;
    private final DevicePolicyManager mDevicePolicyManager;
    @VisibleForTesting
    final IBiometricService.Stub mImpl;
    @VisibleForTesting
@@ -648,6 +650,10 @@ public class BiometricService extends SystemService {
                throw new SecurityException("Invalid authenticator configuration");
            }

            if (bundle.getBoolean(BiometricPrompt.EXTRA_DISALLOW_BIOMETRICS_IF_POLICY_EXISTS)) {
                checkInternalPermission();
            }

            Utils.combineAuthenticatorBundles(bundle);

            // Check the usage of this in system server. Need to remove this check if it becomes a
@@ -712,8 +718,8 @@ public class BiometricService extends SystemService {
            int biometricConstantsResult = BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE;
            final long ident = Binder.clearCallingIdentity();
            try {
                biometricConstantsResult =
                        checkAndGetAuthenticators(userId, bundle, opPackageName).second;
                biometricConstantsResult = checkAndGetAuthenticators(userId, bundle, opPackageName,
                        false /* checkDevicePolicyManager */).second;
                if (biometricConstantsResult != BiometricConstants.BIOMETRIC_SUCCESS
                        && Utils.isDeviceCredentialAllowed(bundle)) {
                    // If there's an issue with biometrics, but device credential is allowed and
@@ -947,6 +953,8 @@ public class BiometricService extends SystemService {
        super(context);

        mInjector = injector;
        mDevicePolicyManager = (DevicePolicyManager) context
                .getSystemService(context.DEVICE_POLICY_SERVICE);
        mImpl = new BiometricServiceWrapper();
        mEnabledOnKeyguardCallbacks = new ArrayList<>();
        mSettingObserver = mInjector.getSettingObserver(context, mHandler,
@@ -977,6 +985,42 @@ public class BiometricService extends SystemService {
        mBiometricStrengthController.startListening();
    }

    /**
     * @param modality one of {@link BiometricAuthenticator#TYPE_FINGERPRINT},
     * {@link BiometricAuthenticator#TYPE_IRIS} or {@link BiometricAuthenticator#TYPE_FACE}
     * @return
     */
    private int mapModalityToDevicePolicyType(int modality) {
        switch (modality) {
            case TYPE_FINGERPRINT:
                return DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT;
            case TYPE_IRIS:
                return DevicePolicyManager.KEYGUARD_DISABLE_IRIS;
            case TYPE_FACE:
                return DevicePolicyManager.KEYGUARD_DISABLE_FACE;
            default:
                Slog.e(TAG, "Error modality=" + modality);
                return DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_NONE;
        }
    }

    // TODO(joshmccloskey): Update this to throw an error if a new modality is added and this
    // logic is not updated.
    private boolean isBiometricDisabledByDevicePolicy(int modality, int effectiveUserId) {
        final int biometricToCheck = mapModalityToDevicePolicyType(modality);
        if (biometricToCheck == DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_NONE) {
            Slog.e(TAG, "Allowing unknown modality " + modality + " to pass Device Policy check");
            return false;
        }
        final int devicePolicyDisabledFeatures =
                mDevicePolicyManager.getKeyguardDisabledFeatures(null, effectiveUserId);
        final boolean isBiometricDisabled =
                (biometricToCheck & devicePolicyDisabledFeatures) != 0;
        Slog.w(TAG, "isBiometricDisabledByDevicePolicy(" + modality + "," + effectiveUserId
                + ")=" + isBiometricDisabled);
        return isBiometricDisabled;
    }

    /**
     * Checks if there are any available biometrics, and returns the modality. This method also
     * returns errors through the callback (no biometric feature, hardware not detected, no
@@ -996,7 +1040,7 @@ public class BiometricService extends SystemService {
     * TODO(kchyn): Update this to handle DEVICE_CREDENTIAL better, reduce duplicate code in callers
     */
    private Pair<Integer, Integer> checkAndGetAuthenticators(int userId, Bundle bundle,
            String opPackageName) throws RemoteException {
            String opPackageName, boolean checkDevicePolicyManager) throws RemoteException {
        if (!Utils.isBiometricAllowed(bundle)
                && Utils.isDeviceCredentialAllowed(bundle)
                && !mTrustManager.isDeviceSecure(userId)) {
@@ -1033,6 +1077,11 @@ public class BiometricService extends SystemService {
                    }
                    if (authenticator.impl.hasEnrolledTemplates(userId, opPackageName)) {
                        hasTemplatesEnrolled = true;
                        // If the device policy manager disables a specific biometric, skip it.
                        if (checkDevicePolicyManager &&
                                isBiometricDisabledByDevicePolicy(modality, userId)) {
                            continue;
                        }
                        if (isEnabledForApp(modality, userId)) {
                            enabledForApps = true;
                            break;
@@ -1043,6 +1092,7 @@ public class BiometricService extends SystemService {
        }

        Slog.d(TAG, "checkAndGetAuthenticators: user=" + userId
                + " checkDevicePolicyManager=" + checkDevicePolicyManager
                + " isHardwareDetected=" + isHardwareDetected
                + " hasTemplatesEnrolled=" + hasTemplatesEnrolled
                + " enabledForApps=" + enabledForApps);
@@ -1502,8 +1552,10 @@ public class BiometricService extends SystemService {
            int result;

            try {
                final boolean checkDevicePolicyManager = bundle.getBoolean(
                        BiometricPrompt.EXTRA_DISALLOW_BIOMETRICS_IF_POLICY_EXISTS, false);
                final Pair<Integer, Integer> pair = checkAndGetAuthenticators(userId, bundle,
                        opPackageName);
                        opPackageName, checkDevicePolicyManager);
                modality = pair.first;
                result = pair.second;
            } catch (RemoteException e) {
+2 −1
Original line number Diff line number Diff line
@@ -301,7 +301,8 @@ class ActivityStartInterceptor {
                FLAG_CANCEL_CURRENT | FLAG_ONE_SHOT | FLAG_IMMUTABLE);
        final KeyguardManager km = (KeyguardManager) mServiceContext
                .getSystemService(KEYGUARD_SERVICE);
        final Intent newIntent = km.createConfirmDeviceCredentialIntent(null, null, userId);
        final Intent newIntent = km.createConfirmDeviceCredentialIntent(null, null, userId,
                true /* disallowBiometricsIfPolicyExists */);
        if (newIntent == null) {
            return null;
        }
Loading