summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Kevin Chyn <kchyn@google.com> 2021-01-14 16:59:57 -0800
committer Kevin Chyn <kchyn@google.com> 2021-01-15 11:24:13 -0800
commit6034d30ea27d4c40bda32a20642dc936f897514a (patch)
tree58e32a5196d8bdf3e298a3aad51f6de4fc586254
parentb9bb08eb83ea577c23fb9a53511d49e162fed42e (diff)
8/n: Schedule invalidation request
This should happen 1) Upon successful enrollment, and 2) After session creation, if the framework detects a previous invalidation has not completed for some reason. Note that invalidation only needs to be requested if the (sensor, user) pair has enrollments. Also fixes the case where no sensors require invalidation. Test: atest com.android.server.biometrics Test: atest CtsBiometricsTestCases, existing tests pass. Additional tests will be added in a subsequent CL. Bug: 159667191 Change-Id: Id14391370904df004380428f1a064224489e2898
-rw-r--r--services/core/java/com/android/server/biometrics/AuthSession.java4
-rw-r--r--services/core/java/com/android/server/biometrics/BiometricSensor.java13
-rw-r--r--services/core/java/com/android/server/biometrics/BiometricService.java29
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/InvalidationRequesterClient.java2
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java17
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/face/aidl/TestSession.java9
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java17
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/TestSession.java6
-rw-r--r--services/tests/servicestests/src/com/android/server/biometrics/InvalidationTrackerTest.java9
9 files changed, 87 insertions, 19 deletions
diff --git a/services/core/java/com/android/server/biometrics/AuthSession.java b/services/core/java/com/android/server/biometrics/AuthSession.java
index e4d90525fc68..52152ab78992 100644
--- a/services/core/java/com/android/server/biometrics/AuthSession.java
+++ b/services/core/java/com/android/server/biometrics/AuthSession.java
@@ -805,7 +805,7 @@ public final class AuthSession implements IBinder.DeathRecipient {
@Override
public String toString() {
return "State: " + mState
- + "\nisCrypto: " + isCrypto()
- + "\nPreAuthInfo: " + mPreAuthInfo;
+ + ", isCrypto: " + isCrypto()
+ + ", PreAuthInfo: " + mPreAuthInfo;
}
}
diff --git a/services/core/java/com/android/server/biometrics/BiometricSensor.java b/services/core/java/com/android/server/biometrics/BiometricSensor.java
index 17ec11233c4e..85de81bb3491 100644
--- a/services/core/java/com/android/server/biometrics/BiometricSensor.java
+++ b/services/core/java/com/android/server/biometrics/BiometricSensor.java
@@ -169,12 +169,11 @@ public abstract class BiometricSensor {
@Override
public String toString() {
return "ID(" + id + ")"
- + "\n oemStrength: " + oemStrength
- + "\n updatedStrength: " + mUpdatedStrength
- + "\n modality " + modality
- + "\n state: " + mSensorState
- + "\n cookie: " + mCookie
- + "\n authenticator: " + impl
- + "\n";
+ + ", oemStrength: " + oemStrength
+ + ", updatedStrength: " + mUpdatedStrength
+ + ", modality " + modality
+ + ", state: " + mSensorState
+ + ", cookie: " + mCookie
+ + ", authenticator: " + impl;
}
}
diff --git a/services/core/java/com/android/server/biometrics/BiometricService.java b/services/core/java/com/android/server/biometrics/BiometricService.java
index fd5ada0ff9be..3387049d69f3 100644
--- a/services/core/java/com/android/server/biometrics/BiometricService.java
+++ b/services/core/java/com/android/server/biometrics/BiometricService.java
@@ -252,12 +252,14 @@ public class BiometricService extends SystemService {
@NonNull private final IInvalidationCallback mClientCallback;
@NonNull private final Set<Integer> mSensorsPendingInvalidation;
- public static InvalidationTracker start(@NonNull ArrayList<BiometricSensor> sensors,
+ public static InvalidationTracker start(@NonNull Context context,
+ @NonNull ArrayList<BiometricSensor> sensors,
int userId, int fromSensorId, @NonNull IInvalidationCallback clientCallback) {
- return new InvalidationTracker(sensors, userId, fromSensorId, clientCallback);
+ return new InvalidationTracker(context, sensors, userId, fromSensorId, clientCallback);
}
- private InvalidationTracker(@NonNull ArrayList<BiometricSensor> sensors, int userId,
+ private InvalidationTracker(@NonNull Context context,
+ @NonNull ArrayList<BiometricSensor> sensors, int userId,
int fromSensorId, @NonNull IInvalidationCallback clientCallback) {
mClientCallback = clientCallback;
mSensorsPendingInvalidation = new ArraySet<>();
@@ -271,6 +273,14 @@ public class BiometricService extends SystemService {
continue;
}
+ try {
+ if (!sensor.impl.hasEnrolledTemplates(userId, context.getOpPackageName())) {
+ continue;
+ }
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Remote Exception", e);
+ }
+
Slog.d(TAG, "Requesting authenticatorId invalidation for sensor: " + sensor.id);
synchronized (this) {
@@ -288,6 +298,17 @@ public class BiometricService extends SystemService {
Slog.d(TAG, "RemoteException", e);
}
}
+
+ synchronized (this) {
+ if (mSensorsPendingInvalidation.isEmpty()) {
+ try {
+ Slog.d(TAG, "No sensors require invalidation");
+ mClientCallback.onCompleted();
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Remote Exception", e);
+ }
+ }
+ }
}
@VisibleForTesting
@@ -742,7 +763,7 @@ public class BiometricService extends SystemService {
IInvalidationCallback callback) {
checkInternalPermission();
- InvalidationTracker.start(mSensors, userId, fromSensorId, callback);
+ InvalidationTracker.start(getContext(), mSensors, userId, fromSensorId, callback);
}
@Override // Binder call
diff --git a/services/core/java/com/android/server/biometrics/sensors/InvalidationRequesterClient.java b/services/core/java/com/android/server/biometrics/sensors/InvalidationRequesterClient.java
index 3c8caf7b4a7f..c97003b875ed 100644
--- a/services/core/java/com/android/server/biometrics/sensors/InvalidationRequesterClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/InvalidationRequesterClient.java
@@ -55,7 +55,7 @@ import android.hardware.biometrics.IInvalidationCallback;
* switches, the framework can check if any sensor has the "invalidationInProgress" flag set. If so,
* the framework should re-start the invalidation process described above.
*/
-public abstract class InvalidationRequesterClient<S extends BiometricAuthenticator.Identifier>
+public class InvalidationRequesterClient<S extends BiometricAuthenticator.Identifier>
extends BaseClientMonitor {
private final BiometricManager mBiometricManager;
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java
index eac2f0dc1641..810489b1c740 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceProvider.java
@@ -47,6 +47,7 @@ import com.android.server.biometrics.sensors.AuthenticationClient;
import com.android.server.biometrics.sensors.BaseClientMonitor;
import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
import com.android.server.biometrics.sensors.HalClientMonitor;
+import com.android.server.biometrics.sensors.InvalidationRequesterClient;
import com.android.server.biometrics.sensors.LockoutResetDispatcher;
import com.android.server.biometrics.sensors.PerformanceTracker;
import com.android.server.biometrics.sensors.face.FaceUtils;
@@ -206,6 +207,12 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider {
// this method "withoutHandler" means it should only ever be invoked from the worker thread,
// so callers will never be blocked.
mSensors.get(sensorId).createNewSession(daemon, sensorId, userId);
+
+ if (FaceUtils.getInstance(sensorId).isInvalidationInProgress(mContext, userId)) {
+ Slog.w(getTag(), "Scheduling unfinished invalidation request for sensor: " + sensorId
+ + ", user: " + userId);
+ scheduleInvalidationRequest(sensorId, userId);
+ }
}
@@ -242,6 +249,15 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider {
});
}
+ private void scheduleInvalidationRequest(int sensorId, int userId) {
+ mHandler.post(() -> {
+ final InvalidationRequesterClient<Face> client =
+ new InvalidationRequesterClient<>(mContext, userId, sensorId,
+ FaceUtils.getInstance(sensorId));
+ mSensors.get(sensorId).getScheduler().scheduleClientMonitor(client);
+ });
+ }
+
@Override
public boolean containsSensor(int sensorId) {
return mSensors.contains(sensorId);
@@ -395,6 +411,7 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider {
boolean success) {
if (success) {
scheduleLoadAuthenticatorIdsForUser(sensorId, userId);
+ scheduleInvalidationRequest(sensorId, userId);
}
}
});
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/TestSession.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/TestSession.java
index fbc26c6498b3..50483d93f92b 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/TestSession.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/TestSession.java
@@ -24,12 +24,13 @@ import android.hardware.common.NativeHandle;
import android.hardware.keymaster.HardwareAuthToken;
import android.os.Binder;
import android.os.IBinder;
+import android.util.Slog;
/**
* Test session that provides mostly no-ops.
*/
public class TestSession extends ISession.Stub {
- private static final String TAG = "TestSession";
+ private static final String TAG = "FaceTestSession";
@NonNull
private final Sensor.HalSessionCallback mHalSessionCallback;
@@ -86,12 +87,16 @@ public class TestSession extends ISession.Stub {
@Override
public void getAuthenticatorId(int cookie) {
+ Slog.d(TAG, "getAuthenticatorId");
+ // Immediately return a value so the framework can continue with subsequent requests.
mHalSessionCallback.onAuthenticatorIdRetrieved(0);
}
@Override
public void invalidateAuthenticatorId(int cookie) {
-
+ Slog.d(TAG, "invalidateAuthenticatorId");
+ // Immediately return a value so the framework can continue with subsequent requests.
+ mHalSessionCallback.onAuthenticatorIdInvalidated(0);
}
@Override
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java
index f1dfb52b6930..8a666f9acb7f 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java
@@ -47,6 +47,7 @@ import com.android.server.biometrics.sensors.AuthenticationClient;
import com.android.server.biometrics.sensors.BaseClientMonitor;
import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
import com.android.server.biometrics.sensors.HalClientMonitor;
+import com.android.server.biometrics.sensors.InvalidationRequesterClient;
import com.android.server.biometrics.sensors.LockoutResetDispatcher;
import com.android.server.biometrics.sensors.PerformanceTracker;
import com.android.server.biometrics.sensors.fingerprint.FingerprintUtils;
@@ -212,6 +213,12 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi
// this method "withoutHandler" means it should only ever be invoked from the worker thread,
// so callers will never be blocked.
mSensors.get(sensorId).createNewSession(daemon, sensorId, userId);
+
+ if (FingerprintUtils.getInstance(sensorId).isInvalidationInProgress(mContext, userId)) {
+ Slog.w(getTag(), "Scheduling unfinished invalidation request for sensor: " + sensorId
+ + ", user: " + userId);
+ scheduleInvalidationRequest(sensorId, userId);
+ }
}
@Override
@@ -268,6 +275,15 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi
});
}
+ private void scheduleInvalidationRequest(int sensorId, int userId) {
+ mHandler.post(() -> {
+ final InvalidationRequesterClient<Fingerprint> client =
+ new InvalidationRequesterClient<>(mContext, userId, sensorId,
+ FingerprintUtils.getInstance(sensorId));
+ mSensors.get(sensorId).getScheduler().scheduleClientMonitor(client);
+ });
+ }
+
@Override
public void scheduleResetLockout(int sensorId, int userId, @Nullable byte[] hardwareAuthToken) {
mHandler.post(() -> {
@@ -378,6 +394,7 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi
boolean success) {
if (success) {
scheduleLoadAuthenticatorIdsForUser(sensorId, userId);
+ scheduleInvalidationRequest(sensorId, userId);
}
}
});
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/TestSession.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/TestSession.java
index ddae1107ff77..ac4f6651613d 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/TestSession.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/TestSession.java
@@ -30,7 +30,7 @@ import android.util.Slog;
*/
class TestSession extends ISession.Stub {
- private static final String TAG = "TestSession";
+ private static final String TAG = "FingerprintTestSession";
@NonNull private final Sensor.HalSessionCallback mHalSessionCallback;
@@ -92,7 +92,9 @@ class TestSession extends ISession.Stub {
@Override
public void invalidateAuthenticatorId(int cookie) {
-
+ Slog.d(TAG, "invalidateAuthenticatorId");
+ // Immediately return a value so the framework can continue with subsequent requests.
+ mHalSessionCallback.onAuthenticatorIdInvalidated(0);
}
@Override
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/InvalidationTrackerTest.java b/services/tests/servicestests/src/com/android/server/biometrics/InvalidationTrackerTest.java
index 340a1d9bdda0..bb2b1c2fb0db 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/InvalidationTrackerTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/InvalidationTrackerTest.java
@@ -22,7 +22,9 @@ import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import android.content.Context;
import android.hardware.biometrics.BiometricAuthenticator;
import android.hardware.biometrics.BiometricManager.Authenticators;
import android.hardware.biometrics.IBiometricAuthenticator;
@@ -44,21 +46,25 @@ public class InvalidationTrackerTest {
@Test
public void testCallbackReceived_whenAllStrongSensorsInvalidated() throws Exception {
final IBiometricAuthenticator authenticator1 = mock(IBiometricAuthenticator.class);
+ when(authenticator1.hasEnrolledTemplates(anyInt(), any())).thenReturn(true);
final TestSensor sensor1 = new TestSensor(0 /* id */,
BiometricAuthenticator.TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG,
authenticator1);
final IBiometricAuthenticator authenticator2 = mock(IBiometricAuthenticator.class);
+ when(authenticator2.hasEnrolledTemplates(anyInt(), any())).thenReturn(true);
final TestSensor sensor2 = new TestSensor(1 /* id */,
BiometricAuthenticator.TYPE_FINGERPRINT, Authenticators.BIOMETRIC_STRONG,
authenticator2);
final IBiometricAuthenticator authenticator3 = mock(IBiometricAuthenticator.class);
+ when(authenticator3.hasEnrolledTemplates(anyInt(), any())).thenReturn(true);
final TestSensor sensor3 = new TestSensor(2 /* id */,
BiometricAuthenticator.TYPE_FACE, Authenticators.BIOMETRIC_STRONG,
authenticator3);
final IBiometricAuthenticator authenticator4 = mock(IBiometricAuthenticator.class);
+ when(authenticator4.hasEnrolledTemplates(anyInt(), any())).thenReturn(true);
final TestSensor sensor4 = new TestSensor(3 /* id */,
BiometricAuthenticator.TYPE_FACE, Authenticators.BIOMETRIC_WEAK,
authenticator4);
@@ -71,7 +77,8 @@ public class InvalidationTrackerTest {
final IInvalidationCallback callback = mock(IInvalidationCallback.class);
final InvalidationTracker tracker =
- InvalidationTracker.start(sensors, 0 /* userId */, 0 /* fromSensorId */, callback);
+ InvalidationTracker.start(mock(Context.class), sensors, 0 /* userId */,
+ 0 /* fromSensorId */, callback);
// The sensor which the request originated from should not be requested to invalidate
// its authenticatorId.