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

Commit 6034d30e authored by Kevin Chyn's avatar Kevin Chyn
Browse files

8/n: Schedule invalidation request

This should happen 1) Upon successful enrollment, and 2) After
session creation, if the framework detects a previous invalidation
has not completed for some reason.

Note that invalidation only needs to be requested if the (sensor, user)
pair has enrollments.

Also fixes the case where no sensors require invalidation.

Test: atest com.android.server.biometrics
Test: atest CtsBiometricsTestCases, existing tests pass. Additional
      tests will be added in a subsequent CL.
Bug: 159667191
Change-Id: Id14391370904df004380428f1a064224489e2898
parent b9bb08eb
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -805,7 +805,7 @@ public final class AuthSession implements IBinder.DeathRecipient {
    @Override
    public String toString() {
        return "State: " + mState
                + "\nisCrypto: " + isCrypto()
                + "\nPreAuthInfo: " + mPreAuthInfo;
                + ", isCrypto: " + isCrypto()
                + ", PreAuthInfo: " + mPreAuthInfo;
    }
}
+6 −7
Original line number Diff line number Diff line
@@ -169,12 +169,11 @@ public abstract class BiometricSensor {
    @Override
    public String toString() {
        return "ID(" + id + ")"
                + "\n oemStrength: " + oemStrength
                + "\n updatedStrength: " + mUpdatedStrength
                + "\n modality " + modality
                + "\n state: " + mSensorState
                + "\n cookie: " + mCookie
                + "\n authenticator: " + impl
                + "\n";
                + ", oemStrength: " + oemStrength
                + ", updatedStrength: " + mUpdatedStrength
                + ", modality " + modality
                + ", state: " + mSensorState
                + ", cookie: " + mCookie
                + ", authenticator: " + impl;
    }
}
+25 −4
Original line number Diff line number Diff line
@@ -252,12 +252,14 @@ public class BiometricService extends SystemService {
        @NonNull private final IInvalidationCallback mClientCallback;
        @NonNull private final Set<Integer> mSensorsPendingInvalidation;

        public static InvalidationTracker start(@NonNull ArrayList<BiometricSensor> sensors,
        public static InvalidationTracker start(@NonNull Context context,
                @NonNull ArrayList<BiometricSensor> sensors,
                int userId, int fromSensorId, @NonNull IInvalidationCallback clientCallback) {
            return new InvalidationTracker(sensors, userId, fromSensorId, clientCallback);
            return new InvalidationTracker(context, sensors, userId, fromSensorId, clientCallback);
        }

        private InvalidationTracker(@NonNull ArrayList<BiometricSensor> sensors, int userId,
        private InvalidationTracker(@NonNull Context context,
                @NonNull ArrayList<BiometricSensor> sensors, int userId,
                int fromSensorId, @NonNull IInvalidationCallback clientCallback) {
            mClientCallback = clientCallback;
            mSensorsPendingInvalidation = new ArraySet<>();
@@ -271,6 +273,14 @@ public class BiometricService extends SystemService {
                    continue;
                }

                try {
                    if (!sensor.impl.hasEnrolledTemplates(userId, context.getOpPackageName())) {
                        continue;
                    }
                } catch (RemoteException e) {
                    Slog.e(TAG, "Remote Exception", e);
                }

                Slog.d(TAG, "Requesting authenticatorId invalidation for sensor: " + sensor.id);

                synchronized (this) {
@@ -288,6 +298,17 @@ public class BiometricService extends SystemService {
                    Slog.d(TAG, "RemoteException", e);
                }
            }

            synchronized (this) {
                if (mSensorsPendingInvalidation.isEmpty()) {
                    try {
                        Slog.d(TAG, "No sensors require invalidation");
                        mClientCallback.onCompleted();
                    } catch (RemoteException e) {
                        Slog.e(TAG, "Remote Exception", e);
                    }
                }
            }
        }

        @VisibleForTesting
@@ -742,7 +763,7 @@ public class BiometricService extends SystemService {
                IInvalidationCallback callback) {
            checkInternalPermission();

            InvalidationTracker.start(mSensors, userId, fromSensorId, callback);
            InvalidationTracker.start(getContext(), mSensors, userId, fromSensorId, callback);
        }

        @Override // Binder call
+1 −1
Original line number Diff line number Diff line
@@ -55,7 +55,7 @@ import android.hardware.biometrics.IInvalidationCallback;
 * switches, the framework can check if any sensor has the "invalidationInProgress" flag set. If so,
 * the framework should re-start the invalidation process described above.
 */
public abstract class InvalidationRequesterClient<S extends BiometricAuthenticator.Identifier>
public class InvalidationRequesterClient<S extends BiometricAuthenticator.Identifier>
        extends BaseClientMonitor {

    private final BiometricManager mBiometricManager;
+17 −0
Original line number Diff line number Diff line
@@ -47,6 +47,7 @@ import com.android.server.biometrics.sensors.AuthenticationClient;
import com.android.server.biometrics.sensors.BaseClientMonitor;
import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
import com.android.server.biometrics.sensors.HalClientMonitor;
import com.android.server.biometrics.sensors.InvalidationRequesterClient;
import com.android.server.biometrics.sensors.LockoutResetDispatcher;
import com.android.server.biometrics.sensors.PerformanceTracker;
import com.android.server.biometrics.sensors.face.FaceUtils;
@@ -206,6 +207,12 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider {
        // this method "withoutHandler" means it should only ever be invoked from the worker thread,
        // so callers will never be blocked.
        mSensors.get(sensorId).createNewSession(daemon, sensorId, userId);

        if (FaceUtils.getInstance(sensorId).isInvalidationInProgress(mContext, userId)) {
            Slog.w(getTag(), "Scheduling unfinished invalidation request for sensor: " + sensorId
                    + ", user: " + userId);
            scheduleInvalidationRequest(sensorId, userId);
        }
    }


@@ -242,6 +249,15 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider {
        });
    }

    private void scheduleInvalidationRequest(int sensorId, int userId) {
        mHandler.post(() -> {
            final InvalidationRequesterClient<Face> client =
                    new InvalidationRequesterClient<>(mContext, userId, sensorId,
                            FaceUtils.getInstance(sensorId));
            mSensors.get(sensorId).getScheduler().scheduleClientMonitor(client);
        });
    }

    @Override
    public boolean containsSensor(int sensorId) {
        return mSensors.contains(sensorId);
@@ -395,6 +411,7 @@ public class FaceProvider implements IBinder.DeathRecipient, ServiceProvider {
                            boolean success) {
                        if (success) {
                            scheduleLoadAuthenticatorIdsForUser(sensorId, userId);
                            scheduleInvalidationRequest(sensorId, userId);
                        }
                    }
                });
Loading