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

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

Merge changes I708312ca,Ie51b4e36

* changes:
  2/n: Keep track of IBiometricsFace@1.0 challenge interruptions
  1/n: Slight changes to ClientMonitor's Callback
parents af25e168 e44a86b2
Loading
Loading
Loading
Loading
+49 −0
Original line number Diff line number Diff line
@@ -72,6 +72,8 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan
    private static final int MSG_SET_FEATURE_COMPLETED = 107;
    private static final int MSG_CHALLENGE_GENERATED = 108;
    private static final int MSG_FACE_DETECTED = 109;
    private static final int MSG_CHALLENGE_INTERRUPTED = 110;
    private static final int MSG_CHALLENGE_INTERRUPT_FINISHED = 111;

    private final IFaceService mService;
    private final Context mContext;
@@ -150,6 +152,16 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan
                mHandler.obtainMessage(MSG_CHALLENGE_GENERATED, challenge).sendToTarget();
            }
        }

        @Override
        public void onChallengeInterrupted(int sensorId) {
            mHandler.obtainMessage(MSG_CHALLENGE_INTERRUPTED, sensorId).sendToTarget();
        }

        @Override
        public void onChallengeInterruptFinished(int sensorId) {
            mHandler.obtainMessage(MSG_CHALLENGE_INTERRUPT_FINISHED, sensorId).sendToTarget();
        }
    };

    /**
@@ -1071,10 +1083,25 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan
    }

    /**
     * Callback structure provided to {@link #generateChallenge(GenerateChallengeCallback)}.
     * @hide
     */
    public interface GenerateChallengeCallback {
        /**
         * Invoked when a challenge has been generated.
         */
        void onGenerateChallengeResult(long challenge);

        /**
         * Invoked if the challenge has not been revoked and a subsequent caller/owner invokes
         * {@link #generateChallenge(GenerateChallengeCallback)}, but
         */
        default void onChallengeInterrupted(int sensorId) {}

        /**
         * Invoked when the interrupting client has finished (e.g. revoked its challenge).
         */
        default void onChallengeInterruptFinished(int sensorId) {}
    }

    private abstract static class InternalGenerateChallengeCallback
@@ -1157,6 +1184,12 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan
                    sendFaceDetected(msg.arg1 /* sensorId */, msg.arg2 /* userId */,
                            (boolean) msg.obj /* isStrongBiometric */);
                    break;
                case MSG_CHALLENGE_INTERRUPTED:
                    sendChallengeInterrupted((int) msg.obj /* sensorId */);
                    break;
                case MSG_CHALLENGE_INTERRUPT_FINISHED:
                    sendChallengeInterruptFinished((int) msg.obj /* sensorId */);
                    break;
                default:
                    Slog.w(TAG, "Unknown message: " + msg.what);
            }
@@ -1193,6 +1226,22 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan
        mFaceDetectionCallback.onFaceDetected(sensorId, userId, isStrongBiometric);
    }

    private void sendChallengeInterrupted(int sensorId) {
        if (mGenerateChallengeCallback == null) {
            Slog.e(TAG, "sendChallengeInterrupted, callback null");
            return;
        }
        mGenerateChallengeCallback.onChallengeInterrupted(sensorId);
    }

    private void sendChallengeInterruptFinished(int sensorId) {
        if (mGenerateChallengeCallback == null) {
            Slog.e(TAG, "sendChallengeInterruptFinished, callback null");
            return;
        }
        mGenerateChallengeCallback.onChallengeInterruptFinished(sensorId);
    }

    private void sendRemovedResult(Face face, int remaining) {
        if (mRemovalCallback == null) {
            return;
+2 −0
Original line number Diff line number Diff line
@@ -32,4 +32,6 @@ oneway interface IFaceServiceReceiver {
    void onFeatureSet(boolean success, int feature);
    void onFeatureGet(boolean success, int feature, boolean value);
    void onChallengeGenerated(long challenge);
    void onChallengeInterrupted(int sensorId);
    void onChallengeInterruptFinished(int sensorId);
}
+4 −4
Original line number Diff line number Diff line
@@ -98,7 +98,7 @@ public abstract class AcquisitionClient<T> extends ClientMonitor<T> implements I
        }

        if (finish) {
            mFinishCallback.onClientFinished(this, false /* success */);
            mCallback.onClientFinished(this, false /* success */);
        }
    }

