Split error and cancellation into separate interfaces

Not all clients need to be cancelled in order for it to receive
onError. For example, IFace#resetLockout.

Bug: 184774513
Test: atest CtsBiometricsTestCases
Test: atest com.android.server.biometrics
Change-Id: I4db4747fe03725976c6c8cfa5248420f82287140
This commit is contained in:
Kevin Chyn
2021-04-07 17:25:56 -07:00
parent f4276c38c2
commit 6ef340b2ef
8 changed files with 63 additions and 36 deletions

View File

@@ -32,7 +32,8 @@ import android.util.Slog;
* Abstract {@link HalClientMonitor} subclass that operations eligible/interested in acquisition
* messages should extend.
*/
public abstract class AcquisitionClient<T> extends HalClientMonitor<T> implements Interruptable {
public abstract class AcquisitionClient<T> extends HalClientMonitor<T> implements Interruptable,
ErrorConsumer {
private static final String TAG = "Biometrics/AcquisitionClient";

View File

@@ -422,9 +422,9 @@ public class BiometricScheduler {
+ mCurrentOperation);
// This should trigger the internal onClientFinished callback, which clears the
// operation and starts the next one.
final Interruptable interruptable =
(Interruptable) mCurrentOperation.mClientMonitor;
interruptable.onError(BiometricConstants.BIOMETRIC_ERROR_CANCELED,
final ErrorConsumer errorConsumer =
(ErrorConsumer) mCurrentOperation.mClientMonitor;
errorConsumer.onError(BiometricConstants.BIOMETRIC_ERROR_CANCELED,
0 /* vendorCode */);
return;
} else {

View File

@@ -0,0 +1,30 @@
/*
* Copyright (C) 2021 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;
/**
* Interface that {@link BaseClientMonitor} subclasses eligible/interested in error callbacks should
* implement.
*/
public interface ErrorConsumer {
/**
* Notifies the client of errors from the HAL.
* @param errorCode defined by the HIDL interface
* @param vendorCode defined by the vendor
*/
void onError(int errorCode, int vendorCode);
}

View File

@@ -19,8 +19,7 @@ package com.android.server.biometrics.sensors;
import android.annotation.NonNull;
/**
* Interface that {@link BaseClientMonitor} subclasses eligible/interested in error callbacks should
* implement.
* Interface that {@link BaseClientMonitor} subclasses eligible for cancellation should implement.
*/
public interface Interruptable {
/**
@@ -28,13 +27,6 @@ public interface Interruptable {
*/
void cancel();
/**
* Notifies the client of errors from the HAL.
* @param errorCode defined by the HIDL interface
* @param vendorCode defined by the vendor
*/
void onError(int errorCode, int vendorCode);
/**
* Notifies the client that it needs to finish before
* {@link BaseClientMonitor#start(BaseClientMonitor.Callback)} was invoked. This usually happens

View File

@@ -52,6 +52,7 @@ import com.android.server.biometrics.sensors.AuthenticationConsumer;
import com.android.server.biometrics.sensors.BaseClientMonitor;
import com.android.server.biometrics.sensors.BiometricScheduler;
import com.android.server.biometrics.sensors.EnumerateConsumer;
import com.android.server.biometrics.sensors.ErrorConsumer;
import com.android.server.biometrics.sensors.HalClientMonitor;
import com.android.server.biometrics.sensors.Interruptable;
import com.android.server.biometrics.sensors.LockoutCache;
@@ -215,14 +216,14 @@ public class Sensor {
+ ", client: " + Utils.getClientName(client)
+ ", error: " + error
+ ", vendorCode: " + vendorCode);
if (!(client instanceof Interruptable)) {
if (!(client instanceof ErrorConsumer)) {
Slog.e(mTag, "onError for non-error consumer: "
+ Utils.getClientName(client));
return;
}
final Interruptable interruptable = (Interruptable) client;
interruptable.onError(error, vendorCode);
final ErrorConsumer errorConsumer = (ErrorConsumer) client;
errorConsumer.onError(error, vendorCode);
if (error == Error.HW_UNAVAILABLE) {
mCallback.onHardwareUnavailable();
@@ -581,8 +582,8 @@ public class Sensor {
final BaseClientMonitor client = mScheduler.getCurrentClient();
if (client instanceof Interruptable) {
Slog.e(mTag, "Sending ERROR_HW_UNAVAILABLE for client: " + client);
final Interruptable interruptable = (Interruptable) client;
interruptable.onError(FaceManager.FACE_ERROR_HW_UNAVAILABLE,
final ErrorConsumer errorConsumer = (ErrorConsumer) client;
errorConsumer.onError(FaceManager.FACE_ERROR_HW_UNAVAILABLE,
0 /* vendorCode */);
FrameworkStatsLog.write(FrameworkStatsLog.BIOMETRIC_SYSTEM_HEALTH_ISSUE_DETECTED,

View File

@@ -64,6 +64,7 @@ import com.android.server.biometrics.sensors.BaseClientMonitor;
import com.android.server.biometrics.sensors.BiometricScheduler;
import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
import com.android.server.biometrics.sensors.EnumerateConsumer;
import com.android.server.biometrics.sensors.ErrorConsumer;
import com.android.server.biometrics.sensors.HalClientMonitor;
import com.android.server.biometrics.sensors.Interruptable;
import com.android.server.biometrics.sensors.LockoutResetDispatcher;
@@ -227,14 +228,14 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider {
+ ", client: " + (client != null ? client.getOwnerString() : null)
+ ", error: " + error
+ ", vendorCode: " + vendorCode);
if (!(client instanceof Interruptable)) {
if (!(client instanceof ErrorConsumer)) {
Slog.e(TAG, "onError for non-error consumer: " + Utils.getClientName(
client));
return;
}
final Interruptable interruptable = (Interruptable) client;
interruptable.onError(error, vendorCode);
final ErrorConsumer errorConsumer = (ErrorConsumer) client;
errorConsumer.onError(error, vendorCode);
if (error == BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE) {
Slog.e(TAG, "Got ERROR_HW_UNAVAILABLE");
@@ -379,10 +380,10 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider {
mCurrentUserId = UserHandle.USER_NULL;
final BaseClientMonitor client = mScheduler.getCurrentClient();
if (client instanceof Interruptable) {
if (client instanceof ErrorConsumer) {
Slog.e(TAG, "Sending ERROR_HW_UNAVAILABLE for client: " + client);
final Interruptable interruptable = (Interruptable) client;
interruptable.onError(BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE,
final ErrorConsumer errorConsumer = (ErrorConsumer) client;
errorConsumer.onError(BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE,
0 /* vendorCode */);
FrameworkStatsLog.write(FrameworkStatsLog.BIOMETRIC_SYSTEM_HEALTH_ISSUE_DETECTED,

View File

@@ -50,6 +50,7 @@ import com.android.server.biometrics.sensors.AuthenticationConsumer;
import com.android.server.biometrics.sensors.BaseClientMonitor;
import com.android.server.biometrics.sensors.BiometricScheduler;
import com.android.server.biometrics.sensors.EnumerateConsumer;
import com.android.server.biometrics.sensors.ErrorConsumer;
import com.android.server.biometrics.sensors.HalClientMonitor;
import com.android.server.biometrics.sensors.Interruptable;
import com.android.server.biometrics.sensors.LockoutCache;
@@ -190,14 +191,14 @@ class Sensor {
+ ", client: " + Utils.getClientName(client)
+ ", error: " + error
+ ", vendorCode: " + vendorCode);
if (!(client instanceof Interruptable)) {
if (!(client instanceof ErrorConsumer)) {
Slog.e(mTag, "onError for non-error consumer: "
+ Utils.getClientName(client));
return;
}
final Interruptable interruptable = (Interruptable) client;
interruptable.onError(error, vendorCode);
final ErrorConsumer errorConsumer = (ErrorConsumer) client;
errorConsumer.onError(error, vendorCode);
if (error == Error.HW_UNAVAILABLE) {
mCallback.onHardwareUnavailable();
@@ -549,10 +550,10 @@ class Sensor {
public void onBinderDied() {
final BaseClientMonitor client = mScheduler.getCurrentClient();
if (client instanceof Interruptable) {
if (client instanceof ErrorConsumer) {
Slog.e(mTag, "Sending ERROR_HW_UNAVAILABLE for client: " + client);
final Interruptable interruptable = (Interruptable) client;
interruptable.onError(FingerprintManager.FINGERPRINT_ERROR_HW_UNAVAILABLE,
final ErrorConsumer errorConsumer = (ErrorConsumer) client;
errorConsumer.onError(FingerprintManager.FINGERPRINT_ERROR_HW_UNAVAILABLE,
0 /* vendorCode */);
FrameworkStatsLog.write(FrameworkStatsLog.BIOMETRIC_SYSTEM_HEALTH_ISSUE_DETECTED,

View File

@@ -68,6 +68,7 @@ import com.android.server.biometrics.sensors.BaseClientMonitor;
import com.android.server.biometrics.sensors.BiometricScheduler;
import com.android.server.biometrics.sensors.ClientMonitorCallbackConverter;
import com.android.server.biometrics.sensors.EnumerateConsumer;
import com.android.server.biometrics.sensors.ErrorConsumer;
import com.android.server.biometrics.sensors.HalClientMonitor;
import com.android.server.biometrics.sensors.Interruptable;
import com.android.server.biometrics.sensors.LockoutResetDispatcher;
@@ -262,13 +263,13 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider
+ ", client: " + Utils.getClientName(client)
+ ", error: " + error
+ ", vendorCode: " + vendorCode);
if (!(client instanceof Interruptable)) {
if (!(client instanceof ErrorConsumer)) {
Slog.e(TAG, "onError for non-error consumer: " + Utils.getClientName(client));
return;
}
final Interruptable interruptable = (Interruptable) client;
interruptable.onError(error, vendorCode);
final ErrorConsumer errorConsumer = (ErrorConsumer) client;
errorConsumer.onError(error, vendorCode);
if (error == BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE) {
Slog.e(TAG, "Got ERROR_HW_UNAVAILABLE");
@@ -392,10 +393,10 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider
mCurrentUserId = UserHandle.USER_NULL;
final BaseClientMonitor client = mScheduler.getCurrentClient();
if (client instanceof Interruptable) {
if (client instanceof ErrorConsumer) {
Slog.e(TAG, "Sending ERROR_HW_UNAVAILABLE for client: " + client);
final Interruptable interruptable = (Interruptable) client;
interruptable.onError(BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE,
final ErrorConsumer errorConsumer = (ErrorConsumer) client;
errorConsumer.onError(BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE,
0 /* vendorCode */);
FrameworkStatsLog.write(FrameworkStatsLog.BIOMETRIC_SYSTEM_HEALTH_ISSUE_DETECTED,