diff options
| author | 2020-06-25 14:10:22 -0700 | |
|---|---|---|
| committer | 2020-06-30 12:51:11 -0700 | |
| commit | da27daf8c41ad7e288cb758b1622a356308d86ed (patch) | |
| tree | fa600a51342e3cc17e8af3924dd5ff2a8789082c | |
| parent | 74b61eb9240d340bd131b84887a4ba3ffcd2da3f (diff) | |
18/n: Make more HAL operations ClientMonitors
1) SetFeature
2) GetFeature
3) ResetLockout
The following will be done in a separate CL
4) SetActiveUser
5) GetAuthenticatorId
Test: Enroll face, go to face settings, toggle attention setting.
Setting is persisted in the HAL and retrieved correctly to
Settings.
Test: Fingerprint/Face lockout, resetLockout
Test: Multi-user / Multi-profile enroll, auth, resetLockout
Bug: 157790417
Change-Id: I063fcc73f0129a1d31214f30928f32708e14e2ff
9 files changed, 294 insertions, 72 deletions
diff --git a/core/java/android/hardware/face/FaceManager.java b/core/java/android/hardware/face/FaceManager.java index 9876de11a2bb..7d33eacfd47c 100644 --- a/core/java/android/hardware/face/FaceManager.java +++ b/core/java/android/hardware/face/FaceManager.java @@ -449,8 +449,8 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan if (mService != null) { try { mSetFeatureCallback = callback; - mService.setFeature(userId, feature, enabled, token, mServiceReceiver, - mContext.getOpPackageName()); + mService.setFeature(mToken, userId, feature, enabled, token, + mServiceReceiver, mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -465,22 +465,8 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan if (mService != null) { try { mGetFeatureCallback = callback; - mService.getFeature(userId, feature, mServiceReceiver, mContext.getOpPackageName()); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - } - - /** - * Pokes the the driver to have it start looking for faces again. - * @hide - */ - @RequiresPermission(MANAGE_BIOMETRIC) - public void userActivity() { - if (mService != null) { - try { - mService.userActivity(); + mService.getFeature(mToken, userId, feature, mServiceReceiver, + mContext.getOpPackageName()); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/core/java/android/hardware/face/IFaceService.aidl b/core/java/android/hardware/face/IFaceService.aidl index 8dbaf2115fe5..0cf233790a8d 100644 --- a/core/java/android/hardware/face/IFaceService.aidl +++ b/core/java/android/hardware/face/IFaceService.aidl @@ -89,12 +89,11 @@ interface IFaceService { // Add a callback which gets notified when the face lockout period expired. void addLockoutResetCallback(IBiometricServiceLockoutResetCallback callback); - void setFeature(int userId, int feature, boolean enabled, in byte [] token, - IFaceServiceReceiver receiver, String opPackageName); + void setFeature(IBinder token, int userId, int feature, boolean enabled, + in byte [] hardwareAuthToken, IFaceServiceReceiver receiver, String opPackageName); - void getFeature(int userId, int feature, IFaceServiceReceiver receiver, String opPackageName); - - void userActivity(); + void getFeature(IBinder token, int userId, int feature, IFaceServiceReceiver receiver, + String opPackageName); // Give FaceService its ID. See AuthService.java void initializeConfiguration(int sensorId); diff --git a/services/core/java/com/android/server/biometrics/sensors/BiometricServiceBase.java b/services/core/java/com/android/server/biometrics/sensors/BiometricServiceBase.java index 4c24d1a61e45..e9ff204ce462 100644 --- a/services/core/java/com/android/server/biometrics/sensors/BiometricServiceBase.java +++ b/services/core/java/com/android/server/biometrics/sensors/BiometricServiceBase.java @@ -751,7 +751,7 @@ public abstract class BiometricServiceBase extends SystemService * @param initiatedByClient true for authenticate, remove and enroll */ @VisibleForTesting - void startClient(ClientMonitor newClient, boolean initiatedByClient) { + protected void startClient(ClientMonitor newClient, boolean initiatedByClient) { ClientMonitor currentClient = mCurrentClient; if (currentClient != null) { if (DEBUG) Slog.v(getTag(), "request stop current client " + diff --git a/services/core/java/com/android/server/biometrics/sensors/ClientMonitor.java b/services/core/java/com/android/server/biometrics/sensors/ClientMonitor.java index ea1fde919a5f..7633a0fd5291 100644 --- a/services/core/java/com/android/server/biometrics/sensors/ClientMonitor.java +++ b/services/core/java/com/android/server/biometrics/sensors/ClientMonitor.java @@ -84,7 +84,7 @@ public abstract class ClientMonitor extends LoggableMonitor implements IBinder.D * @param statsClient One of {@link BiometricsProtoEnums} CLIENT_* constants */ public ClientMonitor(@NonNull FinishCallback finishCallback, @NonNull Context context, - IBinder token, @Nullable ClientMonitorCallbackConverter listener, int userId, + @Nullable IBinder token, @Nullable ClientMonitorCallbackConverter listener, int userId, boolean restricted, @NonNull String owner, int cookie, int sensorId, int statsModality, int statsAction, int statsClient) { super(statsModality, statsAction, statsClient); diff --git a/services/core/java/com/android/server/biometrics/sensors/ClientMonitorCallbackConverter.java b/services/core/java/com/android/server/biometrics/sensors/ClientMonitorCallbackConverter.java index f4863f59db4d..ad14531a9001 100644 --- a/services/core/java/com/android/server/biometrics/sensors/ClientMonitorCallbackConverter.java +++ b/services/core/java/com/android/server/biometrics/sensors/ClientMonitorCallbackConverter.java @@ -126,4 +126,17 @@ public final class ClientMonitorCallbackConverter { mFingerprintServiceReceiver.onChallengeGenerated(challenge); } } + + public void onFeatureSet(boolean success, int feature) throws RemoteException { + if (mFaceServiceReceiver != null) { + mFaceServiceReceiver.onFeatureSet(success, feature); + } + } + + public void onFeatureGet(boolean success, int feature, boolean value) + throws RemoteException { + if (mFaceServiceReceiver != null) { + mFaceServiceReceiver.onFeatureGet(success, feature, value); + } + } } diff --git a/services/core/java/com/android/server/biometrics/sensors/face/FaceGetFeatureClient.java b/services/core/java/com/android/server/biometrics/sensors/face/FaceGetFeatureClient.java new file mode 100644 index 000000000000..a54e71c72ed6 --- /dev/null +++ b/services/core/java/com/android/server/biometrics/sensors/face/FaceGetFeatureClient.java @@ -0,0 +1,76 @@ +/* + * 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.face; + +import android.annotation.NonNull; +import android.content.Context; +import android.hardware.biometrics.BiometricsProtoEnums; +import android.hardware.biometrics.face.V1_0.IBiometricsFace; +import android.hardware.biometrics.face.V1_0.OptionalBool; +import android.hardware.biometrics.face.V1_0.Status; +import android.os.IBinder; +import android.os.RemoteException; +import android.util.Slog; + +import com.android.server.biometrics.sensors.ClientMonitor; +import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter; + +/** + * Face-specific getFeature client supporting the {@link android.hardware.biometrics.face.V1_0} + * and {@link android.hardware.biometrics.face.V1_1} HIDL interfaces. + */ +public class FaceGetFeatureClient extends ClientMonitor { + + private static final String TAG = "FaceGetFeatureClient"; + + private final IBiometricsFace mDaemon; + private final int mFeature; + private final int mFaceId; + + FaceGetFeatureClient(@NonNull FinishCallback finishCallback, @NonNull Context context, + @NonNull IBiometricsFace daemon, @NonNull IBinder token, + @NonNull ClientMonitorCallbackConverter listener, int userId, @NonNull String owner, + int sensorId, int feature, int faceId) { + super(finishCallback, context, token, listener, userId, false /* restricted */, owner, + 0 /* cookie */, sensorId, BiometricsProtoEnums.MODALITY_UNKNOWN, + BiometricsProtoEnums.ACTION_UNKNOWN, BiometricsProtoEnums.CLIENT_UNKNOWN); + mDaemon = daemon; + mFeature = feature; + mFaceId = faceId; + + } + @Override + public void start() { + startHalOperation(); + } + + @Override + protected void startHalOperation() { + try { + final OptionalBool result = mDaemon.getFeature(mFeature, mFaceId); + getListener().onFeatureGet(result.status == Status.OK, mFeature, result.value); + } catch (RemoteException e) { + Slog.e(TAG, "Unable to getFeature", e); + } + mFinishCallback.onClientFinished(this); + } + + @Override + protected void stopHalOperation() { + // Not supported for GetFeature + } +} diff --git a/services/core/java/com/android/server/biometrics/sensors/face/FaceResetLockoutClient.java b/services/core/java/com/android/server/biometrics/sensors/face/FaceResetLockoutClient.java new file mode 100644 index 000000000000..a54a0176dac1 --- /dev/null +++ b/services/core/java/com/android/server/biometrics/sensors/face/FaceResetLockoutClient.java @@ -0,0 +1,75 @@ +/* + * 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.face; + +import android.annotation.NonNull; +import android.content.Context; +import android.hardware.biometrics.BiometricsProtoEnums; +import android.hardware.biometrics.face.V1_0.IBiometricsFace; +import android.os.RemoteException; +import android.util.Slog; + +import com.android.server.biometrics.sensors.ClientMonitor; + +import java.util.ArrayList; + +/** + * Face-specific resetLockout client supporting the {@link android.hardware.biometrics.face.V1_0} + * and {@link android.hardware.biometrics.face.V1_1} HIDL interfaces. + */ +public class FaceResetLockoutClient extends ClientMonitor { + + private static final String TAG = "FaceResetLockoutClient"; + + private final IBiometricsFace mDaemon; + private final ArrayList<Byte> mHardwareAuthToken; + + FaceResetLockoutClient(@NonNull FinishCallback finishCallback, @NonNull Context context, + @NonNull IBiometricsFace daemon, int userId, String owner, int sensorId, + byte[] hardwareAuthToken) { + super(finishCallback, context, null /* token */, null /* listener */, userId, + false /* restricted */, owner, 0 /* cookie */, sensorId, + BiometricsProtoEnums.MODALITY_UNKNOWN, BiometricsProtoEnums.ACTION_UNKNOWN, + BiometricsProtoEnums.CLIENT_UNKNOWN); + mDaemon = daemon; + + mHardwareAuthToken = new ArrayList<>(); + for (byte b : hardwareAuthToken) { + mHardwareAuthToken.add(b); + } + } + + @Override + public void start() { + startHalOperation(); + } + + @Override + protected void startHalOperation() { + try { + mDaemon.resetLockout(mHardwareAuthToken); + } catch (RemoteException e) { + Slog.e(TAG, "Unable to reset lockout", e); + } + mFinishCallback.onClientFinished(this); + } + + @Override + protected void stopHalOperation() { + // Not supported for resetLockout + } +} diff --git a/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java b/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java index 088762c1f39d..eae5c1e69cce 100644 --- a/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java +++ b/services/core/java/com/android/server/biometrics/sensors/face/FaceService.java @@ -386,22 +386,24 @@ public class FaceService extends BiometricServiceBase { Slog.d(TAG, "Resetting lockout for user: " + userId); - updateActiveGroup(userId, null /* opPackageName */); - try { - final ArrayList<Byte> token = new ArrayList<>(); - for (int i = 0; i < hardwareAuthToken.length; i++) { - token.add(hardwareAuthToken[i]); - } - mDaemon.resetLockout(token); - } catch (RemoteException e) { - Slog.e(getTag(), "Unable to reset lockout", e); + final IBiometricsFace daemon = getFaceDaemon(); + if (daemon == null) { + Slog.e(TAG, "daemon null, skipping template cleanup"); + return; } + + updateActiveGroup(userId, null /* opPackageName */); + final FaceResetLockoutClient client = new FaceResetLockoutClient( + mClientFinishCallback, getContext(), daemon, userId, + getContext().getOpPackageName(), getSensorId(), hardwareAuthToken); + startClient(client, true /* initiatedByClient */); }); } @Override - public void setFeature(int userId, int feature, boolean enabled, final byte[] token, - IFaceServiceReceiver receiver, final String opPackageName) { + public void setFeature(final IBinder token, int userId, int feature, boolean enabled, + final byte[] hardwareAuthToken, IFaceServiceReceiver receiver, + final String opPackageName) { checkPermission(MANAGE_BIOMETRIC); mHandler.post(() -> { @@ -414,30 +416,26 @@ public class FaceService extends BiometricServiceBase { return; } - final ArrayList<Byte> byteToken = new ArrayList<>(); - for (int i = 0; i < token.length; i++) { - byteToken.add(token[i]); - } - - // TODO: Support multiple faces final int faceId = getFirstTemplateForUser(mCurrentUserId); - if (mDaemon != null) { - try { - final int result = mDaemon.setFeature(feature, enabled, byteToken, faceId); - receiver.onFeatureSet(result == Status.OK, feature); - } catch (RemoteException e) { - Slog.e(getTag(), "Unable to set feature: " + feature - + " to enabled:" + enabled, e); - } + final IBiometricsFace daemon = getFaceDaemon(); + if (daemon == null) { + Slog.e(TAG, "daemon null, skipping template cleanup"); + return; } + + final FaceSetFeatureClient client = new FaceSetFeatureClient(mClientFinishCallback, + getContext(), daemon, token, new ClientMonitorCallbackConverter(receiver), + userId, opPackageName, getSensorId(), feature, enabled, hardwareAuthToken, + faceId); + startClient(client, true /* initiatedByClient */); }); } @Override - public void getFeature(int userId, int feature, IFaceServiceReceiver receiver, - final String opPackageName) { + public void getFeature(final IBinder token, int userId, int feature, + IFaceServiceReceiver receiver, final String opPackageName) { checkPermission(MANAGE_BIOMETRIC); mHandler.post(() -> { @@ -455,29 +453,18 @@ public class FaceService extends BiometricServiceBase { // TODO: Support multiple faces final int faceId = getFirstTemplateForUser(mCurrentUserId); - if (mDaemon != null) { - try { - OptionalBool result = mDaemon.getFeature(feature, faceId); - receiver.onFeatureGet(result.status == Status.OK, feature, result.value); - } catch (RemoteException e) { - Slog.e(getTag(), "Unable to getRequireAttention", e); - } + final IBiometricsFace daemon = getFaceDaemon(); + if (daemon == null) { + Slog.e(TAG, "daemon null, skipping template cleanup"); + return; } - }); - } - - @Override - public void userActivity() { - checkPermission(MANAGE_BIOMETRIC); + final FaceGetFeatureClient client = new FaceGetFeatureClient(mClientFinishCallback, + getContext(), daemon, token, new ClientMonitorCallbackConverter(receiver), + userId, opPackageName, getSensorId(), feature, faceId); + startClient(client, true /* initiatedByClient */); + }); - if (mDaemon != null) { - try { - mDaemon.userActivity(); - } catch (RemoteException e) { - Slog.e(getTag(), "Unable to send userActivity", e); - } - } } // TODO: Support multiple faces diff --git a/services/core/java/com/android/server/biometrics/sensors/face/FaceSetFeatureClient.java b/services/core/java/com/android/server/biometrics/sensors/face/FaceSetFeatureClient.java new file mode 100644 index 000000000000..c0420f49b9ed --- /dev/null +++ b/services/core/java/com/android/server/biometrics/sensors/face/FaceSetFeatureClient.java @@ -0,0 +1,86 @@ +/* + * 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.face; + +import android.annotation.NonNull; +import android.content.Context; +import android.hardware.biometrics.BiometricsProtoEnums; +import android.hardware.biometrics.face.V1_0.IBiometricsFace; +import android.hardware.biometrics.face.V1_0.Status; +import android.os.IBinder; +import android.os.RemoteException; +import android.util.Slog; + +import com.android.server.biometrics.sensors.ClientMonitor; +import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter; + +import java.util.ArrayList; + +/** + * Face-specific setFeature client supporting the {@link android.hardware.biometrics.face.V1_0} + * and {@link android.hardware.biometrics.face.V1_1} HIDL interfaces. + */ +public class FaceSetFeatureClient extends ClientMonitor { + + private static final String TAG = "FaceSetFeatureClient"; + + private final IBiometricsFace mDaemon; + private final int mFeature; + private final boolean mEnabled; + private final ArrayList<Byte> mHardwareAuthToken; + private final int mFaceId; + + FaceSetFeatureClient(@NonNull FinishCallback finishCallback, @NonNull Context context, + @NonNull IBiometricsFace daemon, @NonNull IBinder token, + @NonNull ClientMonitorCallbackConverter listener, int userId, + @NonNull String owner, int sensorId, int feature, boolean enabled, + byte[] hardwareAuthToken, int faceId) { + super(finishCallback, context, token, listener, userId, false /* restricted */, + owner, 0 /* cookie */, sensorId, BiometricsProtoEnums.MODALITY_UNKNOWN, + BiometricsProtoEnums.ACTION_UNKNOWN, BiometricsProtoEnums.CLIENT_UNKNOWN); + mDaemon = daemon; + mFeature = feature; + mEnabled = enabled; + mFaceId = faceId; + + mHardwareAuthToken = new ArrayList<>(); + for (byte b : hardwareAuthToken) { + mHardwareAuthToken.add(b); + } + } + + @Override + public void start() { + startHalOperation(); + mFinishCallback.onClientFinished(this); + } + + @Override + protected void startHalOperation() { + try { + final int result = mDaemon.setFeature(mFeature, mEnabled, mHardwareAuthToken, mFaceId); + getListener().onFeatureSet(result == Status.OK, mFeature); + } catch (RemoteException e) { + Slog.e(TAG, "Unable to set feature: " + mFeature + " to enabled: " + mEnabled, e); + } + } + + @Override + protected void stopHalOperation() { + // Not supported for SetFeature + } +} |