@@ -114,7 +114,7 @@ public abstract class AcquisitionClient<T> extends ClientMonitor<T> implements I
    }

    @Override
    public void cancelWithoutStarting(@NonNull FinishCallback finishCallback) {
    public void cancelWithoutStarting(@NonNull Callback callback) {
        final int errorCode = BiometricConstants.BIOMETRIC_ERROR_CANCELED;
        try {
            if (getListener() != null) {
@@ -123,7 +123,7 @@ public abstract class AcquisitionClient<T> extends ClientMonitor<T> implements I
        } catch (RemoteException e) {
            Slog.w(TAG, "Failed to invoke sendError", e);
        }
        finishCallback.onClientFinished(this, true /* success */);
        callback.onClientFinished(this, true /* success */);
    }

    /**
@@ -155,7 +155,7 @@ public abstract class AcquisitionClient<T> extends ClientMonitor<T> implements I
            }
        } catch (RemoteException e) {
            Slog.w(TAG, "Failed to invoke sendAcquired", e);
            mFinishCallback.onClientFinished(this, false /* success */);
            mCallback.onClientFinished(this, false /* success */);
        }
    }

+3 −3
Original line number Diff line number Diff line
@@ -191,7 +191,7 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T>
            }
        } catch (RemoteException e) {
            Slog.e(TAG, "Unable to notify listener, finishing", e);
            mFinishCallback.onClientFinished(this, false /* success */);
            mCallback.onClientFinished(this, false /* success */);
        }
    }

@@ -211,8 +211,8 @@ public abstract class AuthenticationClient<T> extends AcquisitionClient<T>
     * Start authentication
     */
    @Override
    public void start(@NonNull FinishCallback finishCallback) {
        super.start(finishCallback);
    public void start(@NonNull Callback callback) {
        super.start(callback);

        final @LockoutTracker.LockoutMode int lockoutMode =
                mLockoutTracker.getLockoutModeForUser(getTargetUserId());
+23 −17
Original line number Diff line number Diff line
@@ -85,7 +85,7 @@ public class BiometricScheduler {
        static final int STATE_WAITING_FOR_COOKIE = 4;

        /**
         * The {@link ClientMonitor.FinishCallback} has been invoked and the client is finished.
         * The {@link ClientMonitor.Callback} has been invoked and the client is finished.
         */
        static final int STATE_FINISHED = 5;

@@ -99,13 +99,13 @@ public class BiometricScheduler {
        @interface OperationState {}

        @NonNull final ClientMonitor<?> clientMonitor;
        @Nullable final ClientMonitor.FinishCallback clientFinishCallback;
        @Nullable final ClientMonitor.Callback mClientCallback;
        @OperationState int state;

        Operation(@NonNull ClientMonitor<?> clientMonitor,
                @Nullable ClientMonitor.FinishCallback finishCallback) {
                @Nullable ClientMonitor.Callback callback) {
            this.clientMonitor = clientMonitor;
            this.clientFinishCallback = finishCallback;
            this.mClientCallback = callback;
            state = STATE_WAITING_IN_QUEUE;
        }

@@ -133,7 +133,7 @@ public class BiometricScheduler {
        public void run() {
            if (operation.state != Operation.STATE_FINISHED) {
                Slog.e(tag, "[Watchdog Triggered]: " + operation);
                operation.clientMonitor.mFinishCallback
                operation.clientMonitor.mCallback
                        .onClientFinished(operation.clientMonitor, false /* success */);
            }
        }
@@ -175,15 +175,15 @@ public class BiometricScheduler {
    @Nullable private final GestureAvailabilityDispatcher mGestureAvailabilityDispatcher;
    @NonNull private final IBiometricService mBiometricService;
    @NonNull private final Handler mHandler = new Handler(Looper.getMainLooper());
    @NonNull private final InternalFinishCallback mInternalFinishCallback;
    @NonNull protected final InternalCallback mInternalCallback;
    @NonNull private final Queue<Operation> mPendingOperations;
    @Nullable private Operation mCurrentOperation;
    @NonNull private final ArrayDeque<CrashState> mCrashStates;

    // Internal finish callback, notified when an operation is complete. Notifies the requester
    // 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).
    private class InternalFinishCallback implements ClientMonitor.FinishCallback {
    public class InternalCallback implements ClientMonitor.Callback {
        @Override
        public void onClientFinished(ClientMonitor<?> clientMonitor, boolean success) {
            mHandler.post(() -> {
@@ -203,8 +203,8 @@ public class BiometricScheduler {
                Slog.d(getTag(), "[Finishing] " + clientMonitor + ", success: " + success);
                mCurrentOperation.state = Operation.STATE_FINISHED;

                if (mCurrentOperation.clientFinishCallback != null) {
                    mCurrentOperation.clientFinishCallback.onClientFinished(clientMonitor, success);
                if (mCurrentOperation.mClientCallback != null) {
                    mCurrentOperation.mClientCallback.onClientFinished(clientMonitor, success);
                }

                if (mGestureAvailabilityDispatcher != null) {
@@ -227,7 +227,7 @@ public class BiometricScheduler {
    public BiometricScheduler(@NonNull String tag,
            @Nullable GestureAvailabilityDispatcher gestureAvailabilityDispatcher) {
        mBiometricTag = tag;
        mInternalFinishCallback = new InternalFinishCallback();
        mInternalCallback = new InternalCallback();
        mGestureAvailabilityDispatcher = gestureAvailabilityDispatcher;
        mPendingOperations = new ArrayDeque<>();
        mBiometricService = IBiometricService.Stub.asInterface(
@@ -262,7 +262,7 @@ public class BiometricScheduler {
            }

            final Interruptable interruptable = (Interruptable) currentClient;
            interruptable.cancelWithoutStarting(mInternalFinishCallback);
            interruptable.cancelWithoutStarting(mInternalCallback);
            // Now we wait for the client to send its FinishCallback, which kicks off the next
            // operation.
            return;
@@ -280,7 +280,10 @@ public class BiometricScheduler {
        final boolean shouldStartNow = currentClient.getCookie() == 0;
        if (shouldStartNow) {
            Slog.d(getTag(), "[Starting] " + mCurrentOperation);
            currentClient.start(mInternalFinishCallback);
            if (mCurrentOperation.mClientCallback != null) {
                mCurrentOperation.mClientCallback.onClientStarted(currentClient);
            }
            currentClient.start(mInternalCallback);
            mCurrentOperation.state = Operation.STATE_STARTED;
        } else {
            try {
@@ -323,8 +326,11 @@ public class BiometricScheduler {
        }

        Slog.d(getTag(), "[Starting] Prepared client: " + mCurrentOperation);
        if (mCurrentOperation.mClientCallback != null) {
            mCurrentOperation.mClientCallback.onClientStarted(mCurrentOperation.clientMonitor);
        }
        mCurrentOperation.state = Operation.STATE_STARTED;
        mCurrentOperation.clientMonitor.start(mInternalFinishCallback);
        mCurrentOperation.clientMonitor.start(mInternalCallback);
    }

    /**
@@ -340,11 +346,11 @@ public class BiometricScheduler {
     * Adds a {@link ClientMonitor} to the pending queue
     *
     * @param clientMonitor        operation to be scheduled
     * @param clientFinishCallback optional callback, invoked when the client is finished, but
     * @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.FinishCallback clientFinishCallback) {
            @Nullable ClientMonitor.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) {
@@ -356,7 +362,7 @@ public class BiometricScheduler {
            }
        }

        mPendingOperations.add(new Operation(clientMonitor, clientFinishCallback));
        mPendingOperations.add(new Operation(clientMonitor, clientCallback));
        Slog.d(getTag(), "[Added] " + clientMonitor
                + ", new queue size: " + mPendingOperations.size());

Loading