Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b9bb08eb authored by Kevin Chyn's avatar Kevin Chyn
Browse files

7/n: Add HalClientMonitor

Adds HalClientMonitor and HAL-related things out of
BaseClientMonitor to HalClientMonitor.

This is mostly a rename, except BiometricScheduler, which adds
a tiny bit of code to handle HalClientMonitor vs BaseClientMonitor

Bug: 159667191
Test: atest com.android.server.biometrics
Test: No effect on devices
Change-Id: Iad79331eca956f8b854fa99a3f95cd21922d1bcc
parent 8b2f2602
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -408,7 +408,7 @@ public class Utils {
        return hasPermission && keyguardPackage != null && keyguardPackage.equals(clientPackage);
    }

    public static String getClientName(@Nullable BaseClientMonitor<?> client) {
    public static String getClientName(@Nullable BaseClientMonitor client) {
        return client != null ? client.getClass().getSimpleName() : "null";
    }

+2 −2
Original line number Diff line number Diff line
@@ -29,10 +29,10 @@ import android.os.Vibrator;
import android.util.Slog;

/**
 * Abstract {@link BaseClientMonitor} subclass that operations eligible/interested in acquisition
 * Abstract {@link HalClientMonitor} subclass that operations eligible/interested in acquisition
 * messages should extend.
 */
public abstract class AcquisitionClient<T> extends BaseClientMonitor<T> implements Interruptable {
public abstract class AcquisitionClient<T> extends HalClientMonitor<T> implements Interruptable {

    private static final String TAG = "Biometrics/AcquisitionClient";

+5 −35
Original line number Diff line number Diff line
@@ -31,7 +31,7 @@ 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 BaseClientMonitor<T> extends LoggableMonitor
public abstract class BaseClientMonitor extends LoggableMonitor
        implements IBinder.DeathRecipient {

    private static final String TAG = "Biometrics/ClientMonitor";
@@ -50,7 +50,7 @@ public abstract class BaseClientMonitor<T> extends LoggableMonitor
         *
         * @param clientMonitor Reference of the ClientMonitor that is starting.
         */
        default void onClientStarted(@NonNull BaseClientMonitor<?> clientMonitor) {}
        default void onClientStarted(@NonNull BaseClientMonitor clientMonitor) {}

        /**
         * Invoked when the ClientMonitor operation is complete. This abstracts away asynchronous
@@ -61,23 +61,11 @@ public abstract class BaseClientMonitor<T> extends LoggableMonitor
         * @param clientMonitor Reference of the ClientMonitor that finished.
         * @param success True if the operation completed successfully.
         */
        default void onClientFinished(@NonNull BaseClientMonitor<?> clientMonitor,
                boolean success) {}
    }

    /**
     * Interface that allows ClientMonitor subclasses to retrieve a fresh instance to the HAL.
     */
    public interface LazyDaemon<T> {
        /**
         * @return A fresh instance to the biometric HAL
         */
        T getDaemon();
        default void onClientFinished(@NonNull BaseClientMonitor clientMonitor, boolean success) {}
    }

    protected final int mSequentialId;
    @NonNull private final Context mContext;
    @NonNull protected final LazyDaemon<T> mLazyDaemon;
    private final int mTargetUserId;
    @NonNull private final String mOwner;
    private final int mSensorId; // sensorId as configured by the framework
@@ -93,7 +81,6 @@ public abstract class BaseClientMonitor<T> extends LoggableMonitor

    /**
     * @param context    system_server context
     * @param lazyDaemon pointer for lazy retrieval of the HAL
     * @param token      a unique token for the client
     * @param listener   recipient of related events (e.g. authentication)
     * @param userId     target user id for operation
@@ -104,14 +91,13 @@ public abstract class BaseClientMonitor<T> extends LoggableMonitor
     * @param statsAction   One of {@link BiometricsProtoEnums} ACTION_* constants
     * @param statsClient   One of {@link BiometricsProtoEnums} CLIENT_* constants
     */
    public BaseClientMonitor(@NonNull Context context, @NonNull LazyDaemon<T> lazyDaemon,
    public BaseClientMonitor(@NonNull Context context,
            @Nullable IBinder token, @Nullable ClientMonitorCallbackConverter listener, int userId,
            @NonNull String owner, int cookie, int sensorId, int statsModality, int statsAction,
            int statsClient) {
        super(statsModality, statsAction, statsClient);
        mSequentialId = sCount++;
        mContext = context;
        mLazyDaemon = lazyDaemon;
        mToken = token;
        mListener = listener;
        mTargetUserId = userId;
@@ -133,15 +119,7 @@ public abstract class BaseClientMonitor<T> extends LoggableMonitor
    }

    /**
     * Invoked if the scheduler is unable to start the ClientMonitor (for example the HAL is null).
     * If such a problem is detected, the scheduler will not invoke
     * {@link #start(Callback)}.
     */
    public abstract void unableToStart();

    /**
     * Starts the ClientMonitor's lifecycle. Invokes {@link #startHalOperation()} when internal book
     * keeping is complete.
     * Starts the ClientMonitor's lifecycle.
     * @param callback invoked when the operation is complete (succeeds, fails, etc)
     */
    public void start(@NonNull Callback callback) {
@@ -149,10 +127,6 @@ public abstract class BaseClientMonitor<T> extends LoggableMonitor
        mCallback.onClientStarted(this);
    }

    /**
     * Starts the HAL operation specific to the ClientMonitor subclass.
     */
    protected abstract void startHalOperation();

    public boolean isAlreadyDone() {
        return mAlreadyDone;
@@ -221,10 +195,6 @@ public abstract class BaseClientMonitor<T> extends LoggableMonitor
        return mSensorId;
    }

    public T getFreshDaemon() {
        return mLazyDaemon.getDaemon();
    }

    @Override
    public String toString() {
        return "{[" + mSequentialId + "] "
+36 −13
Original line number Diff line number Diff line
@@ -101,17 +101,34 @@ public class BiometricScheduler {
        @Retention(RetentionPolicy.SOURCE)
        @interface OperationState {}

        @NonNull final BaseClientMonitor<?> mClientMonitor;
        @NonNull final BaseClientMonitor mClientMonitor;
        @Nullable final BaseClientMonitor.Callback mClientCallback;
        @OperationState int mState;

        Operation(@NonNull BaseClientMonitor<?> clientMonitor,
        Operation(@NonNull BaseClientMonitor clientMonitor,
                @Nullable BaseClientMonitor.Callback callback) {
            this.mClientMonitor = clientMonitor;
            this.mClientCallback = callback;
            mState = STATE_WAITING_IN_QUEUE;
        }

        public boolean isHalOperation() {
            return mClientMonitor instanceof HalClientMonitor<?>;
        }

        /**
         * @return true if the operation requires the HAL, and the HAL is null.
         */
        public boolean isUnstartableHalOperation() {
            if (isHalOperation()) {
                final HalClientMonitor<?> client = (HalClientMonitor<?>) mClientMonitor;
                if (client.getFreshDaemon() == null) {
                    return true;
                }
            }
            return false;
        }

        @Override
        public String toString() {
            return mClientMonitor + ", State: " + mState;
@@ -188,7 +205,7 @@ public class BiometricScheduler {
    // starting the next client).
    public class InternalCallback implements BaseClientMonitor.Callback {
        @Override
        public void onClientStarted(@NonNull BaseClientMonitor<?> clientMonitor) {
        public void onClientStarted(@NonNull BaseClientMonitor clientMonitor) {
            Slog.d(getTag(), "[Started] " + clientMonitor);
            if (mCurrentOperation.mClientCallback != null) {
                mCurrentOperation.mClientCallback.onClientStarted(clientMonitor);
@@ -196,7 +213,7 @@ public class BiometricScheduler {
        }

        @Override
        public void onClientFinished(@NonNull BaseClientMonitor<?> clientMonitor, boolean success) {
        public void onClientFinished(@NonNull BaseClientMonitor clientMonitor, boolean success) {
            mHandler.post(() -> {
                if (mCurrentOperation == null) {
                    Slog.e(getTag(), "[Finishing] " + clientMonitor
@@ -276,7 +293,7 @@ public class BiometricScheduler {
        }

        mCurrentOperation = mPendingOperations.poll();
        final BaseClientMonitor<?> currentClient = mCurrentOperation.mClientMonitor;
        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.
@@ -305,7 +322,9 @@ 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.mClientMonitor.getFreshDaemon() == null) {
            if (mCurrentOperation.isUnstartableHalOperation()) {
                final HalClientMonitor<?> halClientMonitor =
                        (HalClientMonitor<?>) mCurrentOperation.mClientMonitor;
                // Note down current length of queue
                final int pendingOperationsLength = mPendingOperations.size();
                final Operation lastOperation = mPendingOperations.peekLast();
@@ -315,7 +334,7 @@ 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.mClientMonitor.unableToStart();
                halClientMonitor.unableToStart();
                if (mCurrentOperation.mClientCallback != null) {
                    mCurrentOperation.mClientCallback.onClientFinished(
                            mCurrentOperation.mClientMonitor, false /* success */);
@@ -331,7 +350,9 @@ public class BiometricScheduler {
                                + ", expected length: " + pendingOperationsLength);
                        break;
                    }
                    operation.mClientMonitor.unableToStart();
                    if (operation.isHalOperation()) {
                        ((HalClientMonitor<?>) operation.mClientMonitor).unableToStart();
                    }
                    if (operation.mClientCallback != null) {
                        operation.mClientCallback.onClientFinished(operation.mClientMonitor,
                                false /* success */);
@@ -401,10 +422,12 @@ public class BiometricScheduler {
            return;
        }

        if (mCurrentOperation.mClientMonitor.getFreshDaemon() == null) {
        if (mCurrentOperation.isUnstartableHalOperation()) {
            Slog.e(getTag(), "[Unable To Start] Prepared client: " + mCurrentOperation);
            // This is BiometricPrompt trying to auth but something's wrong with the HAL.
            mCurrentOperation.mClientMonitor.unableToStart();
            final HalClientMonitor<?> halClientMonitor =
                    (HalClientMonitor<?>) mCurrentOperation.mClientMonitor;
            halClientMonitor.unableToStart();
            if (mCurrentOperation.mClientCallback != null) {
                mCurrentOperation.mClientCallback.onClientFinished(mCurrentOperation.mClientMonitor,
                        false /* success */);
@@ -423,7 +446,7 @@ public class BiometricScheduler {
     *
     * @param clientMonitor operation to be scheduled
     */
    public void scheduleClientMonitor(@NonNull BaseClientMonitor<?> clientMonitor) {
    public void scheduleClientMonitor(@NonNull BaseClientMonitor clientMonitor) {
        scheduleClientMonitor(clientMonitor, null /* clientFinishCallback */);
    }

@@ -434,7 +457,7 @@ public class BiometricScheduler {
     * @param clientCallback optional callback, invoked when the client is finished, but
     *                             before it has been removed from the queue.
     */
    public void scheduleClientMonitor(@NonNull BaseClientMonitor<?> clientMonitor,
    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.
@@ -537,7 +560,7 @@ public class BiometricScheduler {
    /**
     * @return the current operation
     */
    public BaseClientMonitor<?> getCurrentClient() {
    public BaseClientMonitor getCurrentClient() {
        if (mCurrentOperation == null) {
            return null;
        }
+1 −1
Original line number Diff line number Diff line
@@ -23,7 +23,7 @@ import android.os.IBinder;
import android.os.RemoteException;
import android.util.Slog;

public abstract class GenerateChallengeClient<T> extends BaseClientMonitor<T> {
public abstract class GenerateChallengeClient<T> extends HalClientMonitor<T> {

    private static final String TAG = "GenerateChallengeClient";

Loading