diff options
author | TreeHugger Robot <treehugger-gerrit@google.com> | 2021-07-19 19:25:44 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2021-07-19 19:25:44 +0000 |
commit | c4815d0f2d03ad5e08e1053d2f3431a788dc97ab (patch) | |
tree | 323790e2912e68e2db43999f15d0b7723c4f882b | |
parent | c4adbc278e61ca62d8deeeb906ec29d951a8a243 (diff) | |
parent | 164f70d4f10291fdee6f59321e5688b8d5d25031 (diff) |
Merge "4/n: Make CoexCoordinator multi-sensor-aware" into sc-dev
12 files changed, 150 insertions, 24 deletions
diff --git a/services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java b/services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java index adda10eb109f..61266071f788 100644 --- a/services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java +++ b/services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java @@ -22,6 +22,7 @@ import android.annotation.Nullable; import android.content.Context; import android.hardware.biometrics.BiometricConstants; import android.hardware.biometrics.IBiometricService; +import android.hardware.fingerprint.FingerprintSensorPropertiesInternal; import android.os.Handler; import android.os.IBinder; import android.os.Looper; @@ -48,8 +49,11 @@ import java.util.Locale; /** * A scheduler for biometric HAL operations. Maintains a queue of {@link BaseClientMonitor} - * operations, without caring about its implementation details. Operations may perform one or more + * operations, without caring about its implementation details. Operations may perform zero or more * interactions with the HAL before finishing. + * + * We currently assume (and require) that each biometric sensor have its own instance of a + * {@link BiometricScheduler}. See {@link CoexCoordinator}. */ public class BiometricScheduler { @@ -58,6 +62,55 @@ public class BiometricScheduler { protected static final int LOG_NUM_RECENT_OPERATIONS = 50; /** + * Unknown sensor type. This should never be used, and is a sign that something is wrong during + * initialization. + */ + public static final int SENSOR_TYPE_UNKNOWN = 0; + + /** + * Face authentication. + */ + public static final int SENSOR_TYPE_FACE = 1; + + /** + * Any UDFPS type. See {@link FingerprintSensorPropertiesInternal#isAnyUdfpsType()}. + */ + public static final int SENSOR_TYPE_UDFPS = 2; + + /** + * Any other fingerprint sensor. We can add additional definitions in the future when necessary. + */ + public static final int SENSOR_TYPE_FP_OTHER = 3; + + @IntDef({SENSOR_TYPE_UNKNOWN, SENSOR_TYPE_FACE, SENSOR_TYPE_UDFPS, SENSOR_TYPE_FP_OTHER}) + @Retention(RetentionPolicy.SOURCE) + public @interface SensorType {} + + public static @SensorType int sensorTypeFromFingerprintProperties( + @NonNull FingerprintSensorPropertiesInternal props) { + if (props.isAnyUdfpsType()) { + return SENSOR_TYPE_UDFPS; + } + + return SENSOR_TYPE_FP_OTHER; + } + + public static String sensorTypeToString(@SensorType int sensorType) { + switch (sensorType) { + case SENSOR_TYPE_UNKNOWN: + return "Unknown"; + case SENSOR_TYPE_FACE: + return "Face"; + case SENSOR_TYPE_UDFPS: + return "Udfps"; + case SENSOR_TYPE_FP_OTHER: + return "OtherFp"; + default: + return "UnknownUnknown"; + } + } + + /** * Contains all the necessary information for a HAL operation. */ @VisibleForTesting @@ -207,6 +260,7 @@ public class BiometricScheduler { } @NonNull protected final String mBiometricTag; + private final @SensorType int mSensorType; @Nullable private final GestureAvailabilityDispatcher mGestureAvailabilityDispatcher; @NonNull private final IBiometricService mBiometricService; @NonNull protected final Handler mHandler = new Handler(Looper.getMainLooper()); @@ -218,6 +272,7 @@ public class BiometricScheduler { private int mTotalOperationsHandled; private final int mRecentOperationsLimit; @NonNull private final List<Integer> mRecentOperations; + @NonNull private final CoexCoordinator mCoexCoordinator; // Internal callback, notified when an operation is complete. Notifies the requester // that the operation is complete, before performing internal scheduler work (such as @@ -226,6 +281,12 @@ public class BiometricScheduler { @Override public void onClientStarted(@NonNull BaseClientMonitor clientMonitor) { Slog.d(getTag(), "[Started] " + clientMonitor); + + if (clientMonitor instanceof AuthenticationClient) { + mCoexCoordinator.addAuthenticationClient(mSensorType, + (AuthenticationClient<?>) clientMonitor); + } + if (mCurrentOperation.mClientCallback != null) { mCurrentOperation.mClientCallback.onClientStarted(clientMonitor); } @@ -248,6 +309,11 @@ public class BiometricScheduler { } Slog.d(getTag(), "[Finishing] " + clientMonitor + ", success: " + success); + if (clientMonitor instanceof AuthenticationClient) { + mCoexCoordinator.removeAuthenticationClient(mSensorType, + (AuthenticationClient<?>) clientMonitor); + } + mCurrentOperation.mState = Operation.STATE_FINISHED; if (mCurrentOperation.mClientCallback != null) { @@ -271,10 +337,12 @@ public class BiometricScheduler { } @VisibleForTesting - BiometricScheduler(@NonNull String tag, + BiometricScheduler(@NonNull String tag, @SensorType int sensorType, @Nullable GestureAvailabilityDispatcher gestureAvailabilityDispatcher, - @NonNull IBiometricService biometricService, int recentOperationsLimit) { + @NonNull IBiometricService biometricService, int recentOperationsLimit, + @NonNull CoexCoordinator coexCoordinator) { mBiometricTag = tag; + mSensorType = sensorType; mInternalCallback = new InternalCallback(); mGestureAvailabilityDispatcher = gestureAvailabilityDispatcher; mPendingOperations = new ArrayDeque<>(); @@ -282,6 +350,7 @@ public class BiometricScheduler { mCrashStates = new ArrayDeque<>(); mRecentOperationsLimit = recentOperationsLimit; mRecentOperations = new ArrayList<>(); + mCoexCoordinator = coexCoordinator; } /** @@ -290,10 +359,11 @@ public class BiometricScheduler { * @param gestureAvailabilityDispatcher may be null if the sensor does not support gestures * (such as fingerprint swipe). */ - public BiometricScheduler(@NonNull String tag, + public BiometricScheduler(@NonNull String tag, @SensorType int sensorType, @Nullable GestureAvailabilityDispatcher gestureAvailabilityDispatcher) { - this(tag, gestureAvailabilityDispatcher, IBiometricService.Stub.asInterface( - ServiceManager.getService(Context.BIOMETRIC_SERVICE)), LOG_NUM_RECENT_OPERATIONS); + this(tag, sensorType, gestureAvailabilityDispatcher, IBiometricService.Stub.asInterface( + ServiceManager.getService(Context.BIOMETRIC_SERVICE)), LOG_NUM_RECENT_OPERATIONS, + CoexCoordinator.getInstance()); } /** @@ -645,6 +715,7 @@ public class BiometricScheduler { public void dump(PrintWriter pw) { pw.println("Dump of BiometricScheduler " + getTag()); + pw.println("Type: " + mSensorType); pw.println("Current operation: " + mCurrentOperation); pw.println("Pending operations: " + mPendingOperations.size()); for (Operation operation : mPendingOperations) { diff --git a/services/core/java/com/android/server/biometrics/sensors/CoexCoordinator.java b/services/core/java/com/android/server/biometrics/sensors/CoexCoordinator.java index cccb6e2d3c90..08bf2e020f75 100644 --- a/services/core/java/com/android/server/biometrics/sensors/CoexCoordinator.java +++ b/services/core/java/com/android/server/biometrics/sensors/CoexCoordinator.java @@ -16,7 +16,13 @@ package com.android.server.biometrics.sensors; +import static com.android.server.biometrics.sensors.BiometricScheduler.sensorTypeToString; + import android.annotation.NonNull; +import android.util.Slog; + +import java.util.HashMap; +import java.util.Map; /** * Singleton that contains the core logic for determining if haptics and authentication callbacks @@ -27,6 +33,7 @@ import android.annotation.NonNull; public class CoexCoordinator { private static final String TAG = "BiometricCoexCoordinator"; + private static final boolean DEBUG = true; /** * Callback interface notifying the owner of "results" from the CoexCoordinator's business @@ -47,10 +54,6 @@ public class CoexCoordinator { private static CoexCoordinator sInstance; - private CoexCoordinator() { - // Singleton - } - @NonNull static CoexCoordinator getInstance() { if (sInstance == null) { @@ -59,6 +62,43 @@ public class CoexCoordinator { return sInstance; } + // SensorType to AuthenticationClient map + private final Map<Integer, AuthenticationClient<?>> mClientMap; + + private CoexCoordinator() { + // Singleton + mClientMap = new HashMap<>(); + } + + public void addAuthenticationClient(@BiometricScheduler.SensorType int sensorType, + @NonNull AuthenticationClient<?> client) { + if (DEBUG) { + Slog.d(TAG, "addAuthenticationClient(" + sensorTypeToString(sensorType) + ")" + + ", client: " + client); + } + + if (mClientMap.containsKey(sensorType)) { + Slog.w(TAG, "Overwriting existing client: " + mClientMap.get(sensorType) + + " with new client: " + client); + } + + mClientMap.put(sensorType, client); + } + + public void removeAuthenticationClient(@BiometricScheduler.SensorType int sensorType, + @NonNull AuthenticationClient<?> client) { + if (DEBUG) { + Slog.d(TAG, "removeAuthenticationClient(" + sensorTypeToString(sensorType) + ")" + + ", client: " + client); + } + + if (!mClientMap.containsKey(sensorType)) { + Slog.e(TAG, "sensorType: " + sensorType + " does not exist in map. Client: " + client); + return; + } + mClientMap.remove(sensorType); + } + public void onAuthenticationSucceeded(@NonNull AuthenticationClient<?> client, @NonNull Callback callback) { if (client.isBiometricPrompt()) { diff --git a/services/core/java/com/android/server/biometrics/sensors/UserAwareBiometricScheduler.java b/services/core/java/com/android/server/biometrics/sensors/UserAwareBiometricScheduler.java index e6e293eb9b4c..b056bf897b5c 100644 --- a/services/core/java/com/android/server/biometrics/sensors/UserAwareBiometricScheduler.java +++ b/services/core/java/com/android/server/biometrics/sensors/UserAwareBiometricScheduler.java @@ -83,24 +83,26 @@ public class UserAwareBiometricScheduler extends BiometricScheduler { } @VisibleForTesting - UserAwareBiometricScheduler(@NonNull String tag, + UserAwareBiometricScheduler(@NonNull String tag, @SensorType int sensorType, @Nullable GestureAvailabilityDispatcher gestureAvailabilityDispatcher, @NonNull IBiometricService biometricService, @NonNull CurrentUserRetriever currentUserRetriever, - @NonNull UserSwitchCallback userSwitchCallback) { - super(tag, gestureAvailabilityDispatcher, biometricService, LOG_NUM_RECENT_OPERATIONS); + @NonNull UserSwitchCallback userSwitchCallback, + @NonNull CoexCoordinator coexCoordinator) { + super(tag, sensorType, gestureAvailabilityDispatcher, biometricService, + LOG_NUM_RECENT_OPERATIONS, coexCoordinator); mCurrentUserRetriever = currentUserRetriever; mUserSwitchCallback = userSwitchCallback; } - public UserAwareBiometricScheduler(@NonNull String tag, + public UserAwareBiometricScheduler(@NonNull String tag, @SensorType int sensorType, @Nullable GestureAvailabilityDispatcher gestureAvailabilityDispatcher, @NonNull CurrentUserRetriever currentUserRetriever, @NonNull UserSwitchCallback userSwitchCallback) { - this(tag, gestureAvailabilityDispatcher, IBiometricService.Stub.asInterface( + this(tag, sensorType, gestureAvailabilityDispatcher, IBiometricService.Stub.asInterface( ServiceManager.getService(Context.BIOMETRIC_SERVICE)), currentUserRetriever, - userSwitchCallback); + userSwitchCallback, CoexCoordinator.getInstance()); } @Override diff --git a/services/core/java/com/android/server/biometrics/sensors/face/aidl/Sensor.java b/services/core/java/com/android/server/biometrics/sensors/face/aidl/Sensor.java index 2f71f44b6bef..4abd402a4da8 100644 --- a/services/core/java/com/android/server/biometrics/sensors/face/aidl/Sensor.java +++ b/services/core/java/com/android/server/biometrics/sensors/face/aidl/Sensor.java @@ -494,7 +494,8 @@ public class Sensor { mToken = new Binder(); mHandler = handler; mSensorProperties = sensorProperties; - mScheduler = new UserAwareBiometricScheduler(tag, null /* gestureAvailabilityDispatcher */, + mScheduler = new UserAwareBiometricScheduler(tag, BiometricScheduler.SENSOR_TYPE_FACE, + null /* gestureAvailabilityDispatcher */, () -> mCurrentSession != null ? mCurrentSession.mUserId : UserHandle.USER_NULL, new UserAwareBiometricScheduler.UserSwitchCallback() { @NonNull diff --git a/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java b/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java index 26c5bca7f726..e95273ae6a41 100644 --- a/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java +++ b/services/core/java/com/android/server/biometrics/sensors/face/hidl/Face10.java @@ -355,7 +355,8 @@ public class Face10 implements IHwBinder.DeathRecipient, ServiceProvider { public Face10(@NonNull Context context, @NonNull FaceSensorPropertiesInternal sensorProps, @NonNull LockoutResetDispatcher lockoutResetDispatcher) { this(context, sensorProps, lockoutResetDispatcher, - new BiometricScheduler(TAG, null /* gestureAvailabilityTracker */)); + new BiometricScheduler(TAG, BiometricScheduler.SENSOR_TYPE_FACE, + null /* gestureAvailabilityTracker */)); } @Override 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 b3b818fd6d3d..59e4b582ca84 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 @@ -449,7 +449,9 @@ class Sensor { mHandler = handler; mSensorProperties = sensorProperties; mLockoutCache = new LockoutCache(); - mScheduler = new UserAwareBiometricScheduler(tag, gestureAvailabilityDispatcher, + mScheduler = new UserAwareBiometricScheduler(tag, + BiometricScheduler.sensorTypeFromFingerprintProperties(mSensorProperties), + gestureAvailabilityDispatcher, () -> mCurrentSession != null ? mCurrentSession.mUserId : UserHandle.USER_NULL, new UserAwareBiometricScheduler.UserSwitchCallback() { @NonNull diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java index 7daea88f0f22..a6385a541b03 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21.java @@ -352,7 +352,9 @@ public class Fingerprint21 implements IHwBinder.DeathRecipient, ServiceProvider @NonNull GestureAvailabilityDispatcher gestureAvailabilityDispatcher) { final Handler handler = new Handler(Looper.getMainLooper()); final BiometricScheduler scheduler = - new BiometricScheduler(TAG, gestureAvailabilityDispatcher); + new BiometricScheduler(TAG, + BiometricScheduler.sensorTypeFromFingerprintProperties(sensorProps), + gestureAvailabilityDispatcher); final HalResultController controller = new HalResultController(sensorProps.sensorId, context, handler, scheduler); diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21UdfpsMock.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21UdfpsMock.java index d1020a6ff068..312c52c4a844 100644 --- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21UdfpsMock.java +++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/hidl/Fingerprint21UdfpsMock.java @@ -138,7 +138,7 @@ public class Fingerprint21UdfpsMock extends Fingerprint21 implements TrustManage TestableBiometricScheduler(@NonNull String tag, @Nullable GestureAvailabilityDispatcher gestureAvailabilityDispatcher) { - super(tag, gestureAvailabilityDispatcher); + super(tag, BiometricScheduler.SENSOR_TYPE_FP_OTHER, gestureAvailabilityDispatcher); mInternalCallback = new TestableInternalCallback(); } diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerTest.java index 109fb22520c8..a8bf0c751e87 100644 --- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerTest.java +++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/BiometricSchedulerTest.java @@ -75,8 +75,9 @@ public class BiometricSchedulerTest { public void setUp() { MockitoAnnotations.initMocks(this); mToken = new Binder(); - mScheduler = new BiometricScheduler(TAG, null /* gestureAvailabilityTracker */, - mBiometricService, LOG_NUM_RECENT_OPERATIONS); + mScheduler = new BiometricScheduler(TAG, BiometricScheduler.SENSOR_TYPE_UNKNOWN, + null /* gestureAvailabilityTracker */, mBiometricService, LOG_NUM_RECENT_OPERATIONS, + CoexCoordinator.getInstance()); } @Test diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/UserAwareBiometricSchedulerTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/UserAwareBiometricSchedulerTest.java index 3a9e629b6ed6..7fccd49db04b 100644 --- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/UserAwareBiometricSchedulerTest.java +++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/UserAwareBiometricSchedulerTest.java @@ -74,6 +74,7 @@ public class UserAwareBiometricSchedulerTest { mUserStoppedCallback = new TestUserStoppedCallback(); mScheduler = new UserAwareBiometricScheduler(TAG, + BiometricScheduler.SENSOR_TYPE_UNKNOWN, null /* gestureAvailabilityDispatcher */, mBiometricService, () -> mCurrentUserId, @@ -92,7 +93,8 @@ public class UserAwareBiometricSchedulerTest { return new TestStartUserClient(mContext, Object::new, mToken, newUserId, TEST_SENSOR_ID, mUserStartedCallback, mStartOperationsFinish); } - }); + }, + CoexCoordinator.getInstance()); } @Test diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/SensorTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/SensorTest.java index b8fbe34a7dcb..a13dff21439d 100644 --- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/SensorTest.java +++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/SensorTest.java @@ -32,6 +32,7 @@ import android.platform.test.annotations.Presubmit; import androidx.test.filters.SmallTest; +import com.android.server.biometrics.sensors.BiometricScheduler; import com.android.server.biometrics.sensors.LockoutCache; import com.android.server.biometrics.sensors.LockoutResetDispatcher; import com.android.server.biometrics.sensors.LockoutTracker; @@ -78,6 +79,7 @@ public class SensorTest { when(mContext.getSystemService(Context.BIOMETRIC_SERVICE)).thenReturn(mBiometricService); mScheduler = new UserAwareBiometricScheduler(TAG, + BiometricScheduler.SENSOR_TYPE_FACE, null /* gestureAvailabilityDispatcher */, () -> USER_ID, mUserSwitchCallback); diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/SensorTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/SensorTest.java index 5dfc24889815..0d520ca9a4e4 100644 --- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/SensorTest.java +++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/fingerprint/aidl/SensorTest.java @@ -32,6 +32,7 @@ import android.platform.test.annotations.Presubmit; import androidx.test.filters.SmallTest; +import com.android.server.biometrics.sensors.BiometricScheduler; import com.android.server.biometrics.sensors.LockoutCache; import com.android.server.biometrics.sensors.LockoutResetDispatcher; import com.android.server.biometrics.sensors.LockoutTracker; @@ -78,6 +79,7 @@ public class SensorTest { when(mContext.getSystemService(Context.BIOMETRIC_SERVICE)).thenReturn(mBiometricService); mScheduler = new UserAwareBiometricScheduler(TAG, + BiometricScheduler.SENSOR_TYPE_FP_OTHER, null /* gestureAvailabilityDispatcher */, () -> USER_ID, mUserSwitchCallback); |