9/n: Add BiometricScheduler proto dump
1) Adds biometrics.proto definition for BaseClientMonitor subtypes 2) Adds BiometricScheduler proto dump When dumping the scheduler, the caller may request for the recent operation queue to be cleared after dumping or not. Note that we don't need BiometricScheduler.Operation#STATE_* in the dump, since (for now) we just want to know what operations have been run. We can always add additional state, success/failure, etc in the future if needed. Bug: 159667191 Test: atest com.android.server.biometrics Test: atest CtsBiometricsTestCases Change-Id: I7d2350f00aaeef03ab7d74013b476af053240320
This commit is contained in:
@@ -38,7 +38,7 @@ interface IBiometricAuthenticator {
|
||||
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
|
||||
|
||||
@@ -35,7 +35,7 @@ interface IFaceService {
|
||||
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);
|
||||
|
||||
@@ -36,7 +36,7 @@ interface IFingerprintService {
|
||||
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);
|
||||
|
||||
@@ -120,8 +120,8 @@ message SensorStateProto {
|
||||
|
||||
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 @@ message UserStateProto {
|
||||
|
||||
// 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;
|
||||
}
|
||||
@@ -37,7 +37,6 @@ import android.hardware.biometrics.IBiometricSysuiReceiver;
|
||||
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 @@ public final class AuthSession implements IBinder.DeathRecipient {
|
||||
private static final String TAG = "BiometricService/AuthSession";
|
||||
private static final boolean DEBUG = false;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Defined in biometrics.proto
|
||||
*/
|
||||
|
||||
@@ -815,12 +815,16 @@ public class BiometricService extends SystemService {
|
||||
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();
|
||||
|
||||
@@ -33,6 +33,7 @@ import android.security.KeyStore;
|
||||
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 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T>
|
||||
mActivityTaskManager.unregisterTaskStackListener(mTaskStackListener);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getProtoEnum() {
|
||||
return BiometricsProto.CM_AUTHENTICATE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,8 @@ import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Slog;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
/**
|
||||
@@ -79,6 +81,12 @@ public abstract class BaseClientMonitor extends LoggableMonitor
|
||||
|
||||
@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
|
||||
@@ -195,10 +203,16 @@ public abstract class BaseClientMonitor extends LoggableMonitor
|
||||
return mSensorId;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public Callback getCallback() {
|
||||
return mCallback;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "{[" + mSequentialId + "] "
|
||||
+ this.getClass().getSimpleName()
|
||||
+ ", " + getProtoEnum()
|
||||
+ ", " + getOwnerString()
|
||||
+ ", " + getCookie() + "}";
|
||||
}
|
||||
|
||||
@@ -28,8 +28,11 @@ import android.os.Looper;
|
||||
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 @@ import java.util.Locale;
|
||||
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 @@ public class BiometricScheduler {
|
||||
@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 @@ public class BiometricScheduler {
|
||||
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 @@ public class BiometricScheduler {
|
||||
@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 class BiometricScheduler {
|
||||
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 class BiometricScheduler {
|
||||
}
|
||||
}
|
||||
|
||||
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.
|
||||
|
||||
@@ -24,6 +24,8 @@ import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Slog;
|
||||
|
||||
import com.android.server.biometrics.BiometricsProto;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
@@ -106,4 +108,9 @@ public abstract class EnrollClient<T> extends AcquisitionClient<T> {
|
||||
false /* enrollSuccessful */);
|
||||
super.onError(error, vendorCode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getProtoEnum() {
|
||||
return BiometricsProto.CM_ENROLL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,8 @@ import android.os.IBinder;
|
||||
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 @@ public abstract class GenerateChallengeClient<T> extends HalClientMonitor<T> {
|
||||
|
||||
startHalOperation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getProtoEnum() {
|
||||
return BiometricsProto.CM_GENERATE_CHALLENGE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import android.os.IBinder;
|
||||
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 @@ public abstract class InternalCleanupClient<S extends BiometricAuthenticator.Ide
|
||||
}
|
||||
((EnumerateConsumer) mCurrentTask).onEnumerationResult(identifier, remaining);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getProtoEnum() {
|
||||
return BiometricsProto.CM_INTERNAL_CLEANUP;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import android.os.IBinder;
|
||||
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 abstract class InternalEnumerateClient<T> extends HalClientMonitor<T>
|
||||
public List<BiometricAuthenticator.Identifier> getUnknownHALTemplates() {
|
||||
return mUnknownHALTemplates;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getProtoEnum() {
|
||||
return BiometricsProto.CM_ENUMERATE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,8 @@ import android.hardware.biometrics.IInvalidationCallback;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Slog;
|
||||
|
||||
import com.android.server.biometrics.BiometricsProto;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
@@ -70,4 +72,9 @@ public abstract class InvalidationClient<S extends BiometricAuthenticator.Identi
|
||||
public void unableToStart() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getProtoEnum() {
|
||||
return BiometricsProto.CM_INVALIDATE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,8 @@ import android.hardware.biometrics.BiometricManager;
|
||||
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 @@ public class InvalidationRequesterClient<S extends BiometricAuthenticator.Identi
|
||||
mBiometricManager.invalidateAuthenticatorIds(getTargetUserId(), getSensorId(),
|
||||
mInvalidationCallback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getProtoEnum() {
|
||||
return BiometricsProto.CM_INVALIDATION_REQUESTER;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,8 @@ import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Slog;
|
||||
|
||||
import com.android.server.biometrics.BiometricsProto;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
@@ -90,4 +92,9 @@ public abstract class RemovalClient<S extends BiometricAuthenticator.Identifier,
|
||||
mCallback.onClientFinished(this, true /* success */);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getProtoEnum() {
|
||||
return BiometricsProto.CM_REMOVE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,8 @@ import android.content.Context;
|
||||
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 @@ public abstract class RevokeChallengeClient<T> extends HalClientMonitor<T> {
|
||||
startHalOperation();
|
||||
mCallback.onClientFinished(this, true /* success */);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getProtoEnum() {
|
||||
return BiometricsProto.CM_REVOKE_CHALLENGE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,8 +52,8 @@ public final class FaceAuthenticator extends IBiometricAuthenticator.Stub {
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] dumpSensorServiceStateProto() throws RemoteException {
|
||||
return mFaceService.dumpSensorServiceStateProto(mSensorId);
|
||||
public byte[] dumpSensorServiceStateProto(boolean clearSchedulerBuffer) throws RemoteException {
|
||||
return mFaceService.dumpSensorServiceStateProto(mSensorId, clearSchedulerBuffer);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -147,13 +147,13 @@ public class FaceService extends SystemService implements BiometricServiceCallba
|
||||
}
|
||||
|
||||
@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 @@ public class FaceService extends SystemService implements BiometricServiceCallba
|
||||
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();
|
||||
|
||||
@@ -121,7 +121,8 @@ public interface ServiceProvider {
|
||||
|
||||
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);
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ import android.hardware.biometrics.face.ISession;
|
||||
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 @@ class FaceGetAuthenticatorIdClient extends HalClientMonitor<ISession> {
|
||||
mAuthenticatorIds.put(getTargetUserId(), authenticatorId);
|
||||
mCallback.onClientFinished(this, true /* success */);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getProtoEnum() {
|
||||
return BiometricsProto.CM_GET_AUTHENTICATOR_ID;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -571,9 +571,10 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider {
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ import android.hardware.keymaster.HardwareAuthToken;
|
||||
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 @@ public class FaceResetLockoutClient extends HalClientMonitor<ISession> {
|
||||
mLockoutResetDispatcher.notifyLockoutResetCallbacks(getSensorId());
|
||||
mCallback.onClientFinished(this, true /* success */);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getProtoEnum() {
|
||||
return BiometricsProto.CM_RESET_LOCKOUT;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -486,12 +486,13 @@ public class Sensor implements IBinder.DeathRecipient {
|
||||
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();
|
||||
|
||||
@@ -767,12 +767,13 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider {
|
||||
}
|
||||
|
||||
@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();
|
||||
|
||||
@@ -27,6 +27,7 @@ import android.os.IBinder;
|
||||
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 @@ public class FaceGetFeatureClient extends HalClientMonitor<IBiometricsFace> {
|
||||
boolean getValue() {
|
||||
return mValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getProtoEnum() {
|
||||
return BiometricsProto.CM_GET_FEATURE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import android.hardware.biometrics.face.V1_0.IBiometricsFace;
|
||||
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 @@ public class FaceResetLockoutClient extends HalClientMonitor<IBiometricsFace> {
|
||||
mCallback.onClientFinished(this, false /* success */);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getProtoEnum() {
|
||||
return BiometricsProto.CM_RESET_LOCKOUT;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ import android.os.IBinder;
|
||||
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 @@ public class FaceSetFeatureClient extends HalClientMonitor<IBiometricsFace> {
|
||||
mCallback.onClientFinished(this, false /* success */);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getProtoEnum() {
|
||||
return BiometricsProto.CM_SET_FEATURE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import android.os.Environment;
|
||||
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 @@ public class FaceUpdateActiveUserClient extends HalClientMonitor<IBiometricsFace
|
||||
mCallback.onClientFinished(this, false /* success */);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getProtoEnum() {
|
||||
return BiometricsProto.CM_UPDATE_ACTIVE_USER;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,8 +53,8 @@ public final class FingerprintAuthenticator extends IBiometricAuthenticator.Stub
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] dumpSensorServiceStateProto() throws RemoteException {
|
||||
return mFingerprintService.dumpSensorServiceStateProto(mSensorId);
|
||||
public byte[] dumpSensorServiceStateProto(boolean clearSchedulerBuffer) throws RemoteException {
|
||||
return mFingerprintService.dumpSensorServiceStateProto(mSensorId, clearSchedulerBuffer);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -116,13 +116,13 @@ public class FingerprintService extends SystemService implements BiometricServic
|
||||
}
|
||||
|
||||
@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 @@ public class FingerprintService extends SystemService implements BiometricServic
|
||||
for (ServiceProvider provider : mServiceProviders) {
|
||||
for (FingerprintSensorPropertiesInternal props
|
||||
: provider.getSensorProperties()) {
|
||||
provider.dumpProtoState(props.sensorId, proto);
|
||||
provider.dumpProtoState(props.sensorId, proto, false);
|
||||
}
|
||||
}
|
||||
proto.flush();
|
||||
|
||||
@@ -128,7 +128,8 @@ public interface ServiceProvider {
|
||||
|
||||
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);
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ import android.os.IBinder;
|
||||
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 @@ class FingerprintDetectClient extends AcquisitionClient<ISession> {
|
||||
mCallback.onClientFinished(this, false /* success */);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getProtoEnum() {
|
||||
return BiometricsProto.CM_DETECT_INTERACTION;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import android.hardware.biometrics.fingerprint.ISession;
|
||||
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 @@ class FingerprintGetAuthenticatorIdClient extends HalClientMonitor<ISession> {
|
||||
mAuthenticatorIds.put(getTargetUserId(), authenticatorId);
|
||||
mCallback.onClientFinished(this, true /* success */);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getProtoEnum() {
|
||||
return BiometricsProto.CM_GET_AUTHENTICATOR_ID;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -627,9 +627,10 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ import android.hardware.keymaster.HardwareAuthToken;
|
||||
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 @@ class FingerprintResetLockoutClient extends HalClientMonitor<ISession> {
|
||||
mLockoutResetDispatcher.notifyLockoutResetCallbacks(getSensorId());
|
||||
mCallback.onClientFinished(this, true /* success */);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getProtoEnum() {
|
||||
return BiometricsProto.CM_RESET_LOCKOUT;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -481,12 +481,13 @@ class Sensor implements IBinder.DeathRecipient {
|
||||
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();
|
||||
|
||||
@@ -714,12 +714,13 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider
|
||||
}
|
||||
|
||||
@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();
|
||||
|
||||
@@ -28,6 +28,7 @@ import android.os.IBinder;
|
||||
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 @@ class FingerprintDetectClient extends AcquisitionClient<IBiometricsFingerprint>
|
||||
Slog.e(TAG, "Remote exception when sending onDetected", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getProtoEnum() {
|
||||
return BiometricsProto.CM_DETECT_INTERACTION;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ import android.os.RemoteException;
|
||||
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 @@ public class FingerprintUpdateActiveUserClient extends HalClientMonitor<IBiometr
|
||||
mCallback.onClientFinished(this, false /* success */);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getProtoEnum() {
|
||||
return BiometricsProto.CM_UPDATE_ACTIVE_USER;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ public final class IrisAuthenticator extends IBiometricAuthenticator.Stub {
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] dumpSensorServiceStateProto() throws RemoteException {
|
||||
public byte[] dumpSensorServiceStateProto(boolean clearSchedulerBuffer) throws RemoteException {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -34,11 +34,14 @@ import android.hardware.biometrics.IBiometricService;
|
||||
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 @@ 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 BiometricScheduler mScheduler;
|
||||
private IBinder mToken;
|
||||
@@ -66,7 +70,7 @@ public class BiometricSchedulerTest {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mToken = new Binder();
|
||||
mScheduler = new BiometricScheduler(TAG, null /* gestureAvailabilityTracker */,
|
||||
mBiometricService);
|
||||
mBiometricService, LOG_NUM_RECENT_OPERATIONS);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -186,6 +190,88 @@ public class BiometricSchedulerTest {
|
||||
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 @@ public class BiometricSchedulerTest {
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
@@ -229,6 +330,13 @@ public class BiometricSchedulerTest {
|
||||
mUnableToStart = true;
|
||||
}
|
||||
|
||||
@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);
|
||||
|
||||
Reference in New Issue
Block a user