8/n: Update biometric utils to have sensorId-specific files
New HAL interfaces have a strongly defined notion of sensorId whereas existing interfaces do not. This change does the following: 1) FingerprintUtils/FaceUtils is updated to contain singleton instances for each sensorId. The retrieved instance is still a utility class for a single sensor 2) Existing devices with old HALs will continue to use settings_fingerprint.xml and settings_face.xml 3) Devices with new HALs will use sensorId-specific files, e.g. on a device where the fingerprint sensorId=0 and face sensorId=1, the below files will be used: settings_fingerprint_0.xml, settings_face_1.xml 4) Updated existing AIDL provider to use sensor-specific utils Bug: 170497736 Test: Enrollments on existing devices not affected Change-Id: I5c48ab927d0450820f165707d60e0710e86be5e4
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.server.biometrics.sensors;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.content.Context;
|
||||
import android.hardware.biometrics.BiometricAuthenticator;
|
||||
import android.os.AsyncTask;
|
||||
@@ -61,11 +62,6 @@ public abstract class BiometricUserState<T extends BiometricAuthenticator.Identi
|
||||
*/
|
||||
protected abstract String getBiometricsTag();
|
||||
|
||||
/**
|
||||
* @return The file where the biometric metadata should be stored.
|
||||
*/
|
||||
protected abstract String getBiometricFile();
|
||||
|
||||
/**
|
||||
* @return The resource for the name template, this is used to generate the default name.
|
||||
*/
|
||||
@@ -88,8 +84,8 @@ public abstract class BiometricUserState<T extends BiometricAuthenticator.Identi
|
||||
throws IOException, XmlPullParserException;
|
||||
|
||||
|
||||
public BiometricUserState(Context context, int userId) {
|
||||
mFile = getFileForUser(userId);
|
||||
public BiometricUserState(Context context, int userId, @NonNull String fileName) {
|
||||
mFile = getFileForUser(userId, fileName);
|
||||
mContext = context;
|
||||
synchronized (this) {
|
||||
readStateSyncLocked();
|
||||
@@ -159,8 +155,8 @@ public abstract class BiometricUserState<T extends BiometricAuthenticator.Identi
|
||||
return true;
|
||||
}
|
||||
|
||||
private File getFileForUser(int userId) {
|
||||
return new File(Environment.getUserSystemDirectory(userId), getBiometricFile());
|
||||
private File getFileForUser(int userId, @NonNull String fileName) {
|
||||
return new File(Environment.getUserSystemDirectory(userId), fileName);
|
||||
}
|
||||
|
||||
private void scheduleWriteStateLocked() {
|
||||
|
||||
@@ -43,7 +43,6 @@ import java.util.ArrayList;
|
||||
public class FaceUserState extends BiometricUserState<Face> {
|
||||
|
||||
private static final String TAG = "FaceState";
|
||||
private static final String FACE_FILE = "settings_face.xml";
|
||||
|
||||
private static final String TAG_FACES = "faces";
|
||||
private static final String TAG_FACE = "face";
|
||||
@@ -51,8 +50,8 @@ public class FaceUserState extends BiometricUserState<Face> {
|
||||
private static final String ATTR_FACE_ID = "faceId";
|
||||
private static final String ATTR_DEVICE_ID = "deviceId";
|
||||
|
||||
public FaceUserState(Context ctx, int userId) {
|
||||
super(ctx, userId);
|
||||
public FaceUserState(Context ctx, int userId, String fileName) {
|
||||
super(ctx, userId, fileName);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -60,11 +59,6 @@ public class FaceUserState extends BiometricUserState<Face> {
|
||||
return TAG_FACES;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getBiometricFile() {
|
||||
return FACE_FILE;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getNameTemplateResource() {
|
||||
return com.android.internal.R.string.face_name_template;
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.server.biometrics.sensors.face;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
import android.content.Context;
|
||||
import android.hardware.biometrics.BiometricAuthenticator;
|
||||
import android.hardware.face.Face;
|
||||
@@ -33,21 +34,56 @@ import java.util.List;
|
||||
public class FaceUtils implements BiometricUtils<Face> {
|
||||
|
||||
private static final Object sInstanceLock = new Object();
|
||||
private static FaceUtils sInstance;
|
||||
// Map<SensorId, FaceUtils>
|
||||
private static SparseArray<FaceUtils> sInstances;
|
||||
private static final String LEGACY_FACE_FILE = "settings_face.xml";
|
||||
|
||||
@GuardedBy("this")
|
||||
private final SparseArray<FaceUserState> mUsers = new SparseArray<>();
|
||||
private final SparseArray<FaceUserState> mUserStates;
|
||||
private final String mFileName;
|
||||
|
||||
public static FaceUtils getInstance() {
|
||||
synchronized (sInstanceLock) {
|
||||
if (sInstance == null) {
|
||||
sInstance = new FaceUtils();
|
||||
}
|
||||
}
|
||||
return sInstance;
|
||||
public static FaceUtils getInstance(int sensorId) {
|
||||
// Specify a null fileName to use an auto-generated sensorId-specific filename.
|
||||
return getInstance(sensorId, null /* fileName */);
|
||||
}
|
||||
|
||||
private FaceUtils() {
|
||||
/**
|
||||
* Retrieves an instance for the specified sensorId. If the fileName is null, a default
|
||||
* filename (e.g. settings_face_<sensorId>.xml will be generated.
|
||||
*
|
||||
* Specifying an explicit fileName allows for backward compatibility with legacy devices,
|
||||
* where everything is stored in settings_face.xml.
|
||||
*/
|
||||
private static FaceUtils getInstance(int sensorId, @Nullable String fileName) {
|
||||
final FaceUtils utils;
|
||||
synchronized (sInstanceLock) {
|
||||
if (sInstances == null) {
|
||||
sInstances = new SparseArray<>();
|
||||
}
|
||||
if (sInstances.get(sensorId) == null) {
|
||||
if (fileName == null) {
|
||||
fileName = "settings_face_" + sensorId + ".xml";
|
||||
}
|
||||
sInstances.put(sensorId, new FaceUtils(fileName));
|
||||
}
|
||||
utils = sInstances.get(sensorId);
|
||||
}
|
||||
return utils;
|
||||
}
|
||||
|
||||
/**
|
||||
* Legacy getter for {@link android.hardware.biometrics.face.V1_0} and its extended subclasses,
|
||||
* which do not support a well defined sensorId from the HAL.
|
||||
*/
|
||||
public static FaceUtils getInstance() {
|
||||
// Note that sensorId for legacy services can be hard-coded to 0 since it's only used
|
||||
// to index into the sensor states map.
|
||||
return getInstance(0 /* sensorId */, LEGACY_FACE_FILE);
|
||||
}
|
||||
|
||||
private FaceUtils(String fileName) {
|
||||
mUserStates = new SparseArray<>();
|
||||
mFileName = fileName;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -81,10 +117,10 @@ public class FaceUtils implements BiometricUtils<Face> {
|
||||
|
||||
private FaceUserState getStateForUser(Context ctx, int userId) {
|
||||
synchronized (this) {
|
||||
FaceUserState state = mUsers.get(userId);
|
||||
FaceUserState state = mUserStates.get(userId);
|
||||
if (state == null) {
|
||||
state = new FaceUserState(ctx, userId);
|
||||
mUsers.put(userId, state);
|
||||
state = new FaceUserState(ctx, userId, mFileName);
|
||||
mUserStates.put(userId, state);
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
@@ -42,7 +42,6 @@ import java.util.ArrayList;
|
||||
public class FingerprintUserState extends BiometricUserState<Fingerprint> {
|
||||
|
||||
private static final String TAG = "FingerprintState";
|
||||
private static final String FINGERPRINT_FILE = "settings_fingerprint.xml";
|
||||
|
||||
private static final String TAG_FINGERPRINTS = "fingerprints";
|
||||
private static final String TAG_FINGERPRINT = "fingerprint";
|
||||
@@ -51,8 +50,8 @@ public class FingerprintUserState extends BiometricUserState<Fingerprint> {
|
||||
private static final String ATTR_FINGER_ID = "fingerId";
|
||||
private static final String ATTR_DEVICE_ID = "deviceId";
|
||||
|
||||
public FingerprintUserState(Context context, int userId) {
|
||||
super(context, userId);
|
||||
public FingerprintUserState(Context context, int userId, String fileName) {
|
||||
super(context, userId, fileName);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -60,11 +59,6 @@ public class FingerprintUserState extends BiometricUserState<Fingerprint> {
|
||||
return TAG_FINGERPRINTS;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getBiometricFile() {
|
||||
return FINGERPRINT_FILE;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getNameTemplateResource() {
|
||||
return com.android.internal.R.string.fingerprint_name_template;
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
|
||||
package com.android.server.biometrics.sensors.fingerprint;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
import android.content.Context;
|
||||
import android.hardware.biometrics.BiometricAuthenticator;
|
||||
import android.hardware.fingerprint.Fingerprint;
|
||||
import android.text.TextUtils;
|
||||
import android.util.SparseArray;
|
||||
@@ -33,21 +33,59 @@ import java.util.List;
|
||||
public class FingerprintUtils implements BiometricUtils<Fingerprint> {
|
||||
|
||||
private static final Object sInstanceLock = new Object();
|
||||
private static FingerprintUtils sInstance;
|
||||
// Map<SensorId, FingerprintUtils>
|
||||
private static SparseArray<FingerprintUtils> sInstances;
|
||||
private static final String LEGACY_FINGERPRINT_FILE = "settings_fingerprint.xml";
|
||||
|
||||
@GuardedBy("this")
|
||||
private final SparseArray<FingerprintUserState> mUsers = new SparseArray<>();
|
||||
private final SparseArray<FingerprintUserState> mUserStates;
|
||||
private final String mFileName;
|
||||
|
||||
public static FingerprintUtils getInstance() {
|
||||
synchronized (sInstanceLock) {
|
||||
if (sInstance == null) {
|
||||
sInstance = new FingerprintUtils();
|
||||
}
|
||||
}
|
||||
return sInstance;
|
||||
/**
|
||||
* Retrieves an instance for the specified sensorId.
|
||||
*/
|
||||
public static FingerprintUtils getInstance(int sensorId) {
|
||||
// Specify a null fileName to use an auto-generated sensorId-specific filename.
|
||||
return getInstance(sensorId, null /* fileName */);
|
||||
}
|
||||
|
||||
private FingerprintUtils() {
|
||||
/**
|
||||
* Retrieves an instance for the specified sensorId. If the fileName is null, a default
|
||||
* filename (e.g. settings_fingerprint_<sensorId>.xml will be generated.
|
||||
*
|
||||
* Specifying an explicit fileName allows for backward compatibility with legacy devices,
|
||||
* where everything is stored in settings_fingerprint.xml.
|
||||
*/
|
||||
private static FingerprintUtils getInstance(int sensorId, @Nullable String fileName) {
|
||||
final FingerprintUtils utils;
|
||||
synchronized (sInstanceLock) {
|
||||
if (sInstances == null) {
|
||||
sInstances = new SparseArray<>();
|
||||
}
|
||||
if (sInstances.get(sensorId) == null) {
|
||||
if (fileName == null) {
|
||||
fileName = "settings_fingerprint_" + sensorId + ".xml";
|
||||
}
|
||||
sInstances.put(sensorId, new FingerprintUtils(fileName));
|
||||
}
|
||||
utils = sInstances.get(sensorId);
|
||||
}
|
||||
return utils;
|
||||
}
|
||||
|
||||
/**
|
||||
* Legacy getter for {@link android.hardware.biometrics.fingerprint.V2_1} ands its extended
|
||||
* subclasses, which do not support a well defined sensorId from the HAL.
|
||||
*/
|
||||
public static FingerprintUtils getInstance() {
|
||||
// Note that sensorId for legacy services can be hard-coded to 0 since it's only used
|
||||
// to index into the sensor states map.
|
||||
return getInstance(0 /* sensorId */, LEGACY_FINGERPRINT_FILE);
|
||||
}
|
||||
|
||||
private FingerprintUtils(String fileName) {
|
||||
mUserStates = new SparseArray<>();
|
||||
mFileName = fileName;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -82,10 +120,10 @@ public class FingerprintUtils implements BiometricUtils<Fingerprint> {
|
||||
|
||||
private FingerprintUserState getStateForUser(Context ctx, int userId) {
|
||||
synchronized (this) {
|
||||
FingerprintUserState state = mUsers.get(userId);
|
||||
FingerprintUserState state = mUserStates.get(userId);
|
||||
if (state == null) {
|
||||
state = new FingerprintUserState(ctx, userId);
|
||||
mUsers.put(userId, state);
|
||||
state = new FingerprintUserState(ctx, userId, mFileName);
|
||||
mUserStates.put(userId, state);
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ public class FingerprintEnrollClient extends EnrollClient<ISession> implements U
|
||||
|
||||
@Override
|
||||
protected boolean hasReachedEnrollmentLimit() {
|
||||
return FingerprintUtils.getInstance()
|
||||
return FingerprintUtils.getInstance(getSensorId())
|
||||
.getBiometricsForUser(getContext(), getTargetUserId()).size()
|
||||
>= mMaxTemplatesPerUser;
|
||||
}
|
||||
|
||||
@@ -285,7 +285,7 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi
|
||||
final FingerprintEnrollClient client = new FingerprintEnrollClient(mContext,
|
||||
mSensors.get(sensorId).getLazySession(), token,
|
||||
new ClientMonitorCallbackConverter(receiver), userId, hardwareAuthToken,
|
||||
opPackageName, FingerprintUtils.getInstance(), sensorId,
|
||||
opPackageName, FingerprintUtils.getInstance(sensorId), sensorId,
|
||||
mUdfpsOverlayController, maxTemplatesPerUser);
|
||||
scheduleForSensor(sensorId, client, new ClientMonitor.Callback() {
|
||||
@Override
|
||||
@@ -380,7 +380,7 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi
|
||||
final FingerprintRemovalClient client = new FingerprintRemovalClient(mContext,
|
||||
mSensors.get(sensorId).getLazySession(), token,
|
||||
new ClientMonitorCallbackConverter(receiver), fingerId, userId,
|
||||
opPackageName, FingerprintUtils.getInstance(), sensorId,
|
||||
opPackageName, FingerprintUtils.getInstance(sensorId), sensorId,
|
||||
mSensors.get(sensorId).getAuthenticatorIds());
|
||||
mSensors.get(sensorId).getScheduler().scheduleClientMonitor(client);
|
||||
} catch (RemoteException e) {
|
||||
|
||||
@@ -162,7 +162,7 @@ class Sensor {
|
||||
}
|
||||
|
||||
final int currentUserId = client.getTargetUserId();
|
||||
final CharSequence name = FingerprintUtils.getInstance()
|
||||
final CharSequence name = FingerprintUtils.getInstance(sensorId)
|
||||
.getUniqueName(mContext, currentUserId);
|
||||
final Fingerprint fingerprint = new Fingerprint(name, enrollmentId, sensorId);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user