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

Commit 50b13e53 authored by Kevin Chyn's avatar Kevin Chyn
Browse files

3/n: Start adding plumbing for some HAL callbacks

Fixes: 168843828
Test: Builds
Change-Id: Ieabf61aa3f447072f23b748d4101ba7908266ad0
parent 275aa876
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -31,6 +31,10 @@ public final class Fingerprint extends BiometricAuthenticator.Identifier {
        mGroupId = groupId;
    }

    public Fingerprint(CharSequence name, int fingerId, long deviceId) {
        super(name, fingerId, deviceId);
    }

    private Fingerprint(Parcel in) {
        super(in.readString(), in.readInt(), in.readLong());
        mGroupId = in.readInt();
+2 −2
Original line number Diff line number Diff line
@@ -79,8 +79,8 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi
                            prop.commonProps.maxEnrollmentsPerUser,
                            prop.sensorType,
                            true /* resetLockoutRequiresHardwareAuthToken */);
            final Sensor sensor = new Sensor(getTag() + "/" + sensorId, internalProp,
                    gestureAvailabilityDispatcher);
            final Sensor sensor = new Sensor(getTag() + "/" + sensorId, mContext, mHandler,
                    internalProp, gestureAvailabilityDispatcher);

            mSensors.put(sensorId, sensor);
            Slog.d(getTag(), "Added: " + internalProp);
+99 −6
Original line number Diff line number Diff line
@@ -18,24 +18,40 @@ package com.android.server.biometrics.sensors.fingerprint.aidl;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
import android.hardware.biometrics.fingerprint.Error;
import android.hardware.biometrics.fingerprint.IFingerprint;
import android.hardware.biometrics.fingerprint.ISession;
import android.hardware.biometrics.fingerprint.ISessionCallback;
import android.hardware.fingerprint.Fingerprint;
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
import android.hardware.keymaster.HardwareAuthToken;
import android.os.Handler;
import android.os.RemoteException;
import android.util.Slog;

import com.android.server.biometrics.HardwareAuthTokenUtils;
import com.android.server.biometrics.Utils;
import com.android.server.biometrics.sensors.AcquisitionClient;
import com.android.server.biometrics.sensors.AuthenticationConsumer;
import com.android.server.biometrics.sensors.BiometricScheduler;
import com.android.server.biometrics.sensors.ClientMonitor;
import com.android.server.biometrics.sensors.Interruptable;
import com.android.server.biometrics.sensors.fingerprint.FingerprintUtils;
import com.android.server.biometrics.sensors.fingerprint.GestureAvailabilityDispatcher;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * Maintains the state of a single sensor within an instance of the
 * {@link android.hardware.biometrics.fingerprint.IFingerprint} HAL.
 */
class Sensor {
    @NonNull private final String mTag;
    @NonNull private final Context mContext;
    @NonNull private final Handler mHandler;
    @NonNull private final FingerprintSensorPropertiesInternal mSensorProperties;
    @NonNull private final BiometricScheduler mScheduler;

@@ -58,10 +74,12 @@ class Sensor {
        }
    }

    Sensor(@NonNull String tag,
    Sensor(@NonNull String tag, @NonNull Context context, @NonNull Handler handler,
            @NonNull FingerprintSensorPropertiesInternal sensorProperties,
            @NonNull GestureAvailabilityDispatcher gestureAvailabilityDispatcher) {
        mTag = tag;
        mContext = context;
        mHandler = handler;
        mSensorProperties = sensorProperties;
        mScheduler = new BiometricScheduler(tag, gestureAvailabilityDispatcher);
        mLazySession = () -> mCurrentSession != null ? mCurrentSession.mSession : null;
@@ -89,27 +107,102 @@ class Sensor {

            @Override
            public void onAcquired(byte info, int vendorCode) {
                mHandler.post(() -> {
                    final ClientMonitor<?> client = mScheduler.getCurrentClient();
                    if (!(client instanceof AcquisitionClient)) {
                        Slog.e(mTag, "onAcquired for non-acquisition client: "
                                + Utils.getClientName(client));
                        return;
                    }

                    final AcquisitionClient<?> acquisitionClient = (AcquisitionClient<?>) client;
                    acquisitionClient.onAcquired(info, vendorCode);
                });
            }

            @Override
            public void onError(byte error, int vendorCode) {
                mHandler.post(() -> {
                    final ClientMonitor<?> client = mScheduler.getCurrentClient();
                    Slog.d(mTag, "onError"
                            + ", client: " + Utils.getClientName(client)
                            + ", error: " + error
                            + ", vendorCode: " + vendorCode);
                    if (!(client instanceof Interruptable)) {
                        Slog.e(mTag, "onError for non-error consumer: "
                                + Utils.getClientName(client));
                        return;
                    }

                    final Interruptable interruptable = (Interruptable) client;
                    interruptable.onError(error, vendorCode);

                    if (error == Error.HW_UNAVAILABLE) {
                        Slog.e(mTag, "Got ERROR_HW_UNAVAILABLE");
                        mCurrentSession = null;
                    }
                });
            }

            @Override
            public void onEnrollmentProgress(int enrollmentId, int remaining) {
                mHandler.post(() -> {
                    final ClientMonitor<?> client = mScheduler.getCurrentClient();
                    if (!(client instanceof FingerprintEnrollClient)) {
                        Slog.e(mTag, "onEnrollmentProgress for non-enroll client: "
                                + Utils.getClientName(client));
                        return;
                    }

                    final int currentUserId = client.getTargetUserId();
                    final CharSequence name = FingerprintUtils.getInstance()
                            .getUniqueName(mContext, currentUserId);
                    final Fingerprint fingerprint = new Fingerprint(name, enrollmentId, sensorId);

                    final FingerprintEnrollClient enrollClient = (FingerprintEnrollClient) client;
                    enrollClient.onEnrollResult(fingerprint, remaining);
                });
            }

            @Override
            public void onAuthenticationSucceeded(int enrollmentId, HardwareAuthToken hat) {
                mHandler.post(() -> {
                    final ClientMonitor<?> client = mScheduler.getCurrentClient();
                    if (!(client instanceof AuthenticationConsumer)) {
                        Slog.e(mTag, "onAuthenticationSucceeded for non-authentication consumer: "
                                + Utils.getClientName(client));
                        return;
                    }

                    final AuthenticationConsumer authenticationConsumer =
                            (AuthenticationConsumer) client;
                    final Fingerprint fp = new Fingerprint("", enrollmentId, sensorId);
                    final byte[] byteArray = HardwareAuthTokenUtils.toByteArray(hat);
                    final ArrayList<Byte> byteList = new ArrayList<>();
                    for (byte b : byteArray) {
                        byteList.add(b);
                    }

                    authenticationConsumer.onAuthenticated(fp, true /* authenticated */, byteList);
                });
            }

            @Override
            public void onAuthenticationFailed() {
                mHandler.post(() -> {
                    final ClientMonitor<?> client = mScheduler.getCurrentClient();
                    if (!(client instanceof AuthenticationConsumer)) {
                        Slog.e(mTag, "onAuthenticationFailed for non-authentication consumer: "
                                + Utils.getClientName(client));
                        return;
                    }

                    final AuthenticationConsumer authenticationConsumer =
                            (AuthenticationConsumer) client;
                    final Fingerprint fp = new Fingerprint("", 0 /* enrollmentId */, sensorId);
                    authenticationConsumer
                            .onAuthenticated(fp, false /* authenticated */, null /* hat */);
                });
            }

            @Override
+1 −1
Original line number Diff line number Diff line
@@ -246,7 +246,7 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider
            mHandler.post(() -> {
                final ClientMonitor<?> client = mScheduler.getCurrentClient();
                Slog.d(TAG, "handleError"
                        + ", client: " + (client != null ? client.getOwnerString() : null)
                        + ", client: " + Utils.getClientName(client)
                        + ", error: " + error
                        + ", vendorCode: " + vendorCode);
                if (!(client instanceof Interruptable)) {