From 78e388067853551178196d6979562eb82a1dfc05 Mon Sep 17 00:00:00 2001 From: Ilya Matyukhin Date: Wed, 15 Sep 2021 01:58:50 -0700 Subject: [PATCH] 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 --- .../server/biometrics/AuthService.java | 50 +++++++++++++++++-- 1 file changed, 47 insertions(+), 3 deletions(-) diff --git a/services/core/java/com/android/server/biometrics/AuthService.java b/services/core/java/com/android/server/biometrics/AuthService.java index 0cd2e3d0ff593..41fb93cdc6a39 100644 --- a/services/core/java/com/android/server/biometrics/AuthService.java +++ b/services/core/java/com/android/server/biometrics/AuthService.java @@ -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,9 +626,19 @@ public class AuthService extends SystemService { final SensorConfig[] hidlConfigs; if (!mInjector.isHidlDisabled(getContext())) { final String[] configStrings = mInjector.getConfiguration(getContext()); - hidlConfigs = new SensorConfig[configStrings.length]; - for (int i = 0; i < configStrings.length; ++i) { - hidlConfigs[i] = new SensorConfig(configStrings[i]); + 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. *