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

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

Change BiometricService/AuthController interface to sensorId

This way, AuthController (SystemUI) can query the system to check
specific info for each sensor.

Test: No effect on existing devices
Test: atest com.android.systemui.biometrics
Test: atest com.android.server.biometrics

Bug: 171071087

Change-Id: I2a33aa25aac880764000d296de328d326709d1a0
parent 0583d29f
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -145,8 +145,8 @@ oneway interface IStatusBar

    // Used to show the authentication dialog (Biometrics, Device Credential)
    void showAuthenticationDialog(in PromptInfo promptInfo, IBiometricSysuiReceiver sysuiReceiver,
            int biometricModality, boolean requireConfirmation, int userId, String opPackageName,
            long operationId);
            in int[] sensorIds, boolean credentialAllowed, boolean requireConfirmation, int userId,
            String opPackageName, long operationId);
    // Used to notify the authentication dialog that a biometric has been authenticated
    void onBiometricAuthenticated();
    // Used to set a temporary message, e.g. fingerprint not recognized, finger moved too fast, etc
+3 −2
Original line number Diff line number Diff line
@@ -106,8 +106,9 @@ interface IStatusBarService

    // Used to show the authentication dialog (Biometrics, Device Credential)
    void showAuthenticationDialog(in PromptInfo promptInfo, IBiometricSysuiReceiver sysuiReceiver,
            int biometricModality, boolean requireConfirmation, int userId, String opPackageName,
            long operationId);
            in int[] sensorIds, boolean credentialAllowed, boolean requireConfirmation,
            int userId, String opPackageName,long operationId);

    // Used to notify the authentication dialog that a biometric has been authenticated
    void onBiometricAuthenticated();
    // Used to set a temporary message, e.g. fingerprint not recognized, finger moved too fast, etc
+34 −15
Original line number Diff line number Diff line
@@ -24,6 +24,9 @@ import android.graphics.PixelFormat;
import android.hardware.biometrics.BiometricAuthenticator;
import android.hardware.biometrics.BiometricConstants;
import android.hardware.biometrics.PromptInfo;
import android.hardware.face.FaceSensorPropertiesInternal;
import android.hardware.fingerprint.FingerprintSensorProperties;
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
@@ -51,6 +54,7 @@ import com.android.systemui.keyguard.WakefulnessLifecycle;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.List;

/**
 * Top level container/controller for the BiometricPrompt UI.
@@ -76,6 +80,8 @@ public class AuthContainerView extends LinearLayout

    final Config mConfig;
    final int mEffectiveUserId;
    @Nullable private final List<FingerprintSensorPropertiesInternal> mFpProps;
    @Nullable private final List<FaceSensorPropertiesInternal> mFaceProps;
    private final Handler mHandler;
    private final Injector mInjector;
    private final IBinder mWindowToken = new Binder();
@@ -111,7 +117,8 @@ public class AuthContainerView extends LinearLayout
        boolean mRequireConfirmation;
        int mUserId;
        String mOpPackageName;
        @BiometricAuthenticator.Modality int mModalityMask;
        int[] mSensorIds;
        boolean mCredentialAllowed;
        boolean mSkipIntro;
        long mOperationId;
    }
@@ -159,9 +166,12 @@ public class AuthContainerView extends LinearLayout
            return this;
        }

        public AuthContainerView build(@BiometricAuthenticator.Modality int modalityMask) {
            mConfig.mModalityMask = modalityMask;
            return new AuthContainerView(mConfig, new Injector());
        public AuthContainerView build(int[] sensorIds, boolean credentialAllowed,
                @Nullable List<FingerprintSensorPropertiesInternal> fpProps,
                @Nullable List<FaceSensorPropertiesInternal> faceProps) {
            mConfig.mSensorIds = sensorIds;
            mConfig.mCredentialAllowed = credentialAllowed;
            return new AuthContainerView(mConfig, new Injector(), fpProps, faceProps);
        }
    }

@@ -242,11 +252,15 @@ public class AuthContainerView extends LinearLayout
    }

    @VisibleForTesting
    AuthContainerView(Config config, Injector injector) {
    AuthContainerView(Config config, Injector injector,
            @Nullable List<FingerprintSensorPropertiesInternal> fpProps,
            @Nullable List<FaceSensorPropertiesInternal> faceProps) {
        super(config.mContext);

        mConfig = config;
        mInjector = injector;
        mFpProps = fpProps;
        mFaceProps = faceProps;

        mEffectiveUserId = mInjector.getUserManager(mContext)
                .getCredentialOwnerProfile(mConfig.mUserId);
@@ -269,20 +283,25 @@ public class AuthContainerView extends LinearLayout

        // Inflate biometric view only if necessary.
        if (Utils.isBiometricAllowed(mConfig.mPromptInfo)) {
            final @BiometricAuthenticator.Modality int biometricModality =
                    config.mModalityMask & ~BiometricAuthenticator.TYPE_CREDENTIAL;

            switch (biometricModality) {
                case BiometricAuthenticator.TYPE_FINGERPRINT:
            if (config.mSensorIds.length == 1) {
                final int singleSensorAuthId = config.mSensorIds[0];
                if (Utils.containsSensorId(mFpProps, singleSensorAuthId)) {
                    mBiometricView = (AuthBiometricFingerprintView)
                            factory.inflate(R.layout.auth_biometric_fingerprint_view, null, false);
                    break;
                case BiometricAuthenticator.TYPE_FACE:
                } else if (Utils.containsSensorId(mFaceProps, singleSensorAuthId)) {
                    mBiometricView = (AuthBiometricFaceView)
                            factory.inflate(R.layout.auth_biometric_face_view, null, false);
                    break;
                default:
                    Log.e(TAG, "Unsupported biometric modality: " + biometricModality);
                } else {
                    // Unknown sensorId
                    Log.e(TAG, "Unknown sensorId: " + singleSensorAuthId);
                    mBiometricView = null;
                    mBackgroundView = null;
                    mBiometricScrollView = null;
                    return;
                }
            } else {
                // The UI currently only supports authentication with a single sensor.
                Log.e(TAG, "Unsupported sensor array, length: " + config.mSensorIds.length);
                mBiometricView = null;
                mBackgroundView = null;
                mBiometricScrollView = null;
+37 −19
Original line number Diff line number Diff line
@@ -29,12 +29,12 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Configuration;
import android.hardware.biometrics.BiometricAuthenticator;
import android.hardware.biometrics.BiometricConstants;
import android.hardware.biometrics.BiometricPrompt;
import android.hardware.biometrics.IBiometricSysuiReceiver;
import android.hardware.biometrics.PromptInfo;
import android.hardware.face.FaceManager;
import android.hardware.face.FaceSensorPropertiesInternal;
import android.hardware.fingerprint.FingerprintManager;
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
import android.os.Bundle;
@@ -74,8 +74,12 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks,
    private final StatusBarStateController mStatusBarStateController;
    private final IActivityTaskManager mActivityTaskManager;
    @Nullable private final FingerprintManager mFingerprintManager;
    @Nullable private final FaceManager mFaceManager;
    private final Provider<UdfpsController> mUdfpsControllerFactory;

    @Nullable private final List<FingerprintSensorPropertiesInternal> mFpProps;
    @Nullable private final List<FaceSensorPropertiesInternal> mFaceProps;

    // TODO: These should just be saved from onSaveState
    private SomeArgs mCurrentDialogArgs;
    @VisibleForTesting
@@ -285,14 +289,20 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks,
            StatusBarStateController statusBarStateController,
            IActivityTaskManager activityTaskManager,
            @Nullable FingerprintManager fingerprintManager,
            @Nullable FaceManager faceManager,
            Provider<UdfpsController> udfpsControllerFactory) {
        super(context);
        mCommandQueue = commandQueue;
        mStatusBarStateController = statusBarStateController;
        mActivityTaskManager = activityTaskManager;
        mFingerprintManager = fingerprintManager;
        mFaceManager = faceManager;
        mUdfpsControllerFactory = udfpsControllerFactory;

        mFpProps = mFingerprintManager != null ? mFingerprintManager.getSensorPropertiesInternal()
                : null;
        mFaceProps = mFaceManager != null ? mFaceManager.getSensorPropertiesInternal() : null;

        IntentFilter filter = new IntentFilter();
        filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);

@@ -326,24 +336,30 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks,

    @Override
    public void showAuthenticationDialog(PromptInfo promptInfo, IBiometricSysuiReceiver receiver,
            @BiometricAuthenticator.Modality int biometricModality, boolean requireConfirmation,
            int[] sensorIds, boolean credentialAllowed, boolean requireConfirmation,
            int userId, String opPackageName, long operationId) {
        @Authenticators.Types final int authenticators = promptInfo.getAuthenticators();

        if (DEBUG) {
            StringBuilder ids = new StringBuilder();
            for (int sensorId : sensorIds) {
                ids.append(sensorId).append(" ");
            }
            Log.d(TAG, "showAuthenticationDialog, authenticators: " + authenticators
                    + ", biometricModality: " + biometricModality
                    + ", sensorIds: " + ids.toString()
                    + ", credentialAllowed: " + credentialAllowed
                    + ", requireConfirmation: " + requireConfirmation
                    + ", operationId: " + operationId);
        }
        SomeArgs args = SomeArgs.obtain();
        args.arg1 = promptInfo;
        args.arg2 = receiver;
        args.argi1 = biometricModality;
        args.arg3 = requireConfirmation;
        args.argi2 = userId;
        args.arg4 = opPackageName;
        args.arg5 = operationId;
        args.arg3 = sensorIds;
        args.arg4 = credentialAllowed;
        args.arg5 = requireConfirmation;
        args.argi1 = userId;
        args.arg6 = opPackageName;
        args.arg7 = operationId;

        boolean skipAnimation = false;
        if (mCurrentDialog != null) {
@@ -458,25 +474,28 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks,

    private void showDialog(SomeArgs args, boolean skipAnimation, Bundle savedState) {
        mCurrentDialogArgs = args;
        final @BiometricAuthenticator.Modality int type = args.argi1;

        final PromptInfo promptInfo = (PromptInfo) args.arg1;
        final boolean requireConfirmation = (boolean) args.arg3;
        final int userId = args.argi2;
        final String opPackageName = (String) args.arg4;
        final long operationId = (long) args.arg5;
        final int[] sensorIds = (int[]) args.arg3;
        final boolean credentialAllowed = (boolean) args.arg4;
        final boolean requireConfirmation = (boolean) args.arg5;
        final int userId = args.argi1;
        final String opPackageName = (String) args.arg6;
        final long operationId = (long) args.arg7;

        // Create a new dialog but do not replace the current one yet.
        final AuthDialog newDialog = buildDialog(
                promptInfo,
                requireConfirmation,
                userId,
                type,
                sensorIds,
                credentialAllowed,
                opPackageName,
                skipAnimation,
                operationId);

        if (newDialog == null) {
            Log.e(TAG, "Unsupported type: " + type);
            Log.e(TAG, "Unsupported type configuration");
            return;
        }

@@ -484,8 +503,7 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks,
            Log.d(TAG, "userId: " + userId
                    + " savedState: " + savedState
                    + " mCurrentDialog: " + mCurrentDialog
                    + " newDialog: " + newDialog
                    + " type: " + type);
                    + " newDialog: " + newDialog);
        }

        if (mCurrentDialog != null) {
@@ -541,7 +559,7 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks,
    }

    protected AuthDialog buildDialog(PromptInfo promptInfo, boolean requireConfirmation,
            int userId, @BiometricAuthenticator.Modality int type, String opPackageName,
            int userId, int[] sensorIds, boolean credentialAllowed, String opPackageName,
            boolean skipIntro, long operationId) {
        return new AuthContainerView.Builder(mContext)
                .setCallback(this)
@@ -551,6 +569,6 @@ public class AuthController extends SystemUI implements CommandQueue.Callbacks,
                .setOpPackageName(opPackageName)
                .setSkipIntro(skipIntro)
                .setOperationId(operationId)
                .build(type);
                .build(sensorIds, credentialAllowed, mFpProps, mFaceProps);
    }
}
+18 −0
Original line number Diff line number Diff line
@@ -20,9 +20,11 @@ import static android.hardware.biometrics.BiometricManager.Authenticators;
import static android.view.accessibility.AccessibilityEvent.CONTENT_CHANGE_TYPE_SUBTREE;

import android.annotation.IntDef;
import android.annotation.Nullable;
import android.app.admin.DevicePolicyManager;
import android.content.Context;
import android.hardware.biometrics.PromptInfo;
import android.hardware.biometrics.SensorPropertiesInternal;
import android.os.UserManager;
import android.util.DisplayMetrics;
import android.view.ViewGroup;
@@ -33,6 +35,7 @@ import com.android.internal.widget.LockPatternUtils;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.List;

public class Utils {

@@ -98,4 +101,19 @@ public class Utils {
        final UserManager userManager = context.getSystemService(UserManager.class);
        return userManager.isManagedProfile(userId);
    }

    static boolean containsSensorId(@Nullable List<? extends SensorPropertiesInternal> properties,
            int sensorId) {
        if (properties == null) {
            return false;
        }

        for (SensorPropertiesInternal prop : properties) {
            if (prop.sensorId == sensorId) {
                return true;
            }
        }

        return false;
    }
}
Loading