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

Commit 78e38806 authored by Ilya Matyukhin's avatar Ilya Matyukhin
Browse files

Assume convenience for biometrics not configured in R

This change restores R biometric behavior for devices that:
- Declare FEATURE_FINGERPRINT or FEATURE_FACE
- Have an empty config_biometric_sensors in config.xml
- Report ro.board.first_api_level as 30 (R)

The behavior is restored by assuming that the device has a biometric
sensor of the convenience strength class.

Bug: 200005662
Test: blueline + R vendor w/o the config + S GSI
Change-Id: I70e16089fa4285b1a382d9433af4fc3523b88fc8
parent aaba1884
Loading
Loading
Loading
Loading
+47 −3
Original line number Diff line number Diff line
@@ -60,6 +60,7 @@ import android.os.Build;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.provider.Settings;
import android.util.Slog;
@@ -81,6 +82,7 @@ public class AuthService extends SystemService {
    private static final String SETTING_HIDL_DISABLED =
            "com.android.server.biometrics.AuthService.hidlDisabled";
    private static final int DEFAULT_HIDL_DISABLED = 0;
    private static final String SYSPROP_FIRST_API_LEVEL = "ro.board.first_api_level";

    private final Injector mInjector;

@@ -624,10 +626,20 @@ public class AuthService extends SystemService {
        final SensorConfig[] hidlConfigs;
        if (!mInjector.isHidlDisabled(getContext())) {
            final String[] configStrings = mInjector.getConfiguration(getContext());
            final boolean isRVendor = SystemProperties.getInt(SYSPROP_FIRST_API_LEVEL, 0)
                    == Build.VERSION_CODES.R;
            if (configStrings.length == 0 && isRVendor) {
                // For backwards compatibility with R where biometrics could work without being
                // configured in config_biometric_sensors. In the absence of a vendor provided
                // configuration, we assume the weakest biometric strength (i.e. convenience).
                Slog.w(TAG, "Found R vendor partition without config_biometric_sensors");
                hidlConfigs = generateRSdkCompatibleConfiguration();
            } else {
                hidlConfigs = new SensorConfig[configStrings.length];
                for (int i = 0; i < configStrings.length; ++i) {
                    hidlConfigs[i] = new SensorConfig(configStrings[i]);
                }
            }
        } else {
            hidlConfigs = null;
        }
@@ -638,6 +650,38 @@ public class AuthService extends SystemService {
        mInjector.publishBinderService(this, mImpl);
    }

    /**
     * Generates SensorConfig[] with an entry that corresponds to the biometric feature declared on
     * the device. Returns an empty SensorConfig[] if no biometric features are declared. If both
     * fingerprint and face are declared, only the fingerprint config will be generated. Biometrics
     * are assumed to be of the weakest strength class, i.e. convenience.
     */
    private @NonNull SensorConfig[] generateRSdkCompatibleConfiguration() {
        final boolean hasFp = getContext().getPackageManager().hasSystemFeature(
                PackageManager.FEATURE_FINGERPRINT);
        final boolean hasFace = getContext().getPackageManager().hasSystemFeature(
                PackageManager.FEATURE_FACE);
        if (hasFp || hasFace) {
            final String id = "0";
            final String strength = String.valueOf(Authenticators.BIOMETRIC_CONVENIENCE);
            final String modality;
            final String logStr;
            if (hasFp) {
                modality = String.valueOf(BiometricAuthenticator.TYPE_FINGERPRINT);
                logStr = "fingerprint";
            } else {
                modality = String.valueOf(BiometricAuthenticator.TYPE_FACE);
                logStr = "face";
            }
            final String config = String.join(":" /* delimiter */, id, modality, strength);
            Slog.d(TAG, "Generated config_biometric_sensors for " + logStr + ": " + config);
            return new SensorConfig[]{new SensorConfig(config)};
        } else {
            Slog.d(TAG, "Couldn't generate config_biometric_sensors. No biometrics found.");
            return new SensorConfig[0];
        }
    }

    /**
     * Registers HIDL and AIDL authenticators for all of the available modalities.
     *