diff --git a/services/core/java/com/android/server/biometrics/sensors/face/FaceUserState.java b/services/core/java/com/android/server/biometrics/sensors/face/FaceUserState.java index 42c7d16951d70..3fdd279486560 100644 --- a/services/core/java/com/android/server/biometrics/sensors/face/FaceUserState.java +++ b/services/core/java/com/android/server/biometrics/sensors/face/FaceUserState.java @@ -17,7 +17,6 @@ package com.android.server.biometrics.sensors.face; import android.content.Context; -import android.hardware.biometrics.BiometricAuthenticator; import android.hardware.face.Face; import android.util.AtomicFile; import android.util.Slog; @@ -41,7 +40,7 @@ import java.util.ArrayList; * Class managing the set of faces per user across device reboots. * @hide */ -public class FaceUserState extends BiometricUserState { +public class FaceUserState extends BiometricUserState { private static final String TAG = "FaceState"; private static final String FACE_FILE = "settings_face.xml"; @@ -72,19 +71,9 @@ public class FaceUserState extends BiometricUserState { } @Override - public void addBiometric(BiometricAuthenticator.Identifier identifier) { - if (identifier instanceof Face) { - super.addBiometric(identifier); - } else { - Slog.w(TAG, "Attempted to add non-face identifier"); - } - } - - @Override - protected ArrayList getCopy(ArrayList array) { - ArrayList result = new ArrayList<>(array.size()); - for (int i = 0; i < array.size(); i++) { - Face f = (Face) array.get(i); + protected ArrayList getCopy(ArrayList array) { + final ArrayList result = new ArrayList<>(); + for (Face f : array) { result.add(new Face(f.getName(), f.getBiometricId(), f.getDeviceId())); } return result; diff --git a/services/core/java/com/android/server/biometrics/sensors/face/FaceUtils.java b/services/core/java/com/android/server/biometrics/sensors/face/FaceUtils.java index 0197028cfd6ed..f47b22839e709 100644 --- a/services/core/java/com/android/server/biometrics/sensors/face/FaceUtils.java +++ b/services/core/java/com/android/server/biometrics/sensors/face/FaceUtils.java @@ -30,7 +30,7 @@ import java.util.List; /** * Utility class for dealing with faces and face settings. */ -public class FaceUtils implements BiometricUtils { +public class FaceUtils implements BiometricUtils { private static final Object sInstanceLock = new Object(); private static FaceUtils sInstance; @@ -56,9 +56,8 @@ public class FaceUtils implements BiometricUtils { } @Override - public void addBiometricForUser(Context ctx, int userId, - BiometricAuthenticator.Identifier identifier) { - getStateForUser(ctx, userId).addBiometric(identifier); + public void addBiometricForUser(Context ctx, int userId, Face face) { + getStateForUser(ctx, userId).addBiometric(face); } @Override diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintUserState.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintUserState.java index 56312bcb16e4f..f32d28c4d7ee4 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintUserState.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintUserState.java @@ -17,7 +17,6 @@ package com.android.server.biometrics.sensors.fingerprint; import android.content.Context; -import android.hardware.biometrics.BiometricAuthenticator; import android.hardware.fingerprint.Fingerprint; import android.util.AtomicFile; import android.util.Slog; @@ -40,7 +39,7 @@ import java.util.ArrayList; * Class managing the set of fingerprint per user across device reboots. * @hide */ -public class FingerprintUserState extends BiometricUserState { +public class FingerprintUserState extends BiometricUserState { private static final String TAG = "FingerprintState"; private static final String FINGERPRINT_FILE = "settings_fingerprint.xml"; @@ -72,19 +71,9 @@ public class FingerprintUserState extends BiometricUserState { } @Override - public void addBiometric(BiometricAuthenticator.Identifier identifier) { - if (identifier instanceof Fingerprint) { - super.addBiometric(identifier); - } else { - Slog.w(TAG, "Attempted to add non-fingerprint identifier"); - } - } - - @Override - protected ArrayList getCopy(ArrayList array) { - ArrayList result = new ArrayList<>(); - for (int i = 0; i < array.size(); i++) { - Fingerprint fp = (Fingerprint) array.get(i); + protected ArrayList getCopy(ArrayList array) { + final ArrayList result = new ArrayList<>(); + for (Fingerprint fp : array) { result.add(new Fingerprint(fp.getName(), fp.getGroupId(), fp.getBiometricId(), fp.getDeviceId())); } diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintUtils.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintUtils.java index f0bfe12db32a3..3bf3a5b3ea37d 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintUtils.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintUtils.java @@ -30,7 +30,7 @@ import java.util.List; /** * Utility class for dealing with fingerprints and fingerprint settings. */ -public class FingerprintUtils implements BiometricUtils { +public class FingerprintUtils implements BiometricUtils { private static final Object sInstanceLock = new Object(); private static FingerprintUtils sInstance; @@ -56,9 +56,8 @@ public class FingerprintUtils implements BiometricUtils { } @Override - public void addBiometricForUser(Context context, int userId, - BiometricAuthenticator.Identifier identifier) { - getStateForUser(context, userId).addBiometric(identifier); + public void addBiometricForUser(Context context, int userId, Fingerprint fingerprint) { + getStateForUser(context, userId).addBiometric(fingerprint); } @Override diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java index 33f5418ee6200..c96bef167e8bb 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintEnrollClient.java @@ -21,6 +21,7 @@ import android.annotation.Nullable; import android.content.Context; import android.hardware.biometrics.BiometricFaceConstants; import android.hardware.biometrics.BiometricFingerprintConstants; +import android.hardware.biometrics.BiometricsProtoEnums; import android.hardware.biometrics.common.ICancellationSignal; import android.hardware.biometrics.fingerprint.ISession; import android.hardware.fingerprint.IUdfpsOverlayController; @@ -48,11 +49,12 @@ public class FingerprintEnrollClient extends EnrollClient implements U public FingerprintEnrollClient(@NonNull Context context, @NonNull LazyDaemon lazyDaemon, @NonNull IBinder token, @NonNull ClientMonitorCallbackConverter listener, int userId, - @NonNull byte[] hardwareAuthToken, @NonNull String owner, @NonNull BiometricUtils utils, - int statsModality, int sensorId, + @NonNull byte[] hardwareAuthToken, @NonNull String owner, + @NonNull FingerprintUtils utils, int sensorId, @Nullable IUdfpsOverlayController udfpsOvelayController, int maxTemplatesPerUser) { super(context, lazyDaemon, token, listener, userId, hardwareAuthToken, owner, utils, - 0 /* timeoutSec */, statsModality, sensorId, true /* shouldVibrate */); + 0 /* timeoutSec */, BiometricsProtoEnums.MODALITY_FINGERPRINT, sensorId, + true /* shouldVibrate */); mUdfpsOverlayController = udfpsOvelayController; mMaxTemplatesPerUser = maxTemplatesPerUser; } @@ -83,7 +85,7 @@ public class FingerprintEnrollClient extends EnrollClient implements U protected void startHalOperation() { UdfpsHelper.showUdfpsOverlay(getSensorId(), mUdfpsOverlayController); try { - getFreshDaemon().enroll(mSequentialId, + mCancellationSignal = getFreshDaemon().enroll(mSequentialId, HardwareAuthTokenUtils.toHardwareAuthToken(mHardwareAuthToken)); } catch (RemoteException e) { Slog.e(TAG, "Remote exception when requesting enroll", e); diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java index 5e6c30ecefc88..bac83b9e21ef5 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintProvider.java @@ -285,8 +285,7 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi final FingerprintEnrollClient client = new FingerprintEnrollClient(mContext, mSensors.get(sensorId).getLazySession(), token, new ClientMonitorCallbackConverter(receiver), userId, hardwareAuthToken, - opPackageName, FingerprintUtils.getInstance(), - BiometricsProtoEnums.MODALITY_FINGERPRINT, sensorId, + opPackageName, FingerprintUtils.getInstance(), sensorId, mUdfpsOverlayController, maxTemplatesPerUser); scheduleForSensor(sensorId, client, new ClientMonitor.Callback() { @Override @@ -363,7 +362,31 @@ public class FingerprintProvider implements IBinder.DeathRecipient, ServiceProvi public void scheduleRemove(int sensorId, @NonNull IBinder token, @NonNull IFingerprintServiceReceiver receiver, int fingerId, int userId, @NonNull String opPackageName) { + mHandler.post(() -> { + final IFingerprint daemon = getHalInstance(); + if (daemon == null) { + Slog.e(getTag(), "Null daemon during remove, sensorId: " + sensorId); + // If this happens, we need to send HW_UNAVAILABLE after the scheduler gets to + // this operation. We should not send the callback yet, since the scheduler may + // be processing something else. + return; + } + try { + if (!mSensors.get(sensorId).hasSessionForUser(userId)) { + createNewSessionWithoutHandler(daemon, sensorId, userId); + } + + final FingerprintRemovalClient client = new FingerprintRemovalClient(mContext, + mSensors.get(sensorId).getLazySession(), token, + new ClientMonitorCallbackConverter(receiver), fingerId, userId, + opPackageName, FingerprintUtils.getInstance(), sensorId, + mSensors.get(sensorId).getAuthenticatorIds()); + mSensors.get(sensorId).getScheduler().scheduleClientMonitor(client); + } catch (RemoteException e) { + Slog.e(getTag(), "Remote exception when scheduling remove", e); + } + }); } @Override diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintRemovalClient.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintRemovalClient.java new file mode 100644 index 0000000000000..df063dc34017d --- /dev/null +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/FingerprintRemovalClient.java @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.biometrics.sensors.fingerprint.aidl; + +import android.annotation.NonNull; +import android.content.Context; +import android.hardware.biometrics.BiometricsProtoEnums; +import android.hardware.biometrics.fingerprint.ISession; +import android.os.IBinder; +import android.os.RemoteException; +import android.util.Slog; + +import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter; +import com.android.server.biometrics.sensors.RemovalClient; +import com.android.server.biometrics.sensors.fingerprint.FingerprintUtils; + +import java.util.Map; + +/** + * Fingerprint-specific removal client supporting the + * {@link android.hardware.biometrics.fingerprint.IFingerprint} interface. + */ +public class FingerprintRemovalClient extends RemovalClient { + private static final String TAG = "FingerprintRemovalClient"; + + public FingerprintRemovalClient(@NonNull Context context, + @NonNull LazyDaemon lazyDaemon, @NonNull IBinder token, + @NonNull ClientMonitorCallbackConverter listener, int biometricId, int userId, + @NonNull String owner, @NonNull FingerprintUtils utils, int sensorId, + @NonNull Map authenticatorIds) { + super(context, lazyDaemon, token, listener, biometricId, userId, owner, utils, sensorId, + authenticatorIds, BiometricsProtoEnums.MODALITY_FINGERPRINT); + } + + @Override + protected void startHalOperation() { + try { + final int[] ids = new int[] {mBiometricId}; + getFreshDaemon().removeEnrollments(mSequentialId, ids); + } catch (RemoteException e) { + Slog.e(TAG, "Remote exception when requesting remove", e); + mCallback.onClientFinished(this, false /* success */); + } + } +} diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/Sensor.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/Sensor.java index dc90be8ea886c..b7aa2d579f546 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/Sensor.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/aidl/Sensor.java @@ -43,7 +43,9 @@ import com.android.server.biometrics.sensors.fingerprint.GestureAvailabilityDisp import java.util.ArrayList; import java.util.Arrays; +import java.util.HashMap; import java.util.List; +import java.util.Map; /** * Maintains the state of a single sensor within an instance of the @@ -56,6 +58,7 @@ class Sensor { @NonNull private final FingerprintSensorPropertiesInternal mSensorProperties; @NonNull private final BiometricScheduler mScheduler; @NonNull private final LockoutCache mLockoutCache; + @NonNull private final Map mAuthenticatorIds; @Nullable private Session mCurrentSession; // TODO: Death recipient @NonNull private final ClientMonitor.LazyDaemon mLazySession; @@ -85,6 +88,7 @@ class Sensor { mSensorProperties = sensorProperties; mScheduler = new BiometricScheduler(tag, gestureAvailabilityDispatcher); mLockoutCache = new LockoutCache(); + mAuthenticatorIds = new HashMap<>(); mLazySession = () -> mCurrentSession != null ? mCurrentSession.mSession : null; } @@ -291,4 +295,8 @@ class Sensor { @NonNull LockoutCache getLockoutCache() { return mLockoutCache; } + + @NonNull Map getAuthenticatorIds() { + return mAuthenticatorIds; + } }