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

Commit 6a68936b authored by Kevin Chyn's avatar Kevin Chyn Committed by Android (Google) Code Review
Browse files

Merge "6/n: Rename ClientMonitor to BaseClientMonitor"

parents c1c9ca96 35c8c3b0
Loading
Loading
Loading
Loading
+2 −3
Original line number Diff line number Diff line
@@ -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;
@@ -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;

@@ -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";
    }

+2 −2
Original line number Diff line number Diff line
@@ -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";

+6 −4
Original line number Diff line number Diff line
@@ -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;
@@ -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
@@ -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) {}
    }

    /**
@@ -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) {
+66 −65
Original line number Diff line number Diff line
@@ -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 {
@@ -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;

@@ -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;
        }
    }

@@ -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 */);
            }
        }
    }
@@ -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);
@@ -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
@@ -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);
@@ -220,7 +220,7 @@ public class BiometricScheduler {

                if (mGestureAvailabilityDispatcher != null) {
                    mGestureAvailabilityDispatcher.markSensorActive(
                            mCurrentOperation.clientMonitor.getSensorId(), false /* active */);
                            mCurrentOperation.mClientMonitor.getSensorId(), false /* active */);
                }

                mCurrentOperation = null;
@@ -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, "
@@ -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 */);
        }

@@ -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();
@@ -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
@@ -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);
@@ -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 {
@@ -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;
        }
    }

@@ -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;
@@ -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;
            }
        }

@@ -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);
        }
@@ -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.
@@ -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);
@@ -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
@@ -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() {
+2 −2
Original line number Diff line number Diff line
@@ -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