Remove InternalCleanupClient enrolled list cache
(mEnrolledList), retrieve the enrolled list from framework
when the client starts.
Bug: 268695802
Test: atest com.android.server.biometrics
atest CtsBiometricsTestCases
atest CtsBiometricsHostTestCases
Change-Id: Iab3663d0dde2f9a96cdcf5aced629451e874b674
This commit is contained in:
@@ -64,7 +64,6 @@ public abstract class InternalCleanupClient<S extends BiometricAuthenticator.Ide
|
||||
private final ArrayList<UserTemplate> mUnknownHALTemplates = new ArrayList<>();
|
||||
private final BiometricUtils<S> mBiometricUtils;
|
||||
private final Map<Integer, Long> mAuthenticatorIds;
|
||||
private final List<S> mEnrolledList;
|
||||
private final boolean mHasEnrollmentsBeforeStarting;
|
||||
private BaseClientMonitor mCurrentTask;
|
||||
private boolean mFavorHalEnrollments = false;
|
||||
@@ -135,13 +134,12 @@ public abstract class InternalCleanupClient<S extends BiometricAuthenticator.Ide
|
||||
protected InternalCleanupClient(@NonNull Context context, @NonNull Supplier<T> lazyDaemon,
|
||||
int userId, @NonNull String owner, int sensorId,
|
||||
@NonNull BiometricLogger logger, @NonNull BiometricContext biometricContext,
|
||||
@NonNull List<S> enrolledList, @NonNull BiometricUtils<S> utils,
|
||||
@NonNull BiometricUtils<S> utils,
|
||||
@NonNull Map<Integer, Long> authenticatorIds) {
|
||||
super(context, lazyDaemon, null /* token */, null /* ClientMonitorCallbackConverter */,
|
||||
userId, owner, 0 /* cookie */, sensorId, logger, biometricContext);
|
||||
mBiometricUtils = utils;
|
||||
mAuthenticatorIds = authenticatorIds;
|
||||
mEnrolledList = enrolledList;
|
||||
mHasEnrollmentsBeforeStarting = !utils.getBiometricsForUser(context, userId).isEmpty();
|
||||
}
|
||||
|
||||
@@ -169,12 +167,16 @@ public abstract class InternalCleanupClient<S extends BiometricAuthenticator.Ide
|
||||
public void start(@NonNull ClientMonitorCallback callback) {
|
||||
super.start(callback);
|
||||
|
||||
final List<S> enrolledList =
|
||||
mBiometricUtils.getBiometricsForUser(getContext(), getTargetUserId());
|
||||
|
||||
// Start enumeration. Removal will start if necessary, when enumeration is completed.
|
||||
mCurrentTask = getEnumerateClient(getContext(), mLazyDaemon, getToken(), getTargetUserId(),
|
||||
getOwnerString(), mEnrolledList, mBiometricUtils, getSensorId(), getLogger(),
|
||||
getOwnerString(), enrolledList, mBiometricUtils, getSensorId(), getLogger(),
|
||||
getBiometricContext());
|
||||
|
||||
Slog.d(TAG, "Starting enumerate: " + mCurrentTask);
|
||||
Slog.d(TAG, "Starting enumerate: " + mCurrentTask + " enrolledList size:"
|
||||
+ enrolledList.size());
|
||||
mCurrentTask.start(mEnumerateCallback);
|
||||
}
|
||||
|
||||
|
||||
@@ -43,10 +43,10 @@ class FaceInternalCleanupClient extends InternalCleanupClient<Face, AidlSession>
|
||||
FaceInternalCleanupClient(@NonNull Context context,
|
||||
@NonNull Supplier<AidlSession> lazyDaemon, int userId, @NonNull String owner,
|
||||
int sensorId, @NonNull BiometricLogger logger,
|
||||
@NonNull BiometricContext biometricContext, @NonNull List<Face> enrolledList,
|
||||
@NonNull BiometricContext biometricContext,
|
||||
@NonNull BiometricUtils<Face> utils, @NonNull Map<Integer, Long> authenticatorIds) {
|
||||
super(context, lazyDaemon, userId, owner, sensorId, logger, biometricContext,
|
||||
enrolledList, utils, authenticatorIds);
|
||||
utils, authenticatorIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -595,14 +595,13 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider {
|
||||
public void scheduleInternalCleanup(int sensorId, int userId,
|
||||
@Nullable ClientMonitorCallback callback, boolean favorHalEnrollments) {
|
||||
mHandler.post(() -> {
|
||||
final List<Face> enrolledList = getEnrolledFaces(sensorId, userId);
|
||||
final FaceInternalCleanupClient client =
|
||||
new FaceInternalCleanupClient(mContext,
|
||||
mSensors.get(sensorId).getLazySession(), userId,
|
||||
mContext.getOpPackageName(), sensorId,
|
||||
createLogger(BiometricsProtoEnums.ACTION_ENUMERATE,
|
||||
BiometricsProtoEnums.CLIENT_UNKNOWN),
|
||||
mBiometricContext, enrolledList,
|
||||
mBiometricContext,
|
||||
FaceUtils.getInstance(sensorId),
|
||||
mSensors.get(sensorId).getAuthenticatorIds());
|
||||
if (favorHalEnrollments) {
|
||||
|
||||
@@ -818,12 +818,11 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider {
|
||||
mHandler.post(() -> {
|
||||
scheduleUpdateActiveUserWithoutHandler(userId);
|
||||
|
||||
final List<Face> enrolledList = getEnrolledFaces(mSensorId, userId);
|
||||
final FaceInternalCleanupClient client = new FaceInternalCleanupClient(mContext,
|
||||
mLazyDaemon, userId, mContext.getOpPackageName(), mSensorId,
|
||||
createLogger(BiometricsProtoEnums.ACTION_ENUMERATE,
|
||||
BiometricsProtoEnums.CLIENT_UNKNOWN),
|
||||
mBiometricContext, enrolledList,
|
||||
mBiometricContext,
|
||||
FaceUtils.getLegacyInstance(mSensorId), mAuthenticatorIds);
|
||||
mScheduler.scheduleClientMonitor(client, new ClientMonitorCompositeCallback(callback,
|
||||
mBiometricStateCallback));
|
||||
|
||||
@@ -42,10 +42,10 @@ class FaceInternalCleanupClient extends InternalCleanupClient<Face, IBiometricsF
|
||||
FaceInternalCleanupClient(@NonNull Context context,
|
||||
@NonNull Supplier<IBiometricsFace> lazyDaemon, int userId, @NonNull String owner,
|
||||
int sensorId, @NonNull BiometricLogger logger,
|
||||
@NonNull BiometricContext biometricContext, @NonNull List<Face> enrolledList,
|
||||
@NonNull BiometricContext biometricContext,
|
||||
@NonNull BiometricUtils<Face> utils, @NonNull Map<Integer, Long> authenticatorIds) {
|
||||
super(context, lazyDaemon, userId, owner, sensorId, logger, biometricContext,
|
||||
enrolledList, utils, authenticatorIds);
|
||||
utils, authenticatorIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -45,10 +45,9 @@ class FingerprintInternalCleanupClient extends InternalCleanupClient<Fingerprint
|
||||
@NonNull Supplier<AidlSession> lazyDaemon,
|
||||
int userId, @NonNull String owner, int sensorId,
|
||||
@NonNull BiometricLogger logger, @NonNull BiometricContext biometricContext,
|
||||
@NonNull List<Fingerprint> enrolledList,
|
||||
@NonNull FingerprintUtils utils, @NonNull Map<Integer, Long> authenticatorIds) {
|
||||
super(context, lazyDaemon, userId, owner, sensorId, logger, biometricContext,
|
||||
enrolledList, utils, authenticatorIds);
|
||||
utils, authenticatorIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -556,7 +556,6 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi
|
||||
public void scheduleInternalCleanup(int sensorId, int userId,
|
||||
@Nullable ClientMonitorCallback callback, boolean favorHalEnrollments) {
|
||||
mHandler.post(() -> {
|
||||
final List<Fingerprint> enrolledList = getEnrolledFingerprints(sensorId, userId);
|
||||
final FingerprintInternalCleanupClient client =
|
||||
new FingerprintInternalCleanupClient(mContext,
|
||||
mSensors.get(sensorId).getLazySession(), userId,
|
||||
@@ -564,7 +563,7 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi
|
||||
createLogger(BiometricsProtoEnums.ACTION_ENUMERATE,
|
||||
BiometricsProtoEnums.CLIENT_UNKNOWN),
|
||||
mBiometricContext,
|
||||
enrolledList, FingerprintUtils.getInstance(sensorId),
|
||||
FingerprintUtils.getInstance(sensorId),
|
||||
mSensors.get(sensorId).getAuthenticatorIds());
|
||||
if (favorHalEnrollments) {
|
||||
client.setFavorHalEnrollments();
|
||||
|
||||
@@ -741,14 +741,12 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider
|
||||
mHandler.post(() -> {
|
||||
scheduleUpdateActiveUserWithoutHandler(userId);
|
||||
|
||||
final List<Fingerprint> enrolledList = getEnrolledFingerprints(
|
||||
mSensorProperties.sensorId, userId);
|
||||
final FingerprintInternalCleanupClient client = new FingerprintInternalCleanupClient(
|
||||
mContext, mLazyDaemon, userId, mContext.getOpPackageName(),
|
||||
mSensorProperties.sensorId,
|
||||
createLogger(BiometricsProtoEnums.ACTION_ENUMERATE,
|
||||
BiometricsProtoEnums.CLIENT_UNKNOWN),
|
||||
mBiometricContext, enrolledList,
|
||||
mBiometricContext,
|
||||
FingerprintUtils.getLegacyInstance(mSensorId), mAuthenticatorIds);
|
||||
mScheduler.scheduleClientMonitor(client, callback);
|
||||
});
|
||||
|
||||
@@ -45,11 +45,10 @@ class FingerprintInternalCleanupClient
|
||||
@NonNull Supplier<IBiometricsFingerprint> lazyDaemon, int userId,
|
||||
@NonNull String owner, int sensorId,
|
||||
@NonNull BiometricLogger logger, @NonNull BiometricContext biometricContext,
|
||||
@NonNull List<Fingerprint> enrolledList,
|
||||
@NonNull BiometricUtils<Fingerprint> utils,
|
||||
@NonNull Map<Integer, Long> authenticatorIds) {
|
||||
super(context, lazyDaemon, userId, owner, sensorId, logger, biometricContext,
|
||||
enrolledList, utils, authenticatorIds);
|
||||
utils, authenticatorIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -39,7 +39,9 @@ import static org.mockito.Mockito.when;
|
||||
import android.content.Context;
|
||||
import android.hardware.biometrics.BiometricAuthenticator;
|
||||
import android.hardware.biometrics.BiometricConstants;
|
||||
import android.hardware.biometrics.BiometricsProtoEnums;
|
||||
import android.hardware.biometrics.IBiometricService;
|
||||
import android.hardware.fingerprint.Fingerprint;
|
||||
import android.os.Binder;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
@@ -48,6 +50,7 @@ import android.platform.test.annotations.Presubmit;
|
||||
import android.testing.AndroidTestingRunner;
|
||||
import android.testing.TestableContext;
|
||||
import android.testing.TestableLooper;
|
||||
import android.util.Slog;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
@@ -58,6 +61,8 @@ import com.android.server.biometrics.log.BiometricContext;
|
||||
import com.android.server.biometrics.log.BiometricLogger;
|
||||
import com.android.server.biometrics.nano.BiometricSchedulerProto;
|
||||
import com.android.server.biometrics.nano.BiometricsProto;
|
||||
import com.android.server.biometrics.sensors.fingerprint.FingerprintUtils;
|
||||
import com.android.server.biometrics.sensors.fingerprint.aidl.AidlSession;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
@@ -67,6 +72,9 @@ import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@Presubmit
|
||||
@@ -78,6 +86,9 @@ public class BiometricSchedulerTest {
|
||||
private static final String TAG = "BiometricSchedulerTest";
|
||||
private static final int TEST_SENSOR_ID = 1;
|
||||
private static final int LOG_NUM_RECENT_OPERATIONS = 2;
|
||||
private static final Fingerprint TEST_FINGERPRINT = new Fingerprint("" /* name */,
|
||||
1 /* fingerId */, TEST_SENSOR_ID);
|
||||
|
||||
@Rule
|
||||
public final TestableContext mContext = new TestableContext(
|
||||
InstrumentationRegistry.getContext(), null);
|
||||
@@ -673,6 +684,56 @@ public class BiometricSchedulerTest {
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTwoInternalCleanupOps_withFirstFavorHalEnrollment() throws Exception {
|
||||
final String owner = "test.owner";
|
||||
final int userId = 1;
|
||||
final Supplier<Object> daemon = () -> mock(AidlSession.class);
|
||||
final FingerprintUtils utils = mock(FingerprintUtils.class);
|
||||
final Map<Integer, Long> authenticatorIds = new HashMap<>();
|
||||
final ClientMonitorCallback callback0 = mock(ClientMonitorCallback.class);
|
||||
final ClientMonitorCallback callback1 = mock(ClientMonitorCallback.class);
|
||||
final ClientMonitorCallback callback2 = mock(ClientMonitorCallback.class);
|
||||
|
||||
final TestInternalCleanupClient client1 = new
|
||||
TestInternalCleanupClient(mContext, daemon, userId,
|
||||
owner, TEST_SENSOR_ID, mock(BiometricLogger.class),
|
||||
mBiometricContext, utils, authenticatorIds);
|
||||
final TestInternalCleanupClient client2 = new
|
||||
TestInternalCleanupClient(mContext, daemon, userId,
|
||||
owner, TEST_SENSOR_ID, mock(BiometricLogger.class),
|
||||
mBiometricContext, utils, authenticatorIds);
|
||||
|
||||
//add initial start client to scheduler, so later clients will be on pending operation queue
|
||||
final TestHalClientMonitor startClient = new TestHalClientMonitor(mContext, mToken,
|
||||
daemon);
|
||||
mScheduler.scheduleClientMonitor(startClient, callback0);
|
||||
|
||||
//add first cleanup client which favors enrollments from HAL
|
||||
client1.setFavorHalEnrollments();
|
||||
mScheduler.scheduleClientMonitor(client1, callback1);
|
||||
assertEquals(1, mScheduler.mPendingOperations.size());
|
||||
|
||||
when(utils.getBiometricsForUser(mContext, userId)).thenAnswer(i ->
|
||||
new ArrayList<>(client1.getFingerprints()));
|
||||
|
||||
//add second cleanup client
|
||||
mScheduler.scheduleClientMonitor(client2, callback2);
|
||||
|
||||
//finish the start client, so other pending clients are processed
|
||||
startClient.getCallback().onClientFinished(startClient, true);
|
||||
|
||||
waitForIdle();
|
||||
|
||||
assertTrue(client1.isAlreadyDone());
|
||||
assertTrue(client2.isAlreadyDone());
|
||||
assertNull(mScheduler.mCurrentOperation);
|
||||
verify(utils, never()).removeBiometricForUser(mContext, userId,
|
||||
TEST_FINGERPRINT.getBiometricId());
|
||||
assertEquals(1, client1.getFingerprints().size());
|
||||
}
|
||||
|
||||
|
||||
private BiometricSchedulerProto getDump(boolean clearSchedulerBuffer) throws Exception {
|
||||
return BiometricSchedulerProto.parseFrom(mScheduler.dumpProtoState(clearSchedulerBuffer));
|
||||
}
|
||||
@@ -835,4 +896,90 @@ public class BiometricSchedulerTest {
|
||||
mDestroyed = true;
|
||||
}
|
||||
}
|
||||
|
||||
private static class TestInternalEnumerateClient extends InternalEnumerateClient<Object> {
|
||||
private static final String TAG = "TestInternalEnumerateClient";
|
||||
|
||||
|
||||
protected TestInternalEnumerateClient(@NonNull Context context,
|
||||
@NonNull Supplier<Object> lazyDaemon, @NonNull IBinder token, int userId,
|
||||
@NonNull String owner, @NonNull List<Fingerprint> enrolledList,
|
||||
@NonNull BiometricUtils<Fingerprint> utils, int sensorId,
|
||||
@NonNull BiometricLogger logger, @NonNull BiometricContext biometricContext) {
|
||||
super(context, lazyDaemon, token, userId, owner, enrolledList, utils, sensorId,
|
||||
logger, biometricContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startHalOperation() {
|
||||
Slog.d(TAG, "TestInternalEnumerateClient#startHalOperation");
|
||||
onEnumerationResult(TEST_FINGERPRINT, 0 /* remaining */);
|
||||
}
|
||||
}
|
||||
|
||||
private static class TestRemovalClient extends RemovalClient<Fingerprint, Object> {
|
||||
private static final String TAG = "TestRemovalClient";
|
||||
|
||||
TestRemovalClient(@NonNull Context context,
|
||||
@NonNull Supplier<Object> lazyDaemon, @NonNull IBinder token,
|
||||
@Nullable ClientMonitorCallbackConverter listener, int[] biometricIds, int userId,
|
||||
@NonNull String owner, @NonNull BiometricUtils<Fingerprint> utils, int sensorId,
|
||||
@NonNull BiometricLogger logger, @NonNull BiometricContext biometricContext,
|
||||
@NonNull Map<Integer, Long> authenticatorIds) {
|
||||
super(context, lazyDaemon, token, listener, userId, owner, utils, sensorId,
|
||||
logger, biometricContext, authenticatorIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startHalOperation() {
|
||||
Slog.d(TAG, "Removing template from hw");
|
||||
onRemoved(TEST_FINGERPRINT, 0);
|
||||
}
|
||||
}
|
||||
|
||||
private static class TestInternalCleanupClient extends
|
||||
InternalCleanupClient<Fingerprint, Object> {
|
||||
private List<Fingerprint> mFingerprints = new ArrayList<>();
|
||||
|
||||
TestInternalCleanupClient(@NonNull Context context,
|
||||
@NonNull Supplier<Object> lazyDaemon,
|
||||
int userId, @NonNull String owner, int sensorId,
|
||||
@NonNull BiometricLogger logger, @NonNull BiometricContext biometricContext,
|
||||
@NonNull FingerprintUtils utils, @NonNull Map<Integer, Long> authenticatorIds) {
|
||||
super(context, lazyDaemon, userId, owner, sensorId, logger, biometricContext,
|
||||
utils, authenticatorIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected InternalEnumerateClient<Object> getEnumerateClient(Context context,
|
||||
Supplier<Object> lazyDaemon, IBinder token, int userId, String owner,
|
||||
List<Fingerprint> enrolledList, BiometricUtils<Fingerprint> utils, int sensorId,
|
||||
@NonNull BiometricLogger logger, @NonNull BiometricContext biometricContext) {
|
||||
return new TestInternalEnumerateClient(context, lazyDaemon, token, userId, owner,
|
||||
enrolledList, utils, sensorId,
|
||||
logger.swapAction(context, BiometricsProtoEnums.ACTION_ENUMERATE),
|
||||
biometricContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected RemovalClient<Fingerprint, Object> getRemovalClient(Context context,
|
||||
Supplier<Object> lazyDaemon, IBinder token, int biometricId, int userId,
|
||||
String owner, BiometricUtils<Fingerprint> utils, int sensorId,
|
||||
@NonNull BiometricLogger logger, @NonNull BiometricContext biometricContext,
|
||||
Map<Integer, Long> authenticatorIds) {
|
||||
return new TestRemovalClient(context, lazyDaemon, token, null,
|
||||
new int[]{biometricId}, userId, owner, utils, sensorId, logger,
|
||||
biometricContext, authenticatorIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onAddUnknownTemplate(int userId,
|
||||
@NonNull BiometricAuthenticator.Identifier identifier) {
|
||||
mFingerprints.add((Fingerprint) identifier);
|
||||
}
|
||||
|
||||
public List<Fingerprint> getFingerprints() {
|
||||
return mFingerprints;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -164,10 +164,9 @@ public class FingerprintInternalCleanupClientTest {
|
||||
}
|
||||
|
||||
protected FingerprintInternalCleanupClient createClient() {
|
||||
final List<Fingerprint> enrollments = new ArrayList<>();
|
||||
final Map<Integer, Long> authenticatorIds = new HashMap<>();
|
||||
return new FingerprintInternalCleanupClient(mContext, () -> mAidlSession, 2 /* userId */,
|
||||
"the.test.owner", SENSOR_ID, mLogger, mBiometricContext, enrollments,
|
||||
"the.test.owner", SENSOR_ID, mLogger, mBiometricContext,
|
||||
mFingerprintUtils, authenticatorIds) {
|
||||
@Override
|
||||
protected void onAddUnknownTemplate(int userId,
|
||||
|
||||
Reference in New Issue
Block a user