Loading services/core/java/com/android/server/biometrics/Utils.java +2 −3 Original line number Diff line number Diff line Loading @@ -52,7 +52,6 @@ import android.hardware.biometrics.SensorProperties; import android.hardware.biometrics.SensorPropertiesInternal; import android.os.Binder; import android.os.Build; import android.os.Process; import android.os.RemoteException; import android.os.ServiceManager; import android.os.UserHandle; Loading @@ -62,7 +61,7 @@ import android.util.Slog; import com.android.internal.R; import com.android.internal.widget.LockPatternUtils; import com.android.server.biometrics.sensors.ClientMonitor; import com.android.server.biometrics.sensors.BaseClientMonitor; import java.util.List; Loading Loading @@ -409,7 +408,7 @@ public class Utils { return hasPermission && keyguardPackage != null && keyguardPackage.equals(clientPackage); } public static String getClientName(@Nullable ClientMonitor<?> client) { public static String getClientName(@Nullable BaseClientMonitor<?> client) { return client != null ? client.getClass().getSimpleName() : "null"; } Loading services/core/java/com/android/server/biometrics/sensors/AcquisitionClient.java +2 −2 Original line number Diff line number Diff line Loading @@ -29,10 +29,10 @@ import android.os.Vibrator; import android.util.Slog; /** * Abstract {@link ClientMonitor} subclass that operations eligible/interested in acquisition * Abstract {@link BaseClientMonitor} subclass that operations eligible/interested in acquisition * messages should extend. */ public abstract class AcquisitionClient<T> extends ClientMonitor<T> implements Interruptable { public abstract class AcquisitionClient<T> extends BaseClientMonitor<T> implements Interruptable { private static final String TAG = "Biometrics/AcquisitionClient"; Loading services/core/java/com/android/server/biometrics/sensors/ClientMonitor.java→services/core/java/com/android/server/biometrics/sensors/BaseClientMonitor.java +6 −4 Original line number Diff line number Diff line Loading @@ -31,7 +31,8 @@ import java.util.NoSuchElementException; * the current client. Subclasses are responsible for coordinating the interaction with * the biometric's HAL for the specific action (e.g. authenticate, enroll, enumerate, etc.). */ public abstract class ClientMonitor<T> extends LoggableMonitor implements IBinder.DeathRecipient { public abstract class BaseClientMonitor<T> extends LoggableMonitor implements IBinder.DeathRecipient { private static final String TAG = "Biometrics/ClientMonitor"; protected static final boolean DEBUG = true; Loading @@ -49,7 +50,7 @@ public abstract class ClientMonitor<T> extends LoggableMonitor implements IBinde * * @param clientMonitor Reference of the ClientMonitor that is starting. */ default void onClientStarted(@NonNull ClientMonitor<?> clientMonitor) {} default void onClientStarted(@NonNull BaseClientMonitor<?> clientMonitor) {} /** * Invoked when the ClientMonitor operation is complete. This abstracts away asynchronous Loading @@ -60,7 +61,8 @@ public abstract class ClientMonitor<T> extends LoggableMonitor implements IBinde * @param clientMonitor Reference of the ClientMonitor that finished. * @param success True if the operation completed successfully. */ default void onClientFinished(@NonNull ClientMonitor<?> clientMonitor, boolean success) {} default void onClientFinished(@NonNull BaseClientMonitor<?> clientMonitor, boolean success) {} } /** Loading Loading @@ -102,7 +104,7 @@ public abstract class ClientMonitor<T> extends LoggableMonitor implements IBinde * @param statsAction One of {@link BiometricsProtoEnums} ACTION_* constants * @param statsClient One of {@link BiometricsProtoEnums} CLIENT_* constants */ public ClientMonitor(@NonNull Context context, @NonNull LazyDaemon<T> lazyDaemon, public BaseClientMonitor(@NonNull Context context, @NonNull LazyDaemon<T> lazyDaemon, @Nullable IBinder token, @Nullable ClientMonitorCallbackConverter listener, int userId, @NonNull String owner, int cookie, int sensorId, int statsModality, int statsAction, int statsClient) { Loading services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java +66 −65 Original line number Diff line number Diff line Loading @@ -44,8 +44,8 @@ import java.util.List; import java.util.Locale; /** * A scheduler for biometric HAL operations. Maintains a queue of {@link ClientMonitor} operations, * without caring about its implementation details. Operations may perform one or more * A scheduler for biometric HAL operations. Maintains a queue of {@link BaseClientMonitor} * operations, without caring about its implementation details. Operations may perform one or more * interactions with the HAL before finishing. */ public class BiometricScheduler { Loading Loading @@ -88,7 +88,7 @@ public class BiometricScheduler { static final int STATE_WAITING_FOR_COOKIE = 4; /** * The {@link ClientMonitor.Callback} has been invoked and the client is finished. * The {@link BaseClientMonitor.Callback} has been invoked and the client is finished. */ static final int STATE_FINISHED = 5; Loading @@ -101,20 +101,20 @@ public class BiometricScheduler { @Retention(RetentionPolicy.SOURCE) @interface OperationState {} @NonNull final ClientMonitor<?> clientMonitor; @Nullable final ClientMonitor.Callback mClientCallback; @OperationState int state; @NonNull final BaseClientMonitor<?> mClientMonitor; @Nullable final BaseClientMonitor.Callback mClientCallback; @OperationState int mState; Operation(@NonNull ClientMonitor<?> clientMonitor, @Nullable ClientMonitor.Callback callback) { this.clientMonitor = clientMonitor; Operation(@NonNull BaseClientMonitor<?> clientMonitor, @Nullable BaseClientMonitor.Callback callback) { this.mClientMonitor = clientMonitor; this.mClientCallback = callback; state = STATE_WAITING_IN_QUEUE; mState = STATE_WAITING_IN_QUEUE; } @Override public String toString() { return clientMonitor + ", State: " + state; return mClientMonitor + ", State: " + mState; } } Loading @@ -134,10 +134,10 @@ public class BiometricScheduler { @Override public void run() { if (operation.state != Operation.STATE_FINISHED) { if (operation.mState != Operation.STATE_FINISHED) { Slog.e(tag, "[Watchdog Triggered]: " + operation); operation.clientMonitor.mCallback .onClientFinished(operation.clientMonitor, false /* success */); operation.mClientMonitor.mCallback .onClientFinished(operation.mClientMonitor, false /* success */); } } } Loading Loading @@ -186,9 +186,9 @@ public class BiometricScheduler { // 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). public class InternalCallback implements ClientMonitor.Callback { public class InternalCallback implements BaseClientMonitor.Callback { @Override public void onClientStarted(@NonNull ClientMonitor<?> clientMonitor) { public void onClientStarted(@NonNull BaseClientMonitor<?> clientMonitor) { Slog.d(getTag(), "[Started] " + clientMonitor); if (mCurrentOperation.mClientCallback != null) { mCurrentOperation.mClientCallback.onClientStarted(clientMonitor); Loading @@ -196,7 +196,7 @@ public class BiometricScheduler { } @Override public void onClientFinished(@NonNull ClientMonitor<?> clientMonitor, boolean success) { public void onClientFinished(@NonNull BaseClientMonitor<?> clientMonitor, boolean success) { mHandler.post(() -> { if (mCurrentOperation == null) { Slog.e(getTag(), "[Finishing] " + clientMonitor Loading @@ -205,14 +205,14 @@ public class BiometricScheduler { return; } if (clientMonitor != mCurrentOperation.clientMonitor) { if (clientMonitor != mCurrentOperation.mClientMonitor) { Slog.e(getTag(), "[Ignoring Finish] " + clientMonitor + " does not match" + " current: " + mCurrentOperation.clientMonitor); + " current: " + mCurrentOperation.mClientMonitor); return; } Slog.d(getTag(), "[Finishing] " + clientMonitor + ", success: " + success); mCurrentOperation.state = Operation.STATE_FINISHED; mCurrentOperation.mState = Operation.STATE_FINISHED; if (mCurrentOperation.mClientCallback != null) { mCurrentOperation.mClientCallback.onClientFinished(clientMonitor, success); Loading @@ -220,7 +220,7 @@ public class BiometricScheduler { if (mGestureAvailabilityDispatcher != null) { mGestureAvailabilityDispatcher.markSensorActive( mCurrentOperation.clientMonitor.getSensorId(), false /* active */); mCurrentOperation.mClientMonitor.getSensorId(), false /* active */); } mCurrentOperation = null; Loading Loading @@ -276,11 +276,11 @@ public class BiometricScheduler { } mCurrentOperation = mPendingOperations.poll(); final ClientMonitor<?> currentClient = mCurrentOperation.clientMonitor; final BaseClientMonitor<?> currentClient = mCurrentOperation.mClientMonitor; // If the operation at the front of the queue has been marked for cancellation, send // ERROR_CANCELED. No need to start this client. if (mCurrentOperation.state == Operation.STATE_WAITING_IN_QUEUE_CANCELING) { if (mCurrentOperation.mState == Operation.STATE_WAITING_IN_QUEUE_CANCELING) { Slog.d(getTag(), "[Now Cancelling] " + mCurrentOperation); if (!(currentClient instanceof Interruptable)) { throw new IllegalStateException("Mis-implemented client or scheduler, " Loading @@ -295,9 +295,9 @@ public class BiometricScheduler { } if (mGestureAvailabilityDispatcher != null && mCurrentOperation.clientMonitor instanceof AcquisitionClient) { && mCurrentOperation.mClientMonitor instanceof AcquisitionClient) { mGestureAvailabilityDispatcher.markSensorActive( mCurrentOperation.clientMonitor.getSensorId(), mCurrentOperation.mClientMonitor.getSensorId(), true /* active */); } Loading @@ -305,7 +305,7 @@ public class BiometricScheduler { // to arrive at the head of the queue, before pinging it to start. final boolean shouldStartNow = currentClient.getCookie() == 0; if (shouldStartNow) { if (mCurrentOperation.clientMonitor.getFreshDaemon() == null) { if (mCurrentOperation.mClientMonitor.getFreshDaemon() == null) { // Note down current length of queue final int pendingOperationsLength = mPendingOperations.size(); final Operation lastOperation = mPendingOperations.peekLast(); Loading @@ -315,10 +315,10 @@ public class BiometricScheduler { // For current operations, 1) unableToStart, which notifies the caller-side, then // 2) notify operation's callback, to notify applicable system service that the // operation failed. mCurrentOperation.clientMonitor.unableToStart(); mCurrentOperation.mClientMonitor.unableToStart(); if (mCurrentOperation.mClientCallback != null) { mCurrentOperation.mClientCallback .onClientFinished(mCurrentOperation.clientMonitor, false /* success */); mCurrentOperation.mClientCallback.onClientFinished( mCurrentOperation.mClientMonitor, false /* success */); } // Then for each operation currently in the pending queue at the time of this Loading @@ -331,9 +331,9 @@ public class BiometricScheduler { + ", expected length: " + pendingOperationsLength); break; } operation.clientMonitor.unableToStart(); operation.mClientMonitor.unableToStart(); if (operation.mClientCallback != null) { operation.mClientCallback.onClientFinished(operation.clientMonitor, operation.mClientCallback.onClientFinished(operation.mClientMonitor, false /* success */); } Slog.w(getTag(), "[Aborted Operation] " + operation); Loading @@ -347,7 +347,7 @@ public class BiometricScheduler { } else { Slog.d(getTag(), "[Starting] " + mCurrentOperation); currentClient.start(getInternalCallback()); mCurrentOperation.state = Operation.STATE_STARTED; mCurrentOperation.mState = Operation.STATE_STARTED; } } else { try { Loading @@ -356,7 +356,7 @@ public class BiometricScheduler { Slog.e(getTag(), "Remote exception when contacting BiometricService", e); } Slog.d(getTag(), "Waiting for cookie before starting: " + mCurrentOperation); mCurrentOperation.state = Operation.STATE_WAITING_FOR_COOKIE; mCurrentOperation.mState = Operation.STATE_WAITING_FOR_COOKIE; } } Loading @@ -378,13 +378,14 @@ public class BiometricScheduler { Slog.e(getTag(), "Current operation is null"); return; } if (mCurrentOperation.state != Operation.STATE_WAITING_FOR_COOKIE) { if (mCurrentOperation.state == Operation.STATE_WAITING_IN_QUEUE_CANCELING) { if (mCurrentOperation.mState != Operation.STATE_WAITING_FOR_COOKIE) { if (mCurrentOperation.mState == Operation.STATE_WAITING_IN_QUEUE_CANCELING) { Slog.d(getTag(), "Operation was marked for cancellation, cancelling now: " + mCurrentOperation); // This should trigger the internal onClientFinished callback, which clears the // operation and starts the next one. final Interruptable interruptable = (Interruptable) mCurrentOperation.clientMonitor; final Interruptable interruptable = (Interruptable) mCurrentOperation.mClientMonitor; interruptable.onError(BiometricConstants.BIOMETRIC_ERROR_CANCELED, 0 /* vendorCode */); return; Loading @@ -394,55 +395,55 @@ public class BiometricScheduler { return; } } if (mCurrentOperation.clientMonitor.getCookie() != cookie) { if (mCurrentOperation.mClientMonitor.getCookie() != cookie) { Slog.e(getTag(), "Mismatched cookie for operation: " + mCurrentOperation + ", received: " + cookie); return; } if (mCurrentOperation.clientMonitor.getFreshDaemon() == null) { if (mCurrentOperation.mClientMonitor.getFreshDaemon() == null) { Slog.e(getTag(), "[Unable To Start] Prepared client: " + mCurrentOperation); // This is BiometricPrompt trying to auth but something's wrong with the HAL. mCurrentOperation.clientMonitor.unableToStart(); mCurrentOperation.mClientMonitor.unableToStart(); if (mCurrentOperation.mClientCallback != null) { mCurrentOperation.mClientCallback.onClientFinished(mCurrentOperation.clientMonitor, mCurrentOperation.mClientCallback.onClientFinished(mCurrentOperation.mClientMonitor, false /* success */); } mCurrentOperation = null; startNextOperationIfIdle(); } else { Slog.d(getTag(), "[Starting] Prepared client: " + mCurrentOperation); mCurrentOperation.state = Operation.STATE_STARTED; mCurrentOperation.clientMonitor.start(getInternalCallback()); mCurrentOperation.mState = Operation.STATE_STARTED; mCurrentOperation.mClientMonitor.start(getInternalCallback()); } } /** * Adds a {@link ClientMonitor} to the pending queue * Adds a {@link BaseClientMonitor} to the pending queue * * @param clientMonitor operation to be scheduled */ public void scheduleClientMonitor(@NonNull ClientMonitor<?> clientMonitor) { public void scheduleClientMonitor(@NonNull BaseClientMonitor<?> clientMonitor) { scheduleClientMonitor(clientMonitor, null /* clientFinishCallback */); } /** * Adds a {@link ClientMonitor} to the pending queue * Adds a {@link BaseClientMonitor} to the pending queue * * @param clientMonitor operation to be scheduled * @param clientCallback optional callback, invoked when the client is finished, but * before it has been removed from the queue. */ public void scheduleClientMonitor(@NonNull ClientMonitor<?> clientMonitor, @Nullable ClientMonitor.Callback clientCallback) { public void scheduleClientMonitor(@NonNull BaseClientMonitor<?> clientMonitor, @Nullable BaseClientMonitor.Callback clientCallback) { // Mark any interruptable pending clients as canceling. Once they reach the head of the // queue, the scheduler will send ERROR_CANCELED and skip the operation. for (Operation operation : mPendingOperations) { if (operation.clientMonitor instanceof Interruptable && operation.state != Operation.STATE_WAITING_IN_QUEUE_CANCELING) { if (operation.mClientMonitor instanceof Interruptable && operation.mState != Operation.STATE_WAITING_IN_QUEUE_CANCELING) { Slog.d(getTag(), "New client incoming, marking pending client as canceling: " + operation.clientMonitor); operation.state = Operation.STATE_WAITING_IN_QUEUE_CANCELING; + operation.mClientMonitor); operation.mState = Operation.STATE_WAITING_IN_QUEUE_CANCELING; } } Loading @@ -451,8 +452,8 @@ public class BiometricScheduler { + ", new queue size: " + mPendingOperations.size()); // If the current operation is cancellable, start the cancellation process. if (mCurrentOperation != null && mCurrentOperation.clientMonitor instanceof Interruptable && mCurrentOperation.state == Operation.STATE_STARTED) { if (mCurrentOperation != null && mCurrentOperation.mClientMonitor instanceof Interruptable && mCurrentOperation.mState == Operation.STATE_STARTED) { Slog.d(getTag(), "[Cancelling Interruptable]: " + mCurrentOperation); cancelInternal(mCurrentOperation); } Loading @@ -465,25 +466,25 @@ public class BiometricScheduler { Slog.e(getTag(), "cancelInternal invoked on non-current operation: " + operation); return; } if (!(operation.clientMonitor instanceof Interruptable)) { if (!(operation.mClientMonitor instanceof Interruptable)) { Slog.w(getTag(), "Operation not interruptable: " + operation); return; } if (operation.state == Operation.STATE_STARTED_CANCELING) { if (operation.mState == Operation.STATE_STARTED_CANCELING) { Slog.w(getTag(), "Cancel already invoked for operation: " + operation); return; } if (operation.state == Operation.STATE_WAITING_FOR_COOKIE) { if (operation.mState == Operation.STATE_WAITING_FOR_COOKIE) { Slog.w(getTag(), "Skipping cancellation for non-started operation: " + operation); // We can set it to null immediately, since the HAL was never notified to start. mCurrentOperation = null; startNextOperationIfIdle(); return; } Slog.d(getTag(), "[Cancelling] Current client: " + operation.clientMonitor); final Interruptable interruptable = (Interruptable) operation.clientMonitor; Slog.d(getTag(), "[Cancelling] Current client: " + operation.mClientMonitor); final Interruptable interruptable = (Interruptable) operation.mClientMonitor; interruptable.cancel(); operation.state = Operation.STATE_STARTED_CANCELING; operation.mState = Operation.STATE_STARTED_CANCELING; // Add a watchdog. If the HAL does not acknowledge within the timeout, we will // forcibly finish this client. Loading @@ -500,8 +501,8 @@ public class BiometricScheduler { Slog.e(getTag(), "Unable to cancel enrollment, null operation"); return; } final boolean isEnrolling = mCurrentOperation.clientMonitor instanceof EnrollClient; final boolean tokenMatches = mCurrentOperation.clientMonitor.getToken() == token; final boolean isEnrolling = mCurrentOperation.mClientMonitor instanceof EnrollClient; final boolean tokenMatches = mCurrentOperation.mClientMonitor.getToken() == token; if (!isEnrolling || !tokenMatches) { Slog.w(getTag(), "Not cancelling enrollment, isEnrolling: " + isEnrolling + " tokenMatches: " + tokenMatches); Loading @@ -521,8 +522,8 @@ public class BiometricScheduler { return; } final boolean isAuthenticating = mCurrentOperation.clientMonitor instanceof AuthenticationConsumer; final boolean tokenMatches = mCurrentOperation.clientMonitor.getToken() == token; mCurrentOperation.mClientMonitor instanceof AuthenticationConsumer; final boolean tokenMatches = mCurrentOperation.mClientMonitor.getToken() == token; if (!isAuthenticating || !tokenMatches) { Slog.w(getTag(), "Not cancelling authentication" + ", current operation : " + mCurrentOperation Loading @@ -536,11 +537,11 @@ public class BiometricScheduler { /** * @return the current operation */ public ClientMonitor<?> getCurrentClient() { public BaseClientMonitor<?> getCurrentClient() { if (mCurrentOperation == null) { return null; } return mCurrentOperation.clientMonitor; return mCurrentOperation.mClientMonitor; } public int getCurrentPendingCount() { Loading services/core/java/com/android/server/biometrics/sensors/EnumerateConsumer.java +2 −2 Original line number Diff line number Diff line Loading @@ -19,8 +19,8 @@ package com.android.server.biometrics.sensors; import android.hardware.biometrics.BiometricAuthenticator; /** * Interface that {@link ClientMonitor} subclasses eligible/interested in enumerate callbacks should * implement. * Interface that {@link BaseClientMonitor} subclasses eligible/interested in enumerate callbacks * should implement. */ public interface EnumerateConsumer { /** Loading Loading
services/core/java/com/android/server/biometrics/Utils.java +2 −3 Original line number Diff line number Diff line Loading @@ -52,7 +52,6 @@ import android.hardware.biometrics.SensorProperties; import android.hardware.biometrics.SensorPropertiesInternal; import android.os.Binder; import android.os.Build; import android.os.Process; import android.os.RemoteException; import android.os.ServiceManager; import android.os.UserHandle; Loading @@ -62,7 +61,7 @@ import android.util.Slog; import com.android.internal.R; import com.android.internal.widget.LockPatternUtils; import com.android.server.biometrics.sensors.ClientMonitor; import com.android.server.biometrics.sensors.BaseClientMonitor; import java.util.List; Loading Loading @@ -409,7 +408,7 @@ public class Utils { return hasPermission && keyguardPackage != null && keyguardPackage.equals(clientPackage); } public static String getClientName(@Nullable ClientMonitor<?> client) { public static String getClientName(@Nullable BaseClientMonitor<?> client) { return client != null ? client.getClass().getSimpleName() : "null"; } Loading
services/core/java/com/android/server/biometrics/sensors/AcquisitionClient.java +2 −2 Original line number Diff line number Diff line Loading @@ -29,10 +29,10 @@ import android.os.Vibrator; import android.util.Slog; /** * Abstract {@link ClientMonitor} subclass that operations eligible/interested in acquisition * Abstract {@link BaseClientMonitor} subclass that operations eligible/interested in acquisition * messages should extend. */ public abstract class AcquisitionClient<T> extends ClientMonitor<T> implements Interruptable { public abstract class AcquisitionClient<T> extends BaseClientMonitor<T> implements Interruptable { private static final String TAG = "Biometrics/AcquisitionClient"; Loading
services/core/java/com/android/server/biometrics/sensors/ClientMonitor.java→services/core/java/com/android/server/biometrics/sensors/BaseClientMonitor.java +6 −4 Original line number Diff line number Diff line Loading @@ -31,7 +31,8 @@ import java.util.NoSuchElementException; * the current client. Subclasses are responsible for coordinating the interaction with * the biometric's HAL for the specific action (e.g. authenticate, enroll, enumerate, etc.). */ public abstract class ClientMonitor<T> extends LoggableMonitor implements IBinder.DeathRecipient { public abstract class BaseClientMonitor<T> extends LoggableMonitor implements IBinder.DeathRecipient { private static final String TAG = "Biometrics/ClientMonitor"; protected static final boolean DEBUG = true; Loading @@ -49,7 +50,7 @@ public abstract class ClientMonitor<T> extends LoggableMonitor implements IBinde * * @param clientMonitor Reference of the ClientMonitor that is starting. */ default void onClientStarted(@NonNull ClientMonitor<?> clientMonitor) {} default void onClientStarted(@NonNull BaseClientMonitor<?> clientMonitor) {} /** * Invoked when the ClientMonitor operation is complete. This abstracts away asynchronous Loading @@ -60,7 +61,8 @@ public abstract class ClientMonitor<T> extends LoggableMonitor implements IBinde * @param clientMonitor Reference of the ClientMonitor that finished. * @param success True if the operation completed successfully. */ default void onClientFinished(@NonNull ClientMonitor<?> clientMonitor, boolean success) {} default void onClientFinished(@NonNull BaseClientMonitor<?> clientMonitor, boolean success) {} } /** Loading Loading @@ -102,7 +104,7 @@ public abstract class ClientMonitor<T> extends LoggableMonitor implements IBinde * @param statsAction One of {@link BiometricsProtoEnums} ACTION_* constants * @param statsClient One of {@link BiometricsProtoEnums} CLIENT_* constants */ public ClientMonitor(@NonNull Context context, @NonNull LazyDaemon<T> lazyDaemon, public BaseClientMonitor(@NonNull Context context, @NonNull LazyDaemon<T> lazyDaemon, @Nullable IBinder token, @Nullable ClientMonitorCallbackConverter listener, int userId, @NonNull String owner, int cookie, int sensorId, int statsModality, int statsAction, int statsClient) { Loading
services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java +66 −65 Original line number Diff line number Diff line Loading @@ -44,8 +44,8 @@ import java.util.List; import java.util.Locale; /** * A scheduler for biometric HAL operations. Maintains a queue of {@link ClientMonitor} operations, * without caring about its implementation details. Operations may perform one or more * A scheduler for biometric HAL operations. Maintains a queue of {@link BaseClientMonitor} * operations, without caring about its implementation details. Operations may perform one or more * interactions with the HAL before finishing. */ public class BiometricScheduler { Loading Loading @@ -88,7 +88,7 @@ public class BiometricScheduler { static final int STATE_WAITING_FOR_COOKIE = 4; /** * The {@link ClientMonitor.Callback} has been invoked and the client is finished. * The {@link BaseClientMonitor.Callback} has been invoked and the client is finished. */ static final int STATE_FINISHED = 5; Loading @@ -101,20 +101,20 @@ public class BiometricScheduler { @Retention(RetentionPolicy.SOURCE) @interface OperationState {} @NonNull final ClientMonitor<?> clientMonitor; @Nullable final ClientMonitor.Callback mClientCallback; @OperationState int state; @NonNull final BaseClientMonitor<?> mClientMonitor; @Nullable final BaseClientMonitor.Callback mClientCallback; @OperationState int mState; Operation(@NonNull ClientMonitor<?> clientMonitor, @Nullable ClientMonitor.Callback callback) { this.clientMonitor = clientMonitor; Operation(@NonNull BaseClientMonitor<?> clientMonitor, @Nullable BaseClientMonitor.Callback callback) { this.mClientMonitor = clientMonitor; this.mClientCallback = callback; state = STATE_WAITING_IN_QUEUE; mState = STATE_WAITING_IN_QUEUE; } @Override public String toString() { return clientMonitor + ", State: " + state; return mClientMonitor + ", State: " + mState; } } Loading @@ -134,10 +134,10 @@ public class BiometricScheduler { @Override public void run() { if (operation.state != Operation.STATE_FINISHED) { if (operation.mState != Operation.STATE_FINISHED) { Slog.e(tag, "[Watchdog Triggered]: " + operation); operation.clientMonitor.mCallback .onClientFinished(operation.clientMonitor, false /* success */); operation.mClientMonitor.mCallback .onClientFinished(operation.mClientMonitor, false /* success */); } } } Loading Loading @@ -186,9 +186,9 @@ public class BiometricScheduler { // 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). public class InternalCallback implements ClientMonitor.Callback { public class InternalCallback implements BaseClientMonitor.Callback { @Override public void onClientStarted(@NonNull ClientMonitor<?> clientMonitor) { public void onClientStarted(@NonNull BaseClientMonitor<?> clientMonitor) { Slog.d(getTag(), "[Started] " + clientMonitor); if (mCurrentOperation.mClientCallback != null) { mCurrentOperation.mClientCallback.onClientStarted(clientMonitor); Loading @@ -196,7 +196,7 @@ public class BiometricScheduler { } @Override public void onClientFinished(@NonNull ClientMonitor<?> clientMonitor, boolean success) { public void onClientFinished(@NonNull BaseClientMonitor<?> clientMonitor, boolean success) { mHandler.post(() -> { if (mCurrentOperation == null) { Slog.e(getTag(), "[Finishing] " + clientMonitor Loading @@ -205,14 +205,14 @@ public class BiometricScheduler { return; } if (clientMonitor != mCurrentOperation.clientMonitor) { if (clientMonitor != mCurrentOperation.mClientMonitor) { Slog.e(getTag(), "[Ignoring Finish] " + clientMonitor + " does not match" + " current: " + mCurrentOperation.clientMonitor); + " current: " + mCurrentOperation.mClientMonitor); return; } Slog.d(getTag(), "[Finishing] " + clientMonitor + ", success: " + success); mCurrentOperation.state = Operation.STATE_FINISHED; mCurrentOperation.mState = Operation.STATE_FINISHED; if (mCurrentOperation.mClientCallback != null) { mCurrentOperation.mClientCallback.onClientFinished(clientMonitor, success); Loading @@ -220,7 +220,7 @@ public class BiometricScheduler { if (mGestureAvailabilityDispatcher != null) { mGestureAvailabilityDispatcher.markSensorActive( mCurrentOperation.clientMonitor.getSensorId(), false /* active */); mCurrentOperation.mClientMonitor.getSensorId(), false /* active */); } mCurrentOperation = null; Loading Loading @@ -276,11 +276,11 @@ public class BiometricScheduler { } mCurrentOperation = mPendingOperations.poll(); final ClientMonitor<?> currentClient = mCurrentOperation.clientMonitor; final BaseClientMonitor<?> currentClient = mCurrentOperation.mClientMonitor; // If the operation at the front of the queue has been marked for cancellation, send // ERROR_CANCELED. No need to start this client. if (mCurrentOperation.state == Operation.STATE_WAITING_IN_QUEUE_CANCELING) { if (mCurrentOperation.mState == Operation.STATE_WAITING_IN_QUEUE_CANCELING) { Slog.d(getTag(), "[Now Cancelling] " + mCurrentOperation); if (!(currentClient instanceof Interruptable)) { throw new IllegalStateException("Mis-implemented client or scheduler, " Loading @@ -295,9 +295,9 @@ public class BiometricScheduler { } if (mGestureAvailabilityDispatcher != null && mCurrentOperation.clientMonitor instanceof AcquisitionClient) { && mCurrentOperation.mClientMonitor instanceof AcquisitionClient) { mGestureAvailabilityDispatcher.markSensorActive( mCurrentOperation.clientMonitor.getSensorId(), mCurrentOperation.mClientMonitor.getSensorId(), true /* active */); } Loading @@ -305,7 +305,7 @@ public class BiometricScheduler { // to arrive at the head of the queue, before pinging it to start. final boolean shouldStartNow = currentClient.getCookie() == 0; if (shouldStartNow) { if (mCurrentOperation.clientMonitor.getFreshDaemon() == null) { if (mCurrentOperation.mClientMonitor.getFreshDaemon() == null) { // Note down current length of queue final int pendingOperationsLength = mPendingOperations.size(); final Operation lastOperation = mPendingOperations.peekLast(); Loading @@ -315,10 +315,10 @@ public class BiometricScheduler { // For current operations, 1) unableToStart, which notifies the caller-side, then // 2) notify operation's callback, to notify applicable system service that the // operation failed. mCurrentOperation.clientMonitor.unableToStart(); mCurrentOperation.mClientMonitor.unableToStart(); if (mCurrentOperation.mClientCallback != null) { mCurrentOperation.mClientCallback .onClientFinished(mCurrentOperation.clientMonitor, false /* success */); mCurrentOperation.mClientCallback.onClientFinished( mCurrentOperation.mClientMonitor, false /* success */); } // Then for each operation currently in the pending queue at the time of this Loading @@ -331,9 +331,9 @@ public class BiometricScheduler { + ", expected length: " + pendingOperationsLength); break; } operation.clientMonitor.unableToStart(); operation.mClientMonitor.unableToStart(); if (operation.mClientCallback != null) { operation.mClientCallback.onClientFinished(operation.clientMonitor, operation.mClientCallback.onClientFinished(operation.mClientMonitor, false /* success */); } Slog.w(getTag(), "[Aborted Operation] " + operation); Loading @@ -347,7 +347,7 @@ public class BiometricScheduler { } else { Slog.d(getTag(), "[Starting] " + mCurrentOperation); currentClient.start(getInternalCallback()); mCurrentOperation.state = Operation.STATE_STARTED; mCurrentOperation.mState = Operation.STATE_STARTED; } } else { try { Loading @@ -356,7 +356,7 @@ public class BiometricScheduler { Slog.e(getTag(), "Remote exception when contacting BiometricService", e); } Slog.d(getTag(), "Waiting for cookie before starting: " + mCurrentOperation); mCurrentOperation.state = Operation.STATE_WAITING_FOR_COOKIE; mCurrentOperation.mState = Operation.STATE_WAITING_FOR_COOKIE; } } Loading @@ -378,13 +378,14 @@ public class BiometricScheduler { Slog.e(getTag(), "Current operation is null"); return; } if (mCurrentOperation.state != Operation.STATE_WAITING_FOR_COOKIE) { if (mCurrentOperation.state == Operation.STATE_WAITING_IN_QUEUE_CANCELING) { if (mCurrentOperation.mState != Operation.STATE_WAITING_FOR_COOKIE) { if (mCurrentOperation.mState == Operation.STATE_WAITING_IN_QUEUE_CANCELING) { Slog.d(getTag(), "Operation was marked for cancellation, cancelling now: " + mCurrentOperation); // This should trigger the internal onClientFinished callback, which clears the // operation and starts the next one. final Interruptable interruptable = (Interruptable) mCurrentOperation.clientMonitor; final Interruptable interruptable = (Interruptable) mCurrentOperation.mClientMonitor; interruptable.onError(BiometricConstants.BIOMETRIC_ERROR_CANCELED, 0 /* vendorCode */); return; Loading @@ -394,55 +395,55 @@ public class BiometricScheduler { return; } } if (mCurrentOperation.clientMonitor.getCookie() != cookie) { if (mCurrentOperation.mClientMonitor.getCookie() != cookie) { Slog.e(getTag(), "Mismatched cookie for operation: " + mCurrentOperation + ", received: " + cookie); return; } if (mCurrentOperation.clientMonitor.getFreshDaemon() == null) { if (mCurrentOperation.mClientMonitor.getFreshDaemon() == null) { Slog.e(getTag(), "[Unable To Start] Prepared client: " + mCurrentOperation); // This is BiometricPrompt trying to auth but something's wrong with the HAL. mCurrentOperation.clientMonitor.unableToStart(); mCurrentOperation.mClientMonitor.unableToStart(); if (mCurrentOperation.mClientCallback != null) { mCurrentOperation.mClientCallback.onClientFinished(mCurrentOperation.clientMonitor, mCurrentOperation.mClientCallback.onClientFinished(mCurrentOperation.mClientMonitor, false /* success */); } mCurrentOperation = null; startNextOperationIfIdle(); } else { Slog.d(getTag(), "[Starting] Prepared client: " + mCurrentOperation); mCurrentOperation.state = Operation.STATE_STARTED; mCurrentOperation.clientMonitor.start(getInternalCallback()); mCurrentOperation.mState = Operation.STATE_STARTED; mCurrentOperation.mClientMonitor.start(getInternalCallback()); } } /** * Adds a {@link ClientMonitor} to the pending queue * Adds a {@link BaseClientMonitor} to the pending queue * * @param clientMonitor operation to be scheduled */ public void scheduleClientMonitor(@NonNull ClientMonitor<?> clientMonitor) { public void scheduleClientMonitor(@NonNull BaseClientMonitor<?> clientMonitor) { scheduleClientMonitor(clientMonitor, null /* clientFinishCallback */); } /** * Adds a {@link ClientMonitor} to the pending queue * Adds a {@link BaseClientMonitor} to the pending queue * * @param clientMonitor operation to be scheduled * @param clientCallback optional callback, invoked when the client is finished, but * before it has been removed from the queue. */ public void scheduleClientMonitor(@NonNull ClientMonitor<?> clientMonitor, @Nullable ClientMonitor.Callback clientCallback) { public void scheduleClientMonitor(@NonNull BaseClientMonitor<?> clientMonitor, @Nullable BaseClientMonitor.Callback clientCallback) { // Mark any interruptable pending clients as canceling. Once they reach the head of the // queue, the scheduler will send ERROR_CANCELED and skip the operation. for (Operation operation : mPendingOperations) { if (operation.clientMonitor instanceof Interruptable && operation.state != Operation.STATE_WAITING_IN_QUEUE_CANCELING) { if (operation.mClientMonitor instanceof Interruptable && operation.mState != Operation.STATE_WAITING_IN_QUEUE_CANCELING) { Slog.d(getTag(), "New client incoming, marking pending client as canceling: " + operation.clientMonitor); operation.state = Operation.STATE_WAITING_IN_QUEUE_CANCELING; + operation.mClientMonitor); operation.mState = Operation.STATE_WAITING_IN_QUEUE_CANCELING; } } Loading @@ -451,8 +452,8 @@ public class BiometricScheduler { + ", new queue size: " + mPendingOperations.size()); // If the current operation is cancellable, start the cancellation process. if (mCurrentOperation != null && mCurrentOperation.clientMonitor instanceof Interruptable && mCurrentOperation.state == Operation.STATE_STARTED) { if (mCurrentOperation != null && mCurrentOperation.mClientMonitor instanceof Interruptable && mCurrentOperation.mState == Operation.STATE_STARTED) { Slog.d(getTag(), "[Cancelling Interruptable]: " + mCurrentOperation); cancelInternal(mCurrentOperation); } Loading @@ -465,25 +466,25 @@ public class BiometricScheduler { Slog.e(getTag(), "cancelInternal invoked on non-current operation: " + operation); return; } if (!(operation.clientMonitor instanceof Interruptable)) { if (!(operation.mClientMonitor instanceof Interruptable)) { Slog.w(getTag(), "Operation not interruptable: " + operation); return; } if (operation.state == Operation.STATE_STARTED_CANCELING) { if (operation.mState == Operation.STATE_STARTED_CANCELING) { Slog.w(getTag(), "Cancel already invoked for operation: " + operation); return; } if (operation.state == Operation.STATE_WAITING_FOR_COOKIE) { if (operation.mState == Operation.STATE_WAITING_FOR_COOKIE) { Slog.w(getTag(), "Skipping cancellation for non-started operation: " + operation); // We can set it to null immediately, since the HAL was never notified to start. mCurrentOperation = null; startNextOperationIfIdle(); return; } Slog.d(getTag(), "[Cancelling] Current client: " + operation.clientMonitor); final Interruptable interruptable = (Interruptable) operation.clientMonitor; Slog.d(getTag(), "[Cancelling] Current client: " + operation.mClientMonitor); final Interruptable interruptable = (Interruptable) operation.mClientMonitor; interruptable.cancel(); operation.state = Operation.STATE_STARTED_CANCELING; operation.mState = Operation.STATE_STARTED_CANCELING; // Add a watchdog. If the HAL does not acknowledge within the timeout, we will // forcibly finish this client. Loading @@ -500,8 +501,8 @@ public class BiometricScheduler { Slog.e(getTag(), "Unable to cancel enrollment, null operation"); return; } final boolean isEnrolling = mCurrentOperation.clientMonitor instanceof EnrollClient; final boolean tokenMatches = mCurrentOperation.clientMonitor.getToken() == token; final boolean isEnrolling = mCurrentOperation.mClientMonitor instanceof EnrollClient; final boolean tokenMatches = mCurrentOperation.mClientMonitor.getToken() == token; if (!isEnrolling || !tokenMatches) { Slog.w(getTag(), "Not cancelling enrollment, isEnrolling: " + isEnrolling + " tokenMatches: " + tokenMatches); Loading @@ -521,8 +522,8 @@ public class BiometricScheduler { return; } final boolean isAuthenticating = mCurrentOperation.clientMonitor instanceof AuthenticationConsumer; final boolean tokenMatches = mCurrentOperation.clientMonitor.getToken() == token; mCurrentOperation.mClientMonitor instanceof AuthenticationConsumer; final boolean tokenMatches = mCurrentOperation.mClientMonitor.getToken() == token; if (!isAuthenticating || !tokenMatches) { Slog.w(getTag(), "Not cancelling authentication" + ", current operation : " + mCurrentOperation Loading @@ -536,11 +537,11 @@ public class BiometricScheduler { /** * @return the current operation */ public ClientMonitor<?> getCurrentClient() { public BaseClientMonitor<?> getCurrentClient() { if (mCurrentOperation == null) { return null; } return mCurrentOperation.clientMonitor; return mCurrentOperation.mClientMonitor; } public int getCurrentPendingCount() { Loading
services/core/java/com/android/server/biometrics/sensors/EnumerateConsumer.java +2 −2 Original line number Diff line number Diff line Loading @@ -19,8 +19,8 @@ package com.android.server.biometrics.sensors; import android.hardware.biometrics.BiometricAuthenticator; /** * Interface that {@link ClientMonitor} subclasses eligible/interested in enumerate callbacks should * implement. * Interface that {@link BaseClientMonitor} subclasses eligible/interested in enumerate callbacks * should implement. */ public interface EnumerateConsumer { /** Loading