Merge "9/n: Add BiometricScheduler proto dump"
diff --git a/core/java/android/hardware/biometrics/IBiometricAuthenticator.aidl b/core/java/android/hardware/biometrics/IBiometricAuthenticator.aidl
index fcdf61e..c854ac98 100644
--- a/core/java/android/hardware/biometrics/IBiometricAuthenticator.aidl
+++ b/core/java/android/hardware/biometrics/IBiometricAuthenticator.aidl
@@ -38,7 +38,7 @@
SensorPropertiesInternal getSensorProperties(String opPackageName);
// Requests a proto dump of the sensor. See biometrics.proto
- byte[] dumpSensorServiceStateProto();
+ byte[] dumpSensorServiceStateProto(boolean clearSchedulerBuffer);
// This method prepares the service to start authenticating, but doesn't start authentication.
// This is protected by the MANAGE_BIOMETRIC signature permission. This method should only be
diff --git a/core/java/android/hardware/face/IFaceService.aidl b/core/java/android/hardware/face/IFaceService.aidl
index 3b19f12..1b188e8 100644
--- a/core/java/android/hardware/face/IFaceService.aidl
+++ b/core/java/android/hardware/face/IFaceService.aidl
@@ -35,7 +35,7 @@
ITestSession createTestSession(int sensorId, String opPackageName);
// Requests a proto dump of the specified sensor
- byte[] dumpSensorServiceStateProto(int sensorId);
+ byte[] dumpSensorServiceStateProto(int sensorId, boolean clearSchedulerBuffer);
// Retrieve static sensor properties for all face sensors
List<FaceSensorPropertiesInternal> getSensorPropertiesInternal(String opPackageName);
diff --git a/core/java/android/hardware/fingerprint/IFingerprintService.aidl b/core/java/android/hardware/fingerprint/IFingerprintService.aidl
index 74c5b58..3657a83 100644
--- a/core/java/android/hardware/fingerprint/IFingerprintService.aidl
+++ b/core/java/android/hardware/fingerprint/IFingerprintService.aidl
@@ -36,7 +36,7 @@
ITestSession createTestSession(int sensorId, String opPackageName);
// Requests a proto dump of the specified sensor
- byte[] dumpSensorServiceStateProto(int sensorId);
+ byte[] dumpSensorServiceStateProto(int sensorId, boolean clearSchedulerBuffer);
// Retrieve static sensor properties for all fingerprint sensors
List<FingerprintSensorPropertiesInternal> getSensorPropertiesInternal(String opPackageName);
diff --git a/core/proto/android/server/biometrics.proto b/core/proto/android/server/biometrics.proto
index 14b5c52..900235e 100644
--- a/core/proto/android/server/biometrics.proto
+++ b/core/proto/android/server/biometrics.proto
@@ -120,8 +120,8 @@
optional Modality modality = 2;
- // State of the sensor's scheduler. True if currently handling an operation, false if idle.
- optional bool is_busy = 3;
+ // State of the sensor's scheduler.
+ optional BiometricSchedulerProto scheduler = 3;
// User states for this sensor.
repeated UserStateProto user_states = 4;
@@ -136,4 +136,39 @@
// Number of fingerprints enrolled
optional int32 num_enrolled = 2;
+}
+
+// BiometricScheduler dump
+message BiometricSchedulerProto {
+ option (.android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ // Operation currently being handled by the BiometricScheduler
+ optional ClientMonitorEnum current_operation = 1;
+
+ // Total number of operations that have been handled, not including the current one if one
+ // exists. Kept in FIFO order (most recent at the end of the array)
+ optional int32 total_operations = 2;
+
+ // A list of recent past operations in the order which they were handled
+ repeated ClientMonitorEnum recent_operations = 3;
+}
+
+// BaseClientMonitor subtypes
+enum ClientMonitorEnum {
+ CM_NONE = 0;
+ CM_UPDATE_ACTIVE_USER = 1;
+ CM_ENROLL = 2;
+ CM_AUTHENTICATE = 3;
+ CM_REMOVE = 4;
+ CM_GET_AUTHENTICATOR_ID = 5;
+ CM_ENUMERATE = 6;
+ CM_INTERNAL_CLEANUP = 7;
+ CM_SET_FEATURE = 8;
+ CM_GET_FEATURE = 9;
+ CM_GENERATE_CHALLENGE = 10;
+ CM_REVOKE_CHALLENGE = 11;
+ CM_RESET_LOCKOUT = 12;
+ CM_DETECT_INTERACTION = 13;
+ CM_INVALIDATION_REQUESTER = 14;
+ CM_INVALIDATE = 15;
}
\ No newline at end of file
diff --git a/services/core/java/com/android/server/biometrics/AuthSession.java b/services/core/java/com/android/server/biometrics/AuthSession.java
index 52152ab..14292d9c 100644
--- a/services/core/java/com/android/server/biometrics/AuthSession.java
+++ b/services/core/java/com/android/server/biometrics/AuthSession.java
@@ -37,7 +37,6 @@
import android.hardware.biometrics.PromptInfo;
import android.hardware.face.FaceManager;
import android.hardware.fingerprint.FingerprintManager;
-import android.hardware.fingerprint.FingerprintSensorProperties;
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
import android.os.IBinder;
import android.os.RemoteException;
@@ -62,8 +61,6 @@
private static final String TAG = "BiometricService/AuthSession";
private static final boolean DEBUG = false;
-
-
/*
* Defined in biometrics.proto
*/
diff --git a/services/core/java/com/android/server/biometrics/BiometricService.java b/services/core/java/com/android/server/biometrics/BiometricService.java
index 3387049..614c5f1 100644
--- a/services/core/java/com/android/server/biometrics/BiometricService.java
+++ b/services/core/java/com/android/server/biometrics/BiometricService.java
@@ -815,12 +815,16 @@
final long ident = Binder.clearCallingIdentity();
try {
if (args.length > 0 && "--proto".equals(args[0])) {
+ final boolean clearSchedulerBuffer = args.length > 1
+ && "--clear-scheduler-buffer".equals(args[1]);
+ Slog.d(TAG, "ClearSchedulerBuffer: " + clearSchedulerBuffer);
final ProtoOutputStream proto = new ProtoOutputStream(fd);
proto.write(BiometricServiceStateProto.AUTH_SESSION_STATE,
mCurrentAuthSession != null ? mCurrentAuthSession.getState()
: STATE_AUTH_IDLE);
for (BiometricSensor sensor : mSensors) {
- byte[] serviceState = sensor.impl.dumpSensorServiceStateProto();
+ byte[] serviceState = sensor.impl
+ .dumpSensorServiceStateProto(clearSchedulerBuffer);
proto.write(BiometricServiceStateProto.SENSOR_SERVICE_STATES, serviceState);
}
proto.flush();
diff --git a/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java b/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java
index 5663495..3f6ae64 100644
--- a/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/AuthenticationClient.java
@@ -33,6 +33,7 @@
import android.util.EventLog;
import android.util.Slog;
+import com.android.server.biometrics.BiometricsProto;
import com.android.server.biometrics.Utils;
import java.util.ArrayList;
@@ -298,4 +299,9 @@
mActivityTaskManager.unregisterTaskStackListener(mTaskStackListener);
}
}
+
+ @Override
+ public int getProtoEnum() {
+ return BiometricsProto.CM_AUTHENTICATE;
+ }
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/BaseClientMonitor.java b/services/core/java/com/android/server/biometrics/sensors/BaseClientMonitor.java
index f3c37ef..8fa3bbb 100644
--- a/services/core/java/com/android/server/biometrics/sensors/BaseClientMonitor.java
+++ b/services/core/java/com/android/server/biometrics/sensors/BaseClientMonitor.java
@@ -24,6 +24,8 @@
import android.os.RemoteException;
import android.util.Slog;
+import com.android.internal.annotations.VisibleForTesting;
+
import java.util.NoSuchElementException;
/**
@@ -80,6 +82,12 @@
@NonNull protected Callback mCallback;
/**
+ * Returns a ClientMonitorEnum constant defined in biometrics.proto
+ * @return
+ */
+ public abstract int getProtoEnum();
+
+ /**
* @param context system_server context
* @param token a unique token for the client
* @param listener recipient of related events (e.g. authentication)
@@ -195,10 +203,16 @@
return mSensorId;
}
+ @VisibleForTesting
+ public Callback getCallback() {
+ return mCallback;
+ }
+
@Override
public String toString() {
return "{[" + mSequentialId + "] "
+ this.getClass().getSimpleName()
+ + ", " + getProtoEnum()
+ ", " + getOwnerString()
+ ", " + getCookie() + "}";
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java b/services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java
index aa7faf5..c86bfcb 100644
--- a/services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java
+++ b/services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java
@@ -28,8 +28,11 @@
import android.os.RemoteException;
import android.os.ServiceManager;
import android.util.Slog;
+import android.util.proto.ProtoOutputStream;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.biometrics.BiometricSchedulerProto;
+import com.android.server.biometrics.BiometricsProto;
import com.android.server.biometrics.sensors.fingerprint.GestureAvailabilityDispatcher;
import java.io.PrintWriter;
@@ -51,6 +54,8 @@
public class BiometricScheduler {
private static final String BASE_TAG = "BiometricScheduler";
+ // Number of recent operations to keep in our logs for dumpsys
+ private static final int LOG_NUM_RECENT_OPERATIONS = 50;
/**
* Contains all the necessary information for a HAL operation.
@@ -200,6 +205,10 @@
@VisibleForTesting @Nullable Operation mCurrentOperation;
@NonNull private final ArrayDeque<CrashState> mCrashStates;
+ private int mTotalOperationsHandled;
+ private final int mRecentOperationsLimit;
+ @NonNull private final List<Integer> mRecentOperations;
+
// Internal callback, notified when an operation is complete. Notifies the requester
// that the operation is complete, before performing internal scheduler work (such as
// starting the next client).
@@ -240,7 +249,12 @@
mCurrentOperation.mClientMonitor.getSensorId(), false /* active */);
}
+ if (mRecentOperations.size() >= mRecentOperationsLimit) {
+ mRecentOperations.remove(0);
+ }
+ mRecentOperations.add(mCurrentOperation.mClientMonitor.getProtoEnum());
mCurrentOperation = null;
+ mTotalOperationsHandled++;
startNextOperationIfIdle();
});
}
@@ -249,13 +263,15 @@
@VisibleForTesting
BiometricScheduler(@NonNull String tag,
@Nullable GestureAvailabilityDispatcher gestureAvailabilityDispatcher,
- @NonNull IBiometricService biometricService) {
+ @NonNull IBiometricService biometricService, int recentOperationsLimit) {
mBiometricTag = tag;
mInternalCallback = new InternalCallback();
mGestureAvailabilityDispatcher = gestureAvailabilityDispatcher;
mPendingOperations = new ArrayDeque<>();
mBiometricService = biometricService;
mCrashStates = new ArrayDeque<>();
+ mRecentOperationsLimit = recentOperationsLimit;
+ mRecentOperations = new ArrayList<>();
}
/**
@@ -267,7 +283,7 @@
public BiometricScheduler(@NonNull String tag,
@Nullable GestureAvailabilityDispatcher gestureAvailabilityDispatcher) {
this(tag, gestureAvailabilityDispatcher, IBiometricService.Stub.asInterface(
- ServiceManager.getService(Context.BIOMETRIC_SERVICE)));
+ ServiceManager.getService(Context.BIOMETRIC_SERVICE)), LOG_NUM_RECENT_OPERATIONS);
}
/**
@@ -602,6 +618,24 @@
}
}
+ public byte[] dumpProtoState(boolean clearSchedulerBuffer) {
+ final ProtoOutputStream proto = new ProtoOutputStream();
+ proto.write(BiometricSchedulerProto.CURRENT_OPERATION, mCurrentOperation != null
+ ? mCurrentOperation.mClientMonitor.getProtoEnum() : BiometricsProto.CM_NONE);
+ proto.write(BiometricSchedulerProto.TOTAL_OPERATIONS, mTotalOperationsHandled);
+ Slog.d(getTag(), "Total operations: " + mTotalOperationsHandled);
+ for (int i = 0; i < mRecentOperations.size(); i++) {
+ Slog.d(getTag(), "Operation: " + mRecentOperations.get(i));
+ proto.write(BiometricSchedulerProto.RECENT_OPERATIONS, mRecentOperations.get(i));
+ }
+ proto.flush();
+
+ if (clearSchedulerBuffer) {
+ mRecentOperations.clear();
+ }
+ return proto.getBytes();
+ }
+
/**
* Clears the scheduler of anything work-related. This should be used for example when the
* HAL dies.
diff --git a/services/core/java/com/android/server/biometrics/sensors/EnrollClient.java b/services/core/java/com/android/server/biometrics/sensors/EnrollClient.java
index 8bf9680..8d81016 100644
--- a/services/core/java/com/android/server/biometrics/sensors/EnrollClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/EnrollClient.java
@@ -24,6 +24,8 @@
import android.os.RemoteException;
import android.util.Slog;
+import com.android.server.biometrics.BiometricsProto;
+
import java.util.Arrays;
/**
@@ -106,4 +108,9 @@
false /* enrollSuccessful */);
super.onError(error, vendorCode);
}
+
+ @Override
+ public int getProtoEnum() {
+ return BiometricsProto.CM_ENROLL;
+ }
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/GenerateChallengeClient.java b/services/core/java/com/android/server/biometrics/sensors/GenerateChallengeClient.java
index 6a622c3..741946e 100644
--- a/services/core/java/com/android/server/biometrics/sensors/GenerateChallengeClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/GenerateChallengeClient.java
@@ -23,6 +23,8 @@
import android.os.RemoteException;
import android.util.Slog;
+import com.android.server.biometrics.BiometricsProto;
+
public abstract class GenerateChallengeClient<T> extends HalClientMonitor<T> {
private static final String TAG = "GenerateChallengeClient";
@@ -50,4 +52,9 @@
startHalOperation();
}
+
+ @Override
+ public int getProtoEnum() {
+ return BiometricsProto.CM_GENERATE_CHALLENGE;
+ }
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/InternalCleanupClient.java b/services/core/java/com/android/server/biometrics/sensors/InternalCleanupClient.java
index 8529e81..ce24e5e 100644
--- a/services/core/java/com/android/server/biometrics/sensors/InternalCleanupClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/InternalCleanupClient.java
@@ -24,6 +24,7 @@
import android.util.Slog;
import com.android.internal.util.FrameworkStatsLog;
+import com.android.server.biometrics.BiometricsProto;
import java.util.ArrayList;
import java.util.List;
@@ -166,4 +167,9 @@
}
((EnumerateConsumer) mCurrentTask).onEnumerationResult(identifier, remaining);
}
+
+ @Override
+ public int getProtoEnum() {
+ return BiometricsProto.CM_INTERNAL_CLEANUP;
+ }
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/InternalEnumerateClient.java b/services/core/java/com/android/server/biometrics/sensors/InternalEnumerateClient.java
index 2693f2f..9d19fdf 100644
--- a/services/core/java/com/android/server/biometrics/sensors/InternalEnumerateClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/InternalEnumerateClient.java
@@ -24,6 +24,7 @@
import android.util.Slog;
import com.android.internal.util.FrameworkStatsLog;
+import com.android.server.biometrics.BiometricsProto;
import java.util.ArrayList;
import java.util.List;
@@ -123,4 +124,9 @@
public List<BiometricAuthenticator.Identifier> getUnknownHALTemplates() {
return mUnknownHALTemplates;
}
+
+ @Override
+ public int getProtoEnum() {
+ return BiometricsProto.CM_ENUMERATE;
+ }
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/InvalidationClient.java b/services/core/java/com/android/server/biometrics/sensors/InvalidationClient.java
index 630e5ea..cede4a7 100644
--- a/services/core/java/com/android/server/biometrics/sensors/InvalidationClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/InvalidationClient.java
@@ -24,6 +24,8 @@
import android.os.RemoteException;
import android.util.Slog;
+import com.android.server.biometrics.BiometricsProto;
+
import java.util.Map;
/**
@@ -70,4 +72,9 @@
public void unableToStart() {
}
+
+ @Override
+ public int getProtoEnum() {
+ return BiometricsProto.CM_INVALIDATE;
+ }
}
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 c97003b..5ba1b00 100644
--- a/services/core/java/com/android/server/biometrics/sensors/InvalidationRequesterClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/InvalidationRequesterClient.java
@@ -23,6 +23,8 @@
import android.hardware.biometrics.BiometricsProtoEnums;
import android.hardware.biometrics.IInvalidationCallback;
+import com.android.server.biometrics.BiometricsProto;
+
/**
* ClientMonitor subclass responsible for coordination of authenticatorId invalidation of other
* sensors. See {@link InvalidationClient} for the ClientMonitor subclass responsible for initiating
@@ -89,4 +91,9 @@
mBiometricManager.invalidateAuthenticatorIds(getTargetUserId(), getSensorId(),
mInvalidationCallback);
}
+
+ @Override
+ public int getProtoEnum() {
+ return BiometricsProto.CM_INVALIDATION_REQUESTER;
+ }
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/RemovalClient.java b/services/core/java/com/android/server/biometrics/sensors/RemovalClient.java
index 4ea48fd..e062695 100644
--- a/services/core/java/com/android/server/biometrics/sensors/RemovalClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/RemovalClient.java
@@ -25,6 +25,8 @@
import android.os.RemoteException;
import android.util.Slog;
+import com.android.server.biometrics.BiometricsProto;
+
import java.util.Map;
/**
@@ -90,4 +92,9 @@
mCallback.onClientFinished(this, true /* success */);
}
}
+
+ @Override
+ public int getProtoEnum() {
+ return BiometricsProto.CM_REMOVE;
+ }
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/RevokeChallengeClient.java b/services/core/java/com/android/server/biometrics/sensors/RevokeChallengeClient.java
index 187193d..90fa1b4 100644
--- a/services/core/java/com/android/server/biometrics/sensors/RevokeChallengeClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/RevokeChallengeClient.java
@@ -21,6 +21,8 @@
import android.hardware.biometrics.BiometricsProtoEnums;
import android.os.IBinder;
+import com.android.server.biometrics.BiometricsProto;
+
public abstract class RevokeChallengeClient<T> extends HalClientMonitor<T> {
public RevokeChallengeClient(@NonNull Context context, @NonNull LazyDaemon<T> lazyDaemon,
@@ -42,4 +44,9 @@
startHalOperation();
mCallback.onClientFinished(this, true /* success */);
}
+
+ @Override
+ public int getProtoEnum() {
+ return BiometricsProto.CM_REVOKE_CHALLENGE;
+ }
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/FaceAuthenticator.java b/services/core/java/com/android/server/biometrics/sensors/face/FaceAuthenticator.java
index 54ab2e5..f37cf18 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/FaceAuthenticator.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/FaceAuthenticator.java
@@ -52,8 +52,8 @@
}
@Override
- public byte[] dumpSensorServiceStateProto() throws RemoteException {
- return mFaceService.dumpSensorServiceStateProto(mSensorId);
+ public byte[] dumpSensorServiceStateProto(boolean clearSchedulerBuffer) throws RemoteException {
+ return mFaceService.dumpSensorServiceStateProto(mSensorId, clearSchedulerBuffer);
}
@Override
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java b/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java
index f055d55..1a63dde 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java
@@ -147,13 +147,13 @@
}
@Override
- public byte[] dumpSensorServiceStateProto(int sensorId) {
+ public byte[] dumpSensorServiceStateProto(int sensorId, boolean clearSchedulerBuffer) {
Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
final ProtoOutputStream proto = new ProtoOutputStream();
final ServiceProvider provider = getProviderForSensor(sensorId);
if (provider != null) {
- provider.dumpProtoState(sensorId, proto);
+ provider.dumpProtoState(sensorId, proto, clearSchedulerBuffer);
}
proto.flush();
return proto.getBytes();
@@ -405,7 +405,7 @@
final ProtoOutputStream proto = new ProtoOutputStream(fd);
for (ServiceProvider provider : mServiceProviders) {
for (FaceSensorPropertiesInternal props : provider.getSensorProperties()) {
- provider.dumpProtoState(props.sensorId, proto);
+ provider.dumpProtoState(props.sensorId, proto, false);
}
}
proto.flush();
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/ServiceProvider.java b/services/core/java/com/android/server/biometrics/sensors/face/ServiceProvider.java
index 51b427d..32428ac1 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/ServiceProvider.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/ServiceProvider.java
@@ -121,7 +121,8 @@
void scheduleInternalCleanup(int sensorId, int userId);
- void dumpProtoState(int sensorId, @NonNull ProtoOutputStream proto);
+ void dumpProtoState(int sensorId, @NonNull ProtoOutputStream proto,
+ boolean clearSchedulerBuffer);
void dumpProtoMetrics(int sensorId, @NonNull FileDescriptor fd);
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceGetAuthenticatorIdClient.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceGetAuthenticatorIdClient.java
index 5fb194c..773647b 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceGetAuthenticatorIdClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceGetAuthenticatorIdClient.java
@@ -23,6 +23,7 @@
import android.os.RemoteException;
import android.util.Slog;
+import com.android.server.biometrics.BiometricsProto;
import com.android.server.biometrics.sensors.HalClientMonitor;
import java.util.Map;
@@ -65,4 +66,9 @@
mAuthenticatorIds.put(getTargetUserId(), authenticatorId);
mCallback.onClientFinished(this, true /* success */);
}
+
+ @Override
+ public int getProtoEnum() {
+ return BiometricsProto.CM_GET_AUTHENTICATOR_ID;
+ }
}
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 810489b1c..20318e3 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
@@ -571,9 +571,10 @@
}
@Override
- public void dumpProtoState(int sensorId, @NonNull ProtoOutputStream proto) {
+ public void dumpProtoState(int sensorId, @NonNull ProtoOutputStream proto,
+ boolean clearSchedulerBuffer) {
if (mSensors.contains(sensorId)) {
- mSensors.get(sensorId).dumpProtoState(sensorId, proto);
+ mSensors.get(sensorId).dumpProtoState(sensorId, proto, clearSchedulerBuffer);
}
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceResetLockoutClient.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceResetLockoutClient.java
index f355158..71bac57 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceResetLockoutClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/FaceResetLockoutClient.java
@@ -25,6 +25,7 @@
import android.os.RemoteException;
import android.util.Slog;
+import com.android.server.biometrics.BiometricsProto;
import com.android.server.biometrics.HardwareAuthTokenUtils;
import com.android.server.biometrics.sensors.HalClientMonitor;
import com.android.server.biometrics.sensors.LockoutCache;
@@ -81,4 +82,9 @@
mLockoutResetDispatcher.notifyLockoutResetCallbacks(getSensorId());
mCallback.onClientFinished(this, true /* success */);
}
+
+ @Override
+ public int getProtoEnum() {
+ return BiometricsProto.CM_RESET_LOCKOUT;
+ }
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/Sensor.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/Sensor.java
index b28713e..9b00ba6 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/Sensor.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/Sensor.java
@@ -486,12 +486,13 @@
mTestHalEnabled = enabled;
}
- void dumpProtoState(int sensorId, @NonNull ProtoOutputStream proto) {
+ void dumpProtoState(int sensorId, @NonNull ProtoOutputStream proto,
+ boolean clearSchedulerBuffer) {
final long sensorToken = proto.start(SensorServiceStateProto.SENSOR_STATES);
proto.write(SensorStateProto.SENSOR_ID, mSensorProperties.sensorId);
proto.write(SensorStateProto.MODALITY, SensorStateProto.FACE);
- proto.write(SensorStateProto.IS_BUSY, mScheduler.getCurrentClient() != null);
+ proto.write(SensorStateProto.SCHEDULER, mScheduler.dumpProtoState(clearSchedulerBuffer));
for (UserInfo user : UserManager.get(mContext).getUsers()) {
final int userId = user.getUserHandle().getIdentifier();
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java b/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java
index 5e7ddeb..7010d96 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java
@@ -767,12 +767,13 @@
}
@Override
- public void dumpProtoState(int sensorId, ProtoOutputStream proto) {
+ public void dumpProtoState(int sensorId, ProtoOutputStream proto,
+ boolean clearSchedulerBuffer) {
final long sensorToken = proto.start(SensorServiceStateProto.SENSOR_STATES);
proto.write(SensorStateProto.SENSOR_ID, mSensorProperties.sensorId);
proto.write(SensorStateProto.MODALITY, SensorStateProto.FACE);
- proto.write(SensorStateProto.IS_BUSY, mScheduler.getCurrentClient() != null);
+ proto.write(SensorStateProto.SCHEDULER, mScheduler.dumpProtoState(clearSchedulerBuffer));
for (UserInfo user : UserManager.get(mContext).getUsers()) {
final int userId = user.getUserHandle().getIdentifier();
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceGetFeatureClient.java b/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceGetFeatureClient.java
index 442303b..722a3b8 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceGetFeatureClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceGetFeatureClient.java
@@ -27,6 +27,7 @@
import android.os.RemoteException;
import android.util.Slog;
+import com.android.server.biometrics.BiometricsProto;
import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
import com.android.server.biometrics.sensors.HalClientMonitor;
@@ -88,4 +89,9 @@
boolean getValue() {
return mValue;
}
+
+ @Override
+ public int getProtoEnum() {
+ return BiometricsProto.CM_GET_FEATURE;
+ }
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceResetLockoutClient.java b/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceResetLockoutClient.java
index e0548e0..14a4648 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceResetLockoutClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceResetLockoutClient.java
@@ -23,6 +23,7 @@
import android.os.RemoteException;
import android.util.Slog;
+import com.android.server.biometrics.BiometricsProto;
import com.android.server.biometrics.sensors.HalClientMonitor;
import java.util.ArrayList;
@@ -71,4 +72,9 @@
mCallback.onClientFinished(this, false /* success */);
}
}
+
+ @Override
+ public int getProtoEnum() {
+ return BiometricsProto.CM_RESET_LOCKOUT;
+ }
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceSetFeatureClient.java b/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceSetFeatureClient.java
index 4356043..6290e00 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceSetFeatureClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceSetFeatureClient.java
@@ -25,6 +25,7 @@
import android.os.RemoteException;
import android.util.Slog;
+import com.android.server.biometrics.BiometricsProto;
import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
import com.android.server.biometrics.sensors.HalClientMonitor;
@@ -88,4 +89,9 @@
mCallback.onClientFinished(this, false /* success */);
}
}
+
+ @Override
+ public int getProtoEnum() {
+ return BiometricsProto.CM_SET_FEATURE;
+ }
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceUpdateActiveUserClient.java b/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceUpdateActiveUserClient.java
index 0e72f94..70e2033 100644
--- a/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceUpdateActiveUserClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/face/hidl/FaceUpdateActiveUserClient.java
@@ -24,6 +24,7 @@
import android.os.RemoteException;
import android.util.Slog;
+import com.android.server.biometrics.BiometricsProto;
import com.android.server.biometrics.sensors.HalClientMonitor;
import java.io.File;
@@ -91,4 +92,9 @@
mCallback.onClientFinished(this, false /* success */);
}
}
+
+ @Override
+ public int getProtoEnum() {
+ return BiometricsProto.CM_UPDATE_ACTIVE_USER;
+ }
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintAuthenticator.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintAuthenticator.java
index 312a3ba..34a9099 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintAuthenticator.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintAuthenticator.java
@@ -53,8 +53,8 @@
}
@Override
- public byte[] dumpSensorServiceStateProto() throws RemoteException {
- return mFingerprintService.dumpSensorServiceStateProto(mSensorId);
+ public byte[] dumpSensorServiceStateProto(boolean clearSchedulerBuffer) throws RemoteException {
+ return mFingerprintService.dumpSensorServiceStateProto(mSensorId, clearSchedulerBuffer);
}
@Override
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
index d541eb3..0265cb9 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
@@ -116,13 +116,13 @@
}
@Override
- public byte[] dumpSensorServiceStateProto(int sensorId) {
+ public byte[] dumpSensorServiceStateProto(int sensorId, boolean clearSchedulerBuffer) {
Utils.checkPermission(getContext(), USE_BIOMETRIC_INTERNAL);
final ProtoOutputStream proto = new ProtoOutputStream();
final ServiceProvider provider = getProviderForSensor(sensorId);
if (provider != null) {
- provider.dumpProtoState(sensorId, proto);
+ provider.dumpProtoState(sensorId, proto, clearSchedulerBuffer);
}
proto.flush();
return proto.getBytes();
@@ -419,7 +419,7 @@
for (ServiceProvider provider : mServiceProviders) {
for (FingerprintSensorPropertiesInternal props
: provider.getSensorProperties()) {
- provider.dumpProtoState(props.sensorId, proto);
+ provider.dumpProtoState(props.sensorId, proto, false);
}
}
proto.flush();
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/ServiceProvider.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/ServiceProvider.java
index 272e2b2..d3b5b5a 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/ServiceProvider.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/ServiceProvider.java
@@ -128,7 +128,8 @@
void setUdfpsOverlayController(@NonNull IUdfpsOverlayController controller);
- void dumpProtoState(int sensorId, @NonNull ProtoOutputStream proto);
+ void dumpProtoState(int sensorId, @NonNull ProtoOutputStream proto,
+ boolean clearSchedulerBuffer);
void dumpProtoMetrics(int sensorId, @NonNull FileDescriptor fd);
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintDetectClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintDetectClient.java
index 3b376fe..b4bb4f8 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintDetectClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintDetectClient.java
@@ -27,6 +27,7 @@
import android.os.RemoteException;
import android.util.Slog;
+import com.android.server.biometrics.BiometricsProto;
import com.android.server.biometrics.sensors.AcquisitionClient;
import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
import com.android.server.biometrics.sensors.fingerprint.UdfpsHelper;
@@ -91,4 +92,9 @@
mCallback.onClientFinished(this, false /* success */);
}
}
+
+ @Override
+ public int getProtoEnum() {
+ return BiometricsProto.CM_DETECT_INTERACTION;
+ }
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintGetAuthenticatorIdClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintGetAuthenticatorIdClient.java
index 02d4ac3..ce1a318 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintGetAuthenticatorIdClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintGetAuthenticatorIdClient.java
@@ -23,6 +23,7 @@
import android.os.RemoteException;
import android.util.Slog;
+import com.android.server.biometrics.BiometricsProto;
import com.android.server.biometrics.sensors.HalClientMonitor;
import java.util.Map;
@@ -65,4 +66,9 @@
mAuthenticatorIds.put(getTargetUserId(), authenticatorId);
mCallback.onClientFinished(this, true /* success */);
}
+
+ @Override
+ public int getProtoEnum() {
+ return BiometricsProto.CM_GET_AUTHENTICATOR_ID;
+ }
}
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 8a666f9..727184f 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
@@ -627,9 +627,10 @@
}
@Override
- public void dumpProtoState(int sensorId, @NonNull ProtoOutputStream proto) {
+ public void dumpProtoState(int sensorId, @NonNull ProtoOutputStream proto,
+ boolean clearSchedulerBuffer) {
if (mSensors.contains(sensorId)) {
- mSensors.get(sensorId).dumpProtoState(sensorId, proto);
+ mSensors.get(sensorId).dumpProtoState(sensorId, proto, clearSchedulerBuffer);
}
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintResetLockoutClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintResetLockoutClient.java
index cd84cdf..ddcfcad 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintResetLockoutClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintResetLockoutClient.java
@@ -25,6 +25,7 @@
import android.os.RemoteException;
import android.util.Slog;
+import com.android.server.biometrics.BiometricsProto;
import com.android.server.biometrics.HardwareAuthTokenUtils;
import com.android.server.biometrics.sensors.HalClientMonitor;
import com.android.server.biometrics.sensors.LockoutCache;
@@ -76,4 +77,9 @@
mLockoutResetDispatcher.notifyLockoutResetCallbacks(getSensorId());
mCallback.onClientFinished(this, true /* success */);
}
+
+ @Override
+ public int getProtoEnum() {
+ return BiometricsProto.CM_RESET_LOCKOUT;
+ }
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/Sensor.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/Sensor.java
index 911f6b4..f0e7e1c 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/Sensor.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/Sensor.java
@@ -481,12 +481,13 @@
mTestHalEnabled = enabled;
}
- void dumpProtoState(int sensorId, @NonNull ProtoOutputStream proto) {
+ void dumpProtoState(int sensorId, @NonNull ProtoOutputStream proto,
+ boolean clearSchedulerBuffer) {
final long sensorToken = proto.start(SensorServiceStateProto.SENSOR_STATES);
proto.write(SensorStateProto.SENSOR_ID, mSensorProperties.sensorId);
proto.write(SensorStateProto.MODALITY, SensorStateProto.FINGERPRINT);
- proto.write(SensorStateProto.IS_BUSY, mScheduler.getCurrentClient() != null);
+ proto.write(SensorStateProto.SCHEDULER, mScheduler.dumpProtoState(clearSchedulerBuffer));
for (UserInfo user : UserManager.get(mContext).getUsers()) {
final int userId = user.getUserHandle().getIdentifier();
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java
index 6cc8687..acc575f 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java
@@ -714,12 +714,13 @@
}
@Override
- public void dumpProtoState(int sensorId, @NonNull ProtoOutputStream proto) {
+ public void dumpProtoState(int sensorId, @NonNull ProtoOutputStream proto,
+ boolean clearSchedulerBuffer) {
final long sensorToken = proto.start(SensorServiceStateProto.SENSOR_STATES);
proto.write(SensorStateProto.SENSOR_ID, mSensorProperties.sensorId);
proto.write(SensorStateProto.MODALITY, SensorStateProto.FINGERPRINT);
- proto.write(SensorStateProto.IS_BUSY, mScheduler.getCurrentClient() != null);
+ proto.write(SensorStateProto.SCHEDULER, mScheduler.dumpProtoState(clearSchedulerBuffer));
for (UserInfo user : UserManager.get(mContext).getUsers()) {
final int userId = user.getUserHandle().getIdentifier();
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintDetectClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintDetectClient.java
index 55995ea..6318139 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintDetectClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintDetectClient.java
@@ -28,6 +28,7 @@
import android.os.RemoteException;
import android.util.Slog;
+import com.android.server.biometrics.BiometricsProto;
import com.android.server.biometrics.sensors.AcquisitionClient;
import com.android.server.biometrics.sensors.AuthenticationConsumer;
import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
@@ -123,4 +124,9 @@
Slog.e(TAG, "Remote exception when sending onDetected", e);
}
}
+
+ @Override
+ public int getProtoEnum() {
+ return BiometricsProto.CM_DETECT_INTERACTION;
+ }
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintUpdateActiveUserClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintUpdateActiveUserClient.java
index f6ec4d9..11ffbb2 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintUpdateActiveUserClient.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/FingerprintUpdateActiveUserClient.java
@@ -26,6 +26,7 @@
import android.os.SELinux;
import android.util.Slog;
+import com.android.server.biometrics.BiometricsProto;
import com.android.server.biometrics.sensors.HalClientMonitor;
import java.io.File;
@@ -121,4 +122,9 @@
mCallback.onClientFinished(this, false /* success */);
}
}
+
+ @Override
+ public int getProtoEnum() {
+ return BiometricsProto.CM_UPDATE_ACTIVE_USER;
+ }
}
diff --git a/services/core/java/com/android/server/biometrics/sensors/iris/IrisAuthenticator.java b/services/core/java/com/android/server/biometrics/sensors/iris/IrisAuthenticator.java
index 3e5b88c..8e84613 100644
--- a/services/core/java/com/android/server/biometrics/sensors/iris/IrisAuthenticator.java
+++ b/services/core/java/com/android/server/biometrics/sensors/iris/IrisAuthenticator.java
@@ -50,7 +50,7 @@
}
@Override
- public byte[] dumpSensorServiceStateProto() throws RemoteException {
+ public byte[] dumpSensorServiceStateProto(boolean clearSchedulerBuffer) throws RemoteException {
return null;
}
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerTest.java
index cc4541b..832f918 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerTest.java
@@ -34,11 +34,14 @@
import android.os.Binder;
import android.os.IBinder;
import android.platform.test.annotations.Presubmit;
+import android.util.proto.ProtoOutputStream;
import androidx.annotation.NonNull;
import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
+import com.android.server.biometrics.nano.BiometricSchedulerProto;
+import com.android.server.biometrics.nano.BiometricsProto;
import com.android.server.biometrics.sensors.BiometricScheduler.Operation;
import org.junit.Before;
@@ -52,6 +55,7 @@
private static final String TAG = "BiometricSchedulerTest";
private static final int TEST_SENSOR_ID = 1;
+ private static final int LOG_NUM_RECENT_OPERATIONS = 2;
private BiometricScheduler mScheduler;
private IBinder mToken;
@@ -66,7 +70,7 @@
MockitoAnnotations.initMocks(this);
mToken = new Binder();
mScheduler = new BiometricScheduler(TAG, null /* gestureAvailabilityTracker */,
- mBiometricService);
+ mBiometricService, LOG_NUM_RECENT_OPERATIONS);
}
@Test
@@ -186,6 +190,88 @@
assertNull(mScheduler.mCurrentOperation);
}
+ @Test
+ public void testProtoDump_singleCurrentOperation() throws Exception {
+ // Nothing so far
+ BiometricSchedulerProto bsp = getDump(true /* clearSchedulerBuffer */);
+ assertEquals(BiometricsProto.CM_NONE, bsp.currentOperation);
+ assertEquals(0, bsp.totalOperations);
+ assertEquals(0, bsp.recentOperations.length);
+
+ // Pretend the scheduler is busy enrolling, and check the proto dump again.
+ final TestClientMonitor2 client = new TestClientMonitor2(mContext, mToken,
+ () -> mock(Object.class), BiometricsProto.CM_ENROLL);
+ mScheduler.scheduleClientMonitor(client);
+ waitForIdle();
+ bsp = getDump(true /* clearSchedulerBuffer */);
+ assertEquals(BiometricsProto.CM_ENROLL, bsp.currentOperation);
+ // No operations have completed yet
+ assertEquals(0, bsp.totalOperations);
+ assertEquals(0, bsp.recentOperations.length);
+ // Finish this operation, so the next scheduled one can start
+ client.getCallback().onClientFinished(client, true);
+ }
+
+ @Test
+ public void testProtoDump_fifo() throws Exception {
+ // Add the first operation
+ final TestClientMonitor2 client = new TestClientMonitor2(mContext, mToken,
+ () -> mock(Object.class), BiometricsProto.CM_ENROLL);
+ mScheduler.scheduleClientMonitor(client);
+ waitForIdle();
+ BiometricSchedulerProto bsp = getDump(false /* clearSchedulerBuffer */);
+ assertEquals(BiometricsProto.CM_ENROLL, bsp.currentOperation);
+ // No operations have completed yet
+ assertEquals(0, bsp.totalOperations);
+ assertEquals(0, bsp.recentOperations.length);
+ // Finish this operation, so the next scheduled one can start
+ client.getCallback().onClientFinished(client, true);
+
+ // Add another operation
+ final TestClientMonitor2 client2 = new TestClientMonitor2(mContext, mToken,
+ () -> mock(Object.class), BiometricsProto.CM_REMOVE);
+ mScheduler.scheduleClientMonitor(client2);
+ waitForIdle();
+ bsp = getDump(false /* clearSchedulerBuffer */);
+ assertEquals(BiometricsProto.CM_REMOVE, bsp.currentOperation);
+ assertEquals(1, bsp.totalOperations); // Enroll finished
+ assertEquals(1, bsp.recentOperations.length);
+ assertEquals(BiometricsProto.CM_ENROLL, bsp.recentOperations[0]);
+ client2.getCallback().onClientFinished(client2, true);
+
+ // And another operation
+ final TestClientMonitor2 client3 = new TestClientMonitor2(mContext, mToken,
+ () -> mock(Object.class), BiometricsProto.CM_AUTHENTICATE);
+ mScheduler.scheduleClientMonitor(client3);
+ waitForIdle();
+ bsp = getDump(false /* clearSchedulerBuffer */);
+ assertEquals(BiometricsProto.CM_AUTHENTICATE, bsp.currentOperation);
+ assertEquals(2, bsp.totalOperations);
+ assertEquals(2, bsp.recentOperations.length);
+ assertEquals(BiometricsProto.CM_ENROLL, bsp.recentOperations[0]);
+ assertEquals(BiometricsProto.CM_REMOVE, bsp.recentOperations[1]);
+
+ // Finish the last operation, and check that the first operation is removed from the FIFO.
+ // The test initializes the scheduler with "LOG_NUM_RECENT_OPERATIONS = 2" :)
+ client3.getCallback().onClientFinished(client3, true);
+ waitForIdle();
+ bsp = getDump(true /* clearSchedulerBuffer */);
+ assertEquals(3, bsp.totalOperations);
+ assertEquals(2, bsp.recentOperations.length);
+ assertEquals(BiometricsProto.CM_REMOVE, bsp.recentOperations[0]);
+ assertEquals(BiometricsProto.CM_AUTHENTICATE, bsp.recentOperations[1]);
+ // Nothing is currently running anymore
+ assertEquals(BiometricsProto.CM_NONE, bsp.currentOperation);
+
+ // RecentOperations queue is cleared (by the previous dump)
+ bsp = getDump(true /* clearSchedulerBuffer */);
+ assertEquals(0, bsp.recentOperations.length);
+ }
+
+ private BiometricSchedulerProto getDump(boolean clearSchedulerBuffer) throws Exception {
+ return BiometricSchedulerProto.parseFrom(mScheduler.dumpProtoState(clearSchedulerBuffer));
+ }
+
private static class BiometricPromptClientMonitor extends AuthenticationClient<Object> {
public BiometricPromptClientMonitor(@NonNull Context context, @NonNull IBinder token,
@@ -207,6 +293,21 @@
}
}
+ private static class TestClientMonitor2 extends TestClientMonitor {
+ private final int mProtoEnum;
+
+ public TestClientMonitor2(@NonNull Context context, @NonNull IBinder token,
+ @NonNull LazyDaemon<Object> lazyDaemon, int protoEnum) {
+ super(context, token, lazyDaemon);
+ mProtoEnum = protoEnum;
+ }
+
+ @Override
+ public int getProtoEnum() {
+ return mProtoEnum;
+ }
+ }
+
private static class TestClientMonitor extends HalClientMonitor<Object> {
private boolean mUnableToStart;
private boolean mStarted;
@@ -230,6 +331,13 @@
}
@Override
+ public int getProtoEnum() {
+ // Anything other than CM_NONE, which is used to represent "idle". Tests that need
+ // real proto enums should use TestClientMonitor2
+ return BiometricsProto.CM_UPDATE_ACTIVE_USER;
+ }
+
+ @Override
public void start(@NonNull Callback callback) {
super.start(callback);
assertFalse(mStarted